From fc4f89eecb87ceffa55b3b4ddf5b9ec3ae862d9d Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 20:27:04 -0300 Subject: [PATCH 001/105] chore: setup inicial do projeto --- app/.gitignore | 1 + app/nodemon.json | 5 + app/package-lock.json | 1573 +++++++++++++++++++++++++++++++++++++++++ app/package.json | 17 + app/tsconfig.json | 16 + 5 files changed, 1612 insertions(+) create mode 100644 app/.gitignore create mode 100644 app/nodemon.json create mode 100644 app/package-lock.json create mode 100644 app/package.json create mode 100644 app/tsconfig.json diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 00000000..b512c09d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/app/nodemon.json b/app/nodemon.json new file mode 100644 index 00000000..db198016 --- /dev/null +++ b/app/nodemon.json @@ -0,0 +1,5 @@ +{ + "execMap": { + "ts": "ts-node" + } +} \ No newline at end of file diff --git a/app/package-lock.json b/app/package-lock.json new file mode 100644 index 00000000..88ec69f0 --- /dev/null +++ b/app/package-lock.json @@ -0,0 +1,1573 @@ +{ + "name": "app", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "app", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "ts-node": "^10.9.1", + "typescript": "^4.8.4", + "vitest": "^0.24.3" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.11.tgz", + "integrity": "sha512-PzMcQLazLBkwDEkrNPi9AbjFt6+3I7HKbiYF2XtWQ7wItrHvEOeO3T8Am434zAozWtVP7lrTue1bEfc2nYWeCA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.11.tgz", + "integrity": "sha512-geWp637tUhNmhL3Xgy4Bj703yXB9dqiLJe05lCUfjSFDrQf9C/8pArusyPUbUbPwlC/EAUjBw32sxuIl/11dZw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", + "dev": true + }, + "node_modules/@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/node": { + "version": "18.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", + "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/esbuild": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.11.tgz", + "integrity": "sha512-OgHGuhlfZ//mToxjte1D5iiiQgWfJ2GByVMwEC/IuoXsBGkuyK1+KrjYu0laSpnN/L1UmLUCv0s25vObdc1bVg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.15.11", + "@esbuild/linux-loong64": "0.15.11", + "esbuild-android-64": "0.15.11", + "esbuild-android-arm64": "0.15.11", + "esbuild-darwin-64": "0.15.11", + "esbuild-darwin-arm64": "0.15.11", + "esbuild-freebsd-64": "0.15.11", + "esbuild-freebsd-arm64": "0.15.11", + "esbuild-linux-32": "0.15.11", + "esbuild-linux-64": "0.15.11", + "esbuild-linux-arm": "0.15.11", + "esbuild-linux-arm64": "0.15.11", + "esbuild-linux-mips64le": "0.15.11", + "esbuild-linux-ppc64le": "0.15.11", + "esbuild-linux-riscv64": "0.15.11", + "esbuild-linux-s390x": "0.15.11", + "esbuild-netbsd-64": "0.15.11", + "esbuild-openbsd-64": "0.15.11", + "esbuild-sunos-64": "0.15.11", + "esbuild-windows-32": "0.15.11", + "esbuild-windows-64": "0.15.11", + "esbuild-windows-arm64": "0.15.11" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.11.tgz", + "integrity": "sha512-rrwoXEiuI1kaw4k475NJpexs8GfJqQUKcD08VR8sKHmuW9RUuTR2VxcupVvHdiGh9ihxL9m3lpqB1kju92Ialw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.11.tgz", + "integrity": "sha512-/hDubOg7BHOhUUsT8KUIU7GfZm5bihqssvqK5PfO4apag7YuObZRZSzViyEKcFn2tPeHx7RKbSBXvAopSHDZJQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.11.tgz", + "integrity": "sha512-1DqHD0ms3AhiwkKnjRUzmiW7JnaJJr5FKrPiR7xuyMwnjDqvNWDdMq4rKSD9OC0piFNK6n0LghsglNMe2MwJtA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.11.tgz", + "integrity": "sha512-OMzhxSbS0lwwrW40HHjRCeVIJTURdXFA8c3GU30MlHKuPCcvWNUIKVucVBtNpJySXmbkQMDJdJNrXzNDyvoqvQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.11.tgz", + "integrity": "sha512-8dKP26r0/Qyez8nTCwpq60QbuYKOeBygdgOAWGCRalunyeqWRoSZj9TQjPDnTTI9joxd3QYw3UhVZTKxO9QdRg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.11.tgz", + "integrity": "sha512-aSGiODiukLGGnSg/O9+cGO2QxEacrdCtCawehkWYTt5VX1ni2b9KoxpHCT9h9Y6wGqNHmXFnB47RRJ8BIqZgmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.11.tgz", + "integrity": "sha512-lsrAfdyJBGx+6aHIQmgqUonEzKYeBnyfJPkT6N2dOf1RoXYYV1BkWB6G02tjsrz1d5wZzaTc3cF+TKmuTo/ZwA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.11.tgz", + "integrity": "sha512-Y2Rh+PcyVhQqXKBTacPCltINN3uIw2xC+dsvLANJ1SpK5NJUtxv8+rqWpjmBgaNWKQT1/uGpMmA9olALy9PLVA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.11.tgz", + "integrity": "sha512-TJllTVk5aSyqPFvvcHTvf6Wu1ZKhWpJ/qNmZO8LL/XeB+LXCclm7HQHNEIz6MT7IX8PmlC1BZYrOiw2sXSB95A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.11.tgz", + "integrity": "sha512-uhcXiTwTmD4OpxJu3xC5TzAAw6Wzf9O1XGWL448EE9bqGjgV1j+oK3lIHAfsHnuIn8K4nDW8yjX0Sv5S++oRuw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.11.tgz", + "integrity": "sha512-WD61y/R1M4BLe4gxXRypoQ0Ci+Vjf714QYzcPNkiYv5I8K8WDz2ZR8Bm6cqKxd6rD+e/rZgPDbhQ9PCf7TMHmA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.11.tgz", + "integrity": "sha512-JVleZS9oPVLTlBhPTWgOwxFWU/wMUdlBwTbGA4GF8c38sLbS13cupj+C8bLq929jU7EMWry4SaL+tKGIaTlqKg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.11.tgz", + "integrity": "sha512-9aLIalZ2HFHIOZpmVU11sEAS9F8TnHw49daEjcgMpBXHFF57VuT9f9/9LKJhw781Gda0P9jDkuCWJ0tFbErvJw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.11.tgz", + "integrity": "sha512-sZHtiXXOKsLI3XGBGoYO4qKBzJlb8xNsWmvFiwFMHFzA4AXgDP1KDp7Dawe9C2pavTRBDvl+Ok4n/DHQ59oaTg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.11.tgz", + "integrity": "sha512-hUC9yN06K9sg7ju4Vgu9ChAPdsEgtcrcLfyNT5IKwKyfpLvKUwCMZSdF+gRD3WpyZelgTQfJ+pDx5XFbXTlB0A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.11.tgz", + "integrity": "sha512-0bBo9SQR4t66Wd91LGMAqmWorzO0TTzVjYiifwoFtel8luFeXuPThQnEm5ztN4g0fnvcp7AnUPPzS/Depf17wQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.11.tgz", + "integrity": "sha512-EuBdTGlsMTjEl1sQnBX2jfygy7iR6CKfvOzi+gEOfhDqbHXsmY1dcpbVtcwHAg9/2yUZSfMJHMAgf1z8M4yyyw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.11.tgz", + "integrity": "sha512-O0/Wo1Wk6dc0rZSxkvGpmTNIycEznHmkObTFz2VHBhjPsO4ZpCgfGxNkCpz4AdAIeMczpTXt/8d5vdJNKEGC+Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.11.tgz", + "integrity": "sha512-x977Q4HhNjnHx00b4XLAnTtj5vfbdEvkxaQwC1Zh5AN8g5EX+izgZ6e5QgqJgpzyRNJqh4hkgIJF1pyy1be0mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.11.tgz", + "integrity": "sha512-VwUHFACuBahrvntdcMKZteUZ9HaYrBRODoKe4tIWxguQRvvYoYb7iu5LrcRS/FQx8KPZNaa72zuqwVtHeXsITw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/local-pkg": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", + "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "2.78.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", + "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-literal": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz", + "integrity": "sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tinybench": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.0.tgz", + "integrity": "sha512-zs1gMVBwyyG2QbVchYIbnabRhMOCGvrwZz/q+SV+LIMa9q5YDQZi2kkI6ZRqV2Bz7ba1uvrc7ieUoE4KWnGeKg==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz", + "integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.0.2.tgz", + "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/vite": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.8.tgz", + "integrity": "sha512-m7jJe3nufUbuOfotkntGFupinL/fmuTNuQmiVE7cH2IZMuf4UbfbGYMUT3jVWgGYuRVLY9j8NnrRqgw5rr5QTg==", + "dev": true, + "dependencies": { + "esbuild": "^0.15.9", + "postcss": "^8.4.16", + "resolve": "^1.22.1", + "rollup": "~2.78.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "less": "*", + "sass": "*", + "stylus": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "0.24.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.24.3.tgz", + "integrity": "sha512-aM0auuPPgMSstWvr851hB74g/LKaKBzSxcG3da7ejfZbx08Y21JpZmbmDYrMTCGhVZKqTGwzcnLMwyfz2WzkhQ==", + "dev": true, + "dependencies": { + "@types/chai": "^4.3.3", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "chai": "^4.3.6", + "debug": "^4.3.4", + "local-pkg": "^0.4.2", + "strip-literal": "^0.4.2", + "tinybench": "^2.3.0", + "tinypool": "^0.3.0", + "tinyspy": "^1.0.2", + "vite": "^3.0.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": ">=v14.16.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/browser": "*", + "@vitest/ui": "*", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@esbuild/android-arm": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.11.tgz", + "integrity": "sha512-PzMcQLazLBkwDEkrNPi9AbjFt6+3I7HKbiYF2XtWQ7wItrHvEOeO3T8Am434zAozWtVP7lrTue1bEfc2nYWeCA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.11.tgz", + "integrity": "sha512-geWp637tUhNmhL3Xgy4Bj703yXB9dqiLJe05lCUfjSFDrQf9C/8pArusyPUbUbPwlC/EAUjBw32sxuIl/11dZw==", + "dev": true, + "optional": true + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", + "dev": true + }, + "@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, + "@types/node": { + "version": "18.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", + "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==", + "dev": true + }, + "acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "esbuild": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.11.tgz", + "integrity": "sha512-OgHGuhlfZ//mToxjte1D5iiiQgWfJ2GByVMwEC/IuoXsBGkuyK1+KrjYu0laSpnN/L1UmLUCv0s25vObdc1bVg==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.15.11", + "@esbuild/linux-loong64": "0.15.11", + "esbuild-android-64": "0.15.11", + "esbuild-android-arm64": "0.15.11", + "esbuild-darwin-64": "0.15.11", + "esbuild-darwin-arm64": "0.15.11", + "esbuild-freebsd-64": "0.15.11", + "esbuild-freebsd-arm64": "0.15.11", + "esbuild-linux-32": "0.15.11", + "esbuild-linux-64": "0.15.11", + "esbuild-linux-arm": "0.15.11", + "esbuild-linux-arm64": "0.15.11", + "esbuild-linux-mips64le": "0.15.11", + "esbuild-linux-ppc64le": "0.15.11", + "esbuild-linux-riscv64": "0.15.11", + "esbuild-linux-s390x": "0.15.11", + "esbuild-netbsd-64": "0.15.11", + "esbuild-openbsd-64": "0.15.11", + "esbuild-sunos-64": "0.15.11", + "esbuild-windows-32": "0.15.11", + "esbuild-windows-64": "0.15.11", + "esbuild-windows-arm64": "0.15.11" + } + }, + "esbuild-android-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.11.tgz", + "integrity": "sha512-rrwoXEiuI1kaw4k475NJpexs8GfJqQUKcD08VR8sKHmuW9RUuTR2VxcupVvHdiGh9ihxL9m3lpqB1kju92Ialw==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.11.tgz", + "integrity": "sha512-/hDubOg7BHOhUUsT8KUIU7GfZm5bihqssvqK5PfO4apag7YuObZRZSzViyEKcFn2tPeHx7RKbSBXvAopSHDZJQ==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.11.tgz", + "integrity": "sha512-1DqHD0ms3AhiwkKnjRUzmiW7JnaJJr5FKrPiR7xuyMwnjDqvNWDdMq4rKSD9OC0piFNK6n0LghsglNMe2MwJtA==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.11.tgz", + "integrity": "sha512-OMzhxSbS0lwwrW40HHjRCeVIJTURdXFA8c3GU30MlHKuPCcvWNUIKVucVBtNpJySXmbkQMDJdJNrXzNDyvoqvQ==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.11.tgz", + "integrity": "sha512-8dKP26r0/Qyez8nTCwpq60QbuYKOeBygdgOAWGCRalunyeqWRoSZj9TQjPDnTTI9joxd3QYw3UhVZTKxO9QdRg==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.11.tgz", + "integrity": "sha512-aSGiODiukLGGnSg/O9+cGO2QxEacrdCtCawehkWYTt5VX1ni2b9KoxpHCT9h9Y6wGqNHmXFnB47RRJ8BIqZgmQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.11.tgz", + "integrity": "sha512-lsrAfdyJBGx+6aHIQmgqUonEzKYeBnyfJPkT6N2dOf1RoXYYV1BkWB6G02tjsrz1d5wZzaTc3cF+TKmuTo/ZwA==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.11.tgz", + "integrity": "sha512-Y2Rh+PcyVhQqXKBTacPCltINN3uIw2xC+dsvLANJ1SpK5NJUtxv8+rqWpjmBgaNWKQT1/uGpMmA9olALy9PLVA==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.11.tgz", + "integrity": "sha512-TJllTVk5aSyqPFvvcHTvf6Wu1ZKhWpJ/qNmZO8LL/XeB+LXCclm7HQHNEIz6MT7IX8PmlC1BZYrOiw2sXSB95A==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.11.tgz", + "integrity": "sha512-uhcXiTwTmD4OpxJu3xC5TzAAw6Wzf9O1XGWL448EE9bqGjgV1j+oK3lIHAfsHnuIn8K4nDW8yjX0Sv5S++oRuw==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.11.tgz", + "integrity": "sha512-WD61y/R1M4BLe4gxXRypoQ0Ci+Vjf714QYzcPNkiYv5I8K8WDz2ZR8Bm6cqKxd6rD+e/rZgPDbhQ9PCf7TMHmA==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.11.tgz", + "integrity": "sha512-JVleZS9oPVLTlBhPTWgOwxFWU/wMUdlBwTbGA4GF8c38sLbS13cupj+C8bLq929jU7EMWry4SaL+tKGIaTlqKg==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.11.tgz", + "integrity": "sha512-9aLIalZ2HFHIOZpmVU11sEAS9F8TnHw49daEjcgMpBXHFF57VuT9f9/9LKJhw781Gda0P9jDkuCWJ0tFbErvJw==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.11.tgz", + "integrity": "sha512-sZHtiXXOKsLI3XGBGoYO4qKBzJlb8xNsWmvFiwFMHFzA4AXgDP1KDp7Dawe9C2pavTRBDvl+Ok4n/DHQ59oaTg==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.11.tgz", + "integrity": "sha512-hUC9yN06K9sg7ju4Vgu9ChAPdsEgtcrcLfyNT5IKwKyfpLvKUwCMZSdF+gRD3WpyZelgTQfJ+pDx5XFbXTlB0A==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.11.tgz", + "integrity": "sha512-0bBo9SQR4t66Wd91LGMAqmWorzO0TTzVjYiifwoFtel8luFeXuPThQnEm5ztN4g0fnvcp7AnUPPzS/Depf17wQ==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.11.tgz", + "integrity": "sha512-EuBdTGlsMTjEl1sQnBX2jfygy7iR6CKfvOzi+gEOfhDqbHXsmY1dcpbVtcwHAg9/2yUZSfMJHMAgf1z8M4yyyw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.11.tgz", + "integrity": "sha512-O0/Wo1Wk6dc0rZSxkvGpmTNIycEznHmkObTFz2VHBhjPsO4ZpCgfGxNkCpz4AdAIeMczpTXt/8d5vdJNKEGC+Q==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.11.tgz", + "integrity": "sha512-x977Q4HhNjnHx00b4XLAnTtj5vfbdEvkxaQwC1Zh5AN8g5EX+izgZ6e5QgqJgpzyRNJqh4hkgIJF1pyy1be0mQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.11.tgz", + "integrity": "sha512-VwUHFACuBahrvntdcMKZteUZ9HaYrBRODoKe4tIWxguQRvvYoYb7iu5LrcRS/FQx8KPZNaa72zuqwVtHeXsITw==", + "dev": true, + "optional": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "local-pkg": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", + "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", + "dev": true + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "postcss": { + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "2.78.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", + "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "strip-literal": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz", + "integrity": "sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==", + "dev": true, + "requires": { + "acorn": "^8.8.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tinybench": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.0.tgz", + "integrity": "sha512-zs1gMVBwyyG2QbVchYIbnabRhMOCGvrwZz/q+SV+LIMa9q5YDQZi2kkI6ZRqV2Bz7ba1uvrc7ieUoE4KWnGeKg==", + "dev": true + }, + "tinypool": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz", + "integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==", + "dev": true + }, + "tinyspy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.0.2.tgz", + "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", + "dev": true + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "vite": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.8.tgz", + "integrity": "sha512-m7jJe3nufUbuOfotkntGFupinL/fmuTNuQmiVE7cH2IZMuf4UbfbGYMUT3jVWgGYuRVLY9j8NnrRqgw5rr5QTg==", + "dev": true, + "requires": { + "esbuild": "^0.15.9", + "fsevents": "~2.3.2", + "postcss": "^8.4.16", + "resolve": "^1.22.1", + "rollup": "~2.78.0" + } + }, + "vitest": { + "version": "0.24.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.24.3.tgz", + "integrity": "sha512-aM0auuPPgMSstWvr851hB74g/LKaKBzSxcG3da7ejfZbx08Y21JpZmbmDYrMTCGhVZKqTGwzcnLMwyfz2WzkhQ==", + "dev": true, + "requires": { + "@types/chai": "^4.3.3", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "chai": "^4.3.6", + "debug": "^4.3.4", + "local-pkg": "^0.4.2", + "strip-literal": "^0.4.2", + "tinybench": "^2.3.0", + "tinypool": "^0.3.0", + "tinyspy": "^1.0.2", + "vite": "^3.0.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/app/package.json b/app/package.json new file mode 100644 index 00000000..9bcaddd9 --- /dev/null +++ b/app/package.json @@ -0,0 +1,17 @@ +{ + "name": "app", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "ts-node": "^10.9.1", + "typescript": "^4.8.4", + "vitest": "^0.24.3" + } +} diff --git a/app/tsconfig.json b/app/tsconfig.json new file mode 100644 index 00000000..59575f39 --- /dev/null +++ b/app/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "outDir": "dist", + "module": "commonjs", + "target": "ES2021", + "esModuleInterop": true, + "strictNullChecks": false, + "sourceMap": true, + "rootDir": "src", + "baseUrl": "src", + "paths": { + "@/*": ["*"] + } + }, + "include": ["src"] +} From 60b8bfa134f53af9c3a00a221e165b9ed0b47167 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 20:27:17 -0300 Subject: [PATCH 002/105] =?UTF-8?q?chore:=20cria=20arquivo=20de=20configur?= =?UTF-8?q?a=C3=A7=C3=A3o=20do=20vitest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/vitest.config.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/vitest.config.ts diff --git a/app/vitest.config.ts b/app/vitest.config.ts new file mode 100644 index 00000000..428b64ee --- /dev/null +++ b/app/vitest.config.ts @@ -0,0 +1,5 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: {} +}) From 84c89e410a4d769a926447e4ddb2b0976f5c185a Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 22:25:41 -0300 Subject: [PATCH 003/105] =?UTF-8?q?chore:=20adiciona=20vers=C3=A3o=20do=20?= =?UTF-8?q?node=20dentro=20do=20engine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/package.json b/app/package.json index 9bcaddd9..abeadc73 100644 --- a/app/package.json +++ b/app/package.json @@ -13,5 +13,8 @@ "ts-node": "^10.9.1", "typescript": "^4.8.4", "vitest": "^0.24.3" + }, + "engines": { + "node": ">=16.0.0" } } From 0a0d5e0276c592edc4bfb619670cf01b0c4d09b4 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 22:25:55 -0300 Subject: [PATCH 004/105] feat: cria model User --- app/src/domain/models/index.ts | 1 + app/src/domain/models/user.ts | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 app/src/domain/models/index.ts create mode 100644 app/src/domain/models/user.ts diff --git a/app/src/domain/models/index.ts b/app/src/domain/models/index.ts new file mode 100644 index 00000000..042420c4 --- /dev/null +++ b/app/src/domain/models/index.ts @@ -0,0 +1 @@ +export * from './user' \ No newline at end of file diff --git a/app/src/domain/models/user.ts b/app/src/domain/models/user.ts new file mode 100644 index 00000000..747832eb --- /dev/null +++ b/app/src/domain/models/user.ts @@ -0,0 +1,10 @@ +export type User = { + id: number; + name: string; + email: string; + brithDay: string; + role: string; + password: string; + createdAt: string; + updatedAt: string; +} \ No newline at end of file From c328115597f2ec96c306823e6aa9b9075b6301a8 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 22:26:20 -0300 Subject: [PATCH 005/105] feat: cria casos de usos do User --- app/src/domain/usecases/users/add-user.ts | 14 +++++++++ app/src/domain/usecases/users/delete-user.ts | 3 ++ app/src/domain/usecases/users/index.ts | 3 ++ app/src/domain/usecases/users/load-users.ts | 32 ++++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 app/src/domain/usecases/users/add-user.ts create mode 100644 app/src/domain/usecases/users/delete-user.ts create mode 100644 app/src/domain/usecases/users/index.ts create mode 100644 app/src/domain/usecases/users/load-users.ts diff --git a/app/src/domain/usecases/users/add-user.ts b/app/src/domain/usecases/users/add-user.ts new file mode 100644 index 00000000..78f01992 --- /dev/null +++ b/app/src/domain/usecases/users/add-user.ts @@ -0,0 +1,14 @@ +import { User } from '../../models'; + +export interface AddUser { + add: (params: AddUser.Params) => Promise +} + +/** + * Namespace to hold all types used by AddUser use case. + * Here we declare all types used by AddUser use case, like the params and the result. + */ +export namespace AddUser { + export type Params = Omit; + export type Result = User; +} \ No newline at end of file diff --git a/app/src/domain/usecases/users/delete-user.ts b/app/src/domain/usecases/users/delete-user.ts new file mode 100644 index 00000000..c66048d8 --- /dev/null +++ b/app/src/domain/usecases/users/delete-user.ts @@ -0,0 +1,3 @@ +export interface DeleteUser { + delete (userId: string): Promise +} diff --git a/app/src/domain/usecases/users/index.ts b/app/src/domain/usecases/users/index.ts new file mode 100644 index 00000000..fab0ce8b --- /dev/null +++ b/app/src/domain/usecases/users/index.ts @@ -0,0 +1,3 @@ +export * from './add-user' +export * from './load-users' +export * from './delete-user' \ No newline at end of file diff --git a/app/src/domain/usecases/users/load-users.ts b/app/src/domain/usecases/users/load-users.ts new file mode 100644 index 00000000..2df15f64 --- /dev/null +++ b/app/src/domain/usecases/users/load-users.ts @@ -0,0 +1,32 @@ +import { User } from '../../models'; + +enum UserOrders { + asc = 'asc', + desc = 'desc' +} + +export interface LoadUsers { + /** + * Load all users from database. + */ + load (params: LoadUsers.Params): Promise + /** + * This method is an overload, it's used to load a single user by id. + */ + load (params: LoadUsers.ParamsById): Promise +} + +/** + * Namespace to hold all types used by LoadUsers use case. + * Here we declare all types used by LoadUsers use case, like the params and the result. + */ +export namespace LoadUsers { + export type Params = { + order?: UserOrders; + }; + + export type ParamsById = { + id: number; + }; + export type Result = User; +} \ No newline at end of file From 68cc54351e27c8da644d22b844a15ca3c0f2eefa Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 22:26:51 -0300 Subject: [PATCH 006/105] feat: cria protocolos para a camada de presentation --- app/src/presentation/protocols/controller.ts | 5 +++++ app/src/presentation/protocols/http.ts | 4 ++++ app/src/presentation/protocols/index.ts | 2 ++ 3 files changed, 11 insertions(+) create mode 100644 app/src/presentation/protocols/controller.ts create mode 100644 app/src/presentation/protocols/http.ts create mode 100644 app/src/presentation/protocols/index.ts diff --git a/app/src/presentation/protocols/controller.ts b/app/src/presentation/protocols/controller.ts new file mode 100644 index 00000000..832f1c00 --- /dev/null +++ b/app/src/presentation/protocols/controller.ts @@ -0,0 +1,5 @@ +import { HttpResponse } from './http' + +export interface Controller { + handle: (request: T) => Promise +} diff --git a/app/src/presentation/protocols/http.ts b/app/src/presentation/protocols/http.ts new file mode 100644 index 00000000..e4d3f300 --- /dev/null +++ b/app/src/presentation/protocols/http.ts @@ -0,0 +1,4 @@ +export type HttpResponse = { + body: T + statusCode: number +} diff --git a/app/src/presentation/protocols/index.ts b/app/src/presentation/protocols/index.ts new file mode 100644 index 00000000..d7d26e21 --- /dev/null +++ b/app/src/presentation/protocols/index.ts @@ -0,0 +1,2 @@ +export * from './controller' +export * from './http' \ No newline at end of file From a1c1cb2f52d88f39720ee40731154542cc83989e Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 22:57:06 -0300 Subject: [PATCH 007/105] chore: configura Vitest para entender os paths do TypesCript --- app/package-lock.json | 221 +++++++++++++++++++++++++++++++++++++++++- app/package.json | 6 +- app/vitest.config.ts | 4 +- 3 files changed, 227 insertions(+), 4 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index 88ec69f0..e9988829 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,9 +9,14 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { + "@faker-js/faker": "^7.6.0", "ts-node": "^10.9.1", "typescript": "^4.8.4", - "vitest": "^0.24.3" + "vitest": "^0.24.3", + "vitest-tsconfig-paths": "^3.4.1" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@cspotcode/source-map-support": { @@ -26,6 +31,12 @@ "node": ">=12" } }, + "node_modules/@cush/relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cush/relative/-/relative-1.0.0.tgz", + "integrity": "sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==", + "dev": true + }, "node_modules/@esbuild/android-arm": { "version": "0.15.11", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.11.tgz", @@ -58,6 +69,16 @@ "node": ">=12" } }, + "node_modules/@faker-js/faker": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz", + "integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==", + "dev": true, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", @@ -122,6 +143,12 @@ "@types/chai": "*" } }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/node": { "version": "18.11.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", @@ -621,6 +648,18 @@ "node": "*" } }, + "node_modules/glob-regex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/glob-regex/-/glob-regex-0.3.2.tgz", + "integrity": "sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==", + "dev": true + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -645,6 +684,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/local-pkg": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", @@ -672,6 +723,15 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -735,6 +795,18 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/recrawl-sync": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", + "integrity": "sha512-E2sI4F25Fu2nrfV+KsnC7/qfk/spQIYXlonfQoS4rwxeNK5BjxnLPbWiRXHVXPwYBOTWtPX5765kTm/zJiL+LQ==", + "dev": true, + "dependencies": { + "@cush/relative": "^1.0.0", + "glob-regex": "^0.3.0", + "slash": "^3.0.0", + "tslib": "^1.9.3" + } + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -767,6 +839,15 @@ "fsevents": "~2.3.2" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -776,6 +857,15 @@ "node": ">=0.10.0" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-literal": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz", @@ -867,6 +957,24 @@ } } }, + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -988,6 +1096,18 @@ } } }, + "node_modules/vitest-tsconfig-paths": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/vitest-tsconfig-paths/-/vitest-tsconfig-paths-3.4.1.tgz", + "integrity": "sha512-CnRpA/jcqgZfnkk0yvwFW92UmIpf03wX/wLiQBNWAcOG7nv6Sdz3GsPESAMEqbVy8kHBoWB3XeNamu6PUrFZLA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "recrawl-sync": "^2.0.3", + "tsconfig-paths": "^3.9.0" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -1008,6 +1128,12 @@ "@jridgewell/trace-mapping": "0.3.9" } }, + "@cush/relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cush/relative/-/relative-1.0.0.tgz", + "integrity": "sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==", + "dev": true + }, "@esbuild/android-arm": { "version": "0.15.11", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.11.tgz", @@ -1022,6 +1148,12 @@ "dev": true, "optional": true }, + "@faker-js/faker": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz", + "integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==", + "dev": true + }, "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", @@ -1083,6 +1215,12 @@ "@types/chai": "*" } }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "@types/node": { "version": "18.11.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", @@ -1353,6 +1491,18 @@ "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, + "glob-regex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/glob-regex/-/glob-regex-0.3.2.tgz", + "integrity": "sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==", + "dev": true + }, + "globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1371,6 +1521,15 @@ "has": "^1.0.3" } }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, "local-pkg": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", @@ -1392,6 +1551,12 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1433,6 +1598,18 @@ "source-map-js": "^1.0.2" } }, + "recrawl-sync": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", + "integrity": "sha512-E2sI4F25Fu2nrfV+KsnC7/qfk/spQIYXlonfQoS4rwxeNK5BjxnLPbWiRXHVXPwYBOTWtPX5765kTm/zJiL+LQ==", + "dev": true, + "requires": { + "@cush/relative": "^1.0.0", + "glob-regex": "^0.3.0", + "slash": "^3.0.0", + "tslib": "^1.9.3" + } + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -1453,12 +1630,24 @@ "fsevents": "~2.3.2" } }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, "strip-literal": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz", @@ -1513,6 +1702,24 @@ "yn": "3.1.1" } }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -1563,6 +1770,18 @@ "vite": "^3.0.0" } }, + "vitest-tsconfig-paths": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/vitest-tsconfig-paths/-/vitest-tsconfig-paths-3.4.1.tgz", + "integrity": "sha512-CnRpA/jcqgZfnkk0yvwFW92UmIpf03wX/wLiQBNWAcOG7nv6Sdz3GsPESAMEqbVy8kHBoWB3XeNamu6PUrFZLA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "recrawl-sync": "^2.0.3", + "tsconfig-paths": "^3.9.0" + } + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/app/package.json b/app/package.json index abeadc73..84f610b1 100644 --- a/app/package.json +++ b/app/package.json @@ -4,15 +4,17 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "vitest" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { + "@faker-js/faker": "^7.6.0", "ts-node": "^10.9.1", "typescript": "^4.8.4", - "vitest": "^0.24.3" + "vitest": "^0.24.3", + "vitest-tsconfig-paths": "^3.4.1" }, "engines": { "node": ">=16.0.0" diff --git a/app/vitest.config.ts b/app/vitest.config.ts index 428b64ee..c68f0944 100644 --- a/app/vitest.config.ts +++ b/app/vitest.config.ts @@ -1,5 +1,7 @@ import { defineConfig } from 'vitest/config' +import tsconfigPaths from 'vitest-tsconfig-paths' export default defineConfig({ - test: {} + test: {}, + plugins: [tsconfigPaths()], }) From f8039637631c5f9fc8ce5e498865cf9244266c64 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:03:10 -0300 Subject: [PATCH 008/105] refactor: arruma tipagens da model do User --- app/src/domain/models/user.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/domain/models/user.ts b/app/src/domain/models/user.ts index 747832eb..577bccb6 100644 --- a/app/src/domain/models/user.ts +++ b/app/src/domain/models/user.ts @@ -2,9 +2,9 @@ export type User = { id: number; name: string; email: string; - brithDay: string; + brithDay: Date; role: string; - password: string; - createdAt: string; - updatedAt: string; + password: string + createdAt: Date; + updatedAt: Date; } \ No newline at end of file From 691ea62bbd769860c2b3873117b61ac615bb4b05 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:04:08 -0300 Subject: [PATCH 009/105] feat: cria AddUserController --- app/src/domain/usecases/users/index.ts | 4 ++- .../usecases/users/load-users-by-email.ts | 14 ++++++++++ .../domain/usecases/users/load-users-by-id.ts | 14 ++++++++++ app/src/domain/usecases/users/load-users.ts | 12 +++------ .../users-controller/add-user-controller.ts | 26 +++++++++++++++++++ .../controllers/users-controller/index.ts | 1 + .../errors/email-already-in-use-error.ts | 8 ++++++ app/src/presentation/errors/index.ts | 1 + app/src/presentation/helpers/http-helper.ts | 21 +++++++++++++++ 9 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 app/src/domain/usecases/users/load-users-by-email.ts create mode 100644 app/src/domain/usecases/users/load-users-by-id.ts create mode 100644 app/src/presentation/controllers/users-controller/add-user-controller.ts create mode 100644 app/src/presentation/controllers/users-controller/index.ts create mode 100644 app/src/presentation/errors/email-already-in-use-error.ts create mode 100644 app/src/presentation/errors/index.ts create mode 100644 app/src/presentation/helpers/http-helper.ts diff --git a/app/src/domain/usecases/users/index.ts b/app/src/domain/usecases/users/index.ts index fab0ce8b..1b3259d1 100644 --- a/app/src/domain/usecases/users/index.ts +++ b/app/src/domain/usecases/users/index.ts @@ -1,3 +1,5 @@ export * from './add-user' export * from './load-users' -export * from './delete-user' \ No newline at end of file +export * from './delete-user' +export * from './load-users-by-id' +export * from './load-users-by-email' \ No newline at end of file diff --git a/app/src/domain/usecases/users/load-users-by-email.ts b/app/src/domain/usecases/users/load-users-by-email.ts new file mode 100644 index 00000000..4af802cf --- /dev/null +++ b/app/src/domain/usecases/users/load-users-by-email.ts @@ -0,0 +1,14 @@ +import { User } from '../../models'; + +export interface LoadUsersByEmail { + loadByEmail (params: LoadUsersByEmail.Params): Promise +} + +export namespace LoadUsersByEmail { + export type Params = { + email: string; + }; + + + export type Result = User; +} \ No newline at end of file diff --git a/app/src/domain/usecases/users/load-users-by-id.ts b/app/src/domain/usecases/users/load-users-by-id.ts new file mode 100644 index 00000000..0f15d38a --- /dev/null +++ b/app/src/domain/usecases/users/load-users-by-id.ts @@ -0,0 +1,14 @@ +import { User } from '../../models'; + +export interface LoadUsersById { + loadById (params: LoadUsersById.Params): Promise +} + +export namespace LoadUsersById { + export type Params = { + userId: string; + }; + + + export type Result = User; +} \ No newline at end of file diff --git a/app/src/domain/usecases/users/load-users.ts b/app/src/domain/usecases/users/load-users.ts index 2df15f64..345cb90e 100644 --- a/app/src/domain/usecases/users/load-users.ts +++ b/app/src/domain/usecases/users/load-users.ts @@ -9,11 +9,7 @@ export interface LoadUsers { /** * Load all users from database. */ - load (params: LoadUsers.Params): Promise - /** - * This method is an overload, it's used to load a single user by id. - */ - load (params: LoadUsers.ParamsById): Promise + load (params: LoadUsers.Params): Promise } /** @@ -25,8 +21,6 @@ export namespace LoadUsers { order?: UserOrders; }; - export type ParamsById = { - id: number; - }; - export type Result = User; + + export type Result = User[]; } \ No newline at end of file diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.ts b/app/src/presentation/controllers/users-controller/add-user-controller.ts new file mode 100644 index 00000000..4c5f37a5 --- /dev/null +++ b/app/src/presentation/controllers/users-controller/add-user-controller.ts @@ -0,0 +1,26 @@ +import { User } from '@/domain/models' +import { AddUser, LoadUsersByEmail } from '@/domain/usecases/users' +import { EmailAlreadyInUseError } from '@/presentation/errors' +import { badRequest } from '@/presentation/helpers/http-helper' +import { Controller, HttpResponse } from '@/presentation/protocols' + +export class AddUserController implements Controller { + constructor(private readonly addUserUseCase: AddUser, private readonly loadUsersByEmailUseCase: LoadUsersByEmail) {} + + async handle( + request: AddUserController.Request + ): Promise { + const emaiInUse = await this.loadUsersByEmailUseCase.loadByEmail({ email: request.email }) + + if (emaiInUse) { + return badRequest(new EmailAlreadyInUseError(request.email)) + } + + return null + } +} + +export namespace AddUserController { + export type Request = Omit + export type Response = HttpResponse +} diff --git a/app/src/presentation/controllers/users-controller/index.ts b/app/src/presentation/controllers/users-controller/index.ts new file mode 100644 index 00000000..ce02c76c --- /dev/null +++ b/app/src/presentation/controllers/users-controller/index.ts @@ -0,0 +1 @@ +export * from './add-user-controller' \ No newline at end of file diff --git a/app/src/presentation/errors/email-already-in-use-error.ts b/app/src/presentation/errors/email-already-in-use-error.ts new file mode 100644 index 00000000..e7efd526 --- /dev/null +++ b/app/src/presentation/errors/email-already-in-use-error.ts @@ -0,0 +1,8 @@ +export class EmailAlreadyInUseError extends Error { + constructor (email) { + super() + this.name = 'EmailAlreadyInUseError' + this.message = `The received email ${email} is already in use.` + } + } + \ No newline at end of file diff --git a/app/src/presentation/errors/index.ts b/app/src/presentation/errors/index.ts new file mode 100644 index 00000000..984945c3 --- /dev/null +++ b/app/src/presentation/errors/index.ts @@ -0,0 +1 @@ +export * from './email-already-in-use-error' diff --git a/app/src/presentation/helpers/http-helper.ts b/app/src/presentation/helpers/http-helper.ts new file mode 100644 index 00000000..9a2e1baa --- /dev/null +++ b/app/src/presentation/helpers/http-helper.ts @@ -0,0 +1,21 @@ +import { HttpResponse } from '@/presentation/protocols/http' + +export const badRequest = (error: Error): HttpResponse => ({ + statusCode: 400, + body: error +}) + +export const ok = (data: any): HttpResponse => ({ + statusCode: 200, + body: data +}) + +export const forbidden = (error: Error): HttpResponse => ({ + statusCode: 403, + body: error +}) + +export const noContent = (): HttpResponse => ({ + statusCode: 204, + body: null +}) From 426312725ec581d98b77ee8110681640b652e86c Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:04:13 -0300 Subject: [PATCH 010/105] test: cria AddUserController --- app/src/domain/tests/users.mock.ts | 53 +++++++++++++++++++ .../add-user-controller.test.ts | 42 +++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 app/src/domain/tests/users.mock.ts create mode 100644 app/src/presentation/controllers/users-controller/add-user-controller.test.ts diff --git a/app/src/domain/tests/users.mock.ts b/app/src/domain/tests/users.mock.ts new file mode 100644 index 00000000..612b9f49 --- /dev/null +++ b/app/src/domain/tests/users.mock.ts @@ -0,0 +1,53 @@ +import { faker } from '@faker-js/faker' +import { User } from '../models' +import { AddUser, LoadUsersById } from '../usecases/users' +import { LoadUsersByEmail } from '../usecases/users/load-users-by-email' + +export function mockUser(): User { + return { + id: faker.datatype.number(), + name: faker.name.fullName(), + email: faker.internet.email(), + password: faker.internet.password(), + brithDay: faker.date.past(), + role: faker.helpers.arrayElement(['admin', 'user']), + createdAt: faker.date.past(), + updatedAt: faker.date.past(), + } +} + +export class LoadUsersByIdSpy implements LoadUsersById { + loadByIdResult: LoadUsersById.Result + loadByIdParams: LoadUsersById.Params + constructor() { + this.loadByIdResult = mockUser() + } + async loadById(params: LoadUsersById.Params): Promise { + this.loadByIdParams = params + return new Promise((resolve) => resolve(this.loadByIdResult)) + } +} + +export class LoadUsersByEmailSpy implements LoadUsersByEmail { + loadByEmailResult: LoadUsersByEmail.Result + loadByEmailParams: LoadUsersByEmail.Params + constructor() { + this.loadByEmailResult = mockUser() + } + async loadByEmail(params: LoadUsersByEmail.Params): Promise { + this.loadByEmailParams = params + return new Promise((resolve) => resolve(this.loadByEmailResult)) + } + } + +export class AddUserSpy implements AddUser { + addResult: AddUser.Result + addParams: AddUser.Params + constructor() { + this.addResult = mockUser() + } + async add(user: AddUser.Params): Promise { + this.addParams = user + return new Promise((resolve) => resolve(this.addResult)) + } +} diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts new file mode 100644 index 00000000..7f01b876 --- /dev/null +++ b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts @@ -0,0 +1,42 @@ +import { describe, expect, test } from 'vitest' +import { AddUserController } from './add-user-controller'; +import { AddUserSpy, LoadUsersByEmailSpy, mockUser } from '@/domain/tests/users.mock'; +import { badRequest } from '@/presentation/helpers/http-helper'; +import { EmailAlreadyInUseError } from '@/presentation/errors'; + +describe('AddUserController', () => { + type SutType = { + sut: AddUserController + addUserUseCaseSpy: AddUserSpy + loadUsersByEmailUseCaseSpy: LoadUsersByEmailSpy + } + function makeSut(): SutType { + const addUserUseCaseSpy = new AddUserSpy() + const loadUsersByEmailUseCaseSpy = new LoadUsersByEmailSpy() + const sut = new AddUserController(addUserUseCaseSpy, loadUsersByEmailUseCaseSpy) + + return { + sut, + addUserUseCaseSpy, + loadUsersByEmailUseCaseSpy + } + } + describe('handle()', () => { + test('should call loadUsersByEmailUseCase with the correct email', async () => { + const { sut, loadUsersByEmailUseCaseSpy } = makeSut() + const mockedUser = mockUser() + await sut.handle(mockedUser) + + expect(loadUsersByEmailUseCaseSpy.loadByEmailParams).toEqual({email:mockedUser.email}) + }); + + test('should return EmailAlreadyInUseError if already exists an user with this email', async () => { + const { sut, loadUsersByEmailUseCaseSpy } = makeSut() + const mockedUser = mockUser() + loadUsersByEmailUseCaseSpy.loadByEmailResult = mockedUser + const response = await sut.handle(mockedUser) + + expect(response).toEqual(badRequest(new EmailAlreadyInUseError(mockedUser.email))) + }); + }); +}); \ No newline at end of file From 9e6b1e37777dbc8fd9553f2a774b6a5910ec9324 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:18:44 -0300 Subject: [PATCH 011/105] feat: garante que AddUserController vai retornar serverError se loadUsersByEmail quebrar --- .../controllers/users-controller/add-user-controller.ts | 6 +++++- app/src/presentation/helpers/http-helper.ts | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.ts b/app/src/presentation/controllers/users-controller/add-user-controller.ts index 4c5f37a5..8db56e54 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.ts @@ -1,7 +1,7 @@ import { User } from '@/domain/models' import { AddUser, LoadUsersByEmail } from '@/domain/usecases/users' import { EmailAlreadyInUseError } from '@/presentation/errors' -import { badRequest } from '@/presentation/helpers/http-helper' +import { badRequest, serverError } from '@/presentation/helpers/http-helper' import { Controller, HttpResponse } from '@/presentation/protocols' export class AddUserController implements Controller { @@ -10,6 +10,7 @@ export class AddUserController implements Controller { async handle( request: AddUserController.Request ): Promise { + try { const emaiInUse = await this.loadUsersByEmailUseCase.loadByEmail({ email: request.email }) if (emaiInUse) { @@ -17,6 +18,9 @@ export class AddUserController implements Controller { } return null + } catch (error) { + return serverError(error) + } } } diff --git a/app/src/presentation/helpers/http-helper.ts b/app/src/presentation/helpers/http-helper.ts index 9a2e1baa..30e159a4 100644 --- a/app/src/presentation/helpers/http-helper.ts +++ b/app/src/presentation/helpers/http-helper.ts @@ -19,3 +19,8 @@ export const noContent = (): HttpResponse => ({ statusCode: 204, body: null }) + +export const serverError = (error: Error): HttpResponse => ({ + statusCode: 500, + body: error +}) \ No newline at end of file From 3f37a28a7875d6ab2aab133430671f64ffda9338 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:18:49 -0300 Subject: [PATCH 012/105] test: garante que AddUserController vai retornar serverError se loadUsersByEmail quebrar --- .../add-user-controller.test.ts | 90 ++++++++++++------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts index 7f01b876..a2ad3614 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts @@ -1,42 +1,64 @@ -import { describe, expect, test } from 'vitest' -import { AddUserController } from './add-user-controller'; -import { AddUserSpy, LoadUsersByEmailSpy, mockUser } from '@/domain/tests/users.mock'; -import { badRequest } from '@/presentation/helpers/http-helper'; -import { EmailAlreadyInUseError } from '@/presentation/errors'; +import { describe, expect, test, vitest } from 'vitest' +import { AddUserController } from './add-user-controller' +import { + AddUserSpy, + LoadUsersByEmailSpy, + mockUser, +} from '@/domain/tests/users.mock' +import { badRequest, serverError } from '@/presentation/helpers/http-helper' +import { EmailAlreadyInUseError } from '@/presentation/errors' describe('AddUserController', () => { - type SutType = { - sut: AddUserController - addUserUseCaseSpy: AddUserSpy - loadUsersByEmailUseCaseSpy: LoadUsersByEmailSpy - } - function makeSut(): SutType { - const addUserUseCaseSpy = new AddUserSpy() - const loadUsersByEmailUseCaseSpy = new LoadUsersByEmailSpy() - const sut = new AddUserController(addUserUseCaseSpy, loadUsersByEmailUseCaseSpy) + type SutType = { + sut: AddUserController + addUserUseCaseSpy: AddUserSpy + loadUsersByEmailUseCaseSpy: LoadUsersByEmailSpy + } + function makeSut(): SutType { + const addUserUseCaseSpy = new AddUserSpy() + const loadUsersByEmailUseCaseSpy = new LoadUsersByEmailSpy() + const sut = new AddUserController( + addUserUseCaseSpy, + loadUsersByEmailUseCaseSpy + ) - return { - sut, - addUserUseCaseSpy, - loadUsersByEmailUseCaseSpy - } + return { + sut, + addUserUseCaseSpy, + loadUsersByEmailUseCaseSpy, } - describe('handle()', () => { - test('should call loadUsersByEmailUseCase with the correct email', async () => { - const { sut, loadUsersByEmailUseCaseSpy } = makeSut() - const mockedUser = mockUser() - await sut.handle(mockedUser) + } + describe('handle()', () => { + test('should call loadUsersByEmailUseCase with the correct email', async () => { + const { sut, loadUsersByEmailUseCaseSpy } = makeSut() + const mockedUser = mockUser() + await sut.handle(mockedUser) + + expect(loadUsersByEmailUseCaseSpy.loadByEmailParams).toEqual({ + email: mockedUser.email, + }) + }) - expect(loadUsersByEmailUseCaseSpy.loadByEmailParams).toEqual({email:mockedUser.email}) - }); + test('should return EmailAlreadyInUseError if already exists an user with this email', async () => { + const { sut, loadUsersByEmailUseCaseSpy } = makeSut() + const mockedUser = mockUser() + loadUsersByEmailUseCaseSpy.loadByEmailResult = mockedUser + const response = await sut.handle(mockedUser) - test('should return EmailAlreadyInUseError if already exists an user with this email', async () => { - const { sut, loadUsersByEmailUseCaseSpy } = makeSut() - const mockedUser = mockUser() - loadUsersByEmailUseCaseSpy.loadByEmailResult = mockedUser - const response = await sut.handle(mockedUser) + expect(response).toEqual( + badRequest(new EmailAlreadyInUseError(mockedUser.email)) + ) + }) - expect(response).toEqual(badRequest(new EmailAlreadyInUseError(mockedUser.email))) - }); + test('should return serverError if loadUsersByEmail throws', async () => { + const { sut, loadUsersByEmailUseCaseSpy } = makeSut() + const mockedUser = mockUser() + const mockedError = new Error('some_error') + vitest.spyOn(loadUsersByEmailUseCaseSpy, 'loadByEmail').mockRejectedValueOnce(mockedError) + const response = await sut.handle(mockedUser) + expect(response).toEqual( + serverError(mockedError) + ) }); -}); \ No newline at end of file + }) +}) From 587db4c959643e40b501cf61e85ef7ba57a6c204 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:26:04 -0300 Subject: [PATCH 013/105] refactor: padroniza nome de arquivo --- app/src/domain/tests/{users.mock.ts => users-mock.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/src/domain/tests/{users.mock.ts => users-mock.ts} (100%) diff --git a/app/src/domain/tests/users.mock.ts b/app/src/domain/tests/users-mock.ts similarity index 100% rename from app/src/domain/tests/users.mock.ts rename to app/src/domain/tests/users-mock.ts From ceef26cf890ac98ddcd32c73b1aa39b3dfbb6d14 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:26:25 -0300 Subject: [PATCH 014/105] =?UTF-8?q?feat:=20garante=20que=20addUserUseCase?= =?UTF-8?q?=20ser=C3=A1=20chamado=20corretamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../users-controller/add-user-controller.ts | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.ts b/app/src/presentation/controllers/users-controller/add-user-controller.ts index 8db56e54..d7fcba6a 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.ts @@ -5,22 +5,29 @@ import { badRequest, serverError } from '@/presentation/helpers/http-helper' import { Controller, HttpResponse } from '@/presentation/protocols' export class AddUserController implements Controller { - constructor(private readonly addUserUseCase: AddUser, private readonly loadUsersByEmailUseCase: LoadUsersByEmail) {} + constructor( + private readonly addUserUseCase: AddUser, + private readonly loadUsersByEmailUseCase: LoadUsersByEmail + ) {} async handle( request: AddUserController.Request ): Promise { - try { - const emaiInUse = await this.loadUsersByEmailUseCase.loadByEmail({ email: request.email }) - - if (emaiInUse) { + try { + const emaiInUse = await this.loadUsersByEmailUseCase.loadByEmail({ + email: request.email, + }) + + if (emaiInUse) { return badRequest(new EmailAlreadyInUseError(request.email)) - } + } - return null - } catch (error) { - return serverError(error) - } + await this.addUserUseCase.add(request) + + return null + } catch (error) { + return serverError(error) + } } } From 8ebab1c4b404e2ef65faae24866a3690911d7011 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:26:28 -0300 Subject: [PATCH 015/105] =?UTF-8?q?test:=20garante=20que=20addUserUseCase?= =?UTF-8?q?=20ser=C3=A1=20chamado=20corretamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../users-controller/add-user-controller.test.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts index a2ad3614..f77676be 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts @@ -4,7 +4,7 @@ import { AddUserSpy, LoadUsersByEmailSpy, mockUser, -} from '@/domain/tests/users.mock' +} from '@/domain/tests/users-mock' import { badRequest, serverError } from '@/presentation/helpers/http-helper' import { EmailAlreadyInUseError } from '@/presentation/errors' @@ -17,6 +17,7 @@ describe('AddUserController', () => { function makeSut(): SutType { const addUserUseCaseSpy = new AddUserSpy() const loadUsersByEmailUseCaseSpy = new LoadUsersByEmailSpy() + loadUsersByEmailUseCaseSpy.loadByEmailResult = null const sut = new AddUserController( addUserUseCaseSpy, loadUsersByEmailUseCaseSpy @@ -60,5 +61,13 @@ describe('AddUserController', () => { serverError(mockedError) ) }); + + test('should call AddUser with correct params', async () => { + const { sut, addUserUseCaseSpy } = makeSut() + const mockedUser = mockUser() + await sut.handle(mockedUser) + + expect(addUserUseCaseSpy.addParams).toEqual(mockedUser) + }); }) }) From 198a22e470cc1cbf694e69d5527cf62483ff5e0b Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:28:11 -0300 Subject: [PATCH 016/105] =?UTF-8?q?feat:=20garante=20que=20AddUserControll?= =?UTF-8?q?er=20ir=C3=A1=20retornar=20um=20usu=C3=A1rio=20no=20caso=20de?= =?UTF-8?q?=20sucesso?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/users-controller/add-user-controller.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.ts b/app/src/presentation/controllers/users-controller/add-user-controller.ts index d7fcba6a..2d753a52 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.ts @@ -1,7 +1,7 @@ import { User } from '@/domain/models' import { AddUser, LoadUsersByEmail } from '@/domain/usecases/users' import { EmailAlreadyInUseError } from '@/presentation/errors' -import { badRequest, serverError } from '@/presentation/helpers/http-helper' +import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' import { Controller, HttpResponse } from '@/presentation/protocols' export class AddUserController implements Controller { @@ -22,9 +22,9 @@ export class AddUserController implements Controller { return badRequest(new EmailAlreadyInUseError(request.email)) } - await this.addUserUseCase.add(request) + const result = await this.addUserUseCase.add(request) - return null + return ok(result) } catch (error) { return serverError(error) } From 7772c389cd30cda603d7e739edf12f67f46544b0 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:28:16 -0300 Subject: [PATCH 017/105] =?UTF-8?q?test:=20garante=20que=20AddUserControll?= =?UTF-8?q?er=20ir=C3=A1=20retornar=20um=20usu=C3=A1rio=20no=20caso=20de?= =?UTF-8?q?=20sucesso?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../users-controller/add-user-controller.test.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts index f77676be..b14dd7e7 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts @@ -5,7 +5,7 @@ import { LoadUsersByEmailSpy, mockUser, } from '@/domain/tests/users-mock' -import { badRequest, serverError } from '@/presentation/helpers/http-helper' +import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' import { EmailAlreadyInUseError } from '@/presentation/errors' describe('AddUserController', () => { @@ -69,5 +69,13 @@ describe('AddUserController', () => { expect(addUserUseCaseSpy.addParams).toEqual(mockedUser) }); + + test('should return 200 on success', async () => { + const { sut, addUserUseCaseSpy } = makeSut() + const mockedUser = mockUser() + const response = await sut.handle(mockedUser) + + expect(response).toEqual(ok(addUserUseCaseSpy.addResult)) + }); }) }) From 9ba01d201d05077f5b4d36a5535a624924def3b1 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Fri, 14 Oct 2022 23:29:18 -0300 Subject: [PATCH 018/105] =?UTF-8?q?test:=20garante=20que=20ser=C3=A1=20ret?= =?UTF-8?q?ornardo=20serverError=20se=20addUserUseCase=20quebrar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../users-controller/add-user-controller.test.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts index b14dd7e7..71980a51 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts @@ -70,12 +70,23 @@ describe('AddUserController', () => { expect(addUserUseCaseSpy.addParams).toEqual(mockedUser) }); - test('should return 200 on success', async () => { + test('should return ok on success', async () => { const { sut, addUserUseCaseSpy } = makeSut() const mockedUser = mockUser() const response = await sut.handle(mockedUser) expect(response).toEqual(ok(addUserUseCaseSpy.addResult)) }); + + test('should return serverError if addUserUseCase throws', async () => { + const { sut, addUserUseCaseSpy } = makeSut() + const mockedUser = mockUser() + const mockedError = new Error('some_error') + vitest.spyOn(addUserUseCaseSpy, 'add').mockRejectedValueOnce(mockedError) + const response = await sut.handle(mockedUser) + expect(response).toEqual( + serverError(mockedError) + ) + }); }) }) From bc86b535a708ea203dd780ee6a91c92692790971 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 00:55:26 -0300 Subject: [PATCH 019/105] chore: configura sequelize --- app/.env.example | 5 + app/.gitignore | 3 +- app/.sequelizerc | 8 + app/package-lock.json | 3958 ++++++++++++++++- app/package.json | 13 +- .../database/sequelize/helpers/_config.js | 15 + app/tsconfig.json | 1 + 7 files changed, 3841 insertions(+), 162 deletions(-) create mode 100644 app/.env.example create mode 100644 app/.sequelizerc create mode 100644 app/src/infra/database/sequelize/helpers/_config.js diff --git a/app/.env.example b/app/.env.example new file mode 100644 index 00000000..7acdbe4c --- /dev/null +++ b/app/.env.example @@ -0,0 +1,5 @@ +DB_HOST= +DB_PORT= +DB_USER= +DB_PASS= +DB_NAME= \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore index b512c09d..1dcef2d9 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1,2 @@ -node_modules \ No newline at end of file +node_modules +.env \ No newline at end of file diff --git a/app/.sequelizerc b/app/.sequelizerc new file mode 100644 index 00000000..f6ade922 --- /dev/null +++ b/app/.sequelizerc @@ -0,0 +1,8 @@ +const path = require("path"); + +module.exports = { + config: path.resolve("src", "infra", "database", "sequelize", "helpers", "_config.js"), + "models-path": path.resolve("src", "infra", "database", "sequelize", "models"), + "seeders-path": path.resolve("src", "infra", "database", "sequelize", "seeders"), + "migrations-path": path.resolve("src", "infra", "database", "sequelize", "migrations"), +}; \ No newline at end of file diff --git a/app/package-lock.json b/app/package-lock.json index e9988829..a172d961 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -8,8 +8,18 @@ "name": "app", "version": "1.0.0", "license": "ISC", + "dependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "mysql2": "^2.3.3", + "sequelize": "^6.25.1", + "sequelize-cli": "^6.5.1" + }, "devDependencies": { "@faker-js/faker": "^7.6.0", + "@types/node": "^18.11.0", + "mockdate": "^3.0.5", + "sqlite3": "^5.1.2", "ts-node": "^10.9.1", "typescript": "^4.8.4", "vitest": "^0.24.3", @@ -79,6 +89,13 @@ "npm": ">=6.0.0" } }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true, + "optional": true + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", @@ -104,6 +121,76 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", + "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "dev": true, + "optional": true, + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "optional": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -143,17 +230,39 @@ "@types/chai": "*" } }, + "node_modules/@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" + }, "node_modules/@types/node": { "version": "18.11.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", - "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==", - "dev": true + "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==" + }, + "node_modules/@types/validator": { + "version": "13.7.7", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", + "integrity": "sha512-jiEw2kTUJ8Jsh4A1K4b5Pkjj9Xz6FktLLOQ36ZVLRkmxFbpTvAV2VRoKMojz8UlZxNg/2dZqzpigH4JYn1bkQg==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/acorn": { "version": "8.8.0", @@ -176,6 +285,88 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", + "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "dev": true, + "optional": true, + "dependencies": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "optional": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -191,6 +382,107 @@ "node": "*" } }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "dev": true, + "optional": true, + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/chai": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", @@ -218,17 +510,150 @@ "node": "*" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -253,6 +678,39 @@ "node": ">=0.12" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -262,6 +720,131 @@ "node": ">=0.3.1" } }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/dottie": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", + "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" + }, + "node_modules/editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dependencies": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "bin": { + "editorconfig": "bin/editorconfig" + } + }, + "node_modules/editorconfig/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/editorconfig/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/editorconfig/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "optional": true + }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "node_modules/esbuild": { "version": "0.15.11", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.11.tgz", @@ -619,16 +1202,77 @@ "node": ">=12" } }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -636,8 +1280,43 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, "node_modules/get-func-name": { "version": "2.0.0", @@ -648,6 +1327,24 @@ "node": "*" } }, + "node_modules/glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-regex": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/glob-regex/-/glob-regex-0.3.2.tgz", @@ -660,11 +1357,15 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -672,11 +1373,133 @@ "node": ">= 0.4.0" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true, + "optional": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true, + "optional": true + }, + "node_modules/inflection": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", + "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==", + "engines": [ + "node >= 0.4.0" + ] + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true, + "optional": true + }, "node_modules/is-core-module": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -684,6 +1507,55 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "optional": true + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/js-beautify": { + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.6.tgz", + "integrity": "sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==", + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^0.15.3", + "glob": "^8.0.3", + "nopt": "^6.0.0" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -696,6 +1568,17 @@ "json5": "lib/cli.js" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/local-pkg": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", @@ -708,6 +1591,16 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/loupe": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", @@ -717,12 +1610,109 @@ "get-func-name": "^2.0.0" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "dev": true, + "optional": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, + "node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/minimist": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", @@ -732,129 +1722,972 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { + "node_modules/minipass": { "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "yallist": "^4.0.0" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", "dev": true, + "optional": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, "engines": { - "node": "*" + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], + "optional": true, "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "minipass": "^3.0.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=8" } }, - "node_modules/recrawl-sync": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", - "integrity": "sha512-E2sI4F25Fu2nrfV+KsnC7/qfk/spQIYXlonfQoS4rwxeNK5BjxnLPbWiRXHVXPwYBOTWtPX5765kTm/zJiL+LQ==", + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", "dev": true, + "optional": true, "dependencies": { - "@cush/relative": "^1.0.0", - "glob-regex": "^0.3.0", - "slash": "^3.0.0", - "tslib": "^1.9.3" + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/resolve": { + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", + "dev": true + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", + "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/mysql2": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "dependencies": { + "denque": "^2.0.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^4.0.0", + "lru-cache": "^6.0.0", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "dependencies": { + "lru-cache": "^4.1.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/named-placeholders/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/named-placeholders/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "dev": true, + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dev": true, + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/node-gyp/node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/node-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/node-gyp/node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dev": true, + "optional": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dev": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "optional": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "optional": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "optional": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/recrawl-sync": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", + "integrity": "sha512-E2sI4F25Fu2nrfV+KsnC7/qfk/spQIYXlonfQoS4rwxeNK5BjxnLPbWiRXHVXPwYBOTWtPX5765kTm/zJiL+LQ==", + "dev": true, + "dependencies": { + "@cush/relative": "^1.0.0", + "glob-regex": "^0.3.0", + "slash": "^3.0.0", + "tslib": "^1.9.3" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-as-promised": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-6.1.0.tgz", + "integrity": "sha512-Hj/jY+wFC+SB9SDlIIFWiGOHnNG0swYbGYsOj2BJ8u2HKUaobNKab0OIC0zOLYzDy0mb7A4xA5BMo4LMz5YtEA==" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/rollup": { + "version": "2.78.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", + "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, + "node_modules/sequelize": { + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.25.1.tgz", + "integrity": "sha512-z2oNoGFhQ8FaDLPuL+UKYA4VXsIyd5pHO6LNSRbzIPuOEma8b2bSbLdde6JjeHeaTIrmIwInC7YF34wMHfcngg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/sequelize" + } + ], + "dependencies": { + "@types/debug": "^4.1.7", + "@types/validator": "^13.7.1", + "debug": "^4.3.3", + "dottie": "^2.0.2", + "inflection": "^1.13.2", + "lodash": "^4.17.21", + "moment": "^2.29.1", + "moment-timezone": "^0.5.34", + "pg-connection-string": "^2.5.0", + "retry-as-promised": "^6.1.0", + "semver": "^7.3.5", + "sequelize-pool": "^7.1.0", + "toposort-class": "^1.0.1", + "uuid": "^8.3.2", + "validator": "^13.7.0", + "wkx": "^0.5.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependenciesMeta": { + "ibm_db": { + "optional": true + }, + "mariadb": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "oracledb": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-hstore": { + "optional": true + }, + "snowflake-sdk": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/sequelize-cli": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-6.5.1.tgz", + "integrity": "sha512-36hfZKNeZkIshp6L0jPVQ27xNLzgDPpiZokQsvo0M882AtAm+KhGOIViR0BecWb0Xz8+uSq03xxcl7RfMgyIRA==", + "dependencies": { + "cli-color": "^2.0.3", + "fs-extra": "^9.1.0", + "js-beautify": "^1.14.5", + "lodash": "^4.17.21", + "resolve": "^1.22.1", + "umzug": "^2.3.0", + "yargs": "^16.2.0" + }, + "bin": { + "sequelize": "lib/sequelize", + "sequelize-cli": "lib/sequelize" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sequelize-pool": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dev": true, + "optional": true, + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "dev": true, + "optional": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sqlite3": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.2.tgz", + "integrity": "sha512-D0Reg6pRWAFXFUnZKsszCI67tthFD8fGPewRddDCX6w4cYwz3MbvuwRICbL+YQjBAh9zbw+lJ/V9oC8nG5j6eg==", "dev": true, + "hasInstallScript": true, "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0", + "tar": "^6.1.11" }, - "bin": { - "resolve": "bin/resolve" + "optionalDependencies": { + "node-gyp": "8.x" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "node-gyp": "8.x" + }, + "peerDependenciesMeta": { + "node-gyp": { + "optional": true + } } }, - "node_modules/rollup": { - "version": "2.78.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", - "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", "dev": true, - "bin": { - "rollup": "dist/bin/rollup" + "optional": true, + "dependencies": { + "minipass": "^3.1.1" }, "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": ">= 8" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { "node": ">=8" } }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/strip-bom": { @@ -882,7 +2715,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -890,6 +2722,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "node_modules/tinybench": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.0.tgz", @@ -914,6 +2772,17 @@ "node": ">=14.0.0" } }, + "node_modules/toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -975,6 +2844,11 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -997,12 +2871,73 @@ "node": ">=4.2.0" } }, + "node_modules/umzug": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", + "integrity": "sha512-Z274K+e8goZK8QJxmbRPhl89HPO1K+ORFtm6rySPhFKfKc5GHhqdzD0SGhSWHkzoXasqJuItdhorSvY7/Cgflw==", + "dependencies": { + "bluebird": "^3.7.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "optional": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "optional": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "node_modules/validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vite": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.8.tgz", @@ -1108,6 +3043,112 @@ "tsconfig-paths": "^3.9.0" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wkx": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -1154,6 +3195,13 @@ "integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==", "dev": true }, + "@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true, + "optional": true + }, "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", @@ -1176,6 +3224,63 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@mapbox/node-pre-gyp": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", + "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "dev": true, + "requires": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "dependencies": { + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "dev": true, + "optional": true, + "requires": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "optional": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "optional": true + }, "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -1215,17 +3320,39 @@ "@types/chai": "*" } }, + "@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "requires": { + "@types/ms": "*" + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" + }, "@types/node": { "version": "18.11.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", - "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==", - "dev": true + "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==" + }, + "@types/validator": { + "version": "13.7.7", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", + "integrity": "sha512-jiEw2kTUJ8Jsh4A1K4b5Pkjj9Xz6FktLLOQ36ZVLRkmxFbpTvAV2VRoKMojz8UlZxNg/2dZqzpigH4JYn1bkQg==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { "version": "8.8.0", @@ -1239,37 +3366,266 @@ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", + "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "optional": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "cacache": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "dev": true, + "optional": true, + "requires": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "optional": true + }, + "cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", - "dev": true, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "ini": "^1.3.4", + "proto-list": "~1.2.1" } }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true }, "create-require": { @@ -1278,11 +3634,37 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -1296,12 +3678,147 @@ "type-detect": "^4.0.0" } }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "dev": true + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "dottie": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", + "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + } + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "optional": true + }, + "err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "optional": true + }, + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "esbuild": { "version": "0.15.11", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.11.tgz", @@ -1472,6 +3989,60 @@ "dev": true, "optional": true }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "requires": { + "type": "^2.7.2" + }, + "dependencies": { + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + } + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -1482,8 +4053,37 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dev": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + } + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { "version": "2.0.0", @@ -1491,6 +4091,18 @@ "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, + "glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, "glob-regex": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/glob-regex/-/glob-regex-0.3.2.tgz", @@ -1503,65 +4115,446 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true, + "optional": true + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "optional": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "optional": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "optional": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "optional": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true, + "optional": true + }, + "inflection": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", + "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true, + "optional": true + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "optional": true + }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "js-beautify": { + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.6.tgz", + "integrity": "sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==", + "requires": { + "config-chain": "^1.1.13", + "editorconfig": "^0.15.3", + "glob": "^8.0.3", + "nopt": "^6.0.0" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "local-pkg": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", + "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", + "dev": true + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "dev": true, + "optional": true, + "requires": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + } + }, + "memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true + }, + "minipass": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", "dev": true, + "optional": true, "requires": { - "function-bind": "^1.1.1" + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" } }, - "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "dev": true, + "optional": true, "requires": { - "has": "^1.0.3" + "minipass": "^3.0.0" } }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, + "optional": true, "requires": { - "minimist": "^1.2.0" + "minipass": "^3.0.0" } }, - "local-pkg": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", - "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", - "dev": true + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^3.0.0" + } }, - "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, "requires": { - "get-func-name": "^2.0.0" + "minipass": "^3.0.0", + "yallist": "^4.0.0" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", "dev": true }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" + }, + "moment-timezone": { + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", + "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", + "requires": { + "moment": ">= 2.9.0" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mysql2": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "requires": { + "denque": "^2.0.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^4.0.0", + "lru-cache": "^6.0.0", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + } + }, + "named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "requires": { + "lru-cache": "^4.1.3" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + } + } }, "nanoid": { "version": "3.3.4", @@ -1569,11 +4562,200 @@ "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", "dev": true }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "optional": true + }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-gyp": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "dev": true, + "optional": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "dependencies": { + "are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "optional": true, + "requires": { + "abbrev": "1" + } + }, + "npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + } + } + } + }, + "nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "requires": { + "abbrev": "^1.0.0" + } + }, + "npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dev": true, + "requires": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "optional": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "pathval": { "version": "1.1.1", @@ -1581,6 +4763,11 @@ "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, + "pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -1598,6 +4785,45 @@ "source-map-js": "^1.0.2" } }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "optional": true + }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "optional": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "recrawl-sync": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", @@ -1610,17 +4836,77 @@ "tslib": "^1.9.3" } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, "requires": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "optional": true + }, + "retry-as-promised": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-6.1.0.tgz", + "integrity": "sha512-Hj/jY+wFC+SB9SDlIIFWiGOHnNG0swYbGYsOj2BJ8u2HKUaobNKab0OIC0zOLYzDy0mb7A4xA5BMo4LMz5YtEA==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, "rollup": { "version": "2.78.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", @@ -1630,18 +4916,198 @@ "fsevents": "~2.3.2" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, + "sequelize": { + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.25.1.tgz", + "integrity": "sha512-z2oNoGFhQ8FaDLPuL+UKYA4VXsIyd5pHO6LNSRbzIPuOEma8b2bSbLdde6JjeHeaTIrmIwInC7YF34wMHfcngg==", + "requires": { + "@types/debug": "^4.1.7", + "@types/validator": "^13.7.1", + "debug": "^4.3.3", + "dottie": "^2.0.2", + "inflection": "^1.13.2", + "lodash": "^4.17.21", + "moment": "^2.29.1", + "moment-timezone": "^0.5.34", + "pg-connection-string": "^2.5.0", + "retry-as-promised": "^6.1.0", + "semver": "^7.3.5", + "sequelize-pool": "^7.1.0", + "toposort-class": "^1.0.1", + "uuid": "^8.3.2", + "validator": "^13.7.0", + "wkx": "^0.5.0" + } + }, + "sequelize-cli": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-6.5.1.tgz", + "integrity": "sha512-36hfZKNeZkIshp6L0jPVQ27xNLzgDPpiZokQsvo0M882AtAm+KhGOIViR0BecWb0Xz8+uSq03xxcl7RfMgyIRA==", + "requires": { + "cli-color": "^2.0.3", + "fs-extra": "^9.1.0", + "js-beautify": "^1.14.5", + "lodash": "^4.17.21", + "resolve": "^1.22.1", + "umzug": "^2.3.0", + "yargs": "^16.2.0" + } + }, + "sequelize-pool": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==" + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "optional": true + }, + "socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dev": true, + "optional": true, + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "dev": true, + "optional": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true }, + "sqlite3": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.2.tgz", + "integrity": "sha512-D0Reg6pRWAFXFUnZKsszCI67tthFD8fGPewRddDCX6w4cYwz3MbvuwRICbL+YQjBAh9zbw+lJ/V9oC8nG5j6eg==", + "dev": true, + "requires": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0", + "node-gyp": "8.x", + "tar": "^6.1.11" + } + }, + "sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==" + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -1660,8 +5126,30 @@ "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } }, "tinybench": { "version": "2.3.0", @@ -1681,6 +5169,17 @@ "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", "dev": true }, + "toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -1720,6 +5219,11 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -1732,12 +5236,61 @@ "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true }, + "umzug": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", + "integrity": "sha512-Z274K+e8goZK8QJxmbRPhl89HPO1K+ORFtm6rySPhFKfKc5GHhqdzD0SGhSWHkzoXasqJuItdhorSvY7/Cgflw==", + "requires": { + "bluebird": "^3.7.2" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "optional": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "optional": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" + }, "vite": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.8.tgz", @@ -1782,6 +5335,91 @@ "tsconfig-paths": "^3.9.0" } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "wkx": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", + "requires": { + "@types/node": "*" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/app/package.json b/app/package.json index 84f610b1..1094e0e5 100644 --- a/app/package.json +++ b/app/package.json @@ -3,14 +3,18 @@ "version": "1.0.0", "description": "", "main": "index.js", + "type": "module", "scripts": { - "test": "vitest" + "test": "cross-env NODE_ENV=test vitest" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@faker-js/faker": "^7.6.0", + "@types/node": "^18.11.0", + "mockdate": "^3.0.5", + "sqlite3": "^5.1.2", "ts-node": "^10.9.1", "typescript": "^4.8.4", "vitest": "^0.24.3", @@ -18,5 +22,12 @@ }, "engines": { "node": ">=16.0.0" + }, + "dependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "mysql2": "^2.3.3", + "sequelize": "^6.25.1", + "sequelize-cli": "^6.5.1" } } diff --git a/app/src/infra/database/sequelize/helpers/_config.js b/app/src/infra/database/sequelize/helpers/_config.js new file mode 100644 index 00000000..84174b6e --- /dev/null +++ b/app/src/infra/database/sequelize/helpers/_config.js @@ -0,0 +1,15 @@ +import { config } from 'dotenv' +config({ + path: process.env.NODE_ENV === 'test' ? '.env.test' : '.env' +}) + + +export default { + host: process.env.DB_HOST, + port: parseInt(process.env.DB_PORT), + username: process.env.DB_USER, + password: process.env.DB_PASS, + database: process.env.DB_NAME, + dialect: process.env.DB_DIALECT || 'mysql', + logging: false +} diff --git a/app/tsconfig.json b/app/tsconfig.json index 59575f39..52de1925 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -8,6 +8,7 @@ "sourceMap": true, "rootDir": "src", "baseUrl": "src", + "allowJs": true, "paths": { "@/*": ["*"] } From eb1a2e22ec52eb4393591ef42b4a92355322c8c8 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 00:56:05 -0300 Subject: [PATCH 020/105] feat: cria model Users para Sequelize --- app/src/domain/models/user.ts | 6 +-- .../database/sequelize/helpers/config.ts | 5 ++ .../20221015033744-create-table-users.js | 46 ++++++++++++++++ .../infra/database/sequelize/models/Users.ts | 52 +++++++++++++++++++ 4 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 app/src/infra/database/sequelize/helpers/config.ts create mode 100644 app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js create mode 100644 app/src/infra/database/sequelize/models/Users.ts diff --git a/app/src/domain/models/user.ts b/app/src/domain/models/user.ts index 577bccb6..18a27908 100644 --- a/app/src/domain/models/user.ts +++ b/app/src/domain/models/user.ts @@ -1,10 +1,10 @@ export type User = { - id: number; + id?: number; name: string; email: string; brithDay: Date; role: string; password: string - createdAt: Date; - updatedAt: Date; + createdAt?: Date; + updatedAt?: Date; } \ No newline at end of file diff --git a/app/src/infra/database/sequelize/helpers/config.ts b/app/src/infra/database/sequelize/helpers/config.ts new file mode 100644 index 00000000..b2aeb7e6 --- /dev/null +++ b/app/src/infra/database/sequelize/helpers/config.ts @@ -0,0 +1,5 @@ +import config from './_config' +import { Options } from 'sequelize'; + + +export const sequelizeConfig: Options = config \ No newline at end of file diff --git a/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js b/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js new file mode 100644 index 00000000..7a0d1775 --- /dev/null +++ b/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js @@ -0,0 +1,46 @@ +'use strict' + +module.exports = { + up: async (queryInterface, Sequelize) => { + return queryInterface.createTable('users', { + id: { + type: Sequelize.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + brithDay: { + type: Sequelize.DATE, + allowNull: false, + }, + email: { + type: Sequelize.STRING, + allowNull: false, + unique: true, + }, + name: { + type: Sequelize.STRING, + }, + password: { + type: Sequelize.STRING, + allowNull: false, + }, + createdAt: { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.NOW, + }, + updatedAt: { + type: Sequelize.DATE, + allowNull: true, + }, + role: { + type: Sequelize.STRING, + allowNull: false, + }, + }) + }, + + down: async (queryInterface, Sequelize) => { + return queryInterface.dropTable('users') + }, +} diff --git a/app/src/infra/database/sequelize/models/Users.ts b/app/src/infra/database/sequelize/models/Users.ts new file mode 100644 index 00000000..4e808cff --- /dev/null +++ b/app/src/infra/database/sequelize/models/Users.ts @@ -0,0 +1,52 @@ +import { User } from '@/domain/models' +import Sequelize, { Model, Optional } from 'sequelize' +import { sequelizeConnection } from '../helpers' + +class UsersSequelize extends Model> {} + +UsersSequelize.init( + { + id: { + type: Sequelize.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + brithDay: { + type: Sequelize.DATE, + allowNull: false, + }, + email: { + type: Sequelize.STRING, + allowNull: false, + unique: true, + }, + name: { + type: Sequelize.STRING, + }, + password: { + type: Sequelize.STRING, + allowNull: false, + }, + createdAt: { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.NOW, + }, + updatedAt: { + type: Sequelize.DATE, + allowNull: true, + }, + role: { + type: Sequelize.STRING, + allowNull: false, + } + }, + { + createdAt: 'createdAt', + updatedAt: 'updatedAt', + sequelize: sequelizeConnection, + tableName: 'users', + }, +) + +export default UsersSequelize \ No newline at end of file From 76eb369d88a8b518a0950a48abcc53fb89a2ff33 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 00:56:27 -0300 Subject: [PATCH 021/105] feat: implementa UsersMySqlReposiory --- .../UsersMySQLRepository/users-mysql-repository.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts new file mode 100644 index 00000000..0032b20c --- /dev/null +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts @@ -0,0 +1,9 @@ +import { AddUser } from '@/domain/usecases/users' +import UsersSequelize from '../models/Users' + +export class UsersMySqlReposiory implements AddUser { + async add(user: AddUser.Params): Promise { + const newUser = await UsersSequelize.create(user) + return newUser as any as AddUser.Result + } +} From dca9cc4a6aaa5e524a171883f0473d4ae007d60b Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 00:56:33 -0300 Subject: [PATCH 022/105] test: implementa UsersMySqlReposiory --- app/src/domain/tests/users-mock.ts | 13 +++++- .../users-mysql-repository.test.ts | 40 +++++++++++++++++++ .../sequelize/__tests__/utils/index.ts | 2 + .../sequelize/__tests__/utils/migrate.ts | 6 +++ .../sequelize/__tests__/utils/truncate.ts | 12 ++++++ .../infra/database/sequelize/helpers/index.ts | 16 ++++++++ 6 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts create mode 100644 app/src/infra/database/sequelize/__tests__/utils/index.ts create mode 100644 app/src/infra/database/sequelize/__tests__/utils/migrate.ts create mode 100644 app/src/infra/database/sequelize/__tests__/utils/truncate.ts create mode 100644 app/src/infra/database/sequelize/helpers/index.ts diff --git a/app/src/domain/tests/users-mock.ts b/app/src/domain/tests/users-mock.ts index 612b9f49..9dd3e209 100644 --- a/app/src/domain/tests/users-mock.ts +++ b/app/src/domain/tests/users-mock.ts @@ -2,6 +2,15 @@ import { faker } from '@faker-js/faker' import { User } from '../models' import { AddUser, LoadUsersById } from '../usecases/users' import { LoadUsersByEmail } from '../usecases/users/load-users-by-email' +export function mockAddUser(): AddUser.Params { + return { + name: faker.name.fullName(), + email: faker.internet.email(), + password: faker.internet.password(), + brithDay: faker.date.past(), + role: faker.helpers.arrayElement(['admin', 'user']), + } +} export function mockUser(): User { return { @@ -11,8 +20,8 @@ export function mockUser(): User { password: faker.internet.password(), brithDay: faker.date.past(), role: faker.helpers.arrayElement(['admin', 'user']), - createdAt: faker.date.past(), - updatedAt: faker.date.past(), + createdAt: new Date(), + updatedAt: null, } } diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts new file mode 100644 index 00000000..33085254 --- /dev/null +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts @@ -0,0 +1,40 @@ +import { mockAddUser } from '@/domain/tests/users-mock' +import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' +import { UsersMySqlReposiory } from './users-mysql-repository' +import { migrate, truncate } from '../__tests__/utils' +import MockDate from 'mockdate' + +describe('UsersMySqlReposiory', () => { + function makeSut() { + const sut = new UsersMySqlReposiory() + return { sut } + } + + beforeAll(async () => { + MockDate.set(new Date()) + await migrate() + }) + + afterAll(async () => { + await truncate() + MockDate.reset() + }) + + beforeEach(async () => { + await truncate() + await migrate() + }) + describe('add()', () => { + test('should return an user on success', async () => { + const { sut } = makeSut() + const mockedUser = mockAddUser() + const user = await sut.add(mockedUser) + expect(user.name).toEqual(mockedUser.name) + expect(user.email).toEqual(mockedUser.email) + expect(user.password).toEqual(mockedUser.password) + expect(user.brithDay).toEqual(mockedUser.brithDay) + expect(user.role).toEqual(mockedUser.role) + expect(user.createdAt).toEqual(new Date()) + }) + }) +}) diff --git a/app/src/infra/database/sequelize/__tests__/utils/index.ts b/app/src/infra/database/sequelize/__tests__/utils/index.ts new file mode 100644 index 00000000..4b8cf7b3 --- /dev/null +++ b/app/src/infra/database/sequelize/__tests__/utils/index.ts @@ -0,0 +1,2 @@ +export * from './migrate' +export * from './truncate' \ No newline at end of file diff --git a/app/src/infra/database/sequelize/__tests__/utils/migrate.ts b/app/src/infra/database/sequelize/__tests__/utils/migrate.ts new file mode 100644 index 00000000..16e34f81 --- /dev/null +++ b/app/src/infra/database/sequelize/__tests__/utils/migrate.ts @@ -0,0 +1,6 @@ +import { sequelizeConnection } from '../../helpers'; + +export function migrate() { + return sequelizeConnection.sync({ force: true }) + } + \ No newline at end of file diff --git a/app/src/infra/database/sequelize/__tests__/utils/truncate.ts b/app/src/infra/database/sequelize/__tests__/utils/truncate.ts new file mode 100644 index 00000000..9a1bce13 --- /dev/null +++ b/app/src/infra/database/sequelize/__tests__/utils/truncate.ts @@ -0,0 +1,12 @@ +import { sequelizeConnection } from '../../helpers' + +export function truncate() { + return Promise.all( + Object.keys(sequelizeConnection.models).map((key) => { + return sequelizeConnection.models[key].destroy({ + truncate: true, + force: true, + }) + }) + ) +} \ No newline at end of file diff --git a/app/src/infra/database/sequelize/helpers/index.ts b/app/src/infra/database/sequelize/helpers/index.ts new file mode 100644 index 00000000..ab880b12 --- /dev/null +++ b/app/src/infra/database/sequelize/helpers/index.ts @@ -0,0 +1,16 @@ +import { config } from 'dotenv' +config({ + path: process.env.NODE_ENV === 'test' ? '.env.test' : '.env', +}) +import { sequelizeConfig } from './config' +import { Sequelize } from 'sequelize' + +function getSequelizeInstance() { + if (process.env.NODE_ENV !== 'test') { + return new Sequelize(sequelizeConfig) + } + + return new Sequelize('sqlite::memory:') +} + +export const sequelizeConnection = getSequelizeInstance() \ No newline at end of file From a91ad66e07b206b4773efcc597ac6a07a26992fb Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 01:15:18 -0300 Subject: [PATCH 023/105] refactor: cria AddUserMongoRepository --- .../protocols/database/users/add-user-repository.ts | 12 ++++++++++++ .../UsersMySQLRepository/users-mysql-repository.ts | 8 ++++---- 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 app/src/data/protocols/database/users/add-user-repository.ts diff --git a/app/src/data/protocols/database/users/add-user-repository.ts b/app/src/data/protocols/database/users/add-user-repository.ts new file mode 100644 index 00000000..b1677ff1 --- /dev/null +++ b/app/src/data/protocols/database/users/add-user-repository.ts @@ -0,0 +1,12 @@ +import { AddUser } from '@/domain/usecases/users' + +export interface AddUserRepository { + add: (user: AddUserRepository.Params) => Promise +} + +export namespace AddUserRepository { + export type Params = AddUser.Params + + export type Result = AddUser.Result + +} diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts index 0032b20c..14a5f608 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts @@ -1,9 +1,9 @@ -import { AddUser } from '@/domain/usecases/users' +import { AddUserRepository } from '@/data/protocols/database/users/add-user-repository' import UsersSequelize from '../models/Users' -export class UsersMySqlReposiory implements AddUser { - async add(user: AddUser.Params): Promise { +export class UsersMySqlReposiory implements AddUserRepository { + async add(user: AddUserRepository.Params): Promise { const newUser = await UsersSequelize.create(user) - return newUser as any as AddUser.Result + return newUser as any as AddUserRepository.Result } } From 97e70b966dadfe5c822dfeef9ebcd406be138b27 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 01:16:43 -0300 Subject: [PATCH 024/105] feat: cria DbAddUser --- app/src/data/usecases/users/db-add-user.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 app/src/data/usecases/users/db-add-user.ts diff --git a/app/src/data/usecases/users/db-add-user.ts b/app/src/data/usecases/users/db-add-user.ts new file mode 100644 index 00000000..04f1b403 --- /dev/null +++ b/app/src/data/usecases/users/db-add-user.ts @@ -0,0 +1,13 @@ +import { AddUserRepository } from '@/data/protocols/database/users/add-user-repository'; +import { AddUser } from '@/domain/usecases/users'; + +export class DbAddUser implements AddUser { + constructor( + private readonly addUserRepository: AddUserRepository, + ) {} + + async add(user: AddUser.Params): Promise { + await this.addUserRepository.add(user); + return null + } +} \ No newline at end of file From b02ac7818b4cb13a2a712eae15a77cfd7dce158e Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 01:16:57 -0300 Subject: [PATCH 025/105] test: cria DbAddUser --- app/src/data/test/users-mock.ts | 14 +++++++++++ .../data/usecases/users/db-add-user.test.ts | 23 +++++++++++++++++++ app/src/data/usecases/users/db-add-user.ts | 4 ++-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 app/src/data/test/users-mock.ts create mode 100644 app/src/data/usecases/users/db-add-user.test.ts diff --git a/app/src/data/test/users-mock.ts b/app/src/data/test/users-mock.ts new file mode 100644 index 00000000..283d061a --- /dev/null +++ b/app/src/data/test/users-mock.ts @@ -0,0 +1,14 @@ +import { mockUser } from '@/domain/tests/users-mock' +import { AddUserRepository } from '../protocols/database/users/add-user-repository' + +export class AddUserRepositorySpy implements AddUserRepository { + addParams: AddUserRepository.Params + addResult: AddUserRepository.Result + constructor() { + this.addResult = mockUser() + } + async add(params: AddUserRepository.Params): Promise { + this.addParams = params + return this.addResult + } +} \ No newline at end of file diff --git a/app/src/data/usecases/users/db-add-user.test.ts b/app/src/data/usecases/users/db-add-user.test.ts new file mode 100644 index 00000000..8b671359 --- /dev/null +++ b/app/src/data/usecases/users/db-add-user.test.ts @@ -0,0 +1,23 @@ +import { AddUserRepositorySpy } from '@/data/test/users-mock'; +import { mockAddUser } from '@/domain/tests/users-mock'; +import { describe, expect, test } from 'vitest'; +import { DbAddUser } from './db-add-user'; + +describe('DbAddUser', () => { + function makeSut() { + const addUserRepositorySpy = new AddUserRepositorySpy() + const sut = new DbAddUser(addUserRepositorySpy); + return { sut, addUserRepositorySpy }; + } + test('should call AddUserRepository with correct params', async () => { + const { sut, addUserRepositorySpy } = makeSut() + const addUser = mockAddUser() + await sut.add(addUser) + expect(addUserRepositorySpy.addParams).toEqual(addUser) + }); + test('should return a valid User on success', async () => { + const { sut, addUserRepositorySpy } = makeSut() + const user = await sut.add(mockAddUser()) + expect(user).toEqual(addUserRepositorySpy.addResult) + }); +}); \ No newline at end of file diff --git a/app/src/data/usecases/users/db-add-user.ts b/app/src/data/usecases/users/db-add-user.ts index 04f1b403..ff34f47b 100644 --- a/app/src/data/usecases/users/db-add-user.ts +++ b/app/src/data/usecases/users/db-add-user.ts @@ -7,7 +7,7 @@ export class DbAddUser implements AddUser { ) {} async add(user: AddUser.Params): Promise { - await this.addUserRepository.add(user); - return null + const newUser = await this.addUserRepository.add(user); + return newUser } } \ No newline at end of file From 9b86ba6846578a60e8b79239b887783dd9b5f1f1 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 01:30:40 -0300 Subject: [PATCH 026/105] feat: implementa LoadUsers --- .../protocols/database/users/load-user-repository.ts | 12 ++++++++++++ app/src/data/usecases/users/db-load-users.ts | 11 +++++++++++ 2 files changed, 23 insertions(+) create mode 100644 app/src/data/protocols/database/users/load-user-repository.ts create mode 100644 app/src/data/usecases/users/db-load-users.ts diff --git a/app/src/data/protocols/database/users/load-user-repository.ts b/app/src/data/protocols/database/users/load-user-repository.ts new file mode 100644 index 00000000..e1b81574 --- /dev/null +++ b/app/src/data/protocols/database/users/load-user-repository.ts @@ -0,0 +1,12 @@ +import { LoadUsers } from '@/domain/usecases/users' + +export interface LoadUsersRepository { + load: (params: LoadUsersRepository.Params) => Promise +} + +export namespace LoadUsersRepository { + export type Params = LoadUsers.Params + + export type Result = LoadUsers.Result + +} diff --git a/app/src/data/usecases/users/db-load-users.ts b/app/src/data/usecases/users/db-load-users.ts new file mode 100644 index 00000000..18c8e304 --- /dev/null +++ b/app/src/data/usecases/users/db-load-users.ts @@ -0,0 +1,11 @@ +import { LoadUsersRepository } from '@/data/protocols/database/users/load-user-repository'; +import { LoadUsers } from '@/domain/usecases/users'; + +export class DbLoadUsers implements LoadUsers { + constructor( + private readonly loadUsersRepository: LoadUsersRepository, + ) {} + async load(params: LoadUsers.Params): Promise { + return this.loadUsersRepository.load(params); + } +} \ No newline at end of file From fd98844419ee349216aacd05e60b071930c3fa38 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 01:30:56 -0300 Subject: [PATCH 027/105] test: implementa LoadUsers --- app/src/data/test/users-mock.ts | 13 ++++++++ .../data/usecases/users/db-load-users.test.ts | 31 +++++++++++++++++++ app/src/domain/usecases/users/load-users.ts | 7 +---- 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 app/src/data/usecases/users/db-load-users.test.ts diff --git a/app/src/data/test/users-mock.ts b/app/src/data/test/users-mock.ts index 283d061a..e20850a4 100644 --- a/app/src/data/test/users-mock.ts +++ b/app/src/data/test/users-mock.ts @@ -1,5 +1,6 @@ import { mockUser } from '@/domain/tests/users-mock' import { AddUserRepository } from '../protocols/database/users/add-user-repository' +import { LoadUsersRepository } from '../protocols/database/users/load-user-repository' export class AddUserRepositorySpy implements AddUserRepository { addParams: AddUserRepository.Params @@ -11,4 +12,16 @@ export class AddUserRepositorySpy implements AddUserRepository { this.addParams = params return this.addResult } +} + +export class LoadUsersRepositorySpy implements LoadUsersRepository { + loadParams: LoadUsersRepository.Params + loadResult: LoadUsersRepository.Result + constructor() { + this.loadResult =[mockUser()] + } + async load(params: LoadUsersRepository.Params): Promise { + this.loadParams = params + return this.loadResult + } } \ No newline at end of file diff --git a/app/src/data/usecases/users/db-load-users.test.ts b/app/src/data/usecases/users/db-load-users.test.ts new file mode 100644 index 00000000..a711f0fd --- /dev/null +++ b/app/src/data/usecases/users/db-load-users.test.ts @@ -0,0 +1,31 @@ +import { LoadUsersRepositorySpy } from '@/data/test/users-mock'; +import { describe, expect, test, vitest } from 'vitest'; +import { DbLoadUsers } from './db-load-users'; + +describe('DbLoadUsers', () => { + function makeSut() { + const loadUsersRepositorySpy = new LoadUsersRepositorySpy(); + const sut = new DbLoadUsers(loadUsersRepositorySpy); + return { sut, loadUsersRepositorySpy }; + } + describe('load()', () => { + test('should call loadUsersRepository with correct params', async () => { + const { sut, loadUsersRepositorySpy } = makeSut(); + await sut.load({order: 'asc'}); + expect(loadUsersRepositorySpy.loadParams).toEqual({order: 'asc'}); + }); + test('should return a list of users on success', async () => { + const { sut, loadUsersRepositorySpy } = makeSut(); + const users = await sut.load({order: 'asc'}); + expect(users).toEqual(loadUsersRepositorySpy.loadResult); + }) + + test('should throw if loadUsersRepository throws', async () => { + const { sut, loadUsersRepositorySpy } = makeSut(); + vitest.spyOn(loadUsersRepositorySpy, 'load').mockImplementationOnce(() => { + throw new Error(); + }); + await expect(sut.load({order: 'asc'})).rejects.toThrow(); + }); + }); +}); \ No newline at end of file diff --git a/app/src/domain/usecases/users/load-users.ts b/app/src/domain/usecases/users/load-users.ts index 345cb90e..74892a55 100644 --- a/app/src/domain/usecases/users/load-users.ts +++ b/app/src/domain/usecases/users/load-users.ts @@ -1,10 +1,5 @@ import { User } from '../../models'; -enum UserOrders { - asc = 'asc', - desc = 'desc' -} - export interface LoadUsers { /** * Load all users from database. @@ -18,7 +13,7 @@ export interface LoadUsers { */ export namespace LoadUsers { export type Params = { - order?: UserOrders; + order?: 'asc' | 'desc'; }; From e9b18c70fe89c42534292baee38ad815437e19d4 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 01:52:30 -0300 Subject: [PATCH 028/105] feat: implementa LoadUserRepository --- app/src/data/protocols/database/users/index.ts | 2 ++ .../database/users/load-user-repository.ts | 2 +- app/src/domain/usecases/users/load-users.ts | 2 +- .../UsersMySQLRepository/users-mysql-repository.ts | 14 ++++++++++++-- 4 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 app/src/data/protocols/database/users/index.ts diff --git a/app/src/data/protocols/database/users/index.ts b/app/src/data/protocols/database/users/index.ts new file mode 100644 index 00000000..97f56779 --- /dev/null +++ b/app/src/data/protocols/database/users/index.ts @@ -0,0 +1,2 @@ +export * from './load-user-repository' +export * from './add-user-repository' \ No newline at end of file diff --git a/app/src/data/protocols/database/users/load-user-repository.ts b/app/src/data/protocols/database/users/load-user-repository.ts index e1b81574..3da5a2d8 100644 --- a/app/src/data/protocols/database/users/load-user-repository.ts +++ b/app/src/data/protocols/database/users/load-user-repository.ts @@ -1,7 +1,7 @@ import { LoadUsers } from '@/domain/usecases/users' export interface LoadUsersRepository { - load: (params: LoadUsersRepository.Params) => Promise + load: (params?: LoadUsersRepository.Params) => Promise } export namespace LoadUsersRepository { diff --git a/app/src/domain/usecases/users/load-users.ts b/app/src/domain/usecases/users/load-users.ts index 74892a55..fd99f79e 100644 --- a/app/src/domain/usecases/users/load-users.ts +++ b/app/src/domain/usecases/users/load-users.ts @@ -4,7 +4,7 @@ export interface LoadUsers { /** * Load all users from database. */ - load (params: LoadUsers.Params): Promise + load (params?: LoadUsers.Params): Promise } /** diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts index 14a5f608..14c332fb 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts @@ -1,9 +1,19 @@ -import { AddUserRepository } from '@/data/protocols/database/users/add-user-repository' +import { AddUserRepository, LoadUsersRepository } from '@/data/protocols/database/users' import UsersSequelize from '../models/Users' -export class UsersMySqlReposiory implements AddUserRepository { +export class UsersMySqlReposiory implements AddUserRepository, LoadUsersRepository { async add(user: AddUserRepository.Params): Promise { const newUser = await UsersSequelize.create(user) return newUser as any as AddUserRepository.Result } + + async load(params?: LoadUsersRepository.Params): Promise { + const users = await UsersSequelize.findAll({ + order: [ + ['createdAt', params?.order || 'DESC'] + ] + }) + + return users as any as LoadUsersRepository.Result + } } From 68ebb0ee62461e6d5ded6bef8cfefcfd4258c34d Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 01:52:35 -0300 Subject: [PATCH 029/105] test: implementa LoadUserRepository --- .../users-mysql-repository.test.ts | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts index 33085254..8e939d47 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts @@ -3,6 +3,8 @@ import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' import { UsersMySqlReposiory } from './users-mysql-repository' import { migrate, truncate } from '../__tests__/utils' import MockDate from 'mockdate' +import UsersSequelize from '../models/Users' +import { User } from '@/domain/models' describe('UsersMySqlReposiory', () => { function makeSut() { @@ -37,4 +39,48 @@ describe('UsersMySqlReposiory', () => { expect(user.createdAt).toEqual(new Date()) }) }) + + describe('load()', () => { + test('should load all Users', async () => { + const { sut } = makeSut() + const mockedUser = mockAddUser() + const mockedOtherUser = mockAddUser() + + await UsersSequelize.create(mockedUser) + await UsersSequelize.create(mockedOtherUser) + + const users = await sut.load() + expect(users.length).toBe(2) + }) + + test('should load all Users in in descending order if called with order desc', async () => { + const { sut } = makeSut() + const mockMostRecentUser = mockAddUser() + mockMostRecentUser.createdAt = new Date('2021-01-01 13:00:00') + + const mockOldestUser = mockAddUser() + mockOldestUser.createdAt = new Date('2021-01-01 12:00:00') + + const mostRecentUser = await UsersSequelize.create(mockMostRecentUser) as any + const oldestUser = await UsersSequelize.create(mockOldestUser) as any + const users = await sut.load({ order: 'desc' }) + expect(users[0].id).toEqual(mostRecentUser.id) + expect(users[1].id).toEqual(oldestUser.id) + }) + + test('should load all Users in in ascending order if called with order asc', async () => { + const { sut } = makeSut() + const mockMostRecentUser = mockAddUser() + mockMostRecentUser.createdAt = new Date('2021-01-01 13:00:00') + + const mockOldestUser = mockAddUser() + mockOldestUser.createdAt = new Date('2021-01-01 12:00:00') + + const mostRecentUser = await UsersSequelize.create(mockMostRecentUser) as any + const oldestUser = await UsersSequelize.create(mockOldestUser) as any + const users = await sut.load({ order: 'asc' }) + expect(users[0].id).toEqual(oldestUser.id) + expect(users[1].id).toEqual(mostRecentUser.id) + }) + }) }) From 1b8f2e69263c06ee8c024274d75f5f4ebac272c7 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 02:01:52 -0300 Subject: [PATCH 030/105] feat: implementa LoadUsersByEmail --- .../data/protocols/database/users/index.ts | 3 +- .../users/load-user-by-email-repository.ts | 12 ++++++++ .../usecases/users/db-load-users-by-email.ts | 11 +++++++ .../users-mysql-repository.ts | 30 +++++++++++++++---- 4 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 app/src/data/protocols/database/users/load-user-by-email-repository.ts create mode 100644 app/src/data/usecases/users/db-load-users-by-email.ts diff --git a/app/src/data/protocols/database/users/index.ts b/app/src/data/protocols/database/users/index.ts index 97f56779..3b5fdddc 100644 --- a/app/src/data/protocols/database/users/index.ts +++ b/app/src/data/protocols/database/users/index.ts @@ -1,2 +1,3 @@ export * from './load-user-repository' -export * from './add-user-repository' \ No newline at end of file +export * from './add-user-repository' +export * from './load-user-by-email-repository' \ No newline at end of file diff --git a/app/src/data/protocols/database/users/load-user-by-email-repository.ts b/app/src/data/protocols/database/users/load-user-by-email-repository.ts new file mode 100644 index 00000000..7c760d33 --- /dev/null +++ b/app/src/data/protocols/database/users/load-user-by-email-repository.ts @@ -0,0 +1,12 @@ +import { LoadUsersByEmail } from '@/domain/usecases/users' + +export interface LoadUsersByEmailRepository { + loadByEmail: (params: LoadUsersByEmailRepository.Params) => Promise +} + +export namespace LoadUsersByEmailRepository { + export type Params = LoadUsersByEmail.Params + + export type Result = LoadUsersByEmail.Result + +} diff --git a/app/src/data/usecases/users/db-load-users-by-email.ts b/app/src/data/usecases/users/db-load-users-by-email.ts new file mode 100644 index 00000000..1e42cd6e --- /dev/null +++ b/app/src/data/usecases/users/db-load-users-by-email.ts @@ -0,0 +1,11 @@ +import { LoadUsersByEmailRepository } from '@/data/protocols/database/users'; +import { LoadUsersByEmail } from '@/domain/usecases/users'; + +export class DbLoadUsersByEmail implements LoadUsersByEmail { + constructor( + private readonly loadUsersByEmailRepository: LoadUsersByEmailRepository, + ) {} + async loadByEmail(params: LoadUsersByEmail.Params): Promise { + return this.loadUsersByEmailRepository.loadByEmail(params); + } +} \ No newline at end of file diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts index 14c332fb..9a7bf452 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts @@ -1,19 +1,37 @@ -import { AddUserRepository, LoadUsersRepository } from '@/data/protocols/database/users' +import { + AddUserRepository, + LoadUsersByEmailRepository, + LoadUsersRepository, +} from '@/data/protocols/database/users' import UsersSequelize from '../models/Users' -export class UsersMySqlReposiory implements AddUserRepository, LoadUsersRepository { +export class UsersMySqlReposiory + implements AddUserRepository, LoadUsersRepository, LoadUsersByEmailRepository +{ async add(user: AddUserRepository.Params): Promise { const newUser = await UsersSequelize.create(user) return newUser as any as AddUserRepository.Result } - async load(params?: LoadUsersRepository.Params): Promise { + async load( + params?: LoadUsersRepository.Params + ): Promise { const users = await UsersSequelize.findAll({ - order: [ - ['createdAt', params?.order || 'DESC'] - ] + order: [['createdAt', params?.order || 'DESC']], }) return users as any as LoadUsersRepository.Result } + + async loadByEmail( + params: LoadUsersByEmailRepository.Params + ): Promise { + const users = await UsersSequelize.findOne({ + where: { + email: params.email, + }, + }) + + return users as any as LoadUsersByEmailRepository.Result + } } From d4db5043cdf890286a9f05313f692d56e62eb10d Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 02:02:01 -0300 Subject: [PATCH 031/105] test: implementa LoadUsersByEmail --- app/src/data/test/users-mock.ts | 13 ++++++++++ .../users/db-load-users-by-email.test.ts | 26 +++++++++++++++++++ .../users-mysql-repository.test.ts | 17 ++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 app/src/data/usecases/users/db-load-users-by-email.test.ts diff --git a/app/src/data/test/users-mock.ts b/app/src/data/test/users-mock.ts index e20850a4..4be59d05 100644 --- a/app/src/data/test/users-mock.ts +++ b/app/src/data/test/users-mock.ts @@ -1,4 +1,5 @@ import { mockUser } from '@/domain/tests/users-mock' +import { LoadUsersByEmailRepository } from '../protocols/database/users' import { AddUserRepository } from '../protocols/database/users/add-user-repository' import { LoadUsersRepository } from '../protocols/database/users/load-user-repository' @@ -24,4 +25,16 @@ export class LoadUsersRepositorySpy implements LoadUsersRepository { this.loadParams = params return this.loadResult } +} + +export class LoadUsersByEmailRepositorySpy implements LoadUsersByEmailRepository { + loadByEmailParams: LoadUsersByEmailRepository.Params + loadByEmailResult: LoadUsersByEmailRepository.Result + constructor() { + this.loadByEmailResult =mockUser() + } + async loadByEmail(params: LoadUsersByEmailRepository.Params): Promise { + this.loadByEmailParams = params + return this.loadByEmailResult + } } \ No newline at end of file diff --git a/app/src/data/usecases/users/db-load-users-by-email.test.ts b/app/src/data/usecases/users/db-load-users-by-email.test.ts new file mode 100644 index 00000000..3e6ed65a --- /dev/null +++ b/app/src/data/usecases/users/db-load-users-by-email.test.ts @@ -0,0 +1,26 @@ +import { LoadUsersByEmailRepositorySpy } from '@/data/test/users-mock'; +import { faker } from '@faker-js/faker'; +import { describe, expect, test, vitest } from 'vitest'; +import { DbLoadUsersByEmail } from './db-load-users-by-email'; + +describe('DbLoadUsersByEmail', () => { + function makeSut() { + const loadUsersByEmailRepositorySpy = new LoadUsersByEmailRepositorySpy(); + const sut = new DbLoadUsersByEmail(loadUsersByEmailRepositorySpy); + return { sut, loadUsersByEmailRepositorySpy }; + } + describe('loadByEmail()', () => { + test('should call loadUsersRepository with correct params', async () => { + const { sut, loadUsersByEmailRepositorySpy } = makeSut(); + const email = faker.internet.email() + await sut.loadByEmail({email}); + expect(loadUsersByEmailRepositorySpy.loadByEmailParams).toEqual({email}); + }); + + test('should return a user on success', async () => { + const { sut, loadUsersByEmailRepositorySpy } = makeSut(); + const user = await sut.loadByEmail({email: faker.internet.email()}); + expect(user).toEqual(loadUsersByEmailRepositorySpy.loadByEmailResult); + }) + }); +}); \ No newline at end of file diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts index 8e939d47..ee711a23 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts @@ -83,4 +83,21 @@ describe('UsersMySqlReposiory', () => { expect(users[1].id).toEqual(mostRecentUser.id) }) }) + + describe('loadByEmail()', () => { + test('should load the correct User according to the email', async () => { + const { sut } = makeSut() + const mockedUser = mockAddUser() + const mockedOtherUser = mockAddUser() + + await UsersSequelize.create(mockedUser) + await UsersSequelize.create(mockedOtherUser) + + const user = await sut.loadByEmail({ + email: mockedUser.email + }) + expect(user.name).toEqual(mockedUser.name) + expect(user.email).toEqual(mockedUser.email) + }) + }) }) From de785a5db8de6c311e971c31d009f7f08c3d61f1 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 02:03:51 -0300 Subject: [PATCH 032/105] feat: cria factories para compor AddUserController --- app/src/data/usecases/users/index.ts | 3 +++ .../controllers/user/add-user-controller-factory.ts | 7 +++++++ app/src/main/factories/controllers/user/index.ts | 0 .../factories/usecases/user/add-user-usecase-factory.ts | 8 ++++++++ app/src/main/factories/usecases/user/index.ts | 3 +++ .../usecases/user/load-users-by-email-usecase-factory.ts | 7 +++++++ .../factories/usecases/user/load-users-usecase-factory.ts | 7 +++++++ 7 files changed, 35 insertions(+) create mode 100644 app/src/data/usecases/users/index.ts create mode 100644 app/src/main/factories/controllers/user/add-user-controller-factory.ts create mode 100644 app/src/main/factories/controllers/user/index.ts create mode 100644 app/src/main/factories/usecases/user/add-user-usecase-factory.ts create mode 100644 app/src/main/factories/usecases/user/index.ts create mode 100644 app/src/main/factories/usecases/user/load-users-by-email-usecase-factory.ts create mode 100644 app/src/main/factories/usecases/user/load-users-usecase-factory.ts diff --git a/app/src/data/usecases/users/index.ts b/app/src/data/usecases/users/index.ts new file mode 100644 index 00000000..8b5f6bc5 --- /dev/null +++ b/app/src/data/usecases/users/index.ts @@ -0,0 +1,3 @@ +export * from './db-add-user' +export * from './db-load-users' +export * from './db-load-users-by-email' \ No newline at end of file diff --git a/app/src/main/factories/controllers/user/add-user-controller-factory.ts b/app/src/main/factories/controllers/user/add-user-controller-factory.ts new file mode 100644 index 00000000..d5c7ecbf --- /dev/null +++ b/app/src/main/factories/controllers/user/add-user-controller-factory.ts @@ -0,0 +1,7 @@ +import { AddUserController } from '@/presentation/controllers/users-controller'; +import { Controller } from '@/presentation/protocols'; +import { makeDbAddUser, makeDbLoadUsersByEmail } from '../../usecases/user'; + +export function makeAddUserController(): Controller { + return new AddUserController(makeDbAddUser(), makeDbLoadUsersByEmail()); +} \ No newline at end of file diff --git a/app/src/main/factories/controllers/user/index.ts b/app/src/main/factories/controllers/user/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/app/src/main/factories/usecases/user/add-user-usecase-factory.ts b/app/src/main/factories/usecases/user/add-user-usecase-factory.ts new file mode 100644 index 00000000..b723c081 --- /dev/null +++ b/app/src/main/factories/usecases/user/add-user-usecase-factory.ts @@ -0,0 +1,8 @@ +import { DbAddUser } from '@/data/usecases/users/db-add-user'; +import { AddUser } from '@/domain/usecases/users'; +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository'; + +export function makeDbAddUser(): AddUser { + const addUserRepository = new UsersMySqlReposiory(); + return new DbAddUser(addUserRepository); +} \ No newline at end of file diff --git a/app/src/main/factories/usecases/user/index.ts b/app/src/main/factories/usecases/user/index.ts new file mode 100644 index 00000000..3875192d --- /dev/null +++ b/app/src/main/factories/usecases/user/index.ts @@ -0,0 +1,3 @@ +export * from './add-user-usecase-factory' +export * from './load-users-usecase-factory' +export * from './load-users-by-email-usecase-factory' \ No newline at end of file diff --git a/app/src/main/factories/usecases/user/load-users-by-email-usecase-factory.ts b/app/src/main/factories/usecases/user/load-users-by-email-usecase-factory.ts new file mode 100644 index 00000000..81ee0d02 --- /dev/null +++ b/app/src/main/factories/usecases/user/load-users-by-email-usecase-factory.ts @@ -0,0 +1,7 @@ +import { DbLoadUsersByEmail } from '@/data/usecases/users' +import { LoadUsersByEmail } from '@/domain/usecases/users' +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository' + +export function makeDbLoadUsersByEmail(): LoadUsersByEmail { + return new DbLoadUsersByEmail(new UsersMySqlReposiory()) +} diff --git a/app/src/main/factories/usecases/user/load-users-usecase-factory.ts b/app/src/main/factories/usecases/user/load-users-usecase-factory.ts new file mode 100644 index 00000000..c06abebf --- /dev/null +++ b/app/src/main/factories/usecases/user/load-users-usecase-factory.ts @@ -0,0 +1,7 @@ +import { DbLoadUsers } from '@/data/usecases/users/db-load-users' +import { LoadUsers } from '@/domain/usecases/users' +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository' + +export function makeDbLoadUsers(): LoadUsers { + return new DbLoadUsers(new UsersMySqlReposiory()) +} From a782782c8bf412d821b827a8574f970eb3a01316 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 02:59:21 -0300 Subject: [PATCH 033/105] =?UTF-8?q?chore:=20configura=20aplica=C3=A7=C3=A3?= =?UTF-8?q?o=20para=20rodar=20migrations=20corretamente=20e=20iniciar=20co?= =?UTF-8?q?rretamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/.gitignore | 3 +- app/nodemon.json | 2 +- app/package-lock.json | 2521 ++++++++++++++++- app/package.json | 12 +- .../database/sequelize/helpers/_config.js | 13 +- app/tsconfig.json | 5 +- 6 files changed, 2434 insertions(+), 122 deletions(-) diff --git a/app/.gitignore b/app/.gitignore index 1dcef2d9..56f07a37 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1,2 +1,3 @@ node_modules -.env \ No newline at end of file +.env +.database.* \ No newline at end of file diff --git a/app/nodemon.json b/app/nodemon.json index db198016..f2d8a4fe 100644 --- a/app/nodemon.json +++ b/app/nodemon.json @@ -1,5 +1,5 @@ { "execMap": { - "ts": "ts-node" + "ts": "ts-node -r tsconfig-paths/register" } } \ No newline at end of file diff --git a/app/package-lock.json b/app/package-lock.json index a172d961..d6d2a3a4 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -11,16 +11,22 @@ "dependencies": { "cross-env": "^7.0.3", "dotenv": "^16.0.3", + "express": "^4.18.2", "mysql2": "^2.3.3", "sequelize": "^6.25.1", - "sequelize-cli": "^6.5.1" + "sequelize-cli": "^6.5.1", + "ts-node-dev": "^2.0.0" }, "devDependencies": { "@faker-js/faker": "^7.6.0", + "@types/express": "^4.17.14", "@types/node": "^18.11.0", "mockdate": "^3.0.5", + "nodemon": "^2.0.20", "sqlite3": "^5.1.2", + "supertest": "^6.3.0", "ts-node": "^10.9.1", + "tsconfig-paths": "^4.1.0", "typescript": "^4.8.4", "vitest": "^0.24.3", "vitest-tsconfig-paths": "^3.4.1" @@ -33,7 +39,6 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -100,7 +105,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -108,14 +112,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -194,26 +196,32 @@ "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } }, "node_modules/@types/chai": { "version": "4.3.3", @@ -230,6 +238,15 @@ "@types/chai": "*" } }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -238,12 +255,41 @@ "@types/ms": "*" } }, + "node_modules/@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "dev": true + }, "node_modules/@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", @@ -254,6 +300,38 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==" }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dev": true, + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==" + }, + "node_modules/@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==" + }, "node_modules/@types/validator": { "version": "13.7.7", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", @@ -264,11 +342,22 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -280,7 +369,6 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -348,6 +436,18 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -370,7 +470,17 @@ "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, "node_modules/assertion-error": { @@ -382,6 +492,12 @@ "node": "*" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -395,11 +511,74 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -408,6 +587,30 @@ "balanced-match": "^1.0.0" } }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/cacache": { "version": "15.3.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", @@ -483,6 +686,18 @@ "node": "*" } }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/chai": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", @@ -510,6 +725,32 @@ "node": "*" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -579,16 +820,33 @@ "color-support": "bin.js" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/config-chain": { "version": "1.1.13", @@ -605,11 +863,48 @@ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "dev": true + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "node_modules/cross-env": { "version": "7.0.3", @@ -678,6 +973,15 @@ "node": ">=0.12" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -702,6 +1006,15 @@ "node": ">= 0.6" } }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/detect-libc": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", @@ -711,11 +1024,20 @@ "node": ">=8" } }, + "node_modules/dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, "engines": { "node": ">=0.3.1" } @@ -733,6 +1055,14 @@ "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" }, + "node_modules/dynamic-dedupe": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", + "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==", + "dependencies": { + "xtend": "^4.0.0" + } + }, "node_modules/editorconfig": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", @@ -769,11 +1099,24 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", @@ -1210,6 +1553,19 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", @@ -1219,6 +1575,68 @@ "es5-ext": "~0.10.14" } }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", @@ -1232,6 +1650,110 @@ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formidable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.0.1.tgz", + "integrity": "sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==", + "dev": true, + "dependencies": { + "dezalgo": "1.0.3", + "hexoid": "1.0.0", + "once": "1.4.0", + "qs": "6.9.3" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/formidable/node_modules/qs": { + "version": "6.9.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz", + "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==", + "dev": true, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -1267,7 +1789,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -1327,6 +1848,19 @@ "node": "*" } }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", @@ -1345,6 +1879,17 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/glob-regex": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/glob-regex/-/glob-regex-0.3.2.tgz", @@ -1373,12 +1918,41 @@ "node": ">= 0.4.0" } }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -1386,6 +1960,29 @@ "dev": true, "optional": true }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/http-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", @@ -1435,6 +2032,12 @@ "node": ">=0.10.0" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -1496,6 +2099,25 @@ "dev": true, "optional": true }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-core-module": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", @@ -1507,6 +2129,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -1515,6 +2145,17 @@ "node": ">=8" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", @@ -1522,6 +2163,14 @@ "dev": true, "optional": true }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", @@ -1557,15 +2206,15 @@ } }, "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, "bin": { "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/jsonfile": { @@ -1656,8 +2305,7 @@ "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "node_modules/make-fetch-happen": { "version": "9.1.0", @@ -1687,6 +2335,14 @@ "node": ">= 10" } }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/memoizee": { "version": "0.4.15", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", @@ -1702,6 +2358,49 @@ "timers-ext": "^0.1.7" } }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", @@ -1717,7 +2416,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1821,7 +2519,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -1918,8 +2615,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "optional": true, "engines": { "node": ">= 0.6" } @@ -2091,6 +2786,74 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/nopt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", @@ -2105,6 +2868,14 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", @@ -2126,6 +2897,25 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2150,11 +2940,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2172,6 +2969,11 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -2192,6 +2994,17 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/postcss": { "version": "8.4.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", @@ -2242,11 +3055,76 @@ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -2261,6 +3139,17 @@ "node": ">= 6" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/recrawl-sync": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", @@ -2388,7 +3277,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -2423,6 +3311,55 @@ "node": ">=10" } }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/seq-queue": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", @@ -2518,12 +3455,31 @@ "node": ">= 10.0.0" } }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2543,6 +3499,19 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", @@ -2554,6 +3523,27 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/simple-update-notifier": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", + "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -2604,6 +3594,14 @@ "node": ">= 10" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -2613,6 +3611,15 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/sqlite3": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.2.tgz", @@ -2657,6 +3664,14 @@ "node": ">= 8" } }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -2694,11 +3709,18 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, "engines": { "node": ">=4" } }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-literal": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz", @@ -2711,6 +3733,65 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/superagent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.2.tgz", + "integrity": "sha512-QtYZ9uaNAMexI7XWl2vAXAh0j4q9H7T0WVEI/y5qaUB3QLwxo+voUgCQ217AokJzUTIVOp0RTo7fhZrwhD7A2Q==", + "deprecated": "Please use v8.0.0 until https://github.com/visionmedia/superagent/issues/1743 is resolved", + "dev": true, + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.3", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.0.1", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=6.4.0 <13 || >=14" + } + }, + "node_modules/superagent/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/supertest": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.0.tgz", + "integrity": "sha512-QgWju1cNoacP81Rv88NKkQ4oXTzGg0eNZtOoxp1ROpbS4OHY/eK5b8meShuFtdni161o5X0VQvgo7ErVyKK+Ow==", + "dev": true, + "dependencies": { + "methods": "^1.1.2", + "superagent": "^8.0.0" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -2772,22 +3853,75 @@ "node": ">=14.0.0" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/toposort-class": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/touch/node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -2826,16 +3960,112 @@ } } }, + "node_modules/ts-node-dev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz", + "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==", + "dependencies": { + "chokidar": "^3.5.1", + "dynamic-dedupe": "^0.3.0", + "minimist": "^1.2.6", + "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": "^10.4.0", + "tsconfig": "^7.0.0" + }, + "bin": { + "ts-node-dev": "lib/bin.js", + "tsnd": "lib/bin.js" + }, + "engines": { + "node": ">=0.8.0" + }, + "peerDependencies": { + "node-notifier": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/ts-node-dev/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/ts-node-dev/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ts-node-dev/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ts-node-dev/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/tsconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "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" + } + }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz", + "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==", "dev": true, "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^2.2.1", "minimist": "^1.2.6", "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/tslib": { @@ -2858,11 +4088,22 @@ "node": ">=4" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2882,6 +4123,12 @@ "node": ">=6.0.0" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "node_modules/unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -2910,12 +4157,28 @@ "node": ">= 10.0.0" } }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -2927,8 +4190,7 @@ "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "node_modules/validator": { "version": "13.7.0", @@ -2938,6 +4200,14 @@ "node": ">= 0.10" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vite": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.8.tgz", @@ -3043,6 +4313,30 @@ "tsconfig-paths": "^3.9.0" } }, + "node_modules/vitest-tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/vitest-tsconfig-paths/node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -3111,6 +4405,14 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -3153,7 +4455,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, "engines": { "node": ">=6" } @@ -3164,7 +4465,6 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" } @@ -3205,20 +4505,17 @@ "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, "@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -3284,26 +4581,32 @@ "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, "@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } }, "@types/chai": { "version": "4.3.3", @@ -3320,6 +4623,15 @@ "@types/chai": "*" } }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -3328,12 +4640,41 @@ "@types/ms": "*" } }, + "@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "dev": true + }, "@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", @@ -3344,6 +4685,38 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==" }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dev": true, + "requires": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==" + }, + "@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==" + }, "@types/validator": { "version": "13.7.7", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", @@ -3354,17 +4727,24 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, "acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" }, "acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" }, "agent-base": { "version": "6.0.2", @@ -3411,6 +4791,15 @@ "color-convert": "^2.0.1" } }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -3430,7 +4819,17 @@ "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, "assertion-error": { @@ -3439,6 +4838,12 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -3449,11 +4854,63 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -3462,6 +4919,24 @@ "balanced-match": "^1.0.0" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, "cacache": { "version": "15.3.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", @@ -3527,6 +5002,15 @@ } } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "chai": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", @@ -3548,6 +5032,21 @@ "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -3602,16 +5101,30 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "config-chain": { "version": "1.1.13", @@ -3628,11 +5141,39 @@ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "dev": true + }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "cross-env": { "version": "7.0.3", @@ -3678,6 +5219,12 @@ "type-detect": "^4.0.0" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -3696,17 +5243,31 @@ "dev": true, "optional": true }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, "detect-libc": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", "dev": true }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" }, "dotenv": { "version": "16.0.3", @@ -3718,6 +5279,14 @@ "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" }, + "dynamic-dedupe": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", + "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==", + "requires": { + "xtend": "^4.0.0" + } + }, "editorconfig": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", @@ -3750,11 +5319,21 @@ } } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, "encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", @@ -3994,6 +5573,16 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", @@ -4003,6 +5592,64 @@ "es5-ext": "~0.10.14" } }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, "ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", @@ -4018,6 +5665,90 @@ } } }, + "fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.0.1.tgz", + "integrity": "sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==", + "dev": true, + "requires": { + "dezalgo": "1.0.3", + "hexoid": "1.0.0", + "once": "1.4.0", + "qs": "6.9.3" + }, + "dependencies": { + "qs": { + "version": "6.9.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz", + "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==", + "dev": true + } + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, "fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -4047,7 +5778,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true }, "function-bind": { @@ -4091,6 +5821,16 @@ "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, "glob": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", @@ -4103,6 +5843,14 @@ "once": "^1.3.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, "glob-regex": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/glob-regex/-/glob-regex-0.3.2.tgz", @@ -4128,12 +5876,29 @@ "function-bind": "^1.1.1" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, + "hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "dev": true + }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -4141,6 +5906,25 @@ "dev": true, "optional": true }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, "http-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", @@ -4181,6 +5965,12 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4233,6 +6023,19 @@ "dev": true, "optional": true }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-core-module": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", @@ -4241,11 +6044,24 @@ "has": "^1.0.3" } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", @@ -4253,6 +6069,11 @@ "dev": true, "optional": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, "is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", @@ -4280,13 +6101,10 @@ } }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true }, "jsonfile": { "version": "6.1.0", @@ -4358,8 +6176,7 @@ "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "make-fetch-happen": { "version": "9.1.0", @@ -4386,6 +6203,11 @@ "ssri": "^8.0.0" } }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, "memoizee": { "version": "0.4.15", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", @@ -4401,6 +6223,34 @@ "timers-ext": "^0.1.7" } }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, "minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", @@ -4412,8 +6262,7 @@ "minimist": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" }, "minipass": { "version": "3.3.4", @@ -4490,8 +6339,7 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "mockdate": { "version": "3.0.5", @@ -4565,9 +6413,7 @@ "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "optional": true + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "next-tick": { "version": "1.1.0", @@ -4697,6 +6543,60 @@ } } }, + "nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, "nopt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", @@ -4705,6 +6605,11 @@ "abbrev": "^1.0.0" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, "npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", @@ -4723,6 +6628,19 @@ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4741,11 +6659,15 @@ "aggregate-error": "^3.0.0" } }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -4757,6 +6679,11 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, "pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -4774,6 +6701,11 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, "postcss": { "version": "8.4.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", @@ -4808,11 +6740,60 @@ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -4824,6 +6805,14 @@ "util-deprecate": "^1.0.1" } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, "recrawl-sync": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.2.tgz", @@ -4919,8 +6908,7 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { "version": "2.1.2", @@ -4935,6 +6923,53 @@ "lru-cache": "^6.0.0" } }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, "seq-queue": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", @@ -4982,12 +7017,28 @@ "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==" }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5001,6 +7052,16 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", @@ -5012,6 +7073,23 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "simple-update-notifier": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", + "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "dev": true, + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5048,12 +7126,26 @@ "socks": "^2.6.2" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "sqlite3": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.2.tgz", @@ -5081,6 +7173,11 @@ "minipass": "^3.1.1" } }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -5111,8 +7208,12 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" }, "strip-literal": { "version": "0.4.2", @@ -5123,6 +7224,51 @@ "acorn": "^8.8.0" } }, + "superagent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.2.tgz", + "integrity": "sha512-QtYZ9uaNAMexI7XWl2vAXAh0j4q9H7T0WVEI/y5qaUB3QLwxo+voUgCQ217AokJzUTIVOp0RTo7fhZrwhD7A2Q==", + "dev": true, + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.3", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.0.1", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0", + "semver": "^7.3.7" + }, + "dependencies": { + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true + } + } + }, + "supertest": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.0.tgz", + "integrity": "sha512-QgWju1cNoacP81Rv88NKkQ4oXTzGg0eNZtOoxp1ROpbS4OHY/eK5b8meShuFtdni161o5X0VQvgo7ErVyKK+Ow==", + "dev": true, + "requires": { + "methods": "^1.1.2", + "superagent": "^8.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -5169,22 +7315,59 @@ "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, "toposort-class": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" + }, "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -5201,14 +7384,81 @@ "yn": "3.1.1" } }, + "ts-node-dev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz", + "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==", + "requires": { + "chokidar": "^3.5.1", + "dynamic-dedupe": "^0.3.0", + "minimist": "^1.2.6", + "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": "^10.4.0", + "tsconfig": "^7.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "tsconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", + "requires": { + "@types/strip-bom": "^3.0.0", + "@types/strip-json-comments": "0.0.30", + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + } + }, "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz", + "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==", "dev": true, "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^2.2.1", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } @@ -5230,11 +7480,19 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, "typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" }, "umzug": { "version": "2.3.0", @@ -5244,6 +7502,12 @@ "bluebird": "^3.7.2" } }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -5269,12 +7533,22 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -5283,14 +7557,18 @@ "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "validator": { "version": "13.7.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, "vite": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.8.tgz", @@ -5333,6 +7611,29 @@ "globrex": "^0.1.2", "recrawl-sync": "^2.0.3", "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + } } }, "webidl-conversions": { @@ -5391,6 +7692,11 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -5423,8 +7729,7 @@ "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" } } } diff --git a/app/package.json b/app/package.json index 1094e0e5..4544215c 100644 --- a/app/package.json +++ b/app/package.json @@ -3,19 +3,23 @@ "version": "1.0.0", "description": "", "main": "index.js", - "type": "module", "scripts": { - "test": "cross-env NODE_ENV=test vitest" + "test": "cross-env NODE_ENV=test vitest", + "start": "nodemon src/main/server.ts " }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@faker-js/faker": "^7.6.0", + "@types/express": "^4.17.14", "@types/node": "^18.11.0", "mockdate": "^3.0.5", + "nodemon": "^2.0.20", "sqlite3": "^5.1.2", + "supertest": "^6.3.0", "ts-node": "^10.9.1", + "tsconfig-paths": "^4.1.0", "typescript": "^4.8.4", "vitest": "^0.24.3", "vitest-tsconfig-paths": "^3.4.1" @@ -26,8 +30,10 @@ "dependencies": { "cross-env": "^7.0.3", "dotenv": "^16.0.3", + "express": "^4.18.2", "mysql2": "^2.3.3", "sequelize": "^6.25.1", - "sequelize-cli": "^6.5.1" + "sequelize-cli": "^6.5.1", + "ts-node-dev": "^2.0.0" } } diff --git a/app/src/infra/database/sequelize/helpers/_config.js b/app/src/infra/database/sequelize/helpers/_config.js index 84174b6e..55a69931 100644 --- a/app/src/infra/database/sequelize/helpers/_config.js +++ b/app/src/infra/database/sequelize/helpers/_config.js @@ -1,15 +1,14 @@ -import { config } from 'dotenv' -config({ +require('dotenv').config({ path: process.env.NODE_ENV === 'test' ? '.env.test' : '.env' }) - - -export default { +const { resolve } = require('path') +module.exports = { host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT), username: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME, - dialect: process.env.DB_DIALECT || 'mysql', - logging: false + dialect: process.env.DB_DIALECT || 'sqlite', + logging: false, + storage: resolve(__dirname, './../__tests__/.database.sqlite'), } diff --git a/app/tsconfig.json b/app/tsconfig.json index 52de1925..c063fae8 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "outDir": "dist", - "module": "commonjs", + "module": "CommonJS", "target": "ES2021", "esModuleInterop": true, "strictNullChecks": false, @@ -11,7 +11,8 @@ "allowJs": true, "paths": { "@/*": ["*"] - } + }, + "moduleResolution": "node" }, "include": ["src"] } From fcc8a7f8c519ebc345a2bc8649c865567fe01aa4 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Sat, 15 Oct 2022 02:59:52 -0300 Subject: [PATCH 034/105] =?UTF-8?q?feat:=20ajustes=20para=20iniciar=20a=20?= =?UTF-8?q?aplica=C3=A7=C3=A3o=20e=20testar=20as=20rotas=20de=20users?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../database/sequelize/helpers/config.ts | 4 +-- .../adapters/express/express-route-adapter.ts | 26 ++++++++++++++++ app/src/main/config/app.ts | 9 ++++++ app/src/main/config/middlewares.ts | 8 +++++ app/src/main/config/routes.ts | 8 +++++ app/src/main/middlewares/body-parser.test.ts | 19 ++++++++++++ app/src/main/middlewares/body-parser.ts | 3 ++ app/src/main/middlewares/content-type.test.ts | 26 ++++++++++++++++ app/src/main/middlewares/content-type.ts | 6 ++++ app/src/main/middlewares/cors.test.ts | 17 ++++++++++ app/src/main/middlewares/cors.ts | 9 ++++++ app/src/main/middlewares/index.ts | 3 ++ app/src/main/routes/index.ts | 1 + app/src/main/routes/users-routes.ts | 8 +++++ app/src/main/server.ts | 31 +++++++++++++++++++ 15 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 app/src/main/adapters/express/express-route-adapter.ts create mode 100644 app/src/main/config/app.ts create mode 100644 app/src/main/config/middlewares.ts create mode 100644 app/src/main/config/routes.ts create mode 100644 app/src/main/middlewares/body-parser.test.ts create mode 100644 app/src/main/middlewares/body-parser.ts create mode 100644 app/src/main/middlewares/content-type.test.ts create mode 100644 app/src/main/middlewares/content-type.ts create mode 100644 app/src/main/middlewares/cors.test.ts create mode 100644 app/src/main/middlewares/cors.ts create mode 100644 app/src/main/middlewares/index.ts create mode 100644 app/src/main/routes/index.ts create mode 100644 app/src/main/routes/users-routes.ts create mode 100644 app/src/main/server.ts diff --git a/app/src/infra/database/sequelize/helpers/config.ts b/app/src/infra/database/sequelize/helpers/config.ts index b2aeb7e6..e5be7251 100644 --- a/app/src/infra/database/sequelize/helpers/config.ts +++ b/app/src/infra/database/sequelize/helpers/config.ts @@ -1,5 +1,5 @@ -import config from './_config' +import config from './_config.js' import { Options } from 'sequelize'; -export const sequelizeConfig: Options = config \ No newline at end of file +export const sequelizeConfig: Options = config as any \ No newline at end of file diff --git a/app/src/main/adapters/express/express-route-adapter.ts b/app/src/main/adapters/express/express-route-adapter.ts new file mode 100644 index 00000000..8194dbfa --- /dev/null +++ b/app/src/main/adapters/express/express-route-adapter.ts @@ -0,0 +1,26 @@ +import { Request, Response } from 'express' +import { Controller } from '@/presentation/protocols' + +export function adaptRoute (controller: Controller) { + return async function (req: Request, res: Response): Promise { + const httpRequest: any = { + ...(req.body || {}), + ...(req.params || {}), + } + try { + const httpResponse = await controller.handle(httpRequest) + if (httpResponse.statusCode >= 200 && httpResponse.statusCode <= 299) { + res.status(httpResponse.statusCode).json(httpResponse.body) + return + } + + res.status(httpResponse.statusCode).json({ + error: httpResponse.body.message + }) + } catch (error) { + res.status(500).json({ + error: error.message + }) + } + } +} diff --git a/app/src/main/config/app.ts b/app/src/main/config/app.ts new file mode 100644 index 00000000..5e4951ba --- /dev/null +++ b/app/src/main/config/app.ts @@ -0,0 +1,9 @@ +import express from 'express' +import { setupMiddlewares } from './middlewares' +import { setupRoutes } from './routes' + +const app = express() +setupMiddlewares(app) +setupRoutes(app) + +export default app diff --git a/app/src/main/config/middlewares.ts b/app/src/main/config/middlewares.ts new file mode 100644 index 00000000..36692775 --- /dev/null +++ b/app/src/main/config/middlewares.ts @@ -0,0 +1,8 @@ +import { Express } from 'express' +import { bodyParser, contentType, cors } from '../middlewares' + +export function setupMiddlewares (app: Express): void { + app.use(contentType) + app.use(bodyParser) + app.use(cors) +} diff --git a/app/src/main/config/routes.ts b/app/src/main/config/routes.ts new file mode 100644 index 00000000..30413217 --- /dev/null +++ b/app/src/main/config/routes.ts @@ -0,0 +1,8 @@ +import { Express, Router } from 'express' +import {usersRoutes} from '../routes/users-routes' + +export function setupRoutes(app: Express) { + const router = Router() + usersRoutes(router) + app.use(router) +} \ No newline at end of file diff --git a/app/src/main/middlewares/body-parser.test.ts b/app/src/main/middlewares/body-parser.test.ts new file mode 100644 index 00000000..5ba91854 --- /dev/null +++ b/app/src/main/middlewares/body-parser.test.ts @@ -0,0 +1,19 @@ +import request from 'supertest' +import { describe, test } from 'vitest' +import app from '../config/app' + +describe('Body Parser Middleware', () => { + test('Should parse body as json', async () => { + const bodyMock = { + name: 'Guilherme' + } + app.post('/test_body_parser', (req, res) => { + return res.send(req.body) + }) + + await request(app) + .post('/test_body_parser') + .send(bodyMock) + .expect(bodyMock) + }) +}) diff --git a/app/src/main/middlewares/body-parser.ts b/app/src/main/middlewares/body-parser.ts new file mode 100644 index 00000000..34d89a46 --- /dev/null +++ b/app/src/main/middlewares/body-parser.ts @@ -0,0 +1,3 @@ +import { json } from 'express' + +export const bodyParser = json() diff --git a/app/src/main/middlewares/content-type.test.ts b/app/src/main/middlewares/content-type.test.ts new file mode 100644 index 00000000..d606abcd --- /dev/null +++ b/app/src/main/middlewares/content-type.test.ts @@ -0,0 +1,26 @@ +import request from 'supertest' +import { describe, test } from 'vitest' +import app from '../config/app' + +describe('Content Type Middleware', () => { + test('Should return default content type as json', async () => { + app.get('/test_content_type', (req, res) => { + return res.send('') + }) + + await request(app) + .get('/test_content_type') + .expect('Content-Type', /json/) + }) + + test('Should return xml content type when forced', async () => { + app.get('/test_content_type_xml', (req, res) => { + res.type('xml') + res.send('') + }) + + await request(app) + .get('/test_content_type_xml') + .expect('Content-Type', /xml/) + }) +}) diff --git a/app/src/main/middlewares/content-type.ts b/app/src/main/middlewares/content-type.ts new file mode 100644 index 00000000..dc8c437c --- /dev/null +++ b/app/src/main/middlewares/content-type.ts @@ -0,0 +1,6 @@ +import { NextFunction, Request, Response } from 'express' + +export const contentType = (req: Request, res: Response, next: NextFunction): void => { + res.type('application/json') + next() +} diff --git a/app/src/main/middlewares/cors.test.ts b/app/src/main/middlewares/cors.test.ts new file mode 100644 index 00000000..a75125f2 --- /dev/null +++ b/app/src/main/middlewares/cors.test.ts @@ -0,0 +1,17 @@ +import request from 'supertest' +import { describe, test } from 'vitest' +import app from '../config/app' + +describe('CORS Middleware', () => { + test('Should enable CORS', async () => { + app.get('/test_cors', (req, res) => { + return res.send() + }) + + await request(app) + .post('/test_cors') + .expect('Access-Control-Allow-Origin', '*') + .expect('Access-Control-Allow-Methods', '*') + .expect('Access-Control-Allow-Headers', '*') + }) +}) diff --git a/app/src/main/middlewares/cors.ts b/app/src/main/middlewares/cors.ts new file mode 100644 index 00000000..78382706 --- /dev/null +++ b/app/src/main/middlewares/cors.ts @@ -0,0 +1,9 @@ +import { NextFunction, Request, Response } from 'express' + +export const cors = (req: Request, res: Response, next: NextFunction): void => { + res.header('Access-Control-Allow-Origin', '*') + res.header('Access-Control-Allow-Methods', '*') + res.header('Access-Control-Allow-Headers', '*') + + next() +} diff --git a/app/src/main/middlewares/index.ts b/app/src/main/middlewares/index.ts new file mode 100644 index 00000000..b8179fbe --- /dev/null +++ b/app/src/main/middlewares/index.ts @@ -0,0 +1,3 @@ +export * from './body-parser' +export * from './content-type' +export * from './cors' \ No newline at end of file diff --git a/app/src/main/routes/index.ts b/app/src/main/routes/index.ts new file mode 100644 index 00000000..777eedad --- /dev/null +++ b/app/src/main/routes/index.ts @@ -0,0 +1 @@ +export * from './users-routes' \ No newline at end of file diff --git a/app/src/main/routes/users-routes.ts b/app/src/main/routes/users-routes.ts new file mode 100644 index 00000000..62e7f1f7 --- /dev/null +++ b/app/src/main/routes/users-routes.ts @@ -0,0 +1,8 @@ +/* eslint-disable @typescript-eslint/no-misused-promises */ +import { Router } from 'express' +import { adaptRoute } from '../adapters/express/express-route-adapter' +import { makeAddUserController } from '../factories/controllers/user/add-user-controller-factory' + +export const usersRoutes = (router: Router): void => { + router.post('/users', adaptRoute(makeAddUserController())) +} diff --git a/app/src/main/server.ts b/app/src/main/server.ts new file mode 100644 index 00000000..80d8f5da --- /dev/null +++ b/app/src/main/server.ts @@ -0,0 +1,31 @@ +import { sequelizeConnection } from '@/infra/database/sequelize/helpers' +import app from './config/app' +const PORT = process.env.PORT || 3000 +async function run() { + try { + console.log('Starting database connection...') + await sequelizeConnection.authenticate() + console.log('Database connection started successfully!') + + const server = app.listen(PORT, () => { + console.log(`Server running at http://localhost:${PORT}`) + }) + + const exitSignals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGQUIT'] + exitSignals.map(sig => { + process.on(sig, () => { + server.close(() => { + console.log(`Server closed at http://localhost:${PORT}`) + sequelizeConnection.close().then(() => { + console.log('Database connection closed successfully!') + }) + }) + }) + }) + } catch (error) { + console.error('Error starting server:', error) + } +} + +run() +.catch(console.error) From 82d467f4019af8feed7394eeb080ed9a36ae119c Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 19:49:39 -0300 Subject: [PATCH 035/105] =?UTF-8?q?chore:=20adiciona=20var=C3=ADaveis=20de?= =?UTF-8?q?=20ambientes=20que=20estavam=20faltando?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/.env.example | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/.env.example b/app/.env.example index 7acdbe4c..45d559ac 100644 --- a/app/.env.example +++ b/app/.env.example @@ -1,3 +1,7 @@ +NODE_ENV + +PORT= + DB_HOST= DB_PORT= DB_USER= From 8b2f8e8461c4cda83d7a798c35acf7f1dd70d2d9 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 20:06:08 -0300 Subject: [PATCH 036/105] =?UTF-8?q?chore:=20separa=20testes=20de=20integra?= =?UTF-8?q?=C3=A7=C3=A3o=20e=20unit=C3=A1rios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/package-lock.json | 1 + app/package.json | 3 +++ .../{body-parser.test.ts => body-parser.spec.ts} | 0 .../{content-type.test.ts => content-type.spec.ts} | 0 app/src/main/middlewares/{cors.test.ts => cors.spec.ts} | 0 app/src/main/routes/users.routes.spec.ts | 0 app/vitest.config.ts | 7 ++++++- app/vitest.integration.config.ts | 9 +++++++++ app/vitest.unit.config.ts | 9 +++++++++ 9 files changed, 28 insertions(+), 1 deletion(-) rename app/src/main/middlewares/{body-parser.test.ts => body-parser.spec.ts} (100%) rename app/src/main/middlewares/{content-type.test.ts => content-type.spec.ts} (100%) rename app/src/main/middlewares/{cors.test.ts => cors.spec.ts} (100%) create mode 100644 app/src/main/routes/users.routes.spec.ts create mode 100644 app/vitest.integration.config.ts create mode 100644 app/vitest.unit.config.ts diff --git a/app/package-lock.json b/app/package-lock.json index d6d2a3a4..fbd52856 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -28,6 +28,7 @@ "ts-node": "^10.9.1", "tsconfig-paths": "^4.1.0", "typescript": "^4.8.4", + "vite": "^3.1.8", "vitest": "^0.24.3", "vitest-tsconfig-paths": "^3.4.1" }, diff --git a/app/package.json b/app/package.json index 4544215c..c4984d50 100644 --- a/app/package.json +++ b/app/package.json @@ -5,6 +5,8 @@ "main": "index.js", "scripts": { "test": "cross-env NODE_ENV=test vitest", + "test:unit": "npm run test -- --config vitest.unit.config.ts", + "test:integration": "npm run test -- --config vitest.integration.config.ts", "start": "nodemon src/main/server.ts " }, "keywords": [], @@ -21,6 +23,7 @@ "ts-node": "^10.9.1", "tsconfig-paths": "^4.1.0", "typescript": "^4.8.4", + "vite": "^3.1.8", "vitest": "^0.24.3", "vitest-tsconfig-paths": "^3.4.1" }, diff --git a/app/src/main/middlewares/body-parser.test.ts b/app/src/main/middlewares/body-parser.spec.ts similarity index 100% rename from app/src/main/middlewares/body-parser.test.ts rename to app/src/main/middlewares/body-parser.spec.ts diff --git a/app/src/main/middlewares/content-type.test.ts b/app/src/main/middlewares/content-type.spec.ts similarity index 100% rename from app/src/main/middlewares/content-type.test.ts rename to app/src/main/middlewares/content-type.spec.ts diff --git a/app/src/main/middlewares/cors.test.ts b/app/src/main/middlewares/cors.spec.ts similarity index 100% rename from app/src/main/middlewares/cors.test.ts rename to app/src/main/middlewares/cors.spec.ts diff --git a/app/src/main/routes/users.routes.spec.ts b/app/src/main/routes/users.routes.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/app/vitest.config.ts b/app/vitest.config.ts index c68f0944..bd0b4042 100644 --- a/app/vitest.config.ts +++ b/app/vitest.config.ts @@ -2,6 +2,11 @@ import { defineConfig } from 'vitest/config' import tsconfigPaths from 'vitest-tsconfig-paths' export default defineConfig({ - test: {}, + test: { + coverage: { + include: ['src/**/*.{ts}'], + provider: 'istanbul' + } + }, plugins: [tsconfigPaths()], }) diff --git a/app/vitest.integration.config.ts b/app/vitest.integration.config.ts new file mode 100644 index 00000000..176a1063 --- /dev/null +++ b/app/vitest.integration.config.ts @@ -0,0 +1,9 @@ +import { mergeConfig } from 'vite' +import { defineConfig } from 'vitest/config' +import vitestConfig from './vitest.config' + +export default mergeConfig(vitestConfig, defineConfig({ + test: { + include: ['src/**/*.spec.ts'], + } +})) diff --git a/app/vitest.unit.config.ts b/app/vitest.unit.config.ts new file mode 100644 index 00000000..f98e43e5 --- /dev/null +++ b/app/vitest.unit.config.ts @@ -0,0 +1,9 @@ +import { mergeConfig } from 'vite' +import { defineConfig } from 'vitest/config' +import vitestConfig from './vitest.config' + +export default mergeConfig(vitestConfig, defineConfig({ + test: { + include: ['src/**/*.test.ts'], + } +})) From 8db8a65163af6e407462dc69fc637d726ddaaf4c Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 20:14:36 -0300 Subject: [PATCH 037/105] =?UTF-8?q?test:=20garante=20que=20POST=20/users?= =?UTF-8?q?=20est=C3=A1=20funcionando?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/routes/users-routes.spec.ts | 29 ++++++++++++++++++++++++ app/src/main/routes/users.routes.spec.ts | 0 2 files changed, 29 insertions(+) create mode 100644 app/src/main/routes/users-routes.spec.ts delete mode 100644 app/src/main/routes/users.routes.spec.ts diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts new file mode 100644 index 00000000..24f6fc5b --- /dev/null +++ b/app/src/main/routes/users-routes.spec.ts @@ -0,0 +1,29 @@ +import { mockAddUser } from '@/domain/tests/users-mock'; +import { migrate, truncate } from '@/infra/database/sequelize/__tests__/utils'; +import request from 'supertest' +import { beforeAll, beforeEach, describe, expect, test } from 'vitest' +import app from '../config/app' + +describe('Users Routes', () => { + describe('POST /users', () => { + beforeAll(async () => { + await migrate() + }) + + beforeEach(async () => { + await truncate() + }) + test('should return 200 with a valid user', async () => { + const body = mockAddUser(); + + const res = await request(app) + .post('/users') + .send(body) + .expect(200) + + expect(res.body.name).toBe(body.name) + expect(res.body.email).toBe(body.email) + expect(res.body.id).toBeTruthy() + }); + }); +}); \ No newline at end of file diff --git a/app/src/main/routes/users.routes.spec.ts b/app/src/main/routes/users.routes.spec.ts deleted file mode 100644 index e69de29b..00000000 From 511355e994dcc32a41c3c77f46ceda1e3bdf2f76 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 20:14:54 -0300 Subject: [PATCH 038/105] chore: adiciona dependencia de tipagem do supertest --- app/package-lock.json | 51 +++++++++++++++++++++++++++++++++++++++++++ app/package.json | 1 + 2 files changed, 52 insertions(+) diff --git a/app/package-lock.json b/app/package-lock.json index fbd52856..5803d01e 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -21,6 +21,7 @@ "@faker-js/faker": "^7.6.0", "@types/express": "^4.17.14", "@types/node": "^18.11.0", + "@types/supertest": "^2.0.12", "mockdate": "^3.0.5", "nodemon": "^2.0.20", "sqlite3": "^5.1.2", @@ -248,6 +249,12 @@ "@types/node": "*" } }, + "node_modules/@types/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", + "dev": true + }, "node_modules/@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -333,6 +340,25 @@ "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==" }, + "node_modules/@types/superagent": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.15.tgz", + "integrity": "sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ==", + "dev": true, + "dependencies": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "node_modules/@types/supertest": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz", + "integrity": "sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==", + "dev": true, + "dependencies": { + "@types/superagent": "*" + } + }, "node_modules/@types/validator": { "version": "13.7.7", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", @@ -4633,6 +4659,12 @@ "@types/node": "*" } }, + "@types/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", + "dev": true + }, "@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -4718,6 +4750,25 @@ "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==" }, + "@types/superagent": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.15.tgz", + "integrity": "sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ==", + "dev": true, + "requires": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "@types/supertest": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz", + "integrity": "sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==", + "dev": true, + "requires": { + "@types/superagent": "*" + } + }, "@types/validator": { "version": "13.7.7", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", diff --git a/app/package.json b/app/package.json index c4984d50..190849e5 100644 --- a/app/package.json +++ b/app/package.json @@ -16,6 +16,7 @@ "@faker-js/faker": "^7.6.0", "@types/express": "^4.17.14", "@types/node": "^18.11.0", + "@types/supertest": "^2.0.12", "mockdate": "^3.0.5", "nodemon": "^2.0.20", "sqlite3": "^5.1.2", From 109c0f69cd00c7e749a65c85457d270a220619c1 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 20:19:59 -0300 Subject: [PATCH 039/105] =?UTF-8?q?feat:=20garante=20que=20LoadUsersContro?= =?UTF-8?q?ller=20ir=C3=A1=20chamar=20LoadUsersUseCase=20corretamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/domain/tests/users-mock.ts | 13 +++++++++- .../users-mysql-repository.ts | 5 ++++ .../users-controller/load-users-controller.ts | 26 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 app/src/presentation/controllers/users-controller/load-users-controller.ts diff --git a/app/src/domain/tests/users-mock.ts b/app/src/domain/tests/users-mock.ts index 9dd3e209..9be1376d 100644 --- a/app/src/domain/tests/users-mock.ts +++ b/app/src/domain/tests/users-mock.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker' import { User } from '../models' -import { AddUser, LoadUsersById } from '../usecases/users' +import { AddUser, LoadUsers, LoadUsersById } from '../usecases/users' import { LoadUsersByEmail } from '../usecases/users/load-users-by-email' export function mockAddUser(): AddUser.Params { return { @@ -37,6 +37,17 @@ export class LoadUsersByIdSpy implements LoadUsersById { } } +export class LoadUsersSpy implements LoadUsers { + loadResult: LoadUsers.Result + loadParams: LoadUsers.Params + constructor() { + this.loadResult = [mockUser(), mockUser()] + } + async load(params: LoadUsers.Params): Promise { + this.loadParams = params + return new Promise((resolve) => resolve(this.loadResult)) + } +} export class LoadUsersByEmailSpy implements LoadUsersByEmail { loadByEmailResult: LoadUsersByEmail.Result loadByEmailParams: LoadUsersByEmail.Params diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts index 9a7bf452..1fce6216 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts @@ -13,6 +13,11 @@ export class UsersMySqlReposiory return newUser as any as AddUserRepository.Result } + /** + * + * Returns all users from database. + * By default it returns all users ordered by createdAt in descending order. + */ async load( params?: LoadUsersRepository.Params ): Promise { diff --git a/app/src/presentation/controllers/users-controller/load-users-controller.ts b/app/src/presentation/controllers/users-controller/load-users-controller.ts new file mode 100644 index 00000000..1c786957 --- /dev/null +++ b/app/src/presentation/controllers/users-controller/load-users-controller.ts @@ -0,0 +1,26 @@ +import { User } from '@/domain/models'; +import { Controller, HttpResponse } from '@/presentation/protocols'; +import { LoadUsers } from '@/domain/usecases/users'; +import { ok, serverError } from '@/presentation/helpers/http-helper'; +export class LoadUsersController implements Controller { + constructor( + private loadUsersUseCase: LoadUsers, + ) {} + + async handle(request?: LoadUsersController.Request): Promise { + try { + const users = await this.loadUsersUseCase.load(request); + return ok(users); + } catch (error) { + return serverError(error) + } + } +} + +export namespace LoadUsersController { + export type Request = { + order?: 'asc' | 'desc'; + } + export type Response = HttpResponse + } + \ No newline at end of file From 1dcc3f3e54f661a93107d2a6b09eef0800b2e9bc Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 20:20:04 -0300 Subject: [PATCH 040/105] =?UTF-8?q?test:=20garante=20que=20LoadUsersContro?= =?UTF-8?q?ller=20ir=C3=A1=20chamar=20LoadUsersUseCase=20corretamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../load-users-controller.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 app/src/presentation/controllers/users-controller/load-users-controller.test.ts diff --git a/app/src/presentation/controllers/users-controller/load-users-controller.test.ts b/app/src/presentation/controllers/users-controller/load-users-controller.test.ts new file mode 100644 index 00000000..d9e6b3b4 --- /dev/null +++ b/app/src/presentation/controllers/users-controller/load-users-controller.test.ts @@ -0,0 +1,55 @@ +import { LoadUsersSpy } from '@/domain/tests/users-mock'; +import { ok, serverError } from '@/presentation/helpers/http-helper'; +import { describe, expect, test, vitest } from 'vitest'; +import { LoadUsersController } from './load-users-controller'; + +describe('LoadUsersController', () => { + function makeSut() { + const loadUsersSpy = new LoadUsersSpy(); + const sut = new LoadUsersController( + loadUsersSpy, + ); + + return { + sut, + loadUsersSpy, + } + } + describe('handle()', () => { + test('should call loadUsersUseCase with correct params', async () => { + const { sut, loadUsersSpy } = makeSut(); + + await sut.handle({ + order: 'asc' + }); + + expect(loadUsersSpy.loadParams).toEqual({ + order: 'asc' + }) + }); + + test('should return 200 with the loadUsersUseCase result', async () => { + const { sut, loadUsersSpy } = makeSut(); + + const res = await sut.handle(); + + expect(res).toEqual(ok( + loadUsersSpy.loadResult + )) + }); + + test('should return 500 if loadUsersUseCase throws', async () => { + const { sut, loadUsersSpy } = makeSut(); + const mockedError = new Error('some_error') + vitest.spyOn(loadUsersSpy, 'load').mockImplementationOnce(() => { + throw mockedError; + }); + + const res = await sut.handle(); + + expect(res).toEqual( + serverError(mockedError) + ) + }); + }) +}); \ No newline at end of file From 74649e35487e597642b14a1bd87ff949ad5af2e6 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 21:32:54 -0300 Subject: [PATCH 041/105] feat: implementa GET /users --- .../controllers/user/load-users-controller-factory.ts | 7 +++++++ app/src/main/routes/users-routes.ts | 2 ++ app/src/presentation/controllers/users-controller/index.ts | 3 ++- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 app/src/main/factories/controllers/user/load-users-controller-factory.ts diff --git a/app/src/main/factories/controllers/user/load-users-controller-factory.ts b/app/src/main/factories/controllers/user/load-users-controller-factory.ts new file mode 100644 index 00000000..f47d5e99 --- /dev/null +++ b/app/src/main/factories/controllers/user/load-users-controller-factory.ts @@ -0,0 +1,7 @@ +import { LoadUsersController } from '@/presentation/controllers/users-controller' +import { Controller } from '@/presentation/protocols' +import { makeDbLoadUsers } from '../../usecases/user' + +export function makeLoadUsersController(): Controller { + return new LoadUsersController(makeDbLoadUsers()) +} diff --git a/app/src/main/routes/users-routes.ts b/app/src/main/routes/users-routes.ts index 62e7f1f7..9a942e6b 100644 --- a/app/src/main/routes/users-routes.ts +++ b/app/src/main/routes/users-routes.ts @@ -2,7 +2,9 @@ import { Router } from 'express' import { adaptRoute } from '../adapters/express/express-route-adapter' import { makeAddUserController } from '../factories/controllers/user/add-user-controller-factory' +import { makeLoadUsersController } from '../factories/controllers/user/load-users-controller-factory' export const usersRoutes = (router: Router): void => { + router.get('/users', adaptRoute(makeLoadUsersController())) router.post('/users', adaptRoute(makeAddUserController())) } diff --git a/app/src/presentation/controllers/users-controller/index.ts b/app/src/presentation/controllers/users-controller/index.ts index ce02c76c..89764744 100644 --- a/app/src/presentation/controllers/users-controller/index.ts +++ b/app/src/presentation/controllers/users-controller/index.ts @@ -1 +1,2 @@ -export * from './add-user-controller' \ No newline at end of file +export * from './add-user-controller' +export * from './load-users-controller' \ No newline at end of file From 9a655261c266736ed36ed39c4922ee134b2489ca Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 21:33:03 -0300 Subject: [PATCH 042/105] test: implementa GET /users --- app/src/main/routes/users-routes.spec.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index 24f6fc5b..6e7f57ff 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -1,4 +1,5 @@ import { mockAddUser } from '@/domain/tests/users-mock'; +import UsersSequelize from '@/infra/database/sequelize/models/Users'; import { migrate, truncate } from '@/infra/database/sequelize/__tests__/utils'; import request from 'supertest' import { beforeAll, beforeEach, describe, expect, test } from 'vitest' @@ -26,4 +27,18 @@ describe('Users Routes', () => { expect(res.body.id).toBeTruthy() }); }); + + describe('GET /users', () => { + test('should return 200 with valid users in descending order', async () => { + + const [userOne, userTwo] = await UsersSequelize.bulkCreate([mockAddUser(),mockAddUser()]) + + const res = await request(app) + .get('/users') + .expect(200) + + expect(res.body[0].id).toBe(userOne.getDataValue('id')) + expect(res.body[1].id).toBe(userTwo.getDataValue('id')) + }); + }); }); \ No newline at end of file From 9d43fad24628041a6c290e022c7a2046bf27bc18 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 21:43:32 -0300 Subject: [PATCH 043/105] refactor: express-route-adaptar agora repassa o objeto de query --- app/src/main/adapters/express/express-route-adapter.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/adapters/express/express-route-adapter.ts b/app/src/main/adapters/express/express-route-adapter.ts index 8194dbfa..fdba75f3 100644 --- a/app/src/main/adapters/express/express-route-adapter.ts +++ b/app/src/main/adapters/express/express-route-adapter.ts @@ -6,6 +6,7 @@ export function adaptRoute (controller: Controller) { const httpRequest: any = { ...(req.body || {}), ...(req.params || {}), + ...(req.query || {}) } try { const httpResponse = await controller.handle(httpRequest) From 19e1f5c210c9294e4a09bcd836bf12ba0de4e319 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 21:43:55 -0300 Subject: [PATCH 044/105] test: garante que vai ordernar de forma ascendente se requisitado --- app/src/main/routes/users-routes.spec.ts | 102 ++++++++++++++--------- 1 file changed, 62 insertions(+), 40 deletions(-) diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index 6e7f57ff..5864de96 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -1,44 +1,66 @@ -import { mockAddUser } from '@/domain/tests/users-mock'; -import UsersSequelize from '@/infra/database/sequelize/models/Users'; -import { migrate, truncate } from '@/infra/database/sequelize/__tests__/utils'; +import { mockAddUser } from '@/domain/tests/users-mock' +import UsersSequelize from '@/infra/database/sequelize/models/Users' +import { migrate, truncate } from '@/infra/database/sequelize/__tests__/utils' import request from 'supertest' -import { beforeAll, beforeEach, describe, expect, test } from 'vitest' +import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' import app from '../config/app' describe('Users Routes', () => { - describe('POST /users', () => { - beforeAll(async () => { - await migrate() - }) - - beforeEach(async () => { - await truncate() - }) - test('should return 200 with a valid user', async () => { - const body = mockAddUser(); - - const res = await request(app) - .post('/users') - .send(body) - .expect(200) - - expect(res.body.name).toBe(body.name) - expect(res.body.email).toBe(body.email) - expect(res.body.id).toBeTruthy() - }); - }); - - describe('GET /users', () => { - test('should return 200 with valid users in descending order', async () => { - - const [userOne, userTwo] = await UsersSequelize.bulkCreate([mockAddUser(),mockAddUser()]) - - const res = await request(app) - .get('/users') - .expect(200) - - expect(res.body[0].id).toBe(userOne.getDataValue('id')) - expect(res.body[1].id).toBe(userTwo.getDataValue('id')) - }); - }); -}); \ No newline at end of file + beforeAll(async () => { + await migrate() + }) + + beforeEach(async () => { + await truncate() + }) + + afterAll(async () => { + await truncate() + }) + describe('POST /users', () => { + test('should return 200 with a valid user', async () => { + const body = mockAddUser() + + const res = await request(app).post('/users').send(body).expect(200) + + expect(res.body.name).toBe(body.name) + expect(res.body.email).toBe(body.email) + expect(res.body.id).toBeTruthy() + }) + }) + + describe('GET /users', () => { + test('should return 200 with valid users in descending order', async () => { + const now = new Date() + const older = new Date(now.getTime() - 1000) + + const [userOne, userTwo] = await UsersSequelize.bulkCreate([ + { ...mockAddUser(), createdAt: now }, + { ...mockAddUser(), createdAt: older }, + ]) + + const res = await request(app).get('/users').expect(200) + + expect(res.body[0].id).toBe(userOne.getDataValue('id')) + expect(res.body[1].id).toBe(userTwo.getDataValue('id')) + }) + + test('should return 200 with valid users in asccending order', async () => { + const now = new Date() + const older = new Date(now.getTime() - 1000) + + const [userOne, userTwo] = await UsersSequelize.bulkCreate([ + { ...mockAddUser(), createdAt: now }, + { ...mockAddUser(), createdAt: older }, + ]) + + const res = await request(app) + .get('/users') + .query({ order: 'asc' }) + .expect(200) + + expect(res.body[0].id).toBe(userTwo.getDataValue('id')) + expect(res.body[1].id).toBe(userOne.getDataValue('id')) + }) + }) +}) From 5fb855031dacf923de8d9568b5d921b9e00b1ba8 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 21:56:59 -0300 Subject: [PATCH 045/105] feat: garante que LoadUsersByIdController ira chamar LoadUserByIdUseCase corretamente --- .../domain/usecases/users/load-users-by-id.ts | 2 +- app/src/main/routes/users-routes.ts | 1 + .../load-user-by-id-controller.ts | 30 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 app/src/presentation/controllers/users-controller/load-user-by-id-controller.ts diff --git a/app/src/domain/usecases/users/load-users-by-id.ts b/app/src/domain/usecases/users/load-users-by-id.ts index 0f15d38a..6693bfde 100644 --- a/app/src/domain/usecases/users/load-users-by-id.ts +++ b/app/src/domain/usecases/users/load-users-by-id.ts @@ -6,7 +6,7 @@ export interface LoadUsersById { export namespace LoadUsersById { export type Params = { - userId: string; + userId: string | number; }; diff --git a/app/src/main/routes/users-routes.ts b/app/src/main/routes/users-routes.ts index 9a942e6b..936a2bd8 100644 --- a/app/src/main/routes/users-routes.ts +++ b/app/src/main/routes/users-routes.ts @@ -6,5 +6,6 @@ import { makeLoadUsersController } from '../factories/controllers/user/load-user export const usersRoutes = (router: Router): void => { router.get('/users', adaptRoute(makeLoadUsersController())) + router.get('/users/:id', adaptRoute(makeLoadUserByIdController())) router.post('/users', adaptRoute(makeAddUserController())) } diff --git a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.ts b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.ts new file mode 100644 index 00000000..990baed8 --- /dev/null +++ b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.ts @@ -0,0 +1,30 @@ +import { User } from '@/domain/models' +import { LoadUsersById } from '@/domain/usecases/users' +import { ok, serverError } from '@/presentation/helpers/http-helper' +import { HttpResponse } from '@/presentation/protocols' + +export class LoadUserByIdController { + constructor(private readonly loadUserByIdUseCase: LoadUsersById) {} + + async handle( + request: LoadUserByIdController.Request + ): Promise { + try { + const { userId } = request + const user = await this.loadUserByIdUseCase.loadById({ + userId, + }) + + return ok(user) + } catch (error) { + return serverError(error) + } + } +} + +export namespace LoadUserByIdController { + export type Request = { + userId: number + } + export type Response = HttpResponse +} From 1b8a4d04ef4031f2ca8355ac98cce5c8980ab30d Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 21:57:02 -0300 Subject: [PATCH 046/105] test: garante que LoadUsersByIdController ira chamar LoadUserByIdUseCase corretamente --- .../load-user-by-id-controller.test.ts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts diff --git a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts new file mode 100644 index 00000000..bee4fcf6 --- /dev/null +++ b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts @@ -0,0 +1,48 @@ +import { LoadUsersByIdSpy } from '@/domain/tests/users-mock' +import { ok, serverError } from '@/presentation/helpers/http-helper' +import { describe, expect, test, vitest } from 'vitest' +import { LoadUserByIdController } from './load-user-by-id-controller' + +describe('LoadUserByIdControler', () => { + function makeSut() { + const loadUserByIdSpy = new LoadUsersByIdSpy() + const sut = new LoadUserByIdController(loadUserByIdSpy) + + return { + sut, + loadUserByIdSpy, + } + } + describe('handle()', () => { + test('should call loadUserByIdUseCase with correct user id', async () => { + const { sut, loadUserByIdSpy } = makeSut() + const request = { + userId: 1, + } + await sut.handle(request) + expect(loadUserByIdSpy.loadByIdParams).toEqual(request) + }) + + test('should return 500 if loadUserByIdUseCase throws', async () => { + const { sut, loadUserByIdSpy } = makeSut() + const mockedError = new Error('some_error') + vitest + .spyOn(loadUserByIdSpy, 'loadById') + .mockRejectedValueOnce(mockedError) + const request = { + userId: 1, + } + const response = await sut.handle(request) + expect(response).toEqual(serverError(mockedError)) + }) + + test('should return 200 if loadUserByIdUseCase succeeds', async () => { + const { sut, loadUserByIdSpy } = makeSut() + const request = { + userId: 1, + } + const response = await sut.handle(request) + expect(response).toEqual(ok(loadUserByIdSpy.loadByIdResult)) + }) + }) +}) From e05f276ffc5d8b73d5462b0ef98bd02a61fd2ee0 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 22:23:05 -0300 Subject: [PATCH 047/105] feat: implemente GET /users/{id} --- .../data/protocols/database/users/index.ts | 3 ++- .../users/load-user-by-id-repository.ts | 12 ++++++++++ app/src/data/test/users-mock.ts | 16 +++++++++++-- .../usecases/users/db-load-users-by-id.ts | 11 +++++++++ app/src/data/usecases/users/index.ts | 3 ++- .../users-mysql-repository.ts | 21 +++++++++++++++-- .../main/factories/controllers/user/index.ts | 2 ++ .../load-user-by-id-controller-factory.ts | 7 ++++++ app/src/main/factories/usecases/user/index.ts | 3 ++- .../user/load-users-by-id-usecase-factory.ts | 7 ++++++ app/src/main/routes/users-routes.ts | 6 ++--- .../load-user-by-id-controller.ts | 23 +++++++++++++------ .../errors/missing-param-error.ts | 6 +++++ .../presentation/errors/not-found-error.ts | 6 +++++ app/src/presentation/helpers/http-helper.ts | 6 +++++ 15 files changed, 115 insertions(+), 17 deletions(-) create mode 100644 app/src/data/protocols/database/users/load-user-by-id-repository.ts create mode 100644 app/src/data/usecases/users/db-load-users-by-id.ts create mode 100644 app/src/main/factories/controllers/user/load-user-by-id-controller-factory.ts create mode 100644 app/src/main/factories/usecases/user/load-users-by-id-usecase-factory.ts create mode 100644 app/src/presentation/errors/missing-param-error.ts create mode 100644 app/src/presentation/errors/not-found-error.ts diff --git a/app/src/data/protocols/database/users/index.ts b/app/src/data/protocols/database/users/index.ts index 3b5fdddc..ff22ae84 100644 --- a/app/src/data/protocols/database/users/index.ts +++ b/app/src/data/protocols/database/users/index.ts @@ -1,3 +1,4 @@ export * from './load-user-repository' export * from './add-user-repository' -export * from './load-user-by-email-repository' \ No newline at end of file +export * from './load-user-by-email-repository' +export * from './load-user-by-id-repository' \ No newline at end of file diff --git a/app/src/data/protocols/database/users/load-user-by-id-repository.ts b/app/src/data/protocols/database/users/load-user-by-id-repository.ts new file mode 100644 index 00000000..98e4ca96 --- /dev/null +++ b/app/src/data/protocols/database/users/load-user-by-id-repository.ts @@ -0,0 +1,12 @@ +import { LoadUsersById } from '@/domain/usecases/users' + +export interface LoadUsersByIdRepository { + loadById: (params?: LoadUsersByIdRepository.Params) => Promise +} + +export namespace LoadUsersByIdRepository { + export type Params = LoadUsersById.Params + + export type Result = LoadUsersById.Result + +} diff --git a/app/src/data/test/users-mock.ts b/app/src/data/test/users-mock.ts index 4be59d05..0450e974 100644 --- a/app/src/data/test/users-mock.ts +++ b/app/src/data/test/users-mock.ts @@ -1,5 +1,5 @@ import { mockUser } from '@/domain/tests/users-mock' -import { LoadUsersByEmailRepository } from '../protocols/database/users' +import { LoadUsersByEmailRepository, LoadUsersByIdRepository } from '../protocols/database/users' import { AddUserRepository } from '../protocols/database/users/add-user-repository' import { LoadUsersRepository } from '../protocols/database/users/load-user-repository' @@ -31,10 +31,22 @@ export class LoadUsersByEmailRepositorySpy implements LoadUsersByEmailRepository loadByEmailParams: LoadUsersByEmailRepository.Params loadByEmailResult: LoadUsersByEmailRepository.Result constructor() { - this.loadByEmailResult =mockUser() + this.loadByEmailResult = mockUser() } async loadByEmail(params: LoadUsersByEmailRepository.Params): Promise { this.loadByEmailParams = params return this.loadByEmailResult } +} + +export class LoadUsersByIdRepositorySpy implements LoadUsersByIdRepository { + loadByIdParams: LoadUsersByIdRepository.Params + loadByIdResult: LoadUsersByIdRepository.Result + constructor() { + this.loadByIdResult = mockUser() + } + async loadById(params: LoadUsersByIdRepository.Params): Promise { + this.loadByIdParams = params + return this.loadByIdResult + } } \ No newline at end of file diff --git a/app/src/data/usecases/users/db-load-users-by-id.ts b/app/src/data/usecases/users/db-load-users-by-id.ts new file mode 100644 index 00000000..b14f2581 --- /dev/null +++ b/app/src/data/usecases/users/db-load-users-by-id.ts @@ -0,0 +1,11 @@ +import { LoadUsersByIdRepository } from '@/data/protocols/database/users' +import { LoadUsersById } from '@/domain/usecases/users' + +export class DbLoadUsersById implements LoadUsersById { + constructor( + private readonly loadUsersByIdRepository: LoadUsersByIdRepository + ) {} + async loadById(params: LoadUsersById.Params): Promise { + return this.loadUsersByIdRepository.loadById(params) + } +} diff --git a/app/src/data/usecases/users/index.ts b/app/src/data/usecases/users/index.ts index 8b5f6bc5..da676d77 100644 --- a/app/src/data/usecases/users/index.ts +++ b/app/src/data/usecases/users/index.ts @@ -1,3 +1,4 @@ export * from './db-add-user' export * from './db-load-users' -export * from './db-load-users-by-email' \ No newline at end of file +export * from './db-load-users-by-email' +export * from './db-load-users-by-id' \ No newline at end of file diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts index 1fce6216..9a95b7db 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts @@ -3,10 +3,15 @@ import { LoadUsersByEmailRepository, LoadUsersRepository, } from '@/data/protocols/database/users' +import { LoadUsersByIdRepository } from '@/data/protocols/database/users/load-user-by-id-repository' import UsersSequelize from '../models/Users' export class UsersMySqlReposiory - implements AddUserRepository, LoadUsersRepository, LoadUsersByEmailRepository + implements + AddUserRepository, + LoadUsersRepository, + LoadUsersByEmailRepository, + LoadUsersByIdRepository { async add(user: AddUserRepository.Params): Promise { const newUser = await UsersSequelize.create(user) @@ -14,7 +19,7 @@ export class UsersMySqlReposiory } /** - * + * * Returns all users from database. * By default it returns all users ordered by createdAt in descending order. */ @@ -28,6 +33,18 @@ export class UsersMySqlReposiory return users as any as LoadUsersRepository.Result } + async loadById( + params: LoadUsersByIdRepository.Params + ): Promise { + const user = await UsersSequelize.findOne({ + where: { + id: params.userId, + } + }) + + return user as any as LoadUsersByIdRepository.Result + } + async loadByEmail( params: LoadUsersByEmailRepository.Params ): Promise { diff --git a/app/src/main/factories/controllers/user/index.ts b/app/src/main/factories/controllers/user/index.ts index e69de29b..706418bb 100644 --- a/app/src/main/factories/controllers/user/index.ts +++ b/app/src/main/factories/controllers/user/index.ts @@ -0,0 +1,2 @@ +export * from './add-user-controller-factory' +export * from './load-users-controller-factory' \ No newline at end of file diff --git a/app/src/main/factories/controllers/user/load-user-by-id-controller-factory.ts b/app/src/main/factories/controllers/user/load-user-by-id-controller-factory.ts new file mode 100644 index 00000000..93cf2bf7 --- /dev/null +++ b/app/src/main/factories/controllers/user/load-user-by-id-controller-factory.ts @@ -0,0 +1,7 @@ +import { LoadUsersByIdController } from '@/presentation/controllers/users-controller/load-user-by-id-controller' +import { Controller } from '@/presentation/protocols' +import { makeDbLoadUsersById } from '../../usecases/user' + +export function makeLoadUsersByIdController(): Controller { + return new LoadUsersByIdController(makeDbLoadUsersById()) +} diff --git a/app/src/main/factories/usecases/user/index.ts b/app/src/main/factories/usecases/user/index.ts index 3875192d..d90ee627 100644 --- a/app/src/main/factories/usecases/user/index.ts +++ b/app/src/main/factories/usecases/user/index.ts @@ -1,3 +1,4 @@ export * from './add-user-usecase-factory' export * from './load-users-usecase-factory' -export * from './load-users-by-email-usecase-factory' \ No newline at end of file +export * from './load-users-by-email-usecase-factory' +export * from './load-users-by-id-usecase-factory' \ No newline at end of file diff --git a/app/src/main/factories/usecases/user/load-users-by-id-usecase-factory.ts b/app/src/main/factories/usecases/user/load-users-by-id-usecase-factory.ts new file mode 100644 index 00000000..c5db802f --- /dev/null +++ b/app/src/main/factories/usecases/user/load-users-by-id-usecase-factory.ts @@ -0,0 +1,7 @@ +import { DbLoadUsersById } from '@/data/usecases/users' +import { LoadUsersById } from '@/domain/usecases/users' +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository' + +export function makeDbLoadUsersById(): LoadUsersById { + return new DbLoadUsersById(new UsersMySqlReposiory()) +} diff --git a/app/src/main/routes/users-routes.ts b/app/src/main/routes/users-routes.ts index 936a2bd8..b75a1063 100644 --- a/app/src/main/routes/users-routes.ts +++ b/app/src/main/routes/users-routes.ts @@ -1,11 +1,11 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ import { Router } from 'express' import { adaptRoute } from '../adapters/express/express-route-adapter' -import { makeAddUserController } from '../factories/controllers/user/add-user-controller-factory' -import { makeLoadUsersController } from '../factories/controllers/user/load-users-controller-factory' +import { makeAddUserController, makeLoadUsersController } from '../factories/controllers/user' +import { makeLoadUsersByIdController } from '../factories/controllers/user/load-user-by-id-controller-factory' export const usersRoutes = (router: Router): void => { router.get('/users', adaptRoute(makeLoadUsersController())) - router.get('/users/:id', adaptRoute(makeLoadUserByIdController())) + router.get('/users/:id', adaptRoute(makeLoadUsersByIdController())) router.post('/users', adaptRoute(makeAddUserController())) } diff --git a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.ts b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.ts index 990baed8..bcb91735 100644 --- a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.ts +++ b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.ts @@ -1,30 +1,39 @@ import { User } from '@/domain/models' import { LoadUsersById } from '@/domain/usecases/users' -import { ok, serverError } from '@/presentation/helpers/http-helper' +import { MissingParamError } from '@/presentation/errors/missing-param-error' +import { ok, serverError, notFound, badRequest } from '@/presentation/helpers/http-helper' import { HttpResponse } from '@/presentation/protocols' -export class LoadUserByIdController { +export class LoadUsersByIdController { constructor(private readonly loadUserByIdUseCase: LoadUsersById) {} async handle( - request: LoadUserByIdController.Request - ): Promise { + request: LoadUsersByIdController.Request + ): Promise { try { - const { userId } = request + const { id: userId } = request + if (!userId) { + return badRequest(new MissingParamError('userId')) + } const user = await this.loadUserByIdUseCase.loadById({ userId, }) + if (!user) { + return notFound('user') + } return ok(user) } catch (error) { + console.error(error); + return serverError(error) } } } -export namespace LoadUserByIdController { +export namespace LoadUsersByIdController { export type Request = { - userId: number + id: number } export type Response = HttpResponse } diff --git a/app/src/presentation/errors/missing-param-error.ts b/app/src/presentation/errors/missing-param-error.ts new file mode 100644 index 00000000..ef1f1ad1 --- /dev/null +++ b/app/src/presentation/errors/missing-param-error.ts @@ -0,0 +1,6 @@ +export class MissingParamError extends Error { + constructor (paramName: string) { + super(`Missing param: ${paramName}`) + this.name = 'MissingParamError' + } +} \ No newline at end of file diff --git a/app/src/presentation/errors/not-found-error.ts b/app/src/presentation/errors/not-found-error.ts new file mode 100644 index 00000000..6176782d --- /dev/null +++ b/app/src/presentation/errors/not-found-error.ts @@ -0,0 +1,6 @@ +export class NotFoundError extends Error { + constructor (item: string) { + super(`${item} not found`) + this.name = 'NotFoundError' + } +} \ No newline at end of file diff --git a/app/src/presentation/helpers/http-helper.ts b/app/src/presentation/helpers/http-helper.ts index 30e159a4..11ae594f 100644 --- a/app/src/presentation/helpers/http-helper.ts +++ b/app/src/presentation/helpers/http-helper.ts @@ -1,4 +1,5 @@ import { HttpResponse } from '@/presentation/protocols/http' +import { NotFoundError } from '../errors/not-found-error' export const badRequest = (error: Error): HttpResponse => ({ statusCode: 400, @@ -23,4 +24,9 @@ export const noContent = (): HttpResponse => ({ export const serverError = (error: Error): HttpResponse => ({ statusCode: 500, body: error +}) + +export const notFound = (item: string): HttpResponse => ({ + statusCode: 404, + body: new NotFoundError(item) }) \ No newline at end of file From 6fc7a63fc41ecafca0d6e70a42037638df2000a1 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 22:23:08 -0300 Subject: [PATCH 048/105] test: implemente GET /users/{id} --- .../users/db-load-users-by-id.test.ts | 41 +++++++++++++++ .../users-mysql-repository.test.ts | 52 ++++++++++++++++--- app/src/main/routes/users-routes.spec.ts | 19 +++++++ .../load-user-by-id-controller.test.ts | 27 ++++++++-- 4 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 app/src/data/usecases/users/db-load-users-by-id.test.ts diff --git a/app/src/data/usecases/users/db-load-users-by-id.test.ts b/app/src/data/usecases/users/db-load-users-by-id.test.ts new file mode 100644 index 00000000..d2cf9e8e --- /dev/null +++ b/app/src/data/usecases/users/db-load-users-by-id.test.ts @@ -0,0 +1,41 @@ +import { LoadUsersByIdRepositorySpy } from '@/data/test/users-mock' +import { faker } from '@faker-js/faker' +import { describe, expect, test, vitest } from 'vitest' +import { DbLoadUsersById } from './db-load-users-by-id' + +describe('DbLoadUsersById', () => { + function makeSut() { + const loadUsersByIdRepositorySpy = new LoadUsersByIdRepositorySpy() + const sut = new DbLoadUsersById(loadUsersByIdRepositorySpy) + return { sut, loadUsersByIdRepositorySpy } + } + describe('loadById()', () => { + test('should call loadUsersByIdRepository with correct params', async () => { + const { sut, loadUsersByIdRepositorySpy } = makeSut() + const userId = faker.datatype.number() + await sut.loadById({ userId }) + expect(loadUsersByIdRepositorySpy.loadByIdParams).toEqual({ userId }) + }) + + test('should return a user on success', async () => { + const { sut, loadUsersByIdRepositorySpy } = makeSut() + const user = await sut.loadById({ userId: faker.datatype.number() }) + expect(user).toEqual(loadUsersByIdRepositorySpy.loadByIdResult) + }) + + test('should return null if any user was found', async () => { + const { sut, loadUsersByIdRepositorySpy } = makeSut() + loadUsersByIdRepositorySpy.loadByIdResult = null + const user = await sut.loadById({ userId: faker.datatype.number() }) + expect(user).toBeNull() + }) + + test('should throw if loadUsersByIdRepository throws', async () => { + const { sut, loadUsersByIdRepositorySpy } = makeSut() + const mockedError = new Error('mocked error') + vitest.spyOn(loadUsersByIdRepositorySpy, 'loadById').mockRejectedValueOnce(mockedError) + const promise = sut.loadById({ userId: faker.datatype.number() }) + await expect(promise).rejects.toThrow(mockedError) + }) + }) +}) diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts index ee711a23..1d6a6d26 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts @@ -45,7 +45,7 @@ describe('UsersMySqlReposiory', () => { const { sut } = makeSut() const mockedUser = mockAddUser() const mockedOtherUser = mockAddUser() - + await UsersSequelize.create(mockedUser) await UsersSequelize.create(mockedOtherUser) @@ -61,8 +61,10 @@ describe('UsersMySqlReposiory', () => { const mockOldestUser = mockAddUser() mockOldestUser.createdAt = new Date('2021-01-01 12:00:00') - const mostRecentUser = await UsersSequelize.create(mockMostRecentUser) as any - const oldestUser = await UsersSequelize.create(mockOldestUser) as any + const mostRecentUser = (await UsersSequelize.create( + mockMostRecentUser + )) as any + const oldestUser = (await UsersSequelize.create(mockOldestUser)) as any const users = await sut.load({ order: 'desc' }) expect(users[0].id).toEqual(mostRecentUser.id) expect(users[1].id).toEqual(oldestUser.id) @@ -76,8 +78,10 @@ describe('UsersMySqlReposiory', () => { const mockOldestUser = mockAddUser() mockOldestUser.createdAt = new Date('2021-01-01 12:00:00') - const mostRecentUser = await UsersSequelize.create(mockMostRecentUser) as any - const oldestUser = await UsersSequelize.create(mockOldestUser) as any + const mostRecentUser = (await UsersSequelize.create( + mockMostRecentUser + )) as any + const oldestUser = (await UsersSequelize.create(mockOldestUser)) as any const users = await sut.load({ order: 'asc' }) expect(users[0].id).toEqual(oldestUser.id) expect(users[1].id).toEqual(mostRecentUser.id) @@ -89,15 +93,49 @@ describe('UsersMySqlReposiory', () => { const { sut } = makeSut() const mockedUser = mockAddUser() const mockedOtherUser = mockAddUser() - + await UsersSequelize.create(mockedUser) await UsersSequelize.create(mockedOtherUser) const user = await sut.loadByEmail({ - email: mockedUser.email + email: mockedUser.email, }) expect(user.name).toEqual(mockedUser.name) expect(user.email).toEqual(mockedUser.email) }) + + test('should return null if the User does not exists', async () => { + const { sut } = makeSut() + const user = await sut.loadByEmail({ + email: 'some_email@mail.com', + }) + expect(user).toBeNull() + }) + }) + + describe('loadById()', () => { + test('should load the correct User according to the id', async () => { + const { sut } = makeSut() + const mockedUser = mockAddUser() + const mockedOtherUser = mockAddUser() + + const { id } = await UsersSequelize.create(mockedUser) as any + await UsersSequelize.create(mockedOtherUser) + + const user = await sut.loadById({ + userId: id + }) + expect(user.id).toBe(id) + expect(user.name).toEqual(mockedUser.name) + expect(user.email).toEqual(mockedUser.email) + }) + + test('should return null if the User does not exists', async () => { + const { sut } = makeSut() + const user = await sut.loadById({ + userId: 1 + }) + expect(user).toBeNull() + }) }) }) diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index 5864de96..4ada9a7d 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -63,4 +63,23 @@ describe('Users Routes', () => { expect(res.body[1].id).toBe(userOne.getDataValue('id')) }) }) + + describe('GET /users/{id}', () => { + test('should return 404 if the user does not exits', async () => { + await request(app) + .get('/users/1') + .expect(404) + .expect({ error: 'user not found' }) + }) + + test('should return 200 with the user', async () => { + const user = await UsersSequelize.create(mockAddUser()) + + const res = await request(app) + .get(`/users/${user.getDataValue('id')}`) + .expect(200) + + expect(res.body.id).toBe(user.getDataValue('id')) + }) + }) }) diff --git a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts index bee4fcf6..46d6844a 100644 --- a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts @@ -1,12 +1,14 @@ import { LoadUsersByIdSpy } from '@/domain/tests/users-mock' -import { ok, serverError } from '@/presentation/helpers/http-helper' +import { MissingParamError } from '@/presentation/errors/missing-param-error' +import { badRequest, notFound, ok, serverError } from '@/presentation/helpers/http-helper' +import { faker } from '@faker-js/faker' import { describe, expect, test, vitest } from 'vitest' -import { LoadUserByIdController } from './load-user-by-id-controller' +import { LoadUsersByIdController } from './load-user-by-id-controller' describe('LoadUserByIdControler', () => { function makeSut() { const loadUserByIdSpy = new LoadUsersByIdSpy() - const sut = new LoadUserByIdController(loadUserByIdSpy) + const sut = new LoadUsersByIdController(loadUserByIdSpy) return { sut, @@ -23,6 +25,25 @@ describe('LoadUserByIdControler', () => { expect(loadUserByIdSpy.loadByIdParams).toEqual(request) }) + test('should return 400 if userId was not provided', async () => { + const { sut } = makeSut() + const request = { + userId: null, + } + const response = await sut.handle(request) + expect(response).toEqual(badRequest(new MissingParamError('userId'))) + }); + + test('should return 404 if loadUserByIdUseCase returns null', async () => { + const { sut,loadUserByIdSpy } = makeSut() + loadUserByIdSpy.loadByIdResult = null + const request = { + userId: faker.datatype.number(), + } + const response = await sut.handle(request) + expect(response).toEqual(notFound('user')) + }); + test('should return 500 if loadUserByIdUseCase throws', async () => { const { sut, loadUserByIdSpy } = makeSut() const mockedError = new Error('some_error') From 79b684ba968b8fb33a6f6dd3c0e8b20df4cf0e10 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 22:25:39 -0300 Subject: [PATCH 049/105] refactor: refatora testes quebrados --- .../load-user-by-id-controller.test.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts index 46d6844a..cf30f9be 100644 --- a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts @@ -19,16 +19,18 @@ describe('LoadUserByIdControler', () => { test('should call loadUserByIdUseCase with correct user id', async () => { const { sut, loadUserByIdSpy } = makeSut() const request = { - userId: 1, + id: 1, } await sut.handle(request) - expect(loadUserByIdSpy.loadByIdParams).toEqual(request) + expect(loadUserByIdSpy.loadByIdParams).toEqual({ + userId: request.id, + }) }) test('should return 400 if userId was not provided', async () => { const { sut } = makeSut() const request = { - userId: null, + id: null, } const response = await sut.handle(request) expect(response).toEqual(badRequest(new MissingParamError('userId'))) @@ -38,7 +40,7 @@ describe('LoadUserByIdControler', () => { const { sut,loadUserByIdSpy } = makeSut() loadUserByIdSpy.loadByIdResult = null const request = { - userId: faker.datatype.number(), + id: faker.datatype.number(), } const response = await sut.handle(request) expect(response).toEqual(notFound('user')) @@ -51,7 +53,7 @@ describe('LoadUserByIdControler', () => { .spyOn(loadUserByIdSpy, 'loadById') .mockRejectedValueOnce(mockedError) const request = { - userId: 1, + id: 1, } const response = await sut.handle(request) expect(response).toEqual(serverError(mockedError)) @@ -60,7 +62,7 @@ describe('LoadUserByIdControler', () => { test('should return 200 if loadUserByIdUseCase succeeds', async () => { const { sut, loadUserByIdSpy } = makeSut() const request = { - userId: 1, + id: 1, } const response = await sut.handle(request) expect(response).toEqual(ok(loadUserByIdSpy.loadByIdResult)) From 9547aa3f4f4bc2f29ed7fecd2afddca9f73f3644 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Mon, 17 Oct 2022 22:29:15 -0300 Subject: [PATCH 050/105] =?UTF-8?q?chore:=20adiciona=20relat=C3=B3rio=20de?= =?UTF-8?q?=20coverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/.gitignore | 3 +- app/package-lock.json | 1262 +++++++++++++++++++++++++++++++++++++++++ app/package.json | 4 +- app/vitest.config.ts | 2 +- 4 files changed, 1268 insertions(+), 3 deletions(-) diff --git a/app/.gitignore b/app/.gitignore index 56f07a37..023d1c30 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1,3 +1,4 @@ node_modules .env -.database.* \ No newline at end of file +.database.* +coverage \ No newline at end of file diff --git a/app/package-lock.json b/app/package-lock.json index 5803d01e..1000caa9 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -22,6 +22,7 @@ "@types/express": "^4.17.14", "@types/node": "^18.11.0", "@types/supertest": "^2.0.12", + "@vitest/coverage-istanbul": "^0.24.3", "mockdate": "^3.0.5", "nodemon": "^2.0.20", "sqlite3": "^5.1.2", @@ -37,6 +38,339 @@ "node": ">=16.0.0" } }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.19.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.19.4", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.19.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.4", + "@babel/types": "^7.19.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -103,6 +437,28 @@ "dev": true, "optional": true }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", @@ -111,6 +467,15 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", @@ -364,6 +729,24 @@ "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", "integrity": "sha512-jiEw2kTUJ8Jsh4A1K4b5Pkjj9Xz6FktLLOQ36ZVLRkmxFbpTvAV2VRoKMojz8UlZxNg/2dZqzpigH4JYn1bkQg==" }, + "node_modules/@vitest/coverage-istanbul": { + "version": "0.24.3", + "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-0.24.3.tgz", + "integrity": "sha512-cPQ5icP/TPih3qeZ29qA2zg1lxAM+wAUuh1ZkQJ75OK7am/8isqhP5QCCeGCLdFOakDsm4Ik8vHHfcDffuxW9Q==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.2.1", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.1.5", + "test-exclude": "^6.0.0", + "vitest": "0.24.3" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -625,6 +1008,34 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -725,6 +1136,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001420", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001420.tgz", + "integrity": "sha512-OnyeJ9ascFA9roEj72ok2Ikp7PHJTKubtEJIQ/VK3fdsS50q4KWy+Z5X0A1/GswEItKX0ctAp8n4SYDE7wTu6A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, "node_modules/chai": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", @@ -743,6 +1170,47 @@ "node": ">=4" } }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -909,6 +1377,12 @@ "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -1131,6 +1605,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1585,6 +2065,15 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -1858,6 +2347,15 @@ "is-property": "^1.0.2" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1923,6 +2421,15 @@ "integrity": "sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==", "dev": true }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", @@ -1980,6 +2487,12 @@ "node": ">=8" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -2213,6 +2726,102 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/js-beautify": { "version": "1.14.6", "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.6.tgz", @@ -2232,6 +2841,24 @@ "node": ">=10" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -2813,6 +3440,12 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "dev": true + }, "node_modules/nodemon": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", @@ -3847,6 +4480,62 @@ "node": ">= 10" } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -3880,6 +4569,15 @@ "node": ">=14.0.0" } }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4192,6 +4890,32 @@ "node": ">= 0.8" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -4488,6 +5212,260 @@ } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", + "dev": true + }, + "@babel/core": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.19.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", + "dev": true, + "requires": { + "@babel/types": "^7.19.4", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "dev": true, + "requires": { + "@babel/types": "^7.19.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", + "dev": true + }, + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.4", + "@babel/types": "^7.19.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, "@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -4529,11 +5507,33 @@ "dev": true, "optional": true }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, "@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", @@ -4774,6 +5774,21 @@ "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", "integrity": "sha512-jiEw2kTUJ8Jsh4A1K4b5Pkjj9Xz6FktLLOQ36ZVLRkmxFbpTvAV2VRoKMojz8UlZxNg/2dZqzpigH4JYn1bkQg==" }, + "@vitest/coverage-istanbul": { + "version": "0.24.3", + "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-0.24.3.tgz", + "integrity": "sha512-cPQ5icP/TPih3qeZ29qA2zg1lxAM+wAUuh1ZkQJ75OK7am/8isqhP5QCCeGCLdFOakDsm4Ik8vHHfcDffuxW9Q==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.2.1", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.1.5", + "test-exclude": "^6.0.0", + "vitest": "0.24.3" + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -4979,6 +5994,18 @@ "fill-range": "^7.0.1" } }, + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + } + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -5063,6 +6090,12 @@ "get-intrinsic": "^1.0.2" } }, + "caniuse-lite": { + "version": "1.0.30001420", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001420.tgz", + "integrity": "sha512-OnyeJ9ascFA9roEj72ok2Ikp7PHJTKubtEJIQ/VK3fdsS50q4KWy+Z5X0A1/GswEItKX0ctAp8n4SYDE7wTu6A==", + "dev": true + }, "chai": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", @@ -5078,6 +6111,43 @@ "type-detect": "^4.0.5" } }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + } + } + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -5206,6 +6276,12 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -5376,6 +6452,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -5630,6 +6712,12 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -5862,6 +6950,12 @@ "is-property": "^1.0.2" } }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -5909,6 +7003,12 @@ "integrity": "sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==", "dev": true }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", @@ -5951,6 +7051,12 @@ "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", "dev": true }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -6141,6 +7247,82 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, "js-beautify": { "version": "1.14.6", "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.6.tgz", @@ -6152,6 +7334,18 @@ "nopt": "^6.0.0" } }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -6595,6 +7789,12 @@ } } }, + "node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "dev": true + }, "nodemon": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", @@ -7340,6 +8540,52 @@ "yallist": "^4.0.0" } }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, "timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -7367,6 +8613,12 @@ "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", "dev": true }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7590,6 +8842,16 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/app/package.json b/app/package.json index 190849e5..9af61554 100644 --- a/app/package.json +++ b/app/package.json @@ -4,10 +4,11 @@ "description": "", "main": "index.js", "scripts": { + "start": "nodemon src/main/server.ts ", "test": "cross-env NODE_ENV=test vitest", "test:unit": "npm run test -- --config vitest.unit.config.ts", "test:integration": "npm run test -- --config vitest.integration.config.ts", - "start": "nodemon src/main/server.ts " + "test:coverage": "npm run test -- --coverage" }, "keywords": [], "author": "", @@ -17,6 +18,7 @@ "@types/express": "^4.17.14", "@types/node": "^18.11.0", "@types/supertest": "^2.0.12", + "@vitest/coverage-istanbul": "^0.24.3", "mockdate": "^3.0.5", "nodemon": "^2.0.20", "sqlite3": "^5.1.2", diff --git a/app/vitest.config.ts b/app/vitest.config.ts index bd0b4042..e3b5e349 100644 --- a/app/vitest.config.ts +++ b/app/vitest.config.ts @@ -4,7 +4,7 @@ import tsconfigPaths from 'vitest-tsconfig-paths' export default defineConfig({ test: { coverage: { - include: ['src/**/*.{ts}'], + include: ['src/**/*.ts'], provider: 'istanbul' } }, From 35753eca519011dc1170f0ea9ebee92a610bfde2 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:06:38 -0300 Subject: [PATCH 051/105] feat: implementa DbDeleteUser --- .../database/users/delete-user-repository.ts | 9 +++++++++ app/src/data/usecases/users/db-delete-user.ts | 11 +++++++++++ app/src/domain/usecases/users/delete-user.ts | 6 +++++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 app/src/data/protocols/database/users/delete-user-repository.ts create mode 100644 app/src/data/usecases/users/db-delete-user.ts diff --git a/app/src/data/protocols/database/users/delete-user-repository.ts b/app/src/data/protocols/database/users/delete-user-repository.ts new file mode 100644 index 00000000..16aa107a --- /dev/null +++ b/app/src/data/protocols/database/users/delete-user-repository.ts @@ -0,0 +1,9 @@ +import { DeleteUser } from '@/domain/usecases/users' + +export interface DeleteUserRepository { + delete: (params?: DeleteUserRepository.Params) => Promise +} + +export namespace DeleteUserRepository { + export type Params = DeleteUser.Params +} diff --git a/app/src/data/usecases/users/db-delete-user.ts b/app/src/data/usecases/users/db-delete-user.ts new file mode 100644 index 00000000..b3ea5405 --- /dev/null +++ b/app/src/data/usecases/users/db-delete-user.ts @@ -0,0 +1,11 @@ +import { DeleteUserRepository } from '@/data/protocols/database/users/delete-user-repository' +import { DeleteUser } from '@/domain/usecases/users' + +export class DbDeleteUser implements DeleteUser { + constructor( + private readonly deleteUserRepository: DeleteUserRepository + ) {} + async delete(params?: DeleteUser.Params): Promise { + await this.deleteUserRepository.delete(params) + } +} diff --git a/app/src/domain/usecases/users/delete-user.ts b/app/src/domain/usecases/users/delete-user.ts index c66048d8..5dba883b 100644 --- a/app/src/domain/usecases/users/delete-user.ts +++ b/app/src/domain/usecases/users/delete-user.ts @@ -1,3 +1,7 @@ export interface DeleteUser { - delete (userId: string): Promise + delete(params: DeleteUser.Params): Promise +} + +export namespace DeleteUser { + export type Params = { userId: string | number } } From 90ad5c56e8cbb72c4cf96147bb207ba967d59172 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:06:42 -0300 Subject: [PATCH 052/105] test: implementa DbDeleteUser --- app/src/data/test/users-mock.ts | 9 ++++++ .../usecases/users/db-delete-user.test.ts | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 app/src/data/usecases/users/db-delete-user.test.ts diff --git a/app/src/data/test/users-mock.ts b/app/src/data/test/users-mock.ts index 0450e974..14ec6ad0 100644 --- a/app/src/data/test/users-mock.ts +++ b/app/src/data/test/users-mock.ts @@ -1,6 +1,7 @@ import { mockUser } from '@/domain/tests/users-mock' import { LoadUsersByEmailRepository, LoadUsersByIdRepository } from '../protocols/database/users' import { AddUserRepository } from '../protocols/database/users/add-user-repository' +import { DeleteUserRepository } from '../protocols/database/users/delete-user-repository' import { LoadUsersRepository } from '../protocols/database/users/load-user-repository' export class AddUserRepositorySpy implements AddUserRepository { @@ -49,4 +50,12 @@ export class LoadUsersByIdRepositorySpy implements LoadUsersByIdRepository { this.loadByIdParams = params return this.loadByIdResult } +} + +export class DeleteUserRepositorySpy implements DeleteUserRepository { + deleteParams: DeleteUserRepository.Params + + async delete(params: DeleteUserRepository.Params): Promise { + this.deleteParams = params + } } \ No newline at end of file diff --git a/app/src/data/usecases/users/db-delete-user.test.ts b/app/src/data/usecases/users/db-delete-user.test.ts new file mode 100644 index 00000000..4dee4a0c --- /dev/null +++ b/app/src/data/usecases/users/db-delete-user.test.ts @@ -0,0 +1,29 @@ +import { DeleteUserRepositorySpy } from '@/data/test/users-mock' +import { faker } from '@faker-js/faker' +import { describe, expect, test, vitest } from 'vitest' +import { DbDeleteUser } from './db-delete-user' + +describe('DbDeleteUser', () => { + function makeSut() { + const deleteUserRepositorySpy = new DeleteUserRepositorySpy() + const sut = new DbDeleteUser(deleteUserRepositorySpy) + return { sut, deleteUserRepositorySpy } + } + describe('loadById()', () => { + test('should call deleteUserRepository with correct params', async () => { + const { sut, deleteUserRepositorySpy } = makeSut() + const userId = faker.datatype.number() + await sut.delete({ userId }) + expect(deleteUserRepositorySpy.deleteParams).toEqual({ userId }) + }) + + test('should throw if deleteUserRepository throws', async () => { + const { sut, deleteUserRepositorySpy } = makeSut() + const mockedError = new Error('mocked error') + vitest.spyOn(deleteUserRepositorySpy, 'delete').mockRejectedValueOnce(mockedError) + const userId = faker.datatype.number() + const promise = sut.delete({ userId }) + await expect(promise).rejects.toThrow(mockedError) + }); + }) +}) From 136b84f5ab2f4ced0f8103c4731fa26eae34d4d0 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:15:25 -0300 Subject: [PATCH 053/105] =?UTF-8?q?feat:=20garante=20que=20DbDeleteUser=20?= =?UTF-8?q?ir=C3=A1=20chamar=20o=20loadUserById=20corretamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/data/protocols/database/users/index.ts | 3 ++- app/src/data/usecases/users/db-delete-user.ts | 11 ++++++++++- app/src/data/usecases/users/index.ts | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/data/protocols/database/users/index.ts b/app/src/data/protocols/database/users/index.ts index ff22ae84..3d5f2c4f 100644 --- a/app/src/data/protocols/database/users/index.ts +++ b/app/src/data/protocols/database/users/index.ts @@ -1,4 +1,5 @@ export * from './load-user-repository' export * from './add-user-repository' export * from './load-user-by-email-repository' -export * from './load-user-by-id-repository' \ No newline at end of file +export * from './load-user-by-id-repository' +export * from './delete-user-repository' \ No newline at end of file diff --git a/app/src/data/usecases/users/db-delete-user.ts b/app/src/data/usecases/users/db-delete-user.ts index b3ea5405..b4b22309 100644 --- a/app/src/data/usecases/users/db-delete-user.ts +++ b/app/src/data/usecases/users/db-delete-user.ts @@ -1,11 +1,20 @@ +import { LoadUsersByIdRepository } from '@/data/protocols/database/users' import { DeleteUserRepository } from '@/data/protocols/database/users/delete-user-repository' import { DeleteUser } from '@/domain/usecases/users' +import { NotFoundError } from '@/presentation/errors/not-found-error' export class DbDeleteUser implements DeleteUser { constructor( - private readonly deleteUserRepository: DeleteUserRepository + private readonly deleteUserRepository: DeleteUserRepository, + private readonly loadUsersByIdRepository: LoadUsersByIdRepository ) {} async delete(params?: DeleteUser.Params): Promise { + const usersExists = await this.loadUsersByIdRepository.loadById({ + userId: params.userId + }) + if (!usersExists) { + throw new NotFoundError('User') + } await this.deleteUserRepository.delete(params) } } diff --git a/app/src/data/usecases/users/index.ts b/app/src/data/usecases/users/index.ts index da676d77..4ebf7877 100644 --- a/app/src/data/usecases/users/index.ts +++ b/app/src/data/usecases/users/index.ts @@ -1,4 +1,5 @@ export * from './db-add-user' export * from './db-load-users' export * from './db-load-users-by-email' -export * from './db-load-users-by-id' \ No newline at end of file +export * from './db-load-users-by-id' +export * from './db-delete-user' \ No newline at end of file From a44658854b3eb263ca0630eaf7289869c95eadd0 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:15:31 -0300 Subject: [PATCH 054/105] =?UTF-8?q?test:=20garante=20que=20DbDeleteUser=20?= =?UTF-8?q?ir=C3=A1=20chamar=20o=20loadUserById=20corretamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usecases/users/db-delete-user.test.ts | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/app/src/data/usecases/users/db-delete-user.test.ts b/app/src/data/usecases/users/db-delete-user.test.ts index 4dee4a0c..2ac562b8 100644 --- a/app/src/data/usecases/users/db-delete-user.test.ts +++ b/app/src/data/usecases/users/db-delete-user.test.ts @@ -1,4 +1,4 @@ -import { DeleteUserRepositorySpy } from '@/data/test/users-mock' +import { DeleteUserRepositorySpy, LoadUsersByIdRepositorySpy } from '@/data/test/users-mock' import { faker } from '@faker-js/faker' import { describe, expect, test, vitest } from 'vitest' import { DbDeleteUser } from './db-delete-user' @@ -6,10 +6,11 @@ import { DbDeleteUser } from './db-delete-user' describe('DbDeleteUser', () => { function makeSut() { const deleteUserRepositorySpy = new DeleteUserRepositorySpy() - const sut = new DbDeleteUser(deleteUserRepositorySpy) - return { sut, deleteUserRepositorySpy } + const loadUsersByIdRepositorySpy = new LoadUsersByIdRepositorySpy() + const sut = new DbDeleteUser(deleteUserRepositorySpy, loadUsersByIdRepositorySpy) + return { sut, deleteUserRepositorySpy, loadUsersByIdRepositorySpy } } - describe('loadById()', () => { + describe('delete()', () => { test('should call deleteUserRepository with correct params', async () => { const { sut, deleteUserRepositorySpy } = makeSut() const userId = faker.datatype.number() @@ -25,5 +26,31 @@ describe('DbDeleteUser', () => { const promise = sut.delete({ userId }) await expect(promise).rejects.toThrow(mockedError) }); + + test('should call LoadUsersByIdRepository with correct values', async () => { + const { sut, loadUsersByIdRepositorySpy } = makeSut() + const userId = faker.datatype.number() + await sut.delete({ userId }) + expect(loadUsersByIdRepositorySpy.loadByIdParams).toEqual({ userId }) + }); + + test('should throw if LoadUsersByIdRepository throws', async () => { + const { sut, loadUsersByIdRepositorySpy } = makeSut() + const mockedError = new Error('mocked error') + vitest.spyOn(loadUsersByIdRepositorySpy, 'loadById').mockRejectedValueOnce(mockedError) + const userId = faker.datatype.number() + const promise = sut.delete({ userId }) + await expect(promise).rejects.toThrow(mockedError) + }) + + test('should throw NotFoundError if the user does not exists', async () => { + const { sut, loadUsersByIdRepositorySpy } = makeSut() + loadUsersByIdRepositorySpy.loadByIdResult = null + const userId = faker.datatype.number() + const promise = sut.delete({ userId }) + await expect(promise).rejects.toThrow('User') + }); + + }) }) From a14c95fc2e38e06fc2a4f94cdf7662e1daaa5fe7 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:32:41 -0300 Subject: [PATCH 055/105] feat: implementa DeleteuserController --- .../delete-user-controller.ts | 28 +++++++++++++++++++ app/src/presentation/errors/client-error.ts | 6 ++++ .../errors/email-already-in-use-error.ts | 6 ++-- .../errors/missing-param-error.ts | 5 +++- .../presentation/errors/not-found-error.ts | 5 +++- app/src/presentation/helpers/http-helper.ts | 27 +++++++++--------- 6 files changed, 60 insertions(+), 17 deletions(-) create mode 100644 app/src/presentation/controllers/users-controller/delete-user-controller.ts create mode 100644 app/src/presentation/errors/client-error.ts diff --git a/app/src/presentation/controllers/users-controller/delete-user-controller.ts b/app/src/presentation/controllers/users-controller/delete-user-controller.ts new file mode 100644 index 00000000..f1d44aa0 --- /dev/null +++ b/app/src/presentation/controllers/users-controller/delete-user-controller.ts @@ -0,0 +1,28 @@ +import { DeleteUser } from "@/domain/usecases/users"; +import { noContent, serverError } from "@/presentation/helpers/http-helper"; +import { Controller, HttpResponse } from "@/presentation/protocols"; + +export class DeleteUserController implements Controller { + constructor( + private readonly deleteUserUseCase: DeleteUser, + ) {} + + async handle(request: DeleteUserController.Request): Promise { + try { + await this.deleteUserUseCase.delete({ + userId: request.id, + }) + return noContent() + } catch (error) { + return serverError(error) + } + } +} + +export namespace DeleteUserController { + export type Request = { + id: number | string; + }; + + export type Response = HttpResponse +} \ No newline at end of file diff --git a/app/src/presentation/errors/client-error.ts b/app/src/presentation/errors/client-error.ts new file mode 100644 index 00000000..e1a60d66 --- /dev/null +++ b/app/src/presentation/errors/client-error.ts @@ -0,0 +1,6 @@ +export class ClientError extends Error { + statusCode: number + constructor (message: string = '') { + super(message) + } +} \ No newline at end of file diff --git a/app/src/presentation/errors/email-already-in-use-error.ts b/app/src/presentation/errors/email-already-in-use-error.ts index e7efd526..33552c94 100644 --- a/app/src/presentation/errors/email-already-in-use-error.ts +++ b/app/src/presentation/errors/email-already-in-use-error.ts @@ -1,5 +1,7 @@ -export class EmailAlreadyInUseError extends Error { - constructor (email) { +import { ClientError } from "./client-error" + +export class EmailAlreadyInUseError extends ClientError { + constructor (email: string) { super() this.name = 'EmailAlreadyInUseError' this.message = `The received email ${email} is already in use.` diff --git a/app/src/presentation/errors/missing-param-error.ts b/app/src/presentation/errors/missing-param-error.ts index ef1f1ad1..057729e2 100644 --- a/app/src/presentation/errors/missing-param-error.ts +++ b/app/src/presentation/errors/missing-param-error.ts @@ -1,6 +1,9 @@ -export class MissingParamError extends Error { +import { ClientError } from "./client-error" + +export class MissingParamError extends ClientError { constructor (paramName: string) { super(`Missing param: ${paramName}`) + this.statusCode = 404 this.name = 'MissingParamError' } } \ No newline at end of file diff --git a/app/src/presentation/errors/not-found-error.ts b/app/src/presentation/errors/not-found-error.ts index 6176782d..61fdee61 100644 --- a/app/src/presentation/errors/not-found-error.ts +++ b/app/src/presentation/errors/not-found-error.ts @@ -1,6 +1,9 @@ -export class NotFoundError extends Error { +import { ClientError } from "./client-error" + +export class NotFoundError extends ClientError { constructor (item: string) { super(`${item} not found`) + this.statusCode = 404 this.name = 'NotFoundError' } } \ No newline at end of file diff --git a/app/src/presentation/helpers/http-helper.ts b/app/src/presentation/helpers/http-helper.ts index 11ae594f..0a4bb56e 100644 --- a/app/src/presentation/helpers/http-helper.ts +++ b/app/src/presentation/helpers/http-helper.ts @@ -1,32 +1,33 @@ import { HttpResponse } from '@/presentation/protocols/http' +import { ClientError } from '../errors/client-error' import { NotFoundError } from '../errors/not-found-error' -export const badRequest = (error: Error): HttpResponse => ({ - statusCode: 400, - body: error +export const badRequest = (error: ClientError): HttpResponse => ({ + statusCode: error.statusCode || 400, + body: error, }) export const ok = (data: any): HttpResponse => ({ statusCode: 200, - body: data + body: data, }) -export const forbidden = (error: Error): HttpResponse => ({ - statusCode: 403, - body: error +export const forbidden = (error: ClientError): HttpResponse => ({ + statusCode: error.statusCode || 403, + body: error, }) export const noContent = (): HttpResponse => ({ statusCode: 204, - body: null + body: null, }) -export const serverError = (error: Error): HttpResponse => ({ - statusCode: 500, - body: error +export const serverError = (error: ClientError): HttpResponse => ({ + statusCode: error.statusCode || 500, + body: error, }) export const notFound = (item: string): HttpResponse => ({ statusCode: 404, - body: new NotFoundError(item) -}) \ No newline at end of file + body: new NotFoundError(item), +}) From a91b0dc9aefa584ddea758a4bcbad6c437d3e4a8 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:32:45 -0300 Subject: [PATCH 056/105] test: implementa DeleteuserController --- app/src/domain/tests/users-mock.ts | 10 +++++- .../delete-user-controller.test.ts | 36 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 app/src/presentation/controllers/users-controller/delete-user-controller.test.ts diff --git a/app/src/domain/tests/users-mock.ts b/app/src/domain/tests/users-mock.ts index 9be1376d..181b7e71 100644 --- a/app/src/domain/tests/users-mock.ts +++ b/app/src/domain/tests/users-mock.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker' import { User } from '../models' -import { AddUser, LoadUsers, LoadUsersById } from '../usecases/users' +import { AddUser, DeleteUser, LoadUsers, LoadUsersById } from '../usecases/users' import { LoadUsersByEmail } from '../usecases/users/load-users-by-email' export function mockAddUser(): AddUser.Params { return { @@ -71,3 +71,11 @@ export class AddUserSpy implements AddUser { return new Promise((resolve) => resolve(this.addResult)) } } + +export class DeleteUserSpy implements DeleteUser { + deleteParams: DeleteUser.Params + async delete(params: DeleteUser.Params): Promise { + this.deleteParams = params + return new Promise((resolve) => resolve()) + } +} \ No newline at end of file diff --git a/app/src/presentation/controllers/users-controller/delete-user-controller.test.ts b/app/src/presentation/controllers/users-controller/delete-user-controller.test.ts new file mode 100644 index 00000000..e0cdbe58 --- /dev/null +++ b/app/src/presentation/controllers/users-controller/delete-user-controller.test.ts @@ -0,0 +1,36 @@ +import { DeleteUserSpy } from "@/domain/tests/users-mock"; +import { NotFoundError } from "@/presentation/errors/not-found-error"; +import { noContent, serverError } from "@/presentation/helpers/http-helper"; +import { describe, expect, test, vitest } from "vitest"; +import { DeleteUserController } from "./delete-user-controller"; + +describe('DeleteUserController', () => { + function makeSut() { + const deleteUserUseCaseSpy = new DeleteUserSpy(); + const sut = new DeleteUserController(deleteUserUseCaseSpy) + + return { sut, deleteUserUseCaseSpy } + } + test('should call deleteUserUseCase with correct values', async () => { + const { sut, deleteUserUseCaseSpy } = makeSut() + const userId = 1 + await sut.handle({ id: userId }) + expect(deleteUserUseCaseSpy.deleteParams).toEqual({ userId }) + }); + + test('should return no content on success', async () => { + const { sut, deleteUserUseCaseSpy } = makeSut() + const userId = 1 + const result = await sut.handle({ id: userId }) + expect(result).toEqual(noContent()) + }); + + test('should return HttpReponse with the error if DeleteUserUseCase throws', async () => { + const { sut, deleteUserUseCaseSpy } = makeSut() + const mockedError = new NotFoundError('user') + vitest.spyOn(deleteUserUseCaseSpy, 'delete').mockRejectedValueOnce(mockedError) + const httpResponse = await sut.handle({ id: 1 }) + expect(httpResponse).toEqual(serverError(mockedError)) + expect(httpResponse.statusCode).toBe(404) + }); +}); \ No newline at end of file From 88767f0a476904c14578cfeab62b85acd5054066 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:35:55 -0300 Subject: [PATCH 057/105] =?UTF-8?q?feat:=20implementa=20m=C3=A9todo=20delt?= =?UTF-8?q?e=20no=20UsersMySqlRepository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UsersMySQLRepository/users-mysql-repository.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts index 9a95b7db..3b8e964f 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts @@ -1,9 +1,11 @@ import { AddUserRepository, + DeleteUserRepository, LoadUsersByEmailRepository, LoadUsersRepository, } from '@/data/protocols/database/users' import { LoadUsersByIdRepository } from '@/data/protocols/database/users/load-user-by-id-repository' +import { DeleteUser } from '@/domain/usecases/users' import UsersSequelize from '../models/Users' export class UsersMySqlReposiory @@ -11,7 +13,8 @@ export class UsersMySqlReposiory AddUserRepository, LoadUsersRepository, LoadUsersByEmailRepository, - LoadUsersByIdRepository + LoadUsersByIdRepository, + DeleteUserRepository { async add(user: AddUserRepository.Params): Promise { const newUser = await UsersSequelize.create(user) @@ -56,4 +59,12 @@ export class UsersMySqlReposiory return users as any as LoadUsersByEmailRepository.Result } + + async delete (params?: DeleteUser.Params): Promise { + await UsersSequelize.destroy({ + where: { + id: params.userId, + }, + }) + }; } From 858d0944b3e4736bdd91c213aa05c02778da40e7 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:35:59 -0300 Subject: [PATCH 058/105] =?UTF-8?q?test:=20implementa=20m=C3=A9todo=20delt?= =?UTF-8?q?e=20no=20UsersMySqlRepository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../users-mysql-repository.test.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts index 1d6a6d26..e4d36cce 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts @@ -138,4 +138,25 @@ describe('UsersMySqlReposiory', () => { expect(user).toBeNull() }) }) + + describe('delete()', () => { + test('should delete the correct User according to the id', async () => { + const { sut } = makeSut() + const mockedUser = mockAddUser() + const mockedOtherUser = mockAddUser() + + const { id } = await UsersSequelize.create(mockedUser) as any + await UsersSequelize.create(mockedOtherUser) + + await sut.delete({ + userId: id + }) + const user = await UsersSequelize.findOne({ + where: { + id + } + }) + expect(user).toBeNull() + }) + }); }) From 344e2d372b5b3f5b9e2bc7f206904b7272dd00bd Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:41:50 -0300 Subject: [PATCH 059/105] feat: implementa rota DELETE /users --- app/src/data/usecases/users/db-delete-user.ts | 2 +- .../controllers/user/delete-user-controller-factory.ts | 7 +++++++ .../factories/usecases/user/delete-user-usecase-factory.ts | 7 +++++++ app/src/main/factories/usecases/user/index.ts | 3 ++- app/src/main/routes/users-routes.ts | 2 ++ 5 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 app/src/main/factories/controllers/user/delete-user-controller-factory.ts create mode 100644 app/src/main/factories/usecases/user/delete-user-usecase-factory.ts diff --git a/app/src/data/usecases/users/db-delete-user.ts b/app/src/data/usecases/users/db-delete-user.ts index b4b22309..b5ebdfec 100644 --- a/app/src/data/usecases/users/db-delete-user.ts +++ b/app/src/data/usecases/users/db-delete-user.ts @@ -13,7 +13,7 @@ export class DbDeleteUser implements DeleteUser { userId: params.userId }) if (!usersExists) { - throw new NotFoundError('User') + throw new NotFoundError('user') } await this.deleteUserRepository.delete(params) } diff --git a/app/src/main/factories/controllers/user/delete-user-controller-factory.ts b/app/src/main/factories/controllers/user/delete-user-controller-factory.ts new file mode 100644 index 00000000..d898b14c --- /dev/null +++ b/app/src/main/factories/controllers/user/delete-user-controller-factory.ts @@ -0,0 +1,7 @@ +import { DeleteUserController } from '@/presentation/controllers/users-controller/delete-user-controller' +import { Controller } from '@/presentation/protocols' +import { makeDbDeleteUser } from '../../usecases/user' + +export function makeDeleteUserController(): Controller { + return new DeleteUserController(makeDbDeleteUser()) +} diff --git a/app/src/main/factories/usecases/user/delete-user-usecase-factory.ts b/app/src/main/factories/usecases/user/delete-user-usecase-factory.ts new file mode 100644 index 00000000..5fa4d899 --- /dev/null +++ b/app/src/main/factories/usecases/user/delete-user-usecase-factory.ts @@ -0,0 +1,7 @@ +import { DbDeleteUser } from '@/data/usecases/users' +import { DeleteUser } from '@/domain/usecases/users' +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository' + +export function makeDbDeleteUser(): DeleteUser { + return new DbDeleteUser(new UsersMySqlReposiory(), new UsersMySqlReposiory()) +} diff --git a/app/src/main/factories/usecases/user/index.ts b/app/src/main/factories/usecases/user/index.ts index d90ee627..09b2ea3a 100644 --- a/app/src/main/factories/usecases/user/index.ts +++ b/app/src/main/factories/usecases/user/index.ts @@ -1,4 +1,5 @@ export * from './add-user-usecase-factory' export * from './load-users-usecase-factory' export * from './load-users-by-email-usecase-factory' -export * from './load-users-by-id-usecase-factory' \ No newline at end of file +export * from './load-users-by-id-usecase-factory' +export * from './delete-user-usecase-factory' \ No newline at end of file diff --git a/app/src/main/routes/users-routes.ts b/app/src/main/routes/users-routes.ts index b75a1063..60da71fd 100644 --- a/app/src/main/routes/users-routes.ts +++ b/app/src/main/routes/users-routes.ts @@ -2,10 +2,12 @@ import { Router } from 'express' import { adaptRoute } from '../adapters/express/express-route-adapter' import { makeAddUserController, makeLoadUsersController } from '../factories/controllers/user' +import { makeDeleteUserController } from '../factories/controllers/user/delete-user-controller-factory' import { makeLoadUsersByIdController } from '../factories/controllers/user/load-user-by-id-controller-factory' export const usersRoutes = (router: Router): void => { router.get('/users', adaptRoute(makeLoadUsersController())) router.get('/users/:id', adaptRoute(makeLoadUsersByIdController())) router.post('/users', adaptRoute(makeAddUserController())) + router.delete('/users/:id', adaptRoute(makeDeleteUserController())) } From f9520f2096074e0e0914f02a0a83da7663635b43 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 14:41:54 -0300 Subject: [PATCH 060/105] test: implementa rota DELETE /users --- app/src/main/routes/users-routes.spec.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index 4ada9a7d..a34ad322 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -82,4 +82,21 @@ describe('Users Routes', () => { expect(res.body.id).toBe(user.getDataValue('id')) }) }) + + describe('Delete /users/{id}', () => { + test('should return 404 if the user does not exits', async () => { + await request(app) + .delete('/users/1') + .expect(404) + .expect({ error: 'user not found' }) + }) + + test('should delete an user according to the id', async () => { + const user = await UsersSequelize.create(mockAddUser()) + const id = user.getDataValue('id') + await request(app).delete(`/users/${id}`).expect(204) + const usersExists = await UsersSequelize.findOne({ where: { id } }) + expect(usersExists).toBeFalsy() + }); + }) }) From d11548093da65c0256e1530d01062ab6f67e6217 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:14:08 -0300 Subject: [PATCH 061/105] feat: implementa ValidatorComposite --- app/src/presentation/errors/client-error.ts | 4 +-- app/src/presentation/errors/index.ts | 3 +++ app/src/presentation/helpers/http-helper.ts | 8 +++--- app/src/presentation/protocols/index.ts | 3 ++- app/src/presentation/protocols/validation.ts | 5 ++++ app/src/validation/test/mock-validation.ts | 11 ++++++++ app/src/validation/validators/index.ts | 2 ++ .../validators/required-field-validator.ts | 12 +++++++++ .../requried-field-validator.test.ts | 27 +++++++++++++++++++ .../validators/validation-composite.ts | 14 ++++++++++ 10 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 app/src/presentation/protocols/validation.ts create mode 100644 app/src/validation/test/mock-validation.ts create mode 100644 app/src/validation/validators/index.ts create mode 100644 app/src/validation/validators/required-field-validator.ts create mode 100644 app/src/validation/validators/requried-field-validator.test.ts create mode 100644 app/src/validation/validators/validation-composite.ts diff --git a/app/src/presentation/errors/client-error.ts b/app/src/presentation/errors/client-error.ts index e1a60d66..d330c184 100644 --- a/app/src/presentation/errors/client-error.ts +++ b/app/src/presentation/errors/client-error.ts @@ -1,6 +1,6 @@ export class ClientError extends Error { - statusCode: number - constructor (message: string = '') { + statusCode?: number + constructor (message: string) { super(message) } } \ No newline at end of file diff --git a/app/src/presentation/errors/index.ts b/app/src/presentation/errors/index.ts index 984945c3..275531c6 100644 --- a/app/src/presentation/errors/index.ts +++ b/app/src/presentation/errors/index.ts @@ -1 +1,4 @@ export * from './email-already-in-use-error' +export * from './client-error' +export * from './missing-param-error' +export * from './not-found-error' \ No newline at end of file diff --git a/app/src/presentation/helpers/http-helper.ts b/app/src/presentation/helpers/http-helper.ts index 0a4bb56e..d5531437 100644 --- a/app/src/presentation/helpers/http-helper.ts +++ b/app/src/presentation/helpers/http-helper.ts @@ -2,7 +2,7 @@ import { HttpResponse } from '@/presentation/protocols/http' import { ClientError } from '../errors/client-error' import { NotFoundError } from '../errors/not-found-error' -export const badRequest = (error: ClientError): HttpResponse => ({ +export const badRequest = (error: ClientError | Error | any): HttpResponse => ({ statusCode: error.statusCode || 400, body: error, }) @@ -12,7 +12,7 @@ export const ok = (data: any): HttpResponse => ({ body: data, }) -export const forbidden = (error: ClientError): HttpResponse => ({ +export const forbidden = (error: ClientError | any | Error): HttpResponse => ({ statusCode: error.statusCode || 403, body: error, }) @@ -22,7 +22,9 @@ export const noContent = (): HttpResponse => ({ body: null, }) -export const serverError = (error: ClientError): HttpResponse => ({ +export const serverError = ( + error: ClientError | any | Error +): HttpResponse => ({ statusCode: error.statusCode || 500, body: error, }) diff --git a/app/src/presentation/protocols/index.ts b/app/src/presentation/protocols/index.ts index d7d26e21..767f2e37 100644 --- a/app/src/presentation/protocols/index.ts +++ b/app/src/presentation/protocols/index.ts @@ -1,2 +1,3 @@ export * from './controller' -export * from './http' \ No newline at end of file +export * from './http' +export * from './validation' \ No newline at end of file diff --git a/app/src/presentation/protocols/validation.ts b/app/src/presentation/protocols/validation.ts new file mode 100644 index 00000000..d1e1e52a --- /dev/null +++ b/app/src/presentation/protocols/validation.ts @@ -0,0 +1,5 @@ +import { ClientError } from "../errors"; + +export interface Validation { + validate: (input: any) => ClientError | undefined +} diff --git a/app/src/validation/test/mock-validation.ts b/app/src/validation/test/mock-validation.ts new file mode 100644 index 00000000..d7881de3 --- /dev/null +++ b/app/src/validation/test/mock-validation.ts @@ -0,0 +1,11 @@ +import { ClientError } from '@/presentation/errors' +import { Validation } from '@/presentation/protocols' + +export class ValidationSpy implements Validation { + input: any + error: ClientError = undefined + validate(input: any): ClientError { + this.input = input + return this.error + } +} diff --git a/app/src/validation/validators/index.ts b/app/src/validation/validators/index.ts new file mode 100644 index 00000000..dab059f3 --- /dev/null +++ b/app/src/validation/validators/index.ts @@ -0,0 +1,2 @@ +export * from './required-field-validator' +export * from './validation-composite' \ No newline at end of file diff --git a/app/src/validation/validators/required-field-validator.ts b/app/src/validation/validators/required-field-validator.ts new file mode 100644 index 00000000..ad2fd946 --- /dev/null +++ b/app/src/validation/validators/required-field-validator.ts @@ -0,0 +1,12 @@ +import { MissingParamError } from '@/presentation/errors' +import { Validation } from '@/presentation/protocols' + +export class RequiredFieldValidation implements Validation { + constructor (private readonly fieldName: string) {} + + validate (input: any): Error { + if (!input[this.fieldName]) { + return new MissingParamError(this.fieldName) + } + } +} diff --git a/app/src/validation/validators/requried-field-validator.test.ts b/app/src/validation/validators/requried-field-validator.test.ts new file mode 100644 index 00000000..f1042c7d --- /dev/null +++ b/app/src/validation/validators/requried-field-validator.test.ts @@ -0,0 +1,27 @@ +import { MissingParamError } from '@/presentation/errors' +import { describe, expect, test } from 'vitest' +import { RequiredFieldValidation } from './required-field-validator' + +function makeSut (): RequiredFieldValidation { + return new RequiredFieldValidation('any_field') +} + +describe('RequiredField Validation', () => { + test('Should return a MissingParamError if validation fails', () => { + const sut = makeSut() + const error = sut.validate({ + any_other_field: 'any_value' + }) + + expect(error).toEqual(new MissingParamError('any_field')) + }) + + test('Should not return if validation succeeds', () => { + const sut = makeSut() + const error = sut.validate({ + any_field: 'any_value' + }) + + expect(error).toBeFalsy() + }) +}) diff --git a/app/src/validation/validators/validation-composite.ts b/app/src/validation/validators/validation-composite.ts new file mode 100644 index 00000000..e3c21baa --- /dev/null +++ b/app/src/validation/validators/validation-composite.ts @@ -0,0 +1,14 @@ +import { Validation } from '@/presentation/protocols' + +export class ValidationComposite implements Validation { + constructor (private readonly validations: Validation[]) {} + + validate (input: any): Error { + for (const validation of this.validations) { + const error = validation.validate(input) + if (error) { + return error + } + } + } +} From b977515dff40f4a5cbf7f0c3bc38f9e4b0b35b78 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:14:35 -0300 Subject: [PATCH 062/105] =?UTF-8?q?feat:=20adiciona=20valida=C3=A7=C3=A3o?= =?UTF-8?q?=20na=20AddUserController?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/add-user-controller-factory.ts | 4 ++- .../add-user-controller-validator.test.ts | 21 ++++++++++++ .../add-user-controller-validator.ts | 15 +++++++++ .../add-user-controller.test.ts | 33 ++++++++++++++----- .../users-controller/add-user-controller.ts | 9 +++-- 5 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 app/src/main/factories/validators/add-user-controller-validator.test.ts create mode 100644 app/src/main/factories/validators/add-user-controller-validator.ts diff --git a/app/src/main/factories/controllers/user/add-user-controller-factory.ts b/app/src/main/factories/controllers/user/add-user-controller-factory.ts index d5c7ecbf..f08e5af3 100644 --- a/app/src/main/factories/controllers/user/add-user-controller-factory.ts +++ b/app/src/main/factories/controllers/user/add-user-controller-factory.ts @@ -1,7 +1,9 @@ import { AddUserController } from '@/presentation/controllers/users-controller'; import { Controller } from '@/presentation/protocols'; import { makeDbAddUser, makeDbLoadUsersByEmail } from '../../usecases/user'; +import { makeAddUserControllerValidator } from '../../validators/add-user-controller-validator'; + export function makeAddUserController(): Controller { - return new AddUserController(makeDbAddUser(), makeDbLoadUsersByEmail()); + return new AddUserController(makeDbAddUser(), makeDbLoadUsersByEmail(), makeAddUserControllerValidator()); } \ No newline at end of file diff --git a/app/src/main/factories/validators/add-user-controller-validator.test.ts b/app/src/main/factories/validators/add-user-controller-validator.test.ts new file mode 100644 index 00000000..fa49d448 --- /dev/null +++ b/app/src/main/factories/validators/add-user-controller-validator.test.ts @@ -0,0 +1,21 @@ +import { RequiredFieldValidation, ValidationComposite } from '@/validation/validators' +import { Validation } from '@/presentation/protocols/validation' +import { makeAddUserControllerValidator } from './add-user-controller-validator' +import { describe, expect, test, vitest } from 'vitest' + +vitest.mock('@/validation/validators/validation-composite') + +describe('AddUserControllerValidator Factory', () => { + test('Should call ValidationComposite with all validators', () => { + makeAddUserControllerValidator() + const validations: Validation [] = [] + for (const field of ['name', 'email', 'birthDay', 'password']) { + validations.push(new RequiredFieldValidation(field)) + } + + + expect(ValidationComposite).toHaveBeenCalledWith([ + ...validations + ]) + }) +}) diff --git a/app/src/main/factories/validators/add-user-controller-validator.ts b/app/src/main/factories/validators/add-user-controller-validator.ts new file mode 100644 index 00000000..6240b8be --- /dev/null +++ b/app/src/main/factories/validators/add-user-controller-validator.ts @@ -0,0 +1,15 @@ +import { Validation } from '@/presentation/protocols' +import { RequiredFieldValidation } from '@/validation/validators/required-field-validator' +import { ValidationComposite } from '@/validation/validators/validation-composite' + +export function makeAddUserControllerValidator(): ValidationComposite { + const validations: Validation[] = [] + const requiredFields = ['name', 'email', 'birthDay', 'password'] + for (const requiredField of requiredFields) { + validations.push(new RequiredFieldValidation(requiredField)) + } + + return new ValidationComposite( + validations + ) +} diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts index 71980a51..fd3c9ec3 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts @@ -6,27 +6,27 @@ import { mockUser, } from '@/domain/tests/users-mock' import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' -import { EmailAlreadyInUseError } from '@/presentation/errors' +import { EmailAlreadyInUseError, MissingParamError } from '@/presentation/errors' +import { ValidationSpy } from '@/validation/test/mock-validation' describe('AddUserController', () => { - type SutType = { - sut: AddUserController - addUserUseCaseSpy: AddUserSpy - loadUsersByEmailUseCaseSpy: LoadUsersByEmailSpy - } - function makeSut(): SutType { + + function makeSut() { const addUserUseCaseSpy = new AddUserSpy() const loadUsersByEmailUseCaseSpy = new LoadUsersByEmailSpy() + const validationSpy = new ValidationSpy() loadUsersByEmailUseCaseSpy.loadByEmailResult = null const sut = new AddUserController( addUserUseCaseSpy, - loadUsersByEmailUseCaseSpy + loadUsersByEmailUseCaseSpy, + validationSpy ) return { sut, addUserUseCaseSpy, loadUsersByEmailUseCaseSpy, + validationSpy } } describe('handle()', () => { @@ -88,5 +88,22 @@ describe('AddUserController', () => { serverError(mockedError) ) }); + + + test('Should call Validation with correct value', async () => { + const { sut, validationSpy } = makeSut() + const request = mockUser() + await sut.handle(request) + expect(validationSpy.input).toEqual(request) + }) + + test('Should return 400 if Validation returns an error', async () => { + const { sut, validationSpy } = makeSut() + const errorMock = new MissingParamError('any_field') + validationSpy.error = errorMock + const request = mockUser() + const httpResponse = await sut.handle(request) + expect(httpResponse).toEqual(badRequest(errorMock)) + }) }) }) diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.ts b/app/src/presentation/controllers/users-controller/add-user-controller.ts index 2d753a52..2d9ff871 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.ts @@ -2,18 +2,23 @@ import { User } from '@/domain/models' import { AddUser, LoadUsersByEmail } from '@/domain/usecases/users' import { EmailAlreadyInUseError } from '@/presentation/errors' import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' -import { Controller, HttpResponse } from '@/presentation/protocols' +import { Controller, HttpResponse, Validation } from '@/presentation/protocols' export class AddUserController implements Controller { constructor( private readonly addUserUseCase: AddUser, - private readonly loadUsersByEmailUseCase: LoadUsersByEmail + private readonly loadUsersByEmailUseCase: LoadUsersByEmail, + private readonly validation: Validation ) {} async handle( request: AddUserController.Request ): Promise { try { + const error = this.validation.validate(request) + if (error) { + return badRequest(error) + } const emaiInUse = await this.loadUsersByEmailUseCase.loadByEmail({ email: request.email, }) From d14c58510fd6e5ddb879c9e6dde2b2c68c328c09 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:15:45 -0300 Subject: [PATCH 063/105] refactor: arruma nome errado da model --- app/src/domain/models/user.ts | 2 +- app/src/domain/tests/users-mock.ts | 4 ++-- .../UsersMySQLRepository/users-mysql-repository.test.ts | 2 +- .../sequelize/migrations/20221015033744-create-table-users.js | 2 +- app/src/infra/database/sequelize/models/Users.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/domain/models/user.ts b/app/src/domain/models/user.ts index 18a27908..4340e691 100644 --- a/app/src/domain/models/user.ts +++ b/app/src/domain/models/user.ts @@ -2,7 +2,7 @@ export type User = { id?: number; name: string; email: string; - brithDay: Date; + birthDay: Date; role: string; password: string createdAt?: Date; diff --git a/app/src/domain/tests/users-mock.ts b/app/src/domain/tests/users-mock.ts index 181b7e71..882ca1cd 100644 --- a/app/src/domain/tests/users-mock.ts +++ b/app/src/domain/tests/users-mock.ts @@ -7,7 +7,7 @@ export function mockAddUser(): AddUser.Params { name: faker.name.fullName(), email: faker.internet.email(), password: faker.internet.password(), - brithDay: faker.date.past(), + birthDay: faker.date.past(), role: faker.helpers.arrayElement(['admin', 'user']), } } @@ -18,7 +18,7 @@ export function mockUser(): User { name: faker.name.fullName(), email: faker.internet.email(), password: faker.internet.password(), - brithDay: faker.date.past(), + birthDay: faker.date.past(), role: faker.helpers.arrayElement(['admin', 'user']), createdAt: new Date(), updatedAt: null, diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts index e4d36cce..c5bc8ff5 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts @@ -34,7 +34,7 @@ describe('UsersMySqlReposiory', () => { expect(user.name).toEqual(mockedUser.name) expect(user.email).toEqual(mockedUser.email) expect(user.password).toEqual(mockedUser.password) - expect(user.brithDay).toEqual(mockedUser.brithDay) + expect(user.birthDay).toEqual(mockedUser.birthDay) expect(user.role).toEqual(mockedUser.role) expect(user.createdAt).toEqual(new Date()) }) diff --git a/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js b/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js index 7a0d1775..e592532f 100644 --- a/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js +++ b/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js @@ -8,7 +8,7 @@ module.exports = { autoIncrement: true, primaryKey: true, }, - brithDay: { + birthDay: { type: Sequelize.DATE, allowNull: false, }, diff --git a/app/src/infra/database/sequelize/models/Users.ts b/app/src/infra/database/sequelize/models/Users.ts index 4e808cff..70fb186d 100644 --- a/app/src/infra/database/sequelize/models/Users.ts +++ b/app/src/infra/database/sequelize/models/Users.ts @@ -11,7 +11,7 @@ UsersSequelize.init( autoIncrement: true, primaryKey: true, }, - brithDay: { + birthDay: { type: Sequelize.DATE, allowNull: false, }, From 51b0b9fcbe015d4b7fe3925ad2bdad10570826de Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:15:54 -0300 Subject: [PATCH 064/105] refactor: arruma teste quebrado --- app/src/data/usecases/users/db-delete-user.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/data/usecases/users/db-delete-user.test.ts b/app/src/data/usecases/users/db-delete-user.test.ts index 2ac562b8..feb8c3af 100644 --- a/app/src/data/usecases/users/db-delete-user.test.ts +++ b/app/src/data/usecases/users/db-delete-user.test.ts @@ -1,4 +1,5 @@ import { DeleteUserRepositorySpy, LoadUsersByIdRepositorySpy } from '@/data/test/users-mock' +import { NotFoundError } from '@/presentation/errors' import { faker } from '@faker-js/faker' import { describe, expect, test, vitest } from 'vitest' import { DbDeleteUser } from './db-delete-user' @@ -48,7 +49,7 @@ describe('DbDeleteUser', () => { loadUsersByIdRepositorySpy.loadByIdResult = null const userId = faker.datatype.number() const promise = sut.delete({ userId }) - await expect(promise).rejects.toThrow('User') + await expect(promise).rejects.toThrow(new NotFoundError('user')) }); From f300d2ef0a087e4db0c5f7340f1e7049941bed0b Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:18:48 -0300 Subject: [PATCH 065/105] fix: arruma tipagem do ClientError --- app/src/presentation/errors/client-error.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/presentation/errors/client-error.ts b/app/src/presentation/errors/client-error.ts index d330c184..09e6e4a5 100644 --- a/app/src/presentation/errors/client-error.ts +++ b/app/src/presentation/errors/client-error.ts @@ -1,6 +1,6 @@ export class ClientError extends Error { statusCode?: number - constructor (message: string) { + constructor (message?: string) { super(message) } } \ No newline at end of file From e2536e95fa1a1b6c7b530e1479c790f4c29c04b0 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:28:41 -0300 Subject: [PATCH 066/105] =?UTF-8?q?refactor:=20garante=20que=20role=20ser?= =?UTF-8?q?=C3=A1=20opcional?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/data/usecases/users/db-add-user.ts | 6 +++++- app/src/domain/models/user.ts | 2 +- app/src/domain/tests/users-mock.ts | 2 +- .../migrations/20221015033744-create-table-users.js | 2 +- app/src/infra/database/sequelize/models/Users.ts | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/src/data/usecases/users/db-add-user.ts b/app/src/data/usecases/users/db-add-user.ts index ff34f47b..119042e2 100644 --- a/app/src/data/usecases/users/db-add-user.ts +++ b/app/src/data/usecases/users/db-add-user.ts @@ -6,7 +6,11 @@ export class DbAddUser implements AddUser { private readonly addUserRepository: AddUserRepository, ) {} - async add(user: AddUser.Params): Promise { + async add(params: AddUser.Params): Promise { + const user: AddUser.Params = { + ...params, + birthDay: new Date(params.birthDay) + } const newUser = await this.addUserRepository.add(user); return newUser } diff --git a/app/src/domain/models/user.ts b/app/src/domain/models/user.ts index 4340e691..8212cc7d 100644 --- a/app/src/domain/models/user.ts +++ b/app/src/domain/models/user.ts @@ -3,7 +3,7 @@ export type User = { name: string; email: string; birthDay: Date; - role: string; + role?: string; password: string createdAt?: Date; updatedAt?: Date; diff --git a/app/src/domain/tests/users-mock.ts b/app/src/domain/tests/users-mock.ts index 882ca1cd..d5be5db7 100644 --- a/app/src/domain/tests/users-mock.ts +++ b/app/src/domain/tests/users-mock.ts @@ -19,7 +19,7 @@ export function mockUser(): User { email: faker.internet.email(), password: faker.internet.password(), birthDay: faker.date.past(), - role: faker.helpers.arrayElement(['admin', 'user']), + role: faker.helpers.arrayElement(['admin', 'user', null]), createdAt: new Date(), updatedAt: null, } diff --git a/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js b/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js index e592532f..75de70de 100644 --- a/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js +++ b/app/src/infra/database/sequelize/migrations/20221015033744-create-table-users.js @@ -35,7 +35,7 @@ module.exports = { }, role: { type: Sequelize.STRING, - allowNull: false, + allowNull: true, }, }) }, diff --git a/app/src/infra/database/sequelize/models/Users.ts b/app/src/infra/database/sequelize/models/Users.ts index 70fb186d..069fabe8 100644 --- a/app/src/infra/database/sequelize/models/Users.ts +++ b/app/src/infra/database/sequelize/models/Users.ts @@ -38,7 +38,7 @@ UsersSequelize.init( }, role: { type: Sequelize.STRING, - allowNull: false, + allowNull: true, } }, { From 023430285d7fc850881f2d75eaff519c48f1f5bf Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:28:44 -0300 Subject: [PATCH 067/105] =?UTF-8?q?test:=20garante=20que=20role=20ser?= =?UTF-8?q?=C3=A1=20opcional?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../users-mysql-repository.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts index c5bc8ff5..365174b0 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts +++ b/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts @@ -38,6 +38,19 @@ describe('UsersMySqlReposiory', () => { expect(user.role).toEqual(mockedUser.role) expect(user.createdAt).toEqual(new Date()) }) + + test('should return an user without role on success', async () => { + const { sut } = makeSut() + const mockedUser = mockAddUser() + delete mockedUser.role + const user = await sut.add(mockedUser) + expect(user.name).toEqual(mockedUser.name) + expect(user.email).toEqual(mockedUser.email) + expect(user.password).toEqual(mockedUser.password) + expect(user.birthDay).toEqual(mockedUser.birthDay) + expect(user.createdAt).toEqual(new Date()) + }) + }) describe('load()', () => { From e34957c637275b317c50bc1838c8267ac7d60850 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:44:49 -0300 Subject: [PATCH 068/105] feat: cria dateFormatter --- app/src/data/protocols/utils/date-formatter.ts | 3 +++ app/src/data/protocols/utils/index.ts | 1 + 2 files changed, 4 insertions(+) create mode 100644 app/src/data/protocols/utils/date-formatter.ts create mode 100644 app/src/data/protocols/utils/index.ts diff --git a/app/src/data/protocols/utils/date-formatter.ts b/app/src/data/protocols/utils/date-formatter.ts new file mode 100644 index 00000000..cca359c5 --- /dev/null +++ b/app/src/data/protocols/utils/date-formatter.ts @@ -0,0 +1,3 @@ +export interface DateFormatter { + format: (date: string|Date) => Date +} \ No newline at end of file diff --git a/app/src/data/protocols/utils/index.ts b/app/src/data/protocols/utils/index.ts new file mode 100644 index 00000000..d5a7902f --- /dev/null +++ b/app/src/data/protocols/utils/index.ts @@ -0,0 +1 @@ +export * from './date-formatter' \ No newline at end of file From ecd781886a97876ff646caaf2f01d376ac0f76f4 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:45:05 -0300 Subject: [PATCH 069/105] refactor: padroniza nome do mock --- app/src/data/test/{users-mock.ts => mock-users.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/src/data/test/{users-mock.ts => mock-users.ts} (100%) diff --git a/app/src/data/test/users-mock.ts b/app/src/data/test/mock-users.ts similarity index 100% rename from app/src/data/test/users-mock.ts rename to app/src/data/test/mock-users.ts From cb5abab19eb2ebd7ef4fcac94ac8bec3b75e10a3 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:45:33 -0300 Subject: [PATCH 070/105] =?UTF-8?q?feat:=20garante=20que=20DbAddUser=20ir?= =?UTF-8?q?=C3=A1=20chamar=20dateFormatter=20com=20os=20parametros=20corre?= =?UTF-8?q?tos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/data/usecases/users/db-add-user.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/data/usecases/users/db-add-user.ts b/app/src/data/usecases/users/db-add-user.ts index 119042e2..d5435e56 100644 --- a/app/src/data/usecases/users/db-add-user.ts +++ b/app/src/data/usecases/users/db-add-user.ts @@ -1,16 +1,15 @@ import { AddUserRepository } from '@/data/protocols/database/users/add-user-repository'; +import { DateFormatter } from '@/data/protocols/utils'; import { AddUser } from '@/domain/usecases/users'; export class DbAddUser implements AddUser { constructor( private readonly addUserRepository: AddUserRepository, + private readonly dateFormatter: DateFormatter ) {} - async add(params: AddUser.Params): Promise { - const user: AddUser.Params = { - ...params, - birthDay: new Date(params.birthDay) - } + async add(user: AddUser.Params): Promise { + user.birthDay = this.dateFormatter.format(user.birthDay) const newUser = await this.addUserRepository.add(user); return newUser } From 7f1898e1292886127254fc4e407f3212aa26800c Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 15:45:50 -0300 Subject: [PATCH 071/105] =?UTF-8?q?test:=20garante=20que=20DbAddUser=20ir?= =?UTF-8?q?=C3=A1=20chamar=20dateFormatter=20com=20os=20parametros=20corre?= =?UTF-8?q?tos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/data/test/mock-date-formatter.ts | 12 +++++++ .../data/usecases/users/db-add-user.test.ts | 33 ++++++++++++++++--- .../usecases/users/db-delete-user.test.ts | 2 +- .../users/db-load-users-by-email.test.ts | 2 +- .../users/db-load-users-by-id.test.ts | 2 +- .../data/usecases/users/db-load-users.test.ts | 2 +- 6 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 app/src/data/test/mock-date-formatter.ts diff --git a/app/src/data/test/mock-date-formatter.ts b/app/src/data/test/mock-date-formatter.ts new file mode 100644 index 00000000..5cdde30a --- /dev/null +++ b/app/src/data/test/mock-date-formatter.ts @@ -0,0 +1,12 @@ +import { faker } from "@faker-js/faker"; +import { DateFormatter } from "../protocols/utils"; + +export class DateFormatterSpy implements DateFormatter { + dateFormat: string = 'YYYY-MM-DD HH:mm:ss' + inputDate: string | Date + finalDate: Date = faker.date.past() + format(inputDate: string|Date): Date { + this.inputDate = inputDate + return this.finalDate + } +} \ No newline at end of file diff --git a/app/src/data/usecases/users/db-add-user.test.ts b/app/src/data/usecases/users/db-add-user.test.ts index 8b671359..fc224b7a 100644 --- a/app/src/data/usecases/users/db-add-user.test.ts +++ b/app/src/data/usecases/users/db-add-user.test.ts @@ -1,13 +1,23 @@ -import { AddUserRepositorySpy } from '@/data/test/users-mock'; +import { DateFormatterSpy } from '@/data/test/mock-date-formatter'; +import { AddUserRepositorySpy } from '@/data/test/mock-users'; import { mockAddUser } from '@/domain/tests/users-mock'; -import { describe, expect, test } from 'vitest'; +import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest'; import { DbAddUser } from './db-add-user'; +import MockDate from 'mockdate' describe('DbAddUser', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) function makeSut() { const addUserRepositorySpy = new AddUserRepositorySpy() - const sut = new DbAddUser(addUserRepositorySpy); - return { sut, addUserRepositorySpy }; + const dateFormatterSpy = new DateFormatterSpy() + const sut = new DbAddUser(addUserRepositorySpy, dateFormatterSpy); + return { sut, addUserRepositorySpy, dateFormatterSpy }; } test('should call AddUserRepository with correct params', async () => { const { sut, addUserRepositorySpy } = makeSut() @@ -15,6 +25,21 @@ describe('DbAddUser', () => { await sut.add(addUser) expect(addUserRepositorySpy.addParams).toEqual(addUser) }); + + test('should call dateFormatter with correct user birthDay', async () => { + const { sut, dateFormatterSpy} = makeSut() + const addUser = mockAddUser() + await sut.add({...addUser}) + expect(dateFormatterSpy.inputDate).toBe(addUser.birthDay) + }); + + test('should format the user birthDay using dateFormatter', async () => { + const { sut, dateFormatterSpy, addUserRepositorySpy} = makeSut() + const addUser = mockAddUser() + const user = await sut.add({...addUser}) + expect(addUserRepositorySpy.addParams.birthDay).toBe(dateFormatterSpy.finalDate) + }); + test('should return a valid User on success', async () => { const { sut, addUserRepositorySpy } = makeSut() const user = await sut.add(mockAddUser()) diff --git a/app/src/data/usecases/users/db-delete-user.test.ts b/app/src/data/usecases/users/db-delete-user.test.ts index feb8c3af..3de01bf4 100644 --- a/app/src/data/usecases/users/db-delete-user.test.ts +++ b/app/src/data/usecases/users/db-delete-user.test.ts @@ -1,4 +1,4 @@ -import { DeleteUserRepositorySpy, LoadUsersByIdRepositorySpy } from '@/data/test/users-mock' +import { DeleteUserRepositorySpy, LoadUsersByIdRepositorySpy } from '@/data/test/mock-users' import { NotFoundError } from '@/presentation/errors' import { faker } from '@faker-js/faker' import { describe, expect, test, vitest } from 'vitest' diff --git a/app/src/data/usecases/users/db-load-users-by-email.test.ts b/app/src/data/usecases/users/db-load-users-by-email.test.ts index 3e6ed65a..4aa752d1 100644 --- a/app/src/data/usecases/users/db-load-users-by-email.test.ts +++ b/app/src/data/usecases/users/db-load-users-by-email.test.ts @@ -1,4 +1,4 @@ -import { LoadUsersByEmailRepositorySpy } from '@/data/test/users-mock'; +import { LoadUsersByEmailRepositorySpy } from '@/data/test/mock-users'; import { faker } from '@faker-js/faker'; import { describe, expect, test, vitest } from 'vitest'; import { DbLoadUsersByEmail } from './db-load-users-by-email'; diff --git a/app/src/data/usecases/users/db-load-users-by-id.test.ts b/app/src/data/usecases/users/db-load-users-by-id.test.ts index d2cf9e8e..fc856c93 100644 --- a/app/src/data/usecases/users/db-load-users-by-id.test.ts +++ b/app/src/data/usecases/users/db-load-users-by-id.test.ts @@ -1,4 +1,4 @@ -import { LoadUsersByIdRepositorySpy } from '@/data/test/users-mock' +import { LoadUsersByIdRepositorySpy } from '@/data/test/mock-users' import { faker } from '@faker-js/faker' import { describe, expect, test, vitest } from 'vitest' import { DbLoadUsersById } from './db-load-users-by-id' diff --git a/app/src/data/usecases/users/db-load-users.test.ts b/app/src/data/usecases/users/db-load-users.test.ts index a711f0fd..8a5b1632 100644 --- a/app/src/data/usecases/users/db-load-users.test.ts +++ b/app/src/data/usecases/users/db-load-users.test.ts @@ -1,4 +1,4 @@ -import { LoadUsersRepositorySpy } from '@/data/test/users-mock'; +import { LoadUsersRepositorySpy } from '@/data/test/mock-users'; import { describe, expect, test, vitest } from 'vitest'; import { DbLoadUsers } from './db-load-users'; From 9af9b4df34242424685064da0a7b899525c02dad Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 16:56:59 -0300 Subject: [PATCH 072/105] feat: cria tratamentos para a tratar a data --- app/package-lock.json | 1 + app/package.json | 1 + .../data/protocols/utils/date-formatter.ts | 2 +- app/src/data/test/mock-date-formatter.ts | 4 +- app/src/domain/models/user.ts | 2 +- .../moment-date-formatter-adapter.test.ts | 38 +++++++++++++++ .../moment-date-formatter-adapter.ts | 9 ++++ app/src/infra/utils/index.ts | 1 + .../moment-date-validator-adapter.test.ts | 33 +++++++++++++ .../moment-date-validator-adapter.ts | 8 ++++ .../usecases/user/add-user-usecase-factory.ts | 5 +- .../add-user-controller-validator.test.ts | 7 +++ .../add-user-controller-validator.ts | 11 +++-- app/src/main/routes/users-routes.spec.ts | 1 + app/src/presentation/errors/index.ts | 3 +- .../errors/invalid-param-error.ts | 9 ++++ .../validation/protocols/date-validator.ts | 3 ++ .../validation/test/mock-date-validator.ts | 11 +++++ app/src/validation/test/mock-validation.ts | 2 +- .../validators/date-validator.test.ts | 48 +++++++++++++++++++ .../validation/validators/date-validator.ts | 18 +++++++ 21 files changed, 207 insertions(+), 10 deletions(-) create mode 100644 app/src/infra/utils/date-formatter/moment-date-formatter-adapter.test.ts create mode 100644 app/src/infra/utils/date-formatter/moment-date-formatter-adapter.ts create mode 100644 app/src/infra/utils/index.ts create mode 100644 app/src/infra/validators/moment-date-validator-adapter.test.ts create mode 100644 app/src/infra/validators/moment-date-validator-adapter.ts create mode 100644 app/src/presentation/errors/invalid-param-error.ts create mode 100644 app/src/validation/protocols/date-validator.ts create mode 100644 app/src/validation/test/mock-date-validator.ts create mode 100644 app/src/validation/validators/date-validator.test.ts create mode 100644 app/src/validation/validators/date-validator.ts diff --git a/app/package-lock.json b/app/package-lock.json index 1000caa9..9148085c 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -12,6 +12,7 @@ "cross-env": "^7.0.3", "dotenv": "^16.0.3", "express": "^4.18.2", + "moment": "^2.29.4", "mysql2": "^2.3.3", "sequelize": "^6.25.1", "sequelize-cli": "^6.5.1", diff --git a/app/package.json b/app/package.json index 9af61554..d79bb92e 100644 --- a/app/package.json +++ b/app/package.json @@ -37,6 +37,7 @@ "cross-env": "^7.0.3", "dotenv": "^16.0.3", "express": "^4.18.2", + "moment": "^2.29.4", "mysql2": "^2.3.3", "sequelize": "^6.25.1", "sequelize-cli": "^6.5.1", diff --git a/app/src/data/protocols/utils/date-formatter.ts b/app/src/data/protocols/utils/date-formatter.ts index cca359c5..c440e0e9 100644 --- a/app/src/data/protocols/utils/date-formatter.ts +++ b/app/src/data/protocols/utils/date-formatter.ts @@ -1,3 +1,3 @@ export interface DateFormatter { - format: (date: string|Date) => Date + format: (date: string|Date) => string } \ No newline at end of file diff --git a/app/src/data/test/mock-date-formatter.ts b/app/src/data/test/mock-date-formatter.ts index 5cdde30a..f0ee14af 100644 --- a/app/src/data/test/mock-date-formatter.ts +++ b/app/src/data/test/mock-date-formatter.ts @@ -4,8 +4,8 @@ import { DateFormatter } from "../protocols/utils"; export class DateFormatterSpy implements DateFormatter { dateFormat: string = 'YYYY-MM-DD HH:mm:ss' inputDate: string | Date - finalDate: Date = faker.date.past() - format(inputDate: string|Date): Date { + finalDate: string = faker.date.past().toDateString() + format(inputDate: string|Date): string { this.inputDate = inputDate return this.finalDate } diff --git a/app/src/domain/models/user.ts b/app/src/domain/models/user.ts index 8212cc7d..a4b0834a 100644 --- a/app/src/domain/models/user.ts +++ b/app/src/domain/models/user.ts @@ -2,7 +2,7 @@ export type User = { id?: number; name: string; email: string; - birthDay: Date; + birthDay: Date | string; role?: string; password: string createdAt?: Date; diff --git a/app/src/infra/utils/date-formatter/moment-date-formatter-adapter.test.ts b/app/src/infra/utils/date-formatter/moment-date-formatter-adapter.test.ts new file mode 100644 index 00000000..da146f3a --- /dev/null +++ b/app/src/infra/utils/date-formatter/moment-date-formatter-adapter.test.ts @@ -0,0 +1,38 @@ +import { faker } from '@faker-js/faker' +import moment from 'moment' +import { describe, expect, test, vitest } from 'vitest' +import { MomentDateFormatter } from './moment-date-formatter-adapter' + +const MOCKED_DATE = faker.date.past().toDateString() +vitest.mock('moment', () => { + const self = { + default: vitest.fn().mockReturnThis(), + format() { + return MOCKED_DATE + }, + } + return self +}) + +describe('MomentDateFormatter', () => { + function makeSut(dateFormat: string = 'YYYY-MM-DD') { + return new MomentDateFormatter(dateFormat) + } + + describe('format()', () => { + test('should call moment with correct params', () => { + const sut = makeSut() + const mockedDate = faker.date.past() + sut.format(mockedDate) + expect(moment).toHaveBeenCalledWith(mockedDate) + }) + + test('should return format result', () => { + const dateFormat = 'YYYY-MM-DD HH:mm:ss' + const sut = makeSut(dateFormat) + const mockedDate = faker.date.past() + const result = sut.format(mockedDate) + expect(result).toBe(MOCKED_DATE) + }) + }) +}) diff --git a/app/src/infra/utils/date-formatter/moment-date-formatter-adapter.ts b/app/src/infra/utils/date-formatter/moment-date-formatter-adapter.ts new file mode 100644 index 00000000..030405a0 --- /dev/null +++ b/app/src/infra/utils/date-formatter/moment-date-formatter-adapter.ts @@ -0,0 +1,9 @@ +import { DateFormatter } from "@/data/protocols/utils"; +import moment from 'moment' +export class MomentDateFormatter implements DateFormatter { + constructor(private readonly dateFormat: string) {} + + format(inputDate: string | Date): string { + return moment(inputDate).format(this.dateFormat) + } +} \ No newline at end of file diff --git a/app/src/infra/utils/index.ts b/app/src/infra/utils/index.ts new file mode 100644 index 00000000..4ffa9180 --- /dev/null +++ b/app/src/infra/utils/index.ts @@ -0,0 +1 @@ +export * from './date-formatter/moment-date-formatter-adapter' \ No newline at end of file diff --git a/app/src/infra/validators/moment-date-validator-adapter.test.ts b/app/src/infra/validators/moment-date-validator-adapter.test.ts new file mode 100644 index 00000000..e8004198 --- /dev/null +++ b/app/src/infra/validators/moment-date-validator-adapter.test.ts @@ -0,0 +1,33 @@ +import { describe, expect, test, vitest } from "vitest"; +import moment from 'moment' +import { faker } from "@faker-js/faker"; +import { MomentDateValidatorAdapter } from "./moment-date-validator-adapter"; + +const MOCKED_IS_VALID = faker.datatype.boolean() +vitest.mock('moment', () => { + const self = { + default: vitest.fn().mockReturnThis(), + isValid() { + return MOCKED_IS_VALID + }, + } + return self +}) +describe('MomentDateValidatorAdapter', () => { + function makeSut() { + return new MomentDateValidatorAdapter() + } + test('should call moment with correct date', () => { + const sut = makeSut() + const mockedDate = faker.date.future() + sut.isValidDate(mockedDate) + expect(moment).toHaveBeenCalledWith(mockedDate) + }); + + test('should return the isValid result', () => { + const sut = makeSut() + const mockedDate = faker.date.future() + const result = sut.isValidDate(mockedDate) + expect(result).toBe(MOCKED_IS_VALID) + }); +}); \ No newline at end of file diff --git a/app/src/infra/validators/moment-date-validator-adapter.ts b/app/src/infra/validators/moment-date-validator-adapter.ts new file mode 100644 index 00000000..59ac1bbf --- /dev/null +++ b/app/src/infra/validators/moment-date-validator-adapter.ts @@ -0,0 +1,8 @@ +import { DateValidator } from "@/validation/protocols/date-validator"; +import moment from 'moment' + +export class MomentDateValidatorAdapter implements DateValidator { + isValidDate(inputDate: Date | string): boolean { + return moment(inputDate).isValid() + } +} \ No newline at end of file diff --git a/app/src/main/factories/usecases/user/add-user-usecase-factory.ts b/app/src/main/factories/usecases/user/add-user-usecase-factory.ts index b723c081..2c66fb13 100644 --- a/app/src/main/factories/usecases/user/add-user-usecase-factory.ts +++ b/app/src/main/factories/usecases/user/add-user-usecase-factory.ts @@ -1,8 +1,11 @@ import { DbAddUser } from '@/data/usecases/users/db-add-user'; import { AddUser } from '@/domain/usecases/users'; import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository'; +import { MomentDateFormatter } from '@/infra/utils'; export function makeDbAddUser(): AddUser { const addUserRepository = new UsersMySqlReposiory(); - return new DbAddUser(addUserRepository); + const dateFormat = 'YYYY-MM-DD' + const momentDateFormatter = new MomentDateFormatter(dateFormat) + return new DbAddUser(addUserRepository, momentDateFormatter); } \ No newline at end of file diff --git a/app/src/main/factories/validators/add-user-controller-validator.test.ts b/app/src/main/factories/validators/add-user-controller-validator.test.ts index fa49d448..ca2134eb 100644 --- a/app/src/main/factories/validators/add-user-controller-validator.test.ts +++ b/app/src/main/factories/validators/add-user-controller-validator.test.ts @@ -2,6 +2,8 @@ import { RequiredFieldValidation, ValidationComposite } from '@/validation/vali import { Validation } from '@/presentation/protocols/validation' import { makeAddUserControllerValidator } from './add-user-controller-validator' import { describe, expect, test, vitest } from 'vitest' +import { DateValidation } from '@/validation/validators/date-validator' +import { MomentDateValidatorAdapter } from '@/infra/validators/moment-date-validator-adapter' vitest.mock('@/validation/validators/validation-composite') @@ -13,6 +15,11 @@ describe('AddUserControllerValidator Factory', () => { validations.push(new RequiredFieldValidation(field)) } + validations.push(new DateValidation( + 'birthDay', + new MomentDateValidatorAdapter() + )) + expect(ValidationComposite).toHaveBeenCalledWith([ ...validations diff --git a/app/src/main/factories/validators/add-user-controller-validator.ts b/app/src/main/factories/validators/add-user-controller-validator.ts index 6240b8be..9732498c 100644 --- a/app/src/main/factories/validators/add-user-controller-validator.ts +++ b/app/src/main/factories/validators/add-user-controller-validator.ts @@ -1,4 +1,6 @@ +import { MomentDateValidatorAdapter } from '@/infra/validators/moment-date-validator-adapter' import { Validation } from '@/presentation/protocols' +import { DateValidation } from '@/validation/validators/date-validator' import { RequiredFieldValidation } from '@/validation/validators/required-field-validator' import { ValidationComposite } from '@/validation/validators/validation-composite' @@ -9,7 +11,10 @@ export function makeAddUserControllerValidator(): ValidationComposite { validations.push(new RequiredFieldValidation(requiredField)) } - return new ValidationComposite( - validations - ) + validations.push(new DateValidation( + 'birthDay', + new MomentDateValidatorAdapter() + )) + + return new ValidationComposite(validations) } diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index a34ad322..986203e2 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -4,6 +4,7 @@ import { migrate, truncate } from '@/infra/database/sequelize/__tests__/utils' import request from 'supertest' import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' import app from '../config/app' +import MockDate from 'mockdate' describe('Users Routes', () => { beforeAll(async () => { diff --git a/app/src/presentation/errors/index.ts b/app/src/presentation/errors/index.ts index 275531c6..f3e1c00e 100644 --- a/app/src/presentation/errors/index.ts +++ b/app/src/presentation/errors/index.ts @@ -1,4 +1,5 @@ export * from './email-already-in-use-error' export * from './client-error' export * from './missing-param-error' -export * from './not-found-error' \ No newline at end of file +export * from './not-found-error' +export * from './invalid-param-error' \ No newline at end of file diff --git a/app/src/presentation/errors/invalid-param-error.ts b/app/src/presentation/errors/invalid-param-error.ts new file mode 100644 index 00000000..83b276d7 --- /dev/null +++ b/app/src/presentation/errors/invalid-param-error.ts @@ -0,0 +1,9 @@ +import { ClientError } from "./client-error" + +export class InvalidParamError extends ClientError { + constructor (paramName: string) { + super(`Invalid param: ${paramName}`) + this.statusCode = 404 + this.name = 'InvalidParamError' + } +} \ No newline at end of file diff --git a/app/src/validation/protocols/date-validator.ts b/app/src/validation/protocols/date-validator.ts new file mode 100644 index 00000000..7cd686fe --- /dev/null +++ b/app/src/validation/protocols/date-validator.ts @@ -0,0 +1,3 @@ +export interface DateValidator { + isValidDate: (date: string | Date ) => boolean +} \ No newline at end of file diff --git a/app/src/validation/test/mock-date-validator.ts b/app/src/validation/test/mock-date-validator.ts new file mode 100644 index 00000000..8065f0da --- /dev/null +++ b/app/src/validation/test/mock-date-validator.ts @@ -0,0 +1,11 @@ +import { DateValidator } from "../protocols/date-validator" + +export class DateValidatorSpy implements DateValidator{ + input: string | Date + isValid: boolean = true + + isValidDate(input: any) { + this.input = input + return this.isValid + } +} \ No newline at end of file diff --git a/app/src/validation/test/mock-validation.ts b/app/src/validation/test/mock-validation.ts index d7881de3..0de3433e 100644 --- a/app/src/validation/test/mock-validation.ts +++ b/app/src/validation/test/mock-validation.ts @@ -8,4 +8,4 @@ export class ValidationSpy implements Validation { this.input = input return this.error } -} +} \ No newline at end of file diff --git a/app/src/validation/validators/date-validator.test.ts b/app/src/validation/validators/date-validator.test.ts new file mode 100644 index 00000000..1f3d4ad6 --- /dev/null +++ b/app/src/validation/validators/date-validator.test.ts @@ -0,0 +1,48 @@ +import { InvalidParamError } from '@/presentation/errors' +import { faker } from '@faker-js/faker' +import { describe, expect, test } from 'vitest' +import { DateValidatorSpy } from '../test/mock-date-validator' +import { DateValidation } from './date-validator' + +function makeSut(fieldDate: string= 'any_field') { + const dateValidatorSpy = new DateValidatorSpy() + const sut = new DateValidation(fieldDate, dateValidatorSpy) + + return { + sut, + dateValidatorSpy, + } +} + +describe('Date Validation', () => { + test('should call dateValidator with correct params', () => { + const { sut, dateValidatorSpy } = makeSut('someDate') + const mockedObject = { + someDate: 'invalid date' + } + + sut.validate(mockedObject) + expect(dateValidatorSpy.input).toEqual(mockedObject.someDate) + }) + + test('should return invalidParamError if dateValidator returns false', () => { + const { sut, dateValidatorSpy } = makeSut('someDate') + dateValidatorSpy.isValid = false + const mockedObject = { + someDate: 'invalid date' + } + + const result = sut.validate(mockedObject) + expect(result).toEqual(new InvalidParamError('someDate')) + }); + + test('should not return if dateValidator returns true', () => { + const { sut, dateValidatorSpy } = makeSut('someDate') + const mockedObject = { + someDate: 'invalid date' + } + + const result = sut.validate(mockedObject) + expect(result).toBe(undefined) + }); +}) diff --git a/app/src/validation/validators/date-validator.ts b/app/src/validation/validators/date-validator.ts new file mode 100644 index 00000000..4b3b96ba --- /dev/null +++ b/app/src/validation/validators/date-validator.ts @@ -0,0 +1,18 @@ +import { InvalidParamError } from '@/presentation/errors' +import { Validation } from '@/presentation/protocols' +import { DateValidator } from '../protocols/date-validator' + +export class DateValidation implements Validation { + constructor( + private readonly fieldName: string, + private readonly dateValidator: DateValidator + ) {} + + validate(input: any ): Error { + const isValidDate = this.dateValidator.isValidDate(input[this.fieldName]) + + if(!isValidDate) { + return new InvalidParamError(this.fieldName) + } + } +} From 7d768f833b63abd714146ee670dcb97c463d13e2 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 17:01:19 -0300 Subject: [PATCH 073/105] feat: adiciona detalhes no InvalidParamError --- app/src/presentation/errors/invalid-param-error.ts | 4 ++-- app/src/validation/validators/date-validator.test.ts | 2 +- app/src/validation/validators/date-validator.ts | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/presentation/errors/invalid-param-error.ts b/app/src/presentation/errors/invalid-param-error.ts index 83b276d7..2c25a991 100644 --- a/app/src/presentation/errors/invalid-param-error.ts +++ b/app/src/presentation/errors/invalid-param-error.ts @@ -1,8 +1,8 @@ import { ClientError } from "./client-error" export class InvalidParamError extends ClientError { - constructor (paramName: string) { - super(`Invalid param: ${paramName}`) + constructor (paramName: string, details?: string) { + super(`Invalid param: ${paramName}`+details?` ${details}`:'') this.statusCode = 404 this.name = 'InvalidParamError' } diff --git a/app/src/validation/validators/date-validator.test.ts b/app/src/validation/validators/date-validator.test.ts index 1f3d4ad6..bc334093 100644 --- a/app/src/validation/validators/date-validator.test.ts +++ b/app/src/validation/validators/date-validator.test.ts @@ -33,7 +33,7 @@ describe('Date Validation', () => { } const result = sut.validate(mockedObject) - expect(result).toEqual(new InvalidParamError('someDate')) + expect(result).toEqual(new InvalidParamError('someDate', `the date invalid date is not valid`)) }); test('should not return if dateValidator returns true', () => { diff --git a/app/src/validation/validators/date-validator.ts b/app/src/validation/validators/date-validator.ts index 4b3b96ba..715e4eca 100644 --- a/app/src/validation/validators/date-validator.ts +++ b/app/src/validation/validators/date-validator.ts @@ -9,10 +9,11 @@ export class DateValidation implements Validation { ) {} validate(input: any ): Error { - const isValidDate = this.dateValidator.isValidDate(input[this.fieldName]) + const dateField = input[this.fieldName] + const isValidDate = this.dateValidator.isValidDate(dateField) if(!isValidDate) { - return new InvalidParamError(this.fieldName) + return new InvalidParamError(this.fieldName, `the date ${dateField} is not valid`) } } } From f371736543eaa8282b81a5963ca5347fde6d6805 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 18:57:16 -0300 Subject: [PATCH 074/105] feat: cria model Transaction --- app/src/domain/models/transactions.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 app/src/domain/models/transactions.ts diff --git a/app/src/domain/models/transactions.ts b/app/src/domain/models/transactions.ts new file mode 100644 index 00000000..94bed886 --- /dev/null +++ b/app/src/domain/models/transactions.ts @@ -0,0 +1,16 @@ +import { User } from "./user"; + +export type Transaction = { + id?: number | string; + description?: string; + amount: number; + type: "debt" | "credit" | "chargeback"; + /** + * The transaction that was charged back. + * This field is only present when the transaction is a chargeback. + */ + chargebackFrom?: Transaction; + from: User; + to: User; + createdAt?: Date; +} \ No newline at end of file From 892e3472235a1198ac24a1271ed216fd1901b7bb Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 18:57:32 -0300 Subject: [PATCH 075/105] =?UTF-8?q?feat:=20adiciona=20campo=20para=20trans?= =?UTF-8?q?a=C3=A7=C3=B5es=20do=20usu=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/domain/models/user.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/domain/models/user.ts b/app/src/domain/models/user.ts index a4b0834a..5a84f6af 100644 --- a/app/src/domain/models/user.ts +++ b/app/src/domain/models/user.ts @@ -1,10 +1,13 @@ +import { Transaction } from "./transactions"; + export type User = { id?: number; name: string; email: string; birthDay: Date | string; - role?: string; + role?: string password: string + transactions?: Transaction[] createdAt?: Date; updatedAt?: Date; } \ No newline at end of file From 644eb35ed73adadbdde4ca594c46958883b7c307 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 22:04:55 -0300 Subject: [PATCH 076/105] feat: implementa db-add-transaction --- .../add-transaction-repository.ts | 12 +++ .../transactions/db-add-transaction.ts | 12 +++ app/src/domain/models/index.ts | 3 +- app/src/domain/models/transaction.ts | 26 ++++++ app/src/domain/models/transactions.ts | 16 ---- app/src/domain/models/user.ts | 32 +++++--- .../tests/{users-mock.ts => mock-users.ts} | 0 .../usecases/transactions/add-transaction.ts | 10 +++ app/src/domain/usecases/transactions/index.ts | 1 + app/src/domain/usecases/users/add-user.ts | 4 +- .../transactions-mysql.repository.ts | 17 ++++ .../users-mysql-repository.ts | 2 +- .../database/sequelize/models/Transaction.ts | 80 +++++++++++++++++++ .../sequelize/models/{Users.ts => User.ts} | 1 + .../usecases/user/add-user-usecase-factory.ts | 2 +- .../user/delete-user-usecase-factory.ts | 2 +- .../load-users-by-email-usecase-factory.ts | 2 +- .../user/load-users-by-id-usecase-factory.ts | 2 +- .../user/load-users-usecase-factory.ts | 2 +- 19 files changed, 190 insertions(+), 36 deletions(-) create mode 100644 app/src/data/protocols/database/transactions/add-transaction-repository.ts create mode 100644 app/src/data/usecases/transactions/db-add-transaction.ts create mode 100644 app/src/domain/models/transaction.ts delete mode 100644 app/src/domain/models/transactions.ts rename app/src/domain/tests/{users-mock.ts => mock-users.ts} (100%) create mode 100644 app/src/domain/usecases/transactions/add-transaction.ts create mode 100644 app/src/domain/usecases/transactions/index.ts create mode 100644 app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts rename app/src/infra/database/sequelize/{UsersMySQLRepository => UsersMySqlRepository}/users-mysql-repository.ts (97%) create mode 100644 app/src/infra/database/sequelize/models/Transaction.ts rename app/src/infra/database/sequelize/models/{Users.ts => User.ts} (97%) diff --git a/app/src/data/protocols/database/transactions/add-transaction-repository.ts b/app/src/data/protocols/database/transactions/add-transaction-repository.ts new file mode 100644 index 00000000..ffdfd6d8 --- /dev/null +++ b/app/src/data/protocols/database/transactions/add-transaction-repository.ts @@ -0,0 +1,12 @@ +import { AddTransaction } from '@/domain/usecases/transactions' + +export interface AddTransactionRepository { + add: (user: AddTransactionRepository.Params) => Promise +} + +export namespace AddTransactionRepository { + export type Params = AddTransaction.Params + + export type Result = AddTransaction.Result + +} diff --git a/app/src/data/usecases/transactions/db-add-transaction.ts b/app/src/data/usecases/transactions/db-add-transaction.ts new file mode 100644 index 00000000..7caaa758 --- /dev/null +++ b/app/src/data/usecases/transactions/db-add-transaction.ts @@ -0,0 +1,12 @@ +import { AddTransactionRepository } from "@/data/protocols/database/transactions/add-transaction-repository" +import { AddTransaction } from "@/domain/usecases/transactions" + +export class DbAddTransaction { + constructor ( + private readonly addTransactionRepository: AddTransactionRepository + ) {} + + async add (params: AddTransaction.Params): Promise { + return this.addTransactionRepository.add(params) + } +} \ No newline at end of file diff --git a/app/src/domain/models/index.ts b/app/src/domain/models/index.ts index 042420c4..b318bc15 100644 --- a/app/src/domain/models/index.ts +++ b/app/src/domain/models/index.ts @@ -1 +1,2 @@ -export * from './user' \ No newline at end of file +export * from './user' +export * from './transaction' \ No newline at end of file diff --git a/app/src/domain/models/transaction.ts b/app/src/domain/models/transaction.ts new file mode 100644 index 00000000..05cf00f4 --- /dev/null +++ b/app/src/domain/models/transaction.ts @@ -0,0 +1,26 @@ +import { User } from './user' + +export type AddTransactionModel = { + description?: string + amount: number + type: 'debt' | 'credit' | 'chargeback' + chargebackFrom?: number + from: number + to: number + createdAt?: Date +} + +export type Transaction = { + id?: number + description?: string + amount: number + type: 'debt' | 'credit' | 'chargeback' + /** + * The transaction that was charged back. + * This field is only present when the transaction is a chargeback. + */ + chargebackFrom?: Transaction + from: User + to: User + createdAt?: Date +} diff --git a/app/src/domain/models/transactions.ts b/app/src/domain/models/transactions.ts deleted file mode 100644 index 94bed886..00000000 --- a/app/src/domain/models/transactions.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { User } from "./user"; - -export type Transaction = { - id?: number | string; - description?: string; - amount: number; - type: "debt" | "credit" | "chargeback"; - /** - * The transaction that was charged back. - * This field is only present when the transaction is a chargeback. - */ - chargebackFrom?: Transaction; - from: User; - to: User; - createdAt?: Date; -} \ No newline at end of file diff --git a/app/src/domain/models/user.ts b/app/src/domain/models/user.ts index 5a84f6af..8d32787a 100644 --- a/app/src/domain/models/user.ts +++ b/app/src/domain/models/user.ts @@ -1,13 +1,23 @@ -import { Transaction } from "./transactions"; +import { Transaction } from './transaction' + +export type AddUserModel = { + name: string + email: string + birthDay: Date | string + role?: string + password: string + initialBalance?: number + createdAt?: Date +} export type User = { - id?: number; - name: string; - email: string; - birthDay: Date | string; - role?: string - password: string - transactions?: Transaction[] - createdAt?: Date; - updatedAt?: Date; -} \ No newline at end of file + id?: number + name: string + email: string + birthDay: Date | string + role?: string + password: string + transactions?: Transaction[] + createdAt?: Date + updatedAt?: Date +} diff --git a/app/src/domain/tests/users-mock.ts b/app/src/domain/tests/mock-users.ts similarity index 100% rename from app/src/domain/tests/users-mock.ts rename to app/src/domain/tests/mock-users.ts diff --git a/app/src/domain/usecases/transactions/add-transaction.ts b/app/src/domain/usecases/transactions/add-transaction.ts new file mode 100644 index 00000000..571c4f22 --- /dev/null +++ b/app/src/domain/usecases/transactions/add-transaction.ts @@ -0,0 +1,10 @@ +import { AddTransactionModel, Transaction } from '../../models'; + +export interface AddTransaction { + add: (params: AddTransaction.Params) => Promise +} + +export namespace AddTransaction { + export type Params = AddTransactionModel; + export type Result = Transaction; +} \ No newline at end of file diff --git a/app/src/domain/usecases/transactions/index.ts b/app/src/domain/usecases/transactions/index.ts new file mode 100644 index 00000000..f90c592b --- /dev/null +++ b/app/src/domain/usecases/transactions/index.ts @@ -0,0 +1 @@ +export * from './add-transaction' \ No newline at end of file diff --git a/app/src/domain/usecases/users/add-user.ts b/app/src/domain/usecases/users/add-user.ts index 78f01992..f40185b5 100644 --- a/app/src/domain/usecases/users/add-user.ts +++ b/app/src/domain/usecases/users/add-user.ts @@ -1,4 +1,4 @@ -import { User } from '../../models'; +import { AddUserModel, User } from '../../models'; export interface AddUser { add: (params: AddUser.Params) => Promise @@ -9,6 +9,6 @@ export interface AddUser { * Here we declare all types used by AddUser use case, like the params and the result. */ export namespace AddUser { - export type Params = Omit; + export type Params = AddUserModel; export type Result = User; } \ No newline at end of file diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts new file mode 100644 index 00000000..4ff4800e --- /dev/null +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts @@ -0,0 +1,17 @@ +import { AddTransactionRepository } from '@/data/protocols/database/transactions/add-transaction-repository' +import TransactionSequelize from '../models/Transaction' +import UsersSequelize from '../models/User' + +export class TransactionsMySqlReposiory implements AddTransactionRepository { + async add( + transaction: AddTransactionRepository.Params + ): Promise { + const newTransaction = await TransactionSequelize.create(transaction, { + include: { + all: true, + nested: true + } + }) + return newTransaction as any as AddTransactionRepository.Result + } +} diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts b/app/src/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository.ts similarity index 97% rename from app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts rename to app/src/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository.ts index 3b8e964f..7063bbc3 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.ts +++ b/app/src/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository.ts @@ -6,7 +6,7 @@ import { } from '@/data/protocols/database/users' import { LoadUsersByIdRepository } from '@/data/protocols/database/users/load-user-by-id-repository' import { DeleteUser } from '@/domain/usecases/users' -import UsersSequelize from '../models/Users' +import UsersSequelize from '../models/User' export class UsersMySqlReposiory implements diff --git a/app/src/infra/database/sequelize/models/Transaction.ts b/app/src/infra/database/sequelize/models/Transaction.ts new file mode 100644 index 00000000..5079964d --- /dev/null +++ b/app/src/infra/database/sequelize/models/Transaction.ts @@ -0,0 +1,80 @@ +import { AddTransactionModel, Transaction, } from '@/domain/models' +import Sequelize, { Model, Optional } from 'sequelize' +import { sequelizeConnection } from '../helpers' +import UsersSequelize from './User' + +class TransactionSequelize extends Model< + Transaction, + AddTransactionModel +> { +} + +TransactionSequelize.init( + { + id: { + type: Sequelize.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + amount: { + type: Sequelize.FLOAT, + allowNull: false, + }, + from: { + type: Sequelize.INTEGER, + allowNull: false, + field: 'fromId', + references: { + model: UsersSequelize, + key: 'id', + }, + }, + to: { + type: Sequelize.INTEGER, + allowNull: false, + field: 'toId', + references: { + model: UsersSequelize, + key: 'id', + }, + }, + type: { + type: Sequelize.STRING, + allowNull: false, + }, + chargebackFrom: { + type: Sequelize.INTEGER, + allowNull: true, + field: 'chargebackFromId', + references: { + model: TransactionSequelize, + key: 'id', + } + }, + createdAt: { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.NOW, + }, + description: { + type: Sequelize.STRING, + allowNull: true, + } + }, + { + createdAt: 'createdAt', + sequelize: sequelizeConnection, + tableName: 'transactions', + modelName: 'Transactions', + } +) +TransactionSequelize.belongsTo(UsersSequelize, { + foreignKey: 'toId', +}) + +TransactionSequelize.belongsTo(UsersSequelize, { + foreignKey: 'fromId', +}) + + +export default TransactionSequelize diff --git a/app/src/infra/database/sequelize/models/Users.ts b/app/src/infra/database/sequelize/models/User.ts similarity index 97% rename from app/src/infra/database/sequelize/models/Users.ts rename to app/src/infra/database/sequelize/models/User.ts index 069fabe8..cc103afa 100644 --- a/app/src/infra/database/sequelize/models/Users.ts +++ b/app/src/infra/database/sequelize/models/User.ts @@ -46,6 +46,7 @@ UsersSequelize.init( updatedAt: 'updatedAt', sequelize: sequelizeConnection, tableName: 'users', + modelName: 'Users', }, ) diff --git a/app/src/main/factories/usecases/user/add-user-usecase-factory.ts b/app/src/main/factories/usecases/user/add-user-usecase-factory.ts index 2c66fb13..d15d1075 100644 --- a/app/src/main/factories/usecases/user/add-user-usecase-factory.ts +++ b/app/src/main/factories/usecases/user/add-user-usecase-factory.ts @@ -1,6 +1,6 @@ import { DbAddUser } from '@/data/usecases/users/db-add-user'; import { AddUser } from '@/domain/usecases/users'; -import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository'; +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository'; import { MomentDateFormatter } from '@/infra/utils'; export function makeDbAddUser(): AddUser { diff --git a/app/src/main/factories/usecases/user/delete-user-usecase-factory.ts b/app/src/main/factories/usecases/user/delete-user-usecase-factory.ts index 5fa4d899..c3d03295 100644 --- a/app/src/main/factories/usecases/user/delete-user-usecase-factory.ts +++ b/app/src/main/factories/usecases/user/delete-user-usecase-factory.ts @@ -1,6 +1,6 @@ import { DbDeleteUser } from '@/data/usecases/users' import { DeleteUser } from '@/domain/usecases/users' -import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository' +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository' export function makeDbDeleteUser(): DeleteUser { return new DbDeleteUser(new UsersMySqlReposiory(), new UsersMySqlReposiory()) diff --git a/app/src/main/factories/usecases/user/load-users-by-email-usecase-factory.ts b/app/src/main/factories/usecases/user/load-users-by-email-usecase-factory.ts index 81ee0d02..fe75069c 100644 --- a/app/src/main/factories/usecases/user/load-users-by-email-usecase-factory.ts +++ b/app/src/main/factories/usecases/user/load-users-by-email-usecase-factory.ts @@ -1,6 +1,6 @@ import { DbLoadUsersByEmail } from '@/data/usecases/users' import { LoadUsersByEmail } from '@/domain/usecases/users' -import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository' +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository' export function makeDbLoadUsersByEmail(): LoadUsersByEmail { return new DbLoadUsersByEmail(new UsersMySqlReposiory()) diff --git a/app/src/main/factories/usecases/user/load-users-by-id-usecase-factory.ts b/app/src/main/factories/usecases/user/load-users-by-id-usecase-factory.ts index c5db802f..a1d88389 100644 --- a/app/src/main/factories/usecases/user/load-users-by-id-usecase-factory.ts +++ b/app/src/main/factories/usecases/user/load-users-by-id-usecase-factory.ts @@ -1,6 +1,6 @@ import { DbLoadUsersById } from '@/data/usecases/users' import { LoadUsersById } from '@/domain/usecases/users' -import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository' +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository' export function makeDbLoadUsersById(): LoadUsersById { return new DbLoadUsersById(new UsersMySqlReposiory()) diff --git a/app/src/main/factories/usecases/user/load-users-usecase-factory.ts b/app/src/main/factories/usecases/user/load-users-usecase-factory.ts index c06abebf..dc98a3d7 100644 --- a/app/src/main/factories/usecases/user/load-users-usecase-factory.ts +++ b/app/src/main/factories/usecases/user/load-users-usecase-factory.ts @@ -1,6 +1,6 @@ import { DbLoadUsers } from '@/data/usecases/users/db-load-users' import { LoadUsers } from '@/domain/usecases/users' -import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository' +import { UsersMySqlReposiory } from '@/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository' export function makeDbLoadUsers(): LoadUsers { return new DbLoadUsers(new UsersMySqlReposiory()) From 63b9c443b3ad997572f6b7f36f6ebf41b1a646fe Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 22:05:05 -0300 Subject: [PATCH 077/105] test: implementa db-add-transaction --- app/src/data/test/mock-transactions.ts | 16 +++++++ app/src/data/test/mock-users.ts | 2 +- .../transactions/db-add-transaction.test.ts | 32 +++++++++++++ .../data/usecases/users/db-add-user.test.ts | 2 +- app/src/domain/tests/mock-transactions.ts | 27 +++++++++++ .../transactions-mysql.repository.test.ts | 48 +++++++++++++++++++ .../users-mysql-repository.test.ts | 4 +- app/src/main/routes/users-routes.spec.ts | 4 +- .../add-user-controller.test.ts | 2 +- .../delete-user-controller.test.ts | 2 +- .../load-user-by-id-controller.test.ts | 2 +- .../load-users-controller.test.ts | 2 +- 12 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 app/src/data/test/mock-transactions.ts create mode 100644 app/src/data/usecases/transactions/db-add-transaction.test.ts create mode 100644 app/src/domain/tests/mock-transactions.ts create mode 100644 app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts rename app/src/infra/database/sequelize/{UsersMySQLRepository => UsersMySqlRepository}/users-mysql-repository.test.ts (98%) diff --git a/app/src/data/test/mock-transactions.ts b/app/src/data/test/mock-transactions.ts new file mode 100644 index 00000000..33b11e51 --- /dev/null +++ b/app/src/data/test/mock-transactions.ts @@ -0,0 +1,16 @@ +import { mockTransaction } from '@/domain/tests/mock-transactions' +import { AddTransactionRepository } from '../protocols/database/transactions/add-transaction-repository' + +export class AddTransactionRepositorySpy implements AddTransactionRepository { + addParams: AddTransactionRepository.Params + addResult: AddTransactionRepository.Result + constructor() { + this.addResult = mockTransaction() + } + async add( + params: AddTransactionRepository.Params + ): Promise { + this.addParams = params + return Promise.resolve(this.addResult) + } +} diff --git a/app/src/data/test/mock-users.ts b/app/src/data/test/mock-users.ts index 14ec6ad0..45635821 100644 --- a/app/src/data/test/mock-users.ts +++ b/app/src/data/test/mock-users.ts @@ -1,4 +1,4 @@ -import { mockUser } from '@/domain/tests/users-mock' +import { mockUser } from '@/domain/tests/mock-users' import { LoadUsersByEmailRepository, LoadUsersByIdRepository } from '../protocols/database/users' import { AddUserRepository } from '../protocols/database/users/add-user-repository' import { DeleteUserRepository } from '../protocols/database/users/delete-user-repository' diff --git a/app/src/data/usecases/transactions/db-add-transaction.test.ts b/app/src/data/usecases/transactions/db-add-transaction.test.ts new file mode 100644 index 00000000..c286df30 --- /dev/null +++ b/app/src/data/usecases/transactions/db-add-transaction.test.ts @@ -0,0 +1,32 @@ +import { AddTransactionRepositorySpy } from "@/data/test/mock-transactions"; +import { mockAddTransaction } from "@/domain/tests/mock-transactions"; +import { describe, expect, test, vitest } from "vitest"; +import { DbAddTransaction } from "./db-add-transaction"; + +describe('DbAddTransaction', () => { + function makeSut() { + const addTransactionRepositorySpy = new AddTransactionRepositorySpy() + const sut = new DbAddTransaction(addTransactionRepositorySpy); + return { + sut, + addTransactionRepositorySpy + } + } + describe('add()', () => { + test('should call addTransactionRepository with correct params', async () => { + const { sut, addTransactionRepositorySpy } = makeSut() + const mockedAddTransaction = mockAddTransaction() + await sut.add(mockedAddTransaction) + expect(addTransactionRepositorySpy.addParams).toEqual(mockedAddTransaction) + }); + + test('should throw if addTransactionRepository throws', async () => { + const { sut, addTransactionRepositorySpy } = makeSut() + const mockedError = new Error('some_erorr') + vitest.spyOn(addTransactionRepositorySpy, 'add').mockRejectedValueOnce(mockedError) + const mockedAddTransaction = mockAddTransaction() + const promise = sut.add(mockedAddTransaction) + await expect(promise).rejects.toThrow(mockedError) + }); + }); +}); \ No newline at end of file diff --git a/app/src/data/usecases/users/db-add-user.test.ts b/app/src/data/usecases/users/db-add-user.test.ts index fc224b7a..1cc9516c 100644 --- a/app/src/data/usecases/users/db-add-user.test.ts +++ b/app/src/data/usecases/users/db-add-user.test.ts @@ -1,6 +1,6 @@ import { DateFormatterSpy } from '@/data/test/mock-date-formatter'; import { AddUserRepositorySpy } from '@/data/test/mock-users'; -import { mockAddUser } from '@/domain/tests/users-mock'; +import { mockAddUser } from '@/domain/tests/mock-users'; import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest'; import { DbAddUser } from './db-add-user'; import MockDate from 'mockdate' diff --git a/app/src/domain/tests/mock-transactions.ts b/app/src/domain/tests/mock-transactions.ts new file mode 100644 index 00000000..c417793d --- /dev/null +++ b/app/src/domain/tests/mock-transactions.ts @@ -0,0 +1,27 @@ +import { faker } from "@faker-js/faker"; +import { AddTransactionModel, Transaction } from "../models"; +import { mockUser } from "./mock-users"; + +export function mockTransaction(): Transaction { + return { + id: faker.datatype.number(), + amount: faker.datatype.float(), + from: mockUser(), + to: mockUser(), + type: faker.helpers.arrayElement(['debt', 'credit', 'chargeback']), + createdAt: faker.date.past(), + chargebackFrom: null, + description: faker.lorem.sentence(), + } +} + +export function mockAddTransaction(): AddTransactionModel { + return { + amount: faker.datatype.float(), + from: mockUser().id, + to: mockUser().id, + type: faker.helpers.arrayElement(['debt', 'credit', 'chargeback']), + chargebackFrom: null, + description: faker.lorem.sentence(), + } +} \ No newline at end of file diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts new file mode 100644 index 00000000..66abcf1c --- /dev/null +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts @@ -0,0 +1,48 @@ +import { User } from '@/domain/models' +import { mockAddTransaction } from '@/domain/tests/mock-transactions' +import { mockAddUser } from '@/domain/tests/mock-users' +import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' +import UsersSequelize from '../models/User' +import { migrate, truncate } from '../__tests__/utils' +import { TransactionsMySqlReposiory } from './transactions-mysql.repository' + +describe('TransactionsMySqlRepository', () => { + function makeSut() { + return new TransactionsMySqlReposiory() + } + + function makeUser(): Promise { + const user = mockAddUser() + return UsersSequelize.create(user) as any + } + + beforeAll(async () => { + await migrate() + }) + + afterAll(async () => { + await truncate() + }) + + beforeEach(async () => { + await truncate() + await migrate() + }) + describe('add()', () => { + test('should add and return an transaction on success ', async () => { + const sut = makeSut() + const to = await makeUser() + const from = await makeUser() + const mockedTransaction = mockAddTransaction() + mockedTransaction.to = to.id + mockedTransaction.from = from.id + const transaction = await sut.add(mockedTransaction) + + expect(transaction.amount).toEqual(mockedTransaction.amount) + expect(transaction.description).toEqual(mockedTransaction.description) + expect(transaction.type).toEqual(mockedTransaction.type) + expect(transaction.to).toEqual(to.id) + expect(transaction.from).toEqual(from.id) + }) + }) +}) diff --git a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts b/app/src/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository.test.ts similarity index 98% rename from app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts rename to app/src/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository.test.ts index 365174b0..00526c99 100644 --- a/app/src/infra/database/sequelize/UsersMySQLRepository/users-mysql-repository.test.ts +++ b/app/src/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository.test.ts @@ -1,9 +1,9 @@ -import { mockAddUser } from '@/domain/tests/users-mock' +import { mockAddUser } from '@/domain/tests/mock-users' import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' import { UsersMySqlReposiory } from './users-mysql-repository' import { migrate, truncate } from '../__tests__/utils' import MockDate from 'mockdate' -import UsersSequelize from '../models/Users' +import UsersSequelize from '../models/User' import { User } from '@/domain/models' describe('UsersMySqlReposiory', () => { diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index 986203e2..5e370edb 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -1,5 +1,5 @@ -import { mockAddUser } from '@/domain/tests/users-mock' -import UsersSequelize from '@/infra/database/sequelize/models/Users' +import { mockAddUser } from '@/domain/tests/mock-users' +import UsersSequelize from '@/infra/database/sequelize/models/User' import { migrate, truncate } from '@/infra/database/sequelize/__tests__/utils' import request from 'supertest' import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' diff --git a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts index fd3c9ec3..cb0a038a 100644 --- a/app/src/presentation/controllers/users-controller/add-user-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/add-user-controller.test.ts @@ -4,7 +4,7 @@ import { AddUserSpy, LoadUsersByEmailSpy, mockUser, -} from '@/domain/tests/users-mock' +} from '@/domain/tests/mock-users' import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' import { EmailAlreadyInUseError, MissingParamError } from '@/presentation/errors' import { ValidationSpy } from '@/validation/test/mock-validation' diff --git a/app/src/presentation/controllers/users-controller/delete-user-controller.test.ts b/app/src/presentation/controllers/users-controller/delete-user-controller.test.ts index e0cdbe58..30b76513 100644 --- a/app/src/presentation/controllers/users-controller/delete-user-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/delete-user-controller.test.ts @@ -1,4 +1,4 @@ -import { DeleteUserSpy } from "@/domain/tests/users-mock"; +import { DeleteUserSpy } from "@/domain/tests/mock-users"; import { NotFoundError } from "@/presentation/errors/not-found-error"; import { noContent, serverError } from "@/presentation/helpers/http-helper"; import { describe, expect, test, vitest } from "vitest"; diff --git a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts index cf30f9be..aec74adc 100644 --- a/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/load-user-by-id-controller.test.ts @@ -1,4 +1,4 @@ -import { LoadUsersByIdSpy } from '@/domain/tests/users-mock' +import { LoadUsersByIdSpy } from '@/domain/tests/mock-users' import { MissingParamError } from '@/presentation/errors/missing-param-error' import { badRequest, notFound, ok, serverError } from '@/presentation/helpers/http-helper' import { faker } from '@faker-js/faker' diff --git a/app/src/presentation/controllers/users-controller/load-users-controller.test.ts b/app/src/presentation/controllers/users-controller/load-users-controller.test.ts index d9e6b3b4..3b5878e1 100644 --- a/app/src/presentation/controllers/users-controller/load-users-controller.test.ts +++ b/app/src/presentation/controllers/users-controller/load-users-controller.test.ts @@ -1,4 +1,4 @@ -import { LoadUsersSpy } from '@/domain/tests/users-mock'; +import { LoadUsersSpy } from '@/domain/tests/mock-users'; import { ok, serverError } from '@/presentation/helpers/http-helper'; import { describe, expect, test, vitest } from 'vitest'; import { LoadUsersController } from './load-users-controller'; From 4761339e87fa6db66a23d9954f525964806abb3c Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 23:47:38 -0300 Subject: [PATCH 078/105] refactor: melhor model Transaction --- app/src/domain/models/transaction.ts | 34 +++++++-------- .../transactions-mysql.repository.ts | 39 ++++++++++++++--- .../database/sequelize/models/Transaction.ts | 42 ++++++++++--------- .../infra/database/sequelize/models/User.ts | 4 +- 4 files changed, 75 insertions(+), 44 deletions(-) diff --git a/app/src/domain/models/transaction.ts b/app/src/domain/models/transaction.ts index 05cf00f4..e6b31a3c 100644 --- a/app/src/domain/models/transaction.ts +++ b/app/src/domain/models/transaction.ts @@ -1,26 +1,26 @@ -import { User } from './user' +import { User } from "./user"; export type AddTransactionModel = { - description?: string - amount: number - type: 'debt' | 'credit' | 'chargeback' - chargebackFrom?: number - from: number - to: number - createdAt?: Date + description?: string; + amount: number; + type: "debt" | "credit" | "chargeback"; + chargebackFrom?: Transaction; + from: User; + to: User; + createdAt?: Date; } export type Transaction = { - id?: number - description?: string - amount: number - type: 'debt' | 'credit' | 'chargeback' + id: number; + description?: string; + amount: number; + type: "debt" | "credit" | "chargeback"; /** * The transaction that was charged back. * This field is only present when the transaction is a chargeback. */ - chargebackFrom?: Transaction - from: User - to: User - createdAt?: Date -} + chargebackFrom?: Transaction; + from: User; + to: User; + createdAt?: Date; +} \ No newline at end of file diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts index 4ff4800e..57fd233c 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts @@ -1,17 +1,44 @@ import { AddTransactionRepository } from '@/data/protocols/database/transactions/add-transaction-repository' -import TransactionSequelize from '../models/Transaction' +import TransactionSequelize, { + TransactionModelSequelize, +} from '../models/Transaction' import UsersSequelize from '../models/User' export class TransactionsMySqlReposiory implements AddTransactionRepository { async add( transaction: AddTransactionRepository.Params ): Promise { - const newTransaction = await TransactionSequelize.create(transaction, { + const newTransaction = (await TransactionSequelize.create({ + ...transaction, + from: transaction.from.id, + to: transaction.to.id, + chargebackFrom: transaction.chargebackFrom?.id, + })).toJSON() + + const insertedTransaction = (await TransactionSequelize.findOne({ + where: { + id: newTransaction.id, + }, include: { - all: true, - nested: true + all: true } - }) - return newTransaction as any as AddTransactionRepository.Result + })).toJSON() + + return this.formatTransaction(insertedTransaction) + } + + private formatTransaction( + transaction: TransactionModelSequelize + ): AddTransactionRepository.Result { + const { From, To, ChargebackFrom, ...prunedTransaction} = transaction + const newTransaction: AddTransactionRepository.Result = { + ...prunedTransaction, + from: transaction.From, + to: transaction.To, + chargebackFrom: transaction.ChargebackFrom, + } + + + return newTransaction } } diff --git a/app/src/infra/database/sequelize/models/Transaction.ts b/app/src/infra/database/sequelize/models/Transaction.ts index 5079964d..63ff3711 100644 --- a/app/src/infra/database/sequelize/models/Transaction.ts +++ b/app/src/infra/database/sequelize/models/Transaction.ts @@ -1,13 +1,22 @@ -import { AddTransactionModel, Transaction, } from '@/domain/models' -import Sequelize, { Model, Optional } from 'sequelize' +import { AddTransactionModel, Transaction, User } from '@/domain/models' +import Sequelize, { Model } from 'sequelize' import { sequelizeConnection } from '../helpers' import UsersSequelize from './User' -class TransactionSequelize extends Model< - Transaction, - AddTransactionModel -> { -} +export type TransactionModelSequelize = { + id: number, + description: string, + amount: number, + type: 'debt' | 'credit' | 'chargeback', + chargebackFrom: number, + ChargebackFrom?: Transaction, + from: number, + From?: User, + To?: User, + to: number, + createdAt?: Date +} +class TransactionSequelize extends Model {} TransactionSequelize.init( { @@ -23,7 +32,6 @@ TransactionSequelize.init( from: { type: Sequelize.INTEGER, allowNull: false, - field: 'fromId', references: { model: UsersSequelize, key: 'id', @@ -32,7 +40,6 @@ TransactionSequelize.init( to: { type: Sequelize.INTEGER, allowNull: false, - field: 'toId', references: { model: UsersSequelize, key: 'id', @@ -45,11 +52,11 @@ TransactionSequelize.init( chargebackFrom: { type: Sequelize.INTEGER, allowNull: true, - field: 'chargebackFromId', references: { model: TransactionSequelize, key: 'id', - } + }, + }, createdAt: { type: Sequelize.DATE, @@ -59,7 +66,7 @@ TransactionSequelize.init( description: { type: Sequelize.STRING, allowNull: true, - } + }, }, { createdAt: 'createdAt', @@ -68,13 +75,8 @@ TransactionSequelize.init( modelName: 'Transactions', } ) -TransactionSequelize.belongsTo(UsersSequelize, { - foreignKey: 'toId', -}) - -TransactionSequelize.belongsTo(UsersSequelize, { - foreignKey: 'fromId', -}) - +TransactionSequelize.belongsTo(UsersSequelize, { as: 'From', foreignKey: 'from', onDelete: 'CASCADE' }) +TransactionSequelize.belongsTo(UsersSequelize, { as: 'To', foreignKey: 'to', onDelete: 'CASCADE' }) +TransactionSequelize.hasOne(TransactionSequelize, { as: 'ChargebackFrom', foreignKey: 'chargebackFrom', onDelete: 'CASCADE' }) export default TransactionSequelize diff --git a/app/src/infra/database/sequelize/models/User.ts b/app/src/infra/database/sequelize/models/User.ts index cc103afa..d1f7e94a 100644 --- a/app/src/infra/database/sequelize/models/User.ts +++ b/app/src/infra/database/sequelize/models/User.ts @@ -39,7 +39,8 @@ UsersSequelize.init( role: { type: Sequelize.STRING, allowNull: true, - } + }, + }, { createdAt: 'createdAt', @@ -48,6 +49,7 @@ UsersSequelize.init( tableName: 'users', modelName: 'Users', }, + ) export default UsersSequelize \ No newline at end of file From 65ad540fae5d9b9a00be33869fa3f81dab9c7b0a Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Tue, 18 Oct 2022 23:47:42 -0300 Subject: [PATCH 079/105] test: melhor model Transaction --- app/src/domain/tests/mock-transactions.ts | 4 ++-- .../transactions-mysql.repository.test.ts | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/src/domain/tests/mock-transactions.ts b/app/src/domain/tests/mock-transactions.ts index c417793d..99912804 100644 --- a/app/src/domain/tests/mock-transactions.ts +++ b/app/src/domain/tests/mock-transactions.ts @@ -18,8 +18,8 @@ export function mockTransaction(): Transaction { export function mockAddTransaction(): AddTransactionModel { return { amount: faker.datatype.float(), - from: mockUser().id, - to: mockUser().id, + from: mockUser(), + to: mockUser(), type: faker.helpers.arrayElement(['debt', 'credit', 'chargeback']), chargebackFrom: null, description: faker.lorem.sentence(), diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts index 66abcf1c..975b65e9 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts @@ -34,15 +34,16 @@ describe('TransactionsMySqlRepository', () => { const to = await makeUser() const from = await makeUser() const mockedTransaction = mockAddTransaction() - mockedTransaction.to = to.id - mockedTransaction.from = from.id + mockedTransaction.to = to + mockedTransaction.from = from const transaction = await sut.add(mockedTransaction) - expect(transaction.amount).toEqual(mockedTransaction.amount) - expect(transaction.description).toEqual(mockedTransaction.description) - expect(transaction.type).toEqual(mockedTransaction.type) - expect(transaction.to).toEqual(to.id) - expect(transaction.from).toEqual(from.id) + expect(transaction.amount).toBe(mockedTransaction.amount) + expect(transaction.description).toBe(mockedTransaction.description) + expect(transaction.type).toBe(mockedTransaction.type) + expect(transaction.to.id).toEqual(to.id) + expect(transaction.from.id).toEqual(from.id) + }) }) }) From 3e0b2a696cc8ac0472fa6f74743918f028cb11b9 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 00:12:12 -0300 Subject: [PATCH 080/105] feat: garante que chargeback ira funcionar --- .../transactions-mysql.repository.ts | 6 ++++-- app/src/infra/database/sequelize/models/Transaction.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts index 57fd233c..bb2c3153 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts @@ -2,7 +2,6 @@ import { AddTransactionRepository } from '@/data/protocols/database/transactions import TransactionSequelize, { TransactionModelSequelize, } from '../models/Transaction' -import UsersSequelize from '../models/User' export class TransactionsMySqlReposiory implements AddTransactionRepository { async add( @@ -14,6 +13,7 @@ export class TransactionsMySqlReposiory implements AddTransactionRepository { to: transaction.to.id, chargebackFrom: transaction.chargebackFrom?.id, })).toJSON() + const insertedTransaction = (await TransactionSequelize.findOne({ where: { @@ -21,9 +21,10 @@ export class TransactionsMySqlReposiory implements AddTransactionRepository { }, include: { all: true + } })).toJSON() - + return this.formatTransaction(insertedTransaction) } @@ -31,6 +32,7 @@ export class TransactionsMySqlReposiory implements AddTransactionRepository { transaction: TransactionModelSequelize ): AddTransactionRepository.Result { const { From, To, ChargebackFrom, ...prunedTransaction} = transaction + const newTransaction: AddTransactionRepository.Result = { ...prunedTransaction, from: transaction.From, diff --git a/app/src/infra/database/sequelize/models/Transaction.ts b/app/src/infra/database/sequelize/models/Transaction.ts index 63ff3711..f0ca7c6e 100644 --- a/app/src/infra/database/sequelize/models/Transaction.ts +++ b/app/src/infra/database/sequelize/models/Transaction.ts @@ -78,5 +78,5 @@ TransactionSequelize.init( TransactionSequelize.belongsTo(UsersSequelize, { as: 'From', foreignKey: 'from', onDelete: 'CASCADE' }) TransactionSequelize.belongsTo(UsersSequelize, { as: 'To', foreignKey: 'to', onDelete: 'CASCADE' }) -TransactionSequelize.hasOne(TransactionSequelize, { as: 'ChargebackFrom', foreignKey: 'chargebackFrom', onDelete: 'CASCADE' }) +TransactionSequelize.belongsTo(TransactionSequelize, { as: 'ChargebackFrom', foreignKey: 'chargebackFrom', onDelete: 'CASCADE' }) export default TransactionSequelize From 264c9f375507afe3ef3cc79f76ad03ef2797de71 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 00:12:15 -0300 Subject: [PATCH 081/105] test: garante que chargeback ira funcionar --- .../transactions-mysql.repository.test.ts | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts index 975b65e9..77d016c0 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts @@ -1,7 +1,8 @@ -import { User } from '@/domain/models' +import { Transaction, User } from '@/domain/models' import { mockAddTransaction } from '@/domain/tests/mock-transactions' import { mockAddUser } from '@/domain/tests/mock-users' import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' +import TransactionSequelize from '../models/Transaction' import UsersSequelize from '../models/User' import { migrate, truncate } from '../__tests__/utils' import { TransactionsMySqlReposiory } from './transactions-mysql.repository' @@ -16,6 +17,39 @@ describe('TransactionsMySqlRepository', () => { return UsersSequelize.create(user) as any } + async function makeTransaction(): Promise { + const transaction = mockAddTransaction() + const to = await makeUser() + const from = await makeUser() + const rawTransactionDb = ( + await TransactionSequelize.create({ + ...transaction, + from: from.id, + to: to.id, + chargebackFrom: transaction.chargebackFrom?.id, + }) + ).toJSON() + + const { From, ChargebackFrom, To, ...transactionDb } = ( + await TransactionSequelize.findOne({ + where: { + id: rawTransactionDb.id, + }, + include: { + all: true, + }, + }) + ).toJSON() + const transactionMapped = { + ...transactionDb, + from: From, + to: To, + chargebackFrom: ChargebackFrom, + } + + return transactionMapped + } + beforeAll(async () => { await migrate() }) @@ -43,7 +77,39 @@ describe('TransactionsMySqlRepository', () => { expect(transaction.type).toBe(mockedTransaction.type) expect(transaction.to.id).toEqual(to.id) expect(transaction.from.id).toEqual(from.id) + + const transactionExists = await TransactionSequelize.findByPk( + transaction.id + ) + expect(transactionExists).toBeTruthy() + expect(transactionExists.toJSON().id).toBe(transaction.id) + }) + + test('should add and return an transaction on success ', async () => { + const sut = makeSut() + const to = await makeUser() + const from = await makeUser() + const mockedChargebackTransaction = await makeTransaction() + + const mockedTransaction = mockAddTransaction() + mockedTransaction.to = to + mockedTransaction.from = from + mockedTransaction.type = 'chargeback' + mockedTransaction.chargebackFrom = mockedChargebackTransaction + const transaction = await sut.add(mockedTransaction) + + expect(transaction.amount).toBe(mockedTransaction.amount) + expect(transaction.description).toBe(mockedTransaction.description) + expect(transaction.type).toBe(mockedTransaction.type) + expect(transaction.to.id).toEqual(to.id) + expect(transaction.from.id).toEqual(from.id) + expect(transaction.chargebackFrom.id).toEqual(mockedChargebackTransaction.id) + const transactionExists = await TransactionSequelize.findByPk( + transaction.id + ) + expect(transactionExists).toBeTruthy() + expect(transactionExists.toJSON().id).toBe(transaction.id) }) }) }) From 8aca85566f3a55dbb3f9c11d65095704d1a0aa5a Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 08:55:12 -0300 Subject: [PATCH 082/105] refactor: modifica tipagem para inserir Transaction --- app/src/domain/models/transaction.ts | 6 +++--- app/src/domain/tests/mock-transactions.ts | 17 +++++++++++++++-- .../transactions-mysql.repository.test.ts | 17 ++++++----------- .../transactions-mysql.repository.ts | 7 +------ 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/app/src/domain/models/transaction.ts b/app/src/domain/models/transaction.ts index e6b31a3c..ca611e33 100644 --- a/app/src/domain/models/transaction.ts +++ b/app/src/domain/models/transaction.ts @@ -4,9 +4,9 @@ export type AddTransactionModel = { description?: string; amount: number; type: "debt" | "credit" | "chargeback"; - chargebackFrom?: Transaction; - from: User; - to: User; + chargebackFrom?: number; + from: number; + to: number; createdAt?: Date; } diff --git a/app/src/domain/tests/mock-transactions.ts b/app/src/domain/tests/mock-transactions.ts index 99912804..09fffba6 100644 --- a/app/src/domain/tests/mock-transactions.ts +++ b/app/src/domain/tests/mock-transactions.ts @@ -1,5 +1,6 @@ import { faker } from "@faker-js/faker"; import { AddTransactionModel, Transaction } from "../models"; +import { AddTransaction } from "../usecases/transactions"; import { mockUser } from "./mock-users"; export function mockTransaction(): Transaction { @@ -18,10 +19,22 @@ export function mockTransaction(): Transaction { export function mockAddTransaction(): AddTransactionModel { return { amount: faker.datatype.float(), - from: mockUser(), - to: mockUser(), + from: mockUser().id, + to: mockUser().id, type: faker.helpers.arrayElement(['debt', 'credit', 'chargeback']), chargebackFrom: null, description: faker.lorem.sentence(), } +} + +export class AddTransactionSpy implements AddTransaction { + addResult: AddTransaction.Result + addParams: AddTransaction.Params + constructor() { + this.addResult = mockTransaction() + } + async add(params: AddTransaction.Params): Promise { + this.addParams = params + return new Promise((resolve) => resolve(this.addResult)) + } } \ No newline at end of file diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts index 77d016c0..05c81e51 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts @@ -22,12 +22,7 @@ describe('TransactionsMySqlRepository', () => { const to = await makeUser() const from = await makeUser() const rawTransactionDb = ( - await TransactionSequelize.create({ - ...transaction, - from: from.id, - to: to.id, - chargebackFrom: transaction.chargebackFrom?.id, - }) + await TransactionSequelize.create({...transaction, to: to.id, from: from.id}) ).toJSON() const { From, ChargebackFrom, To, ...transactionDb } = ( @@ -68,8 +63,8 @@ describe('TransactionsMySqlRepository', () => { const to = await makeUser() const from = await makeUser() const mockedTransaction = mockAddTransaction() - mockedTransaction.to = to - mockedTransaction.from = from + mockedTransaction.to = to.id + mockedTransaction.from = from.id const transaction = await sut.add(mockedTransaction) expect(transaction.amount).toBe(mockedTransaction.amount) @@ -92,10 +87,10 @@ describe('TransactionsMySqlRepository', () => { const mockedChargebackTransaction = await makeTransaction() const mockedTransaction = mockAddTransaction() - mockedTransaction.to = to - mockedTransaction.from = from + mockedTransaction.to = to.id + mockedTransaction.from = from.id mockedTransaction.type = 'chargeback' - mockedTransaction.chargebackFrom = mockedChargebackTransaction + mockedTransaction.chargebackFrom = mockedChargebackTransaction.id const transaction = await sut.add(mockedTransaction) expect(transaction.amount).toBe(mockedTransaction.amount) diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts index bb2c3153..51cde2f2 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts @@ -7,12 +7,7 @@ export class TransactionsMySqlReposiory implements AddTransactionRepository { async add( transaction: AddTransactionRepository.Params ): Promise { - const newTransaction = (await TransactionSequelize.create({ - ...transaction, - from: transaction.from.id, - to: transaction.to.id, - chargebackFrom: transaction.chargebackFrom?.id, - })).toJSON() + const newTransaction = (await TransactionSequelize.create(transaction)).toJSON() const insertedTransaction = (await TransactionSequelize.findOne({ From 0d493dede8e5543529c6c5820ec6d977409d9cb2 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 08:55:39 -0300 Subject: [PATCH 083/105] feat: implementa AddTransactionController --- .../add-transaction-controller.ts | 31 +++++++++++++++++++ .../transactions-controllers/index.ts | 1 + app/src/presentation/protocols/validation.ts | 4 +-- 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 app/src/presentation/controllers/transactions-controllers/add-transaction-controller.ts create mode 100644 app/src/presentation/controllers/transactions-controllers/index.ts diff --git a/app/src/presentation/controllers/transactions-controllers/add-transaction-controller.ts b/app/src/presentation/controllers/transactions-controllers/add-transaction-controller.ts new file mode 100644 index 00000000..43a43322 --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/add-transaction-controller.ts @@ -0,0 +1,31 @@ +import { AddTransaction } from '@/domain/usecases/transactions' +import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' +import { Controller, HttpResponse, Validation } from '@/presentation/protocols' + +export class AddTransactionController implements Controller { + constructor( + private readonly addTransactionUseCase: AddTransaction, + private readonly validation: Validation + ) {} + + async handle( + request: AddTransactionController.Request + ): Promise { + try { + const error = this.validation.validate(request) + if (error) { + return badRequest(error) + } + const result = await this.addTransactionUseCase.add(request) + return ok(result) + } catch (error) { + return serverError(error) + } + } +} + +export namespace AddTransactionController { + export type Request = AddTransaction.Params + + export type Response = HttpResponse +} diff --git a/app/src/presentation/controllers/transactions-controllers/index.ts b/app/src/presentation/controllers/transactions-controllers/index.ts new file mode 100644 index 00000000..19135917 --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/index.ts @@ -0,0 +1 @@ +export * from './add-transaction-controller' \ No newline at end of file diff --git a/app/src/presentation/protocols/validation.ts b/app/src/presentation/protocols/validation.ts index d1e1e52a..a1cd5921 100644 --- a/app/src/presentation/protocols/validation.ts +++ b/app/src/presentation/protocols/validation.ts @@ -1,5 +1,5 @@ import { ClientError } from "../errors"; -export interface Validation { - validate: (input: any) => ClientError | undefined +export interface Validation { + validate: (input: T) => ClientError | undefined } From c37c8154c089f79b54a3906d679632e96fa182c7 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 08:55:43 -0300 Subject: [PATCH 084/105] test: implementa AddTransactionController --- .../add-transaction-controller.test.ts | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 app/src/presentation/controllers/transactions-controllers/add-transaction-controller.test.ts diff --git a/app/src/presentation/controllers/transactions-controllers/add-transaction-controller.test.ts b/app/src/presentation/controllers/transactions-controllers/add-transaction-controller.test.ts new file mode 100644 index 00000000..16513f5f --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/add-transaction-controller.test.ts @@ -0,0 +1,73 @@ +import { + AddTransactionSpy, + mockAddTransaction, +} from '@/domain/tests/mock-transactions' +import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' +import { ValidationSpy } from '@/validation/test/mock-validation' +import { describe, expect, test, vitest } from 'vitest' +import { AddTransactionController } from './add-transaction-controller' + +describe('AddTransactionController', () => { + function makeSut() { + const addTransactionUseCaseSpy = new AddTransactionSpy() + const validationSpy = new ValidationSpy() + const sut = new AddTransactionController( + addTransactionUseCaseSpy, + validationSpy + ) + return { + sut, + addTransactionUseCaseSpy, + validationSpy, + } + } + describe('handle()', () => { + test('should call validation with correct params', async () => { + const { sut, validationSpy } = makeSut() + const request = mockAddTransaction() + await sut.handle(request) + expect(validationSpy.input).toEqual(request) + }) + + test('should return badRequest if validation returns an error', async () => { + const { sut, validationSpy } = makeSut() + const error = new Error('any_error') + validationSpy.error = error + const response = await sut.handle(mockAddTransaction()) + expect(response).toEqual(badRequest(error)) + }) + + test('should return serverError if validation throws', async () => { + const { sut, validationSpy } = makeSut() + vitest.spyOn(validationSpy, 'validate').mockImplementationOnce(() => { + throw new Error('any_error') + }) + const response = await sut.handle(mockAddTransaction()) + expect(response).toEqual(serverError(new Error('any_error'))) + }) + test('should call addTransactionUseCase with correct params', async () => { + const { sut, addTransactionUseCaseSpy } = makeSut() + const request = mockAddTransaction() + await sut.handle(request) + expect(addTransactionUseCaseSpy.addParams).toEqual(request) + }) + + test('should return ok with addTransactionUseCase result', async () => { + const { sut, addTransactionUseCaseSpy } = makeSut() + const response = await sut.handle(mockAddTransaction()) + expect(response).toEqual(ok(addTransactionUseCaseSpy.addResult)) + }) + + describe('should return serverError if addTransactionUseCase throws', () => { + test('should return serverError if addTransactionUseCase throws', async () => { + const { sut, addTransactionUseCaseSpy } = makeSut() + const mockedError = new Error('mocked_error') + vitest + .spyOn(addTransactionUseCaseSpy, 'add') + .mockRejectedValueOnce(mockedError) + const response = await sut.handle(mockAddTransaction()) + expect(response).toEqual(serverError(mockedError)) + }) + }) + }) +}) From c26cd9ecf084cfaa77f34839283df839705dafdd Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 09:31:21 -0300 Subject: [PATCH 085/105] =?UTF-8?q?refactor:=20valida=20se=20os=20usu?= =?UTF-8?q?=C3=A1rios=20existem=20antes=20de=20gerar=20a=20transa=C3=A7?= =?UTF-8?q?=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/data/test/mock-users.ts | 4 +-- .../transactions/db-add-transaction.test.ts | 30 +++++++++++++++++-- .../transactions/db-add-transaction.ts | 17 +++++++++-- .../usecases/users/db-delete-user.test.ts | 2 +- .../users/db-load-users-by-id.test.ts | 2 +- app/src/main/routes/users-routes.spec.ts | 4 +-- .../presentation/errors/not-found-error.ts | 4 +-- 7 files changed, 51 insertions(+), 12 deletions(-) diff --git a/app/src/data/test/mock-users.ts b/app/src/data/test/mock-users.ts index 45635821..cb0fae1c 100644 --- a/app/src/data/test/mock-users.ts +++ b/app/src/data/test/mock-users.ts @@ -41,13 +41,13 @@ export class LoadUsersByEmailRepositorySpy implements LoadUsersByEmailRepository } export class LoadUsersByIdRepositorySpy implements LoadUsersByIdRepository { - loadByIdParams: LoadUsersByIdRepository.Params + loadByIdParams: LoadUsersByIdRepository.Params[] = [] loadByIdResult: LoadUsersByIdRepository.Result constructor() { this.loadByIdResult = mockUser() } async loadById(params: LoadUsersByIdRepository.Params): Promise { - this.loadByIdParams = params + this.loadByIdParams.push(params) return this.loadByIdResult } } diff --git a/app/src/data/usecases/transactions/db-add-transaction.test.ts b/app/src/data/usecases/transactions/db-add-transaction.test.ts index c286df30..c7a0799d 100644 --- a/app/src/data/usecases/transactions/db-add-transaction.test.ts +++ b/app/src/data/usecases/transactions/db-add-transaction.test.ts @@ -1,15 +1,19 @@ import { AddTransactionRepositorySpy } from "@/data/test/mock-transactions"; +import { LoadUsersByIdRepositorySpy } from "@/data/test/mock-users"; import { mockAddTransaction } from "@/domain/tests/mock-transactions"; +import { NotFoundError } from "@/presentation/errors"; import { describe, expect, test, vitest } from "vitest"; import { DbAddTransaction } from "./db-add-transaction"; describe('DbAddTransaction', () => { function makeSut() { const addTransactionRepositorySpy = new AddTransactionRepositorySpy() - const sut = new DbAddTransaction(addTransactionRepositorySpy); + const loadUsersByIdRepository = new LoadUsersByIdRepositorySpy() + const sut = new DbAddTransaction(addTransactionRepositorySpy, loadUsersByIdRepository); return { sut, - addTransactionRepositorySpy + addTransactionRepositorySpy, + loadUsersByIdRepository } } describe('add()', () => { @@ -28,5 +32,27 @@ describe('DbAddTransaction', () => { const promise = sut.add(mockedAddTransaction) await expect(promise).rejects.toThrow(mockedError) }); + + test('should call loadUsersByIdRepository with the user that make the transaction', async () => { + const { sut, loadUsersByIdRepository } = makeSut() + const mockedAddTransaction = mockAddTransaction() + await sut.add(mockedAddTransaction) + expect(loadUsersByIdRepository.loadByIdParams[0]).toEqual({userId: mockedAddTransaction.from}) + }); + + test('should call loadUsersByIdRepository with the user that will receive the transaction', async () => { + const { sut, loadUsersByIdRepository } = makeSut() + const mockedAddTransaction = mockAddTransaction() + await sut.add(mockedAddTransaction) + expect(loadUsersByIdRepository.loadByIdParams[1]).toEqual({userId: mockedAddTransaction.to}) + }); + + test('should throw not found if loadUsersById returns null', async () => { + const { sut, loadUsersByIdRepository } = makeSut() + const mockedAddTransaction = mockAddTransaction() + loadUsersByIdRepository.loadByIdResult = null + const promise = sut.add(mockedAddTransaction) + await expect(promise).rejects.toBeInstanceOf(NotFoundError) + }); }); }); \ No newline at end of file diff --git a/app/src/data/usecases/transactions/db-add-transaction.ts b/app/src/data/usecases/transactions/db-add-transaction.ts index 7caaa758..6e708b15 100644 --- a/app/src/data/usecases/transactions/db-add-transaction.ts +++ b/app/src/data/usecases/transactions/db-add-transaction.ts @@ -1,12 +1,25 @@ import { AddTransactionRepository } from "@/data/protocols/database/transactions/add-transaction-repository" +import { LoadUsersByIdRepository } from "@/data/protocols/database/users" import { AddTransaction } from "@/domain/usecases/transactions" +import { NotFoundError } from "@/presentation/errors" -export class DbAddTransaction { +export class DbAddTransaction implements AddTransaction { constructor ( - private readonly addTransactionRepository: AddTransactionRepository + private readonly addTransactionRepository: AddTransactionRepository, + private readonly loadUsersByIdRepository: LoadUsersByIdRepository ) {} async add (params: AddTransaction.Params): Promise { + const userFromExists = await this.loadUsersByIdRepository.loadById({userId: params.from}) + if (!userFromExists) { + throw new NotFoundError('from', `The user ${params.from} does not exists`) + } + + const userToExists = await this.loadUsersByIdRepository.loadById({userId: params.to}) + if (!userToExists) { + throw new NotFoundError('to', `The user ${params.to} does not exists`) + } + return this.addTransactionRepository.add(params) } } \ No newline at end of file diff --git a/app/src/data/usecases/users/db-delete-user.test.ts b/app/src/data/usecases/users/db-delete-user.test.ts index 3de01bf4..2d02ce53 100644 --- a/app/src/data/usecases/users/db-delete-user.test.ts +++ b/app/src/data/usecases/users/db-delete-user.test.ts @@ -32,7 +32,7 @@ describe('DbDeleteUser', () => { const { sut, loadUsersByIdRepositorySpy } = makeSut() const userId = faker.datatype.number() await sut.delete({ userId }) - expect(loadUsersByIdRepositorySpy.loadByIdParams).toEqual({ userId }) + expect(loadUsersByIdRepositorySpy.loadByIdParams[0]).toEqual({ userId }) }); test('should throw if LoadUsersByIdRepository throws', async () => { diff --git a/app/src/data/usecases/users/db-load-users-by-id.test.ts b/app/src/data/usecases/users/db-load-users-by-id.test.ts index fc856c93..1a4267f4 100644 --- a/app/src/data/usecases/users/db-load-users-by-id.test.ts +++ b/app/src/data/usecases/users/db-load-users-by-id.test.ts @@ -14,7 +14,7 @@ describe('DbLoadUsersById', () => { const { sut, loadUsersByIdRepositorySpy } = makeSut() const userId = faker.datatype.number() await sut.loadById({ userId }) - expect(loadUsersByIdRepositorySpy.loadByIdParams).toEqual({ userId }) + expect(loadUsersByIdRepositorySpy.loadByIdParams[0]).toEqual({ userId }) }) test('should return a user on success', async () => { diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index 5e370edb..01f56a88 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -70,7 +70,7 @@ describe('Users Routes', () => { await request(app) .get('/users/1') .expect(404) - .expect({ error: 'user not found' }) + .expect({ error: 'Not Found: user' }) }) test('should return 200 with the user', async () => { @@ -89,7 +89,7 @@ describe('Users Routes', () => { await request(app) .delete('/users/1') .expect(404) - .expect({ error: 'user not found' }) + .expect({ error: 'Not Found: user' }) }) test('should delete an user according to the id', async () => { diff --git a/app/src/presentation/errors/not-found-error.ts b/app/src/presentation/errors/not-found-error.ts index 61fdee61..a03047e5 100644 --- a/app/src/presentation/errors/not-found-error.ts +++ b/app/src/presentation/errors/not-found-error.ts @@ -1,8 +1,8 @@ import { ClientError } from "./client-error" export class NotFoundError extends ClientError { - constructor (item: string) { - super(`${item} not found`) + constructor (item: string, details?:string) { + super(`Not Found: ${item}`+ (details ? `: ${details}` : '')) this.statusCode = 404 this.name = 'NotFoundError' } From 14ab32b86b3e97b0990369cc0a1b3f6011343529 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 10:52:08 -0300 Subject: [PATCH 086/105] feat: cria migration para o transaction --- ...0221019131316-create-table-transactions.js | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 app/src/infra/database/sequelize/migrations/20221019131316-create-table-transactions.js diff --git a/app/src/infra/database/sequelize/migrations/20221019131316-create-table-transactions.js b/app/src/infra/database/sequelize/migrations/20221019131316-create-table-transactions.js new file mode 100644 index 00000000..5fb06e34 --- /dev/null +++ b/app/src/infra/database/sequelize/migrations/20221019131316-create-table-transactions.js @@ -0,0 +1,66 @@ +'use strict' + +module.exports = { + up: async (queryInterface, Sequelize) => { + return queryInterface.createTable('transactions', { + id: { + type: Sequelize.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + amount: { + type: Sequelize.FLOAT, + allowNull: false, + }, + from: { + type: Sequelize.INTEGER, + allowNull: false, + references: { + model: 'users', + key: 'id', + }, + }, + to: { + type: Sequelize.INTEGER, + allowNull: false, + references: { + model: 'users', + key: 'id', + }, + }, + type: { + type: Sequelize.STRING, + allowNull: false, + }, + chargebackFrom: { + type: Sequelize.INTEGER, + allowNull: true, + }, + createdAt: { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.NOW, + }, + description: { + type: Sequelize.STRING, + allowNull: true, + }, + }).then(function () { + queryInterface.addConstraint('transactions', { + type: 'FOREIGN KEY', + fields: ['chargebackFrom'], + name: 'FK_chargebackFrom_transaction', + references: { + table: 'transactions', + field: 'id' + }, + onDelete: 'cascade', + onUpdate: 'cascade' + }) + }) + }, + + down: async (queryInterface, Sequelize) => { + return queryInterface.dropTable('transactions') + }, +} From 4444334e23f86be4171b681fa6cf493b8e2fda5d Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 10:52:52 -0300 Subject: [PATCH 087/105] feat: cria POST /users/:id/transactions --- .../database/sequelize/models/Transaction.ts | 1 + .../add-transaction-controller-factory.ts | 11 +++++++ .../controllers/transaction/index.ts | 1 + .../user/add-user-controller-factory.ts | 2 +- .../add-transaction-usecase-factory.ts | 11 +++++++ .../factories/usecases/transaction/index.ts | 1 + ...ction-controller-validator-factory.test.ts | 30 +++++++++++++++++++ ...ransaction-controller-validator-factory.ts | 22 ++++++++++++++ .../factories/validators/transaction/index.ts | 1 + .../add-user-controller-validator.test.ts | 0 .../add-user-controller-validator.ts | 0 .../main/factories/validators/users/index.ts | 1 + app/src/main/routes/users-routes.ts | 3 ++ .../field-should-be-validator.test.ts | 25 ++++++++++++++++ .../validators/field-should-be-validator.ts | 16 ++++++++++ 15 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 app/src/main/factories/controllers/transaction/add-transaction-controller-factory.ts create mode 100644 app/src/main/factories/controllers/transaction/index.ts create mode 100644 app/src/main/factories/usecases/transaction/add-transaction-usecase-factory.ts create mode 100644 app/src/main/factories/usecases/transaction/index.ts create mode 100644 app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.test.ts create mode 100644 app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.ts create mode 100644 app/src/main/factories/validators/transaction/index.ts rename app/src/main/factories/validators/{ => users}/add-user-controller-validator.test.ts (100%) rename app/src/main/factories/validators/{ => users}/add-user-controller-validator.ts (100%) create mode 100644 app/src/main/factories/validators/users/index.ts create mode 100644 app/src/validation/validators/field-should-be-validator.test.ts create mode 100644 app/src/validation/validators/field-should-be-validator.ts diff --git a/app/src/infra/database/sequelize/models/Transaction.ts b/app/src/infra/database/sequelize/models/Transaction.ts index f0ca7c6e..f1e93d66 100644 --- a/app/src/infra/database/sequelize/models/Transaction.ts +++ b/app/src/infra/database/sequelize/models/Transaction.ts @@ -70,6 +70,7 @@ TransactionSequelize.init( }, { createdAt: 'createdAt', + updatedAt: false, sequelize: sequelizeConnection, tableName: 'transactions', modelName: 'Transactions', diff --git a/app/src/main/factories/controllers/transaction/add-transaction-controller-factory.ts b/app/src/main/factories/controllers/transaction/add-transaction-controller-factory.ts new file mode 100644 index 00000000..58d00606 --- /dev/null +++ b/app/src/main/factories/controllers/transaction/add-transaction-controller-factory.ts @@ -0,0 +1,11 @@ +import { AddTransactionController } from "@/presentation/controllers/transactions-controllers"; +import { Controller } from "@/presentation/protocols"; +import { makeAddTransactionUseCase } from "../../usecases/transaction"; +import { makeAddTransactionControllerValidator } from "../../validators/transaction/add-transaction-controller-validator-factory"; + +export function makeAddTransactionController(): Controller { + return new AddTransactionController( + makeAddTransactionUseCase(), + makeAddTransactionControllerValidator() + ) +} \ No newline at end of file diff --git a/app/src/main/factories/controllers/transaction/index.ts b/app/src/main/factories/controllers/transaction/index.ts new file mode 100644 index 00000000..c17f6815 --- /dev/null +++ b/app/src/main/factories/controllers/transaction/index.ts @@ -0,0 +1 @@ +export * from './add-transaction-controller-factory' \ No newline at end of file diff --git a/app/src/main/factories/controllers/user/add-user-controller-factory.ts b/app/src/main/factories/controllers/user/add-user-controller-factory.ts index f08e5af3..170ef9bb 100644 --- a/app/src/main/factories/controllers/user/add-user-controller-factory.ts +++ b/app/src/main/factories/controllers/user/add-user-controller-factory.ts @@ -1,7 +1,7 @@ import { AddUserController } from '@/presentation/controllers/users-controller'; import { Controller } from '@/presentation/protocols'; import { makeDbAddUser, makeDbLoadUsersByEmail } from '../../usecases/user'; -import { makeAddUserControllerValidator } from '../../validators/add-user-controller-validator'; +import { makeAddUserControllerValidator } from '../../validators/users/add-user-controller-validator'; export function makeAddUserController(): Controller { diff --git a/app/src/main/factories/usecases/transaction/add-transaction-usecase-factory.ts b/app/src/main/factories/usecases/transaction/add-transaction-usecase-factory.ts new file mode 100644 index 00000000..8f4aece9 --- /dev/null +++ b/app/src/main/factories/usecases/transaction/add-transaction-usecase-factory.ts @@ -0,0 +1,11 @@ +import { DbAddTransaction } from "@/data/usecases/transactions/db-add-transaction"; +import { AddTransaction } from "@/domain/usecases/transactions"; +import { TransactionsMySqlReposiory } from "@/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository"; +import { UsersMySqlReposiory } from "@/infra/database/sequelize/UsersMySqlRepository/users-mysql-repository"; + +export function makeAddTransactionUseCase(): AddTransaction { + return new DbAddTransaction( + new TransactionsMySqlReposiory(), + new UsersMySqlReposiory() + ) +} \ No newline at end of file diff --git a/app/src/main/factories/usecases/transaction/index.ts b/app/src/main/factories/usecases/transaction/index.ts new file mode 100644 index 00000000..0a54e259 --- /dev/null +++ b/app/src/main/factories/usecases/transaction/index.ts @@ -0,0 +1 @@ +export * from './add-transaction-usecase-factory' \ No newline at end of file diff --git a/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.test.ts b/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.test.ts new file mode 100644 index 00000000..1aa0c381 --- /dev/null +++ b/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.test.ts @@ -0,0 +1,30 @@ +import { RequiredFieldValidation, ValidationComposite } from '@/validation/validators' +import { Validation } from '@/presentation/protocols/validation' +import { describe, expect, test, vitest } from 'vitest' +import { makeAddTransactionControllerValidator } from './add-transaction-controller-validator-factory' +import { AddTransactionController } from '@/presentation/controllers/transactions-controllers' +import { FieldShouldBeValidation } from '@/validation/validators/field-should-be-validator' + +vitest.mock('@/validation/validators/validation-composite') + +describe('AddTransactionControllerValidator Factory', () => { + test('Should call ValidationComposite with all validators', () => { + makeAddTransactionControllerValidator() + const validations: Validation[] = [] + const requiredFields = [ + 'amount', + 'type', + 'from', + 'to', + ] + for (const requiredField of requiredFields) { + validations.push(new RequiredFieldValidation(requiredField)) + } + + validations.push(new FieldShouldBeValidation('type', ['credit', 'debit', 'chargeback'])) + + expect(ValidationComposite).toHaveBeenCalledWith([ + ...validations + ]) + }) +}) diff --git a/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.ts b/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.ts new file mode 100644 index 00000000..948d78d4 --- /dev/null +++ b/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.ts @@ -0,0 +1,22 @@ +import { AddTransactionController } from "@/presentation/controllers/transactions-controllers" +import { Validation } from "@/presentation/protocols" +import { RequiredFieldValidation, ValidationComposite } from "@/validation/validators" +import { FieldShouldBeValidation } from "@/validation/validators/field-should-be-validator" + +export function makeAddTransactionControllerValidator(): ValidationComposite { + const validations: Validation[] = [] + const requiredFields = [ + 'amount', + 'type', + 'from', + 'to', + ] + for (const requiredField of requiredFields) { + validations.push(new RequiredFieldValidation(requiredField)) + } + + validations.push(new FieldShouldBeValidation('type', ['credit', 'debit', 'chargeback'])) + + + return new ValidationComposite(validations) +} \ No newline at end of file diff --git a/app/src/main/factories/validators/transaction/index.ts b/app/src/main/factories/validators/transaction/index.ts new file mode 100644 index 00000000..ccc1e5cb --- /dev/null +++ b/app/src/main/factories/validators/transaction/index.ts @@ -0,0 +1 @@ +export * from './add-transaction-controller-validator-factory' \ No newline at end of file diff --git a/app/src/main/factories/validators/add-user-controller-validator.test.ts b/app/src/main/factories/validators/users/add-user-controller-validator.test.ts similarity index 100% rename from app/src/main/factories/validators/add-user-controller-validator.test.ts rename to app/src/main/factories/validators/users/add-user-controller-validator.test.ts diff --git a/app/src/main/factories/validators/add-user-controller-validator.ts b/app/src/main/factories/validators/users/add-user-controller-validator.ts similarity index 100% rename from app/src/main/factories/validators/add-user-controller-validator.ts rename to app/src/main/factories/validators/users/add-user-controller-validator.ts diff --git a/app/src/main/factories/validators/users/index.ts b/app/src/main/factories/validators/users/index.ts new file mode 100644 index 00000000..d6390d52 --- /dev/null +++ b/app/src/main/factories/validators/users/index.ts @@ -0,0 +1 @@ +export * from './add-user-controller-validator' \ No newline at end of file diff --git a/app/src/main/routes/users-routes.ts b/app/src/main/routes/users-routes.ts index 60da71fd..8741c665 100644 --- a/app/src/main/routes/users-routes.ts +++ b/app/src/main/routes/users-routes.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ import { Router } from 'express' import { adaptRoute } from '../adapters/express/express-route-adapter' +import { makeAddTransactionController } from '../factories/controllers/transaction' import { makeAddUserController, makeLoadUsersController } from '../factories/controllers/user' import { makeDeleteUserController } from '../factories/controllers/user/delete-user-controller-factory' import { makeLoadUsersByIdController } from '../factories/controllers/user/load-user-by-id-controller-factory' @@ -10,4 +11,6 @@ export const usersRoutes = (router: Router): void => { router.get('/users/:id', adaptRoute(makeLoadUsersByIdController())) router.post('/users', adaptRoute(makeAddUserController())) router.delete('/users/:id', adaptRoute(makeDeleteUserController())) + + router.post('/users/:from/transactions', adaptRoute(makeAddTransactionController())) } diff --git a/app/src/validation/validators/field-should-be-validator.test.ts b/app/src/validation/validators/field-should-be-validator.test.ts new file mode 100644 index 00000000..31370011 --- /dev/null +++ b/app/src/validation/validators/field-should-be-validator.test.ts @@ -0,0 +1,25 @@ +import { InvalidParamError } from "@/presentation/errors"; +import { describe, expect, test } from "vitest"; +import { FieldShouldBeValidation } from "./field-should-be-validator"; + +describe('FileShouldBeValidation', () => { + describe('validate()', () => { + test('should return InvalidParamError if validation fails', () => { + const sut = new FieldShouldBeValidation('any_field', ['any_value', 'any_other_value']) + const error = sut.validate({ + any_field: 'invalid_value' + }) + + expect(error).toEqual(new InvalidParamError('any_field', 'The value should be any_value or any_other_value')) + }); + + test('should not return if validation succeeds', () => { + const sut = new FieldShouldBeValidation('any_field', ['any_value', 'any_other_value']) + const error = sut.validate({ + any_field: 'any_value' + }) + + expect(error).toBeFalsy() + }) + }); +}); \ No newline at end of file diff --git a/app/src/validation/validators/field-should-be-validator.ts b/app/src/validation/validators/field-should-be-validator.ts new file mode 100644 index 00000000..0f8746d0 --- /dev/null +++ b/app/src/validation/validators/field-should-be-validator.ts @@ -0,0 +1,16 @@ +import { InvalidParamError } from '@/presentation/errors' +import { Validation } from '@/presentation/protocols' + +export class FieldShouldBeValidation implements Validation { + constructor ( + private readonly fieldName: string, + private readonly possibleValues: string[] | number[]) {} + + validate (input: any): Error { + if (!this.possibleValues.includes(input[this.fieldName] as never)) { + // @ts-ignore + const possibleValuesFormatted = new Intl.ListFormat('en-US', { style: 'long', type: 'disjunction' }).format(this.possibleValues) + return new InvalidParamError(this.fieldName, `The value should be ${possibleValuesFormatted}`) + } + } +} From fbb6359c07a40c6c91ca1c44268f3d0b8735a94f Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 10:56:22 -0300 Subject: [PATCH 088/105] refactor: melhora tratamento de erro AddTransactionController --- .../transaction/add-transaction-controller-validator-factory.ts | 2 +- app/src/presentation/errors/invalid-param-error.ts | 2 +- app/src/presentation/errors/not-found-error.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.ts b/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.ts index 948d78d4..5f2f8e2b 100644 --- a/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.ts +++ b/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.ts @@ -15,7 +15,7 @@ export function makeAddTransactionControllerValidator(): ValidationComposite { validations.push(new RequiredFieldValidation(requiredField)) } - validations.push(new FieldShouldBeValidation('type', ['credit', 'debit', 'chargeback'])) + validations.push(new FieldShouldBeValidation('type', ['credit', 'debt', 'chargeback'])) return new ValidationComposite(validations) diff --git a/app/src/presentation/errors/invalid-param-error.ts b/app/src/presentation/errors/invalid-param-error.ts index 2c25a991..80de82cf 100644 --- a/app/src/presentation/errors/invalid-param-error.ts +++ b/app/src/presentation/errors/invalid-param-error.ts @@ -2,7 +2,7 @@ import { ClientError } from "./client-error" export class InvalidParamError extends ClientError { constructor (paramName: string, details?: string) { - super(`Invalid param: ${paramName}`+details?` ${details}`:'') + super(`Invalid param: ${paramName}`+(details?`. ${details}`:'')) this.statusCode = 404 this.name = 'InvalidParamError' } diff --git a/app/src/presentation/errors/not-found-error.ts b/app/src/presentation/errors/not-found-error.ts index a03047e5..b5250972 100644 --- a/app/src/presentation/errors/not-found-error.ts +++ b/app/src/presentation/errors/not-found-error.ts @@ -2,7 +2,7 @@ import { ClientError } from "./client-error" export class NotFoundError extends ClientError { constructor (item: string, details?:string) { - super(`Not Found: ${item}`+ (details ? `: ${details}` : '')) + super(`Not Found: ${item}`+ (details ? `. ${details}` : '')) this.statusCode = 404 this.name = 'NotFoundError' } From cadb8a15622986aa195ef5543f0bbd2fadbf7477 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 11:58:40 -0300 Subject: [PATCH 089/105] feat: implementa LoadTransactionByUser --- .../load-transaction-by-user-repository.ts | 13 +++++ .../db-load-transaction-by-user.test.ts | 53 +++++++++++++++++++ .../db-load-transaction-by-user.ts | 15 ++++++ app/src/domain/usecases/pagination.ts | 14 +++++ app/src/domain/usecases/transactions/index.ts | 3 +- .../transactions/load-transactions-by-user.ts | 14 +++++ 6 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 app/src/data/protocols/database/transactions/load-transaction-by-user-repository.ts create mode 100644 app/src/data/usecases/transactions/db-load-transaction-by-user.test.ts create mode 100644 app/src/data/usecases/transactions/db-load-transaction-by-user.ts create mode 100644 app/src/domain/usecases/pagination.ts create mode 100644 app/src/domain/usecases/transactions/load-transactions-by-user.ts diff --git a/app/src/data/protocols/database/transactions/load-transaction-by-user-repository.ts b/app/src/data/protocols/database/transactions/load-transaction-by-user-repository.ts new file mode 100644 index 00000000..51664e43 --- /dev/null +++ b/app/src/data/protocols/database/transactions/load-transaction-by-user-repository.ts @@ -0,0 +1,13 @@ +import { LoadTransactionByUser } from '@/domain/usecases/transactions' + +export interface LoadTransactionByUserRepository { + loadByUser: ( + params: LoadTransactionByUserRepository.Params + ) => Promise +} + +export namespace LoadTransactionByUserRepository { + export type Params = LoadTransactionByUser.Params + + export type Result = LoadTransactionByUser.Result +} diff --git a/app/src/data/usecases/transactions/db-load-transaction-by-user.test.ts b/app/src/data/usecases/transactions/db-load-transaction-by-user.test.ts new file mode 100644 index 00000000..c9e99e8f --- /dev/null +++ b/app/src/data/usecases/transactions/db-load-transaction-by-user.test.ts @@ -0,0 +1,53 @@ +import { LoadTransactionByUserRepositorySpy } from "@/data/test/mock-transactions"; +import { faker } from "@faker-js/faker"; +import { describe, expect, test, vitest } from "vitest"; +import { DbLoadTransactionByUser } from "./db-load-transaction-by-user"; + +describe('DbLoadTransactionByUser', () => { + function makeSut() { + const loadTransactionByUserRepositorySpy = new LoadTransactionByUserRepositorySpy() + const sut = new DbLoadTransactionByUser( + loadTransactionByUserRepositorySpy + ) + + return { + sut, + loadTransactionByUserRepositorySpy + } + } + describe('lodByUser()', () => { + test('should call loadTransactionByUserRepository with correct params', async () => { + const { sut, loadTransactionByUserRepositorySpy } = makeSut() + const params = { + userId: faker.datatype.number(), + page: faker.datatype.number(), + perPage: faker.datatype.number() + } + + await sut.loadByUser(params) + expect(loadTransactionByUserRepositorySpy.loadByUserParams).toEqual(params) + }); + + test('should return user\'s transaction paginated', async () => { + const { sut, loadTransactionByUserRepositorySpy } = makeSut() + const result = await sut.loadByUser({ + userId: faker.datatype.number(), + page: faker.datatype.number(), + perPage: faker.datatype.number() + }) + expect(result).toEqual(loadTransactionByUserRepositorySpy.loadByUserResult) + }); + + test('should throw if loadTransactionByUserRepository throws', async () => { + const { sut, loadTransactionByUserRepositorySpy } = makeSut() + const mockedError = new Error('some_error') + vitest.spyOn(loadTransactionByUserRepositorySpy, 'loadByUser').mockRejectedValueOnce(mockedError) + const promise = sut.loadByUser({ + userId: faker.datatype.number(), + page: faker.datatype.number(), + perPage: faker.datatype.number() + }) + await expect(promise).rejects.toThrow(mockedError) + }); + }); +}); \ No newline at end of file diff --git a/app/src/data/usecases/transactions/db-load-transaction-by-user.ts b/app/src/data/usecases/transactions/db-load-transaction-by-user.ts new file mode 100644 index 00000000..a00f3e96 --- /dev/null +++ b/app/src/data/usecases/transactions/db-load-transaction-by-user.ts @@ -0,0 +1,15 @@ +import { LoadTransactionByUserRepository } from '@/data/protocols/database/transactions/load-transaction-by-user-repository' +import { LoadTransactionByUser } from '@/domain/usecases/transactions' + +export class DbLoadTransactionByUser implements LoadTransactionByUser { + constructor( + private readonly loadTransactionByUserRepository: LoadTransactionByUserRepository + ) {} + + async loadByUser( + params: LoadTransactionByUser.Params + ): Promise { + const usersTransactions = await this.loadTransactionByUserRepository.loadByUser(params) + return usersTransactions + } +} diff --git a/app/src/domain/usecases/pagination.ts b/app/src/domain/usecases/pagination.ts new file mode 100644 index 00000000..38eefe38 --- /dev/null +++ b/app/src/domain/usecases/pagination.ts @@ -0,0 +1,14 @@ +export type GetPaginatedParams = { + page: number; + perPage: number; +} + +export type Paginated = { + data: T[]; + pagination: { + page: number; + perPage: number; + total: number; + totalPages: number; + } +} \ No newline at end of file diff --git a/app/src/domain/usecases/transactions/index.ts b/app/src/domain/usecases/transactions/index.ts index f90c592b..8817f983 100644 --- a/app/src/domain/usecases/transactions/index.ts +++ b/app/src/domain/usecases/transactions/index.ts @@ -1 +1,2 @@ -export * from './add-transaction' \ No newline at end of file +export * from './add-transaction' +export * from './load-transactions-by-user' \ No newline at end of file diff --git a/app/src/domain/usecases/transactions/load-transactions-by-user.ts b/app/src/domain/usecases/transactions/load-transactions-by-user.ts new file mode 100644 index 00000000..59bc04d1 --- /dev/null +++ b/app/src/domain/usecases/transactions/load-transactions-by-user.ts @@ -0,0 +1,14 @@ +import { Transaction } from "@/domain/models"; +import { GetPaginatedParams, Paginated } from "../pagination"; + +export interface LoadTransactionByUser { + loadByUser: (params: LoadTransactionByUser.Params) => Promise +} + +export namespace LoadTransactionByUser { + export type Params = { + userId: number; + }&GetPaginatedParams; + + export type Result = Paginated; +} \ No newline at end of file From 0b6e9cc40d9938ee4262826e3c2c5249544586f6 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 11:58:43 -0300 Subject: [PATCH 090/105] test: implementa LoadTransactionByUser --- app/src/data/test/mock-transactions.ts | 23 +++++++++++++++++++ ...ction-controller-validator-factory.test.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/src/data/test/mock-transactions.ts b/app/src/data/test/mock-transactions.ts index 33b11e51..5306f73a 100644 --- a/app/src/data/test/mock-transactions.ts +++ b/app/src/data/test/mock-transactions.ts @@ -1,5 +1,7 @@ import { mockTransaction } from '@/domain/tests/mock-transactions' +import { faker } from '@faker-js/faker' import { AddTransactionRepository } from '../protocols/database/transactions/add-transaction-repository' +import { LoadTransactionByUserRepository } from '../protocols/database/transactions/load-transaction-by-user-repository' export class AddTransactionRepositorySpy implements AddTransactionRepository { addParams: AddTransactionRepository.Params @@ -14,3 +16,24 @@ export class AddTransactionRepositorySpy implements AddTransactionRepository { return Promise.resolve(this.addResult) } } + + +export class LoadTransactionByUserRepositorySpy implements LoadTransactionByUserRepository { + loadByUserParams: LoadTransactionByUserRepository.Params + loadByUserResult: LoadTransactionByUserRepository.Result + constructor() { + this.loadByUserResult = { + data: [mockTransaction()], + pagination: { + page: faker.datatype.number(), + perPage: faker.datatype.number(), + total: faker.datatype.number(), + totalPages: faker.datatype.number() + } + } + } + async loadByUser(params: LoadTransactionByUserRepository.Params): Promise { + this.loadByUserParams = params + return this.loadByUserResult + } +} \ No newline at end of file diff --git a/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.test.ts b/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.test.ts index 1aa0c381..36476b66 100644 --- a/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.test.ts +++ b/app/src/main/factories/validators/transaction/add-transaction-controller-validator-factory.test.ts @@ -21,7 +21,7 @@ describe('AddTransactionControllerValidator Factory', () => { validations.push(new RequiredFieldValidation(requiredField)) } - validations.push(new FieldShouldBeValidation('type', ['credit', 'debit', 'chargeback'])) + validations.push(new FieldShouldBeValidation('type', ['credit', 'debt', 'chargeback'])) expect(ValidationComposite).toHaveBeenCalledWith([ ...validations From bb0174b6c4a84c47cb3335de6cc7841f4f61aa1a Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 12:38:32 -0300 Subject: [PATCH 091/105] feat: implementa loadByUser na TransactionMySqlRepository --- .../transactions-mysql.repository.ts | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts index 51cde2f2..65d4e53e 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts @@ -1,9 +1,11 @@ import { AddTransactionRepository } from '@/data/protocols/database/transactions/add-transaction-repository' +import { LoadTransactionByUserRepository } from '@/data/protocols/database/transactions/load-transaction-by-user-repository' +import { Op } from 'sequelize' import TransactionSequelize, { TransactionModelSequelize, } from '../models/Transaction' -export class TransactionsMySqlReposiory implements AddTransactionRepository { +export class TransactionsMySqlReposiory implements AddTransactionRepository, LoadTransactionByUserRepository { async add( transaction: AddTransactionRepository.Params ): Promise { @@ -38,4 +40,36 @@ export class TransactionsMySqlReposiory implements AddTransactionRepository { return newTransaction } + + async loadByUser(params: LoadTransactionByUserRepository.Params): Promise { + const { page, perPage, userId } = params + const offset = (page - 1) * perPage + + const transactions = await TransactionSequelize.findAndCountAll({ + where: { + [Op.or]: { + from: userId, + to: userId, + } + }, + offset, + limit: perPage, + include: { + all: true, + } + }) + + const data = transactions.rows.map(transaction => this.formatTransaction(transaction.toJSON())) + const pagination = { + page, + perPage, + total: transactions.count, + totalPages: Math.ceil(transactions.count / perPage) + } + + return { + data, + pagination + } + } } From e258577e1b67cec3c7a685085b4516c06a170ef2 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 12:38:35 -0300 Subject: [PATCH 092/105] test: implementa loadByUser na TransactionMySqlRepository --- .../transactions-mysql.repository.test.ts | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts index 05c81e51..a6665f6b 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts @@ -107,4 +107,99 @@ describe('TransactionsMySqlRepository', () => { expect(transactionExists.toJSON().id).toBe(transaction.id) }) }) + + describe('loadByUser()', () => { + test('should return an empty array with the pagination if no transactions are found', async () => { + const sut = makeSut() + const user = await makeUser() + const transactions = await sut.loadByUser({ + userId: user.id, + page: 1, + perPage: 10, + }) + expect(transactions).toEqual({ + data: [], + pagination: { + page: 1, + perPage: 10, + total: 0, + totalPages: 0, + } + }) + }) + + test('should return valid pagination if transactions was found', async () => { + const sut = makeSut() + const userOne = await makeUser() + const userTwo = await makeUser() + const transactionOne = mockAddTransaction() + transactionOne.to = userOne.id + transactionOne.from = userTwo.id + const transactionTwo = mockAddTransaction() + transactionTwo.to = userOne.id + transactionTwo.from = userTwo.id + const transactionThree = mockAddTransaction() + transactionThree.from = userOne.id + transactionThree.to = userTwo.id + + const [transactionOneInserted] =await TransactionSequelize.bulkCreate([ + transactionOne, + transactionTwo, + transactionThree, + ]) + const transactionsOfUserOne = await sut.loadByUser({ + userId: userOne.id, + page: 1, + perPage: 10, + }) + + expect(transactionsOfUserOne.pagination).toEqual({ + page: 1, + perPage: 10, + total: 3, + totalPages: 1, + }) + + expect(transactionsOfUserOne.data[0].id).toBe(transactionOneInserted.getDataValue('id')) + expect(transactionsOfUserOne.data[0].to.id).toEqual(userOne.id) + expect(transactionsOfUserOne.data[0].from.id).toEqual(userTwo.id) + }); + + test('should change the page correctly', async () => { + const sut = makeSut() + const userOne = await makeUser() + const userTwo = await makeUser() + const transactionOne = mockAddTransaction() + transactionOne.to = userOne.id + transactionOne.from = userTwo.id + const transactionTwo = mockAddTransaction() + transactionTwo.to = userOne.id + transactionTwo.from = userTwo.id + const transactionThree = mockAddTransaction() + transactionThree.from = userOne.id + transactionThree.to = userTwo.id + + const [_,transactionTwoInserted] =await TransactionSequelize.bulkCreate([ + transactionOne, + transactionTwo, + transactionThree, + ]) + const transactionsOfUserOne = await sut.loadByUser({ + userId: userOne.id, + page: 2, + perPage: 1, + }) + + expect(transactionsOfUserOne.pagination).toEqual({ + page: 2, + perPage: 1, + total: 3, + totalPages: 3, + }) + + expect(transactionsOfUserOne.data[0].id).toBe(transactionTwoInserted.getDataValue('id')) + expect(transactionsOfUserOne.data[0].to.id).toEqual(userOne.id) + expect(transactionsOfUserOne.data[0].from.id).toEqual(userTwo.id) + }); + }); }) From d1014b31492d459edef35fcdfa968be26021fd36 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 23:23:39 -0300 Subject: [PATCH 093/105] feat: cria LoadTransactionsByUser --- .../load-transactions-by-user-controller.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.ts diff --git a/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.ts b/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.ts new file mode 100644 index 00000000..463b7d36 --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.ts @@ -0,0 +1,30 @@ +import { LoadTransactionByUser } from '@/domain/usecases/transactions' +import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' +import { Controller, HttpResponse, Validation } from '@/presentation/protocols' + +export class LoadTransactionByUserController implements Controller { + constructor( + private readonly loadTransactionByUserUseCase: LoadTransactionByUser, + private readonly validation: Validation + ) {} + async handle( + params: LoadTransactionByUserController.Request + ): Promise { + try { + const error = this.validation.validate(params) + if (error) { + return badRequest(error) + } + + const result = await this.loadTransactionByUserUseCase.loadByUser(params) + return ok(result) + } catch (error) { + return serverError(error) + } + } +} + +export namespace LoadTransactionByUserController { + export type Request = LoadTransactionByUser.Params + export type Response = HttpResponse +} From dc98dc4dcaee82f9c2002c1ef2445ed4d836c2f9 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Wed, 19 Oct 2022 23:23:57 -0300 Subject: [PATCH 094/105] test: cria LoadTransactionsByUser --- app/src/domain/tests/mock-pagination.ts | 14 +++ app/src/domain/tests/mock-transactions.ts | 15 +++- ...ad-transactions-by-user-controller.test.ts | 89 +++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 app/src/domain/tests/mock-pagination.ts create mode 100644 app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.test.ts diff --git a/app/src/domain/tests/mock-pagination.ts b/app/src/domain/tests/mock-pagination.ts new file mode 100644 index 00000000..678e0751 --- /dev/null +++ b/app/src/domain/tests/mock-pagination.ts @@ -0,0 +1,14 @@ +import { faker } from "@faker-js/faker"; +import { Paginated } from "../usecases/pagination"; + +export function mockPagination(data:T[]):Paginated { + return { + data, + pagination: { + page: faker.datatype.number(), + perPage: faker.datatype.number(), + total: faker.datatype.number(), + totalPages: faker.datatype.number(), + } + } +} \ No newline at end of file diff --git a/app/src/domain/tests/mock-transactions.ts b/app/src/domain/tests/mock-transactions.ts index 09fffba6..ce0b6b7a 100644 --- a/app/src/domain/tests/mock-transactions.ts +++ b/app/src/domain/tests/mock-transactions.ts @@ -1,6 +1,7 @@ import { faker } from "@faker-js/faker"; import { AddTransactionModel, Transaction } from "../models"; -import { AddTransaction } from "../usecases/transactions"; +import { AddTransaction, LoadTransactionByUser } from "../usecases/transactions"; +import { mockPagination } from "./mock-pagination"; import { mockUser } from "./mock-users"; export function mockTransaction(): Transaction { @@ -37,4 +38,16 @@ export class AddTransactionSpy implements AddTransaction { this.addParams = params return new Promise((resolve) => resolve(this.addResult)) } +} + +export class LoadTransactionByUserSpy implements LoadTransactionByUser { + loadByUserResult: LoadTransactionByUser.Result + loadByUserParams: LoadTransactionByUser.Params + constructor() { + this.loadByUserResult = mockPagination([mockTransaction()]) + } + async loadByUser(params: LoadTransactionByUser.Params): Promise { + this.loadByUserParams = params + return new Promise((resolve) => resolve(this.loadByUserResult)) + } } \ No newline at end of file diff --git a/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.test.ts b/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.test.ts new file mode 100644 index 00000000..bf3261bf --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.test.ts @@ -0,0 +1,89 @@ +import { LoadTransactionByUserSpy } from "@/domain/tests/mock-transactions"; +import { badRequest, ok, serverError } from "@/presentation/helpers/http-helper"; +import { ValidationSpy } from "@/validation/test/mock-validation"; +import { faker } from "@faker-js/faker"; +import { describe, expect, test, vitest } from "vitest"; +import { LoadTransactionByUserController } from "./load-transactions-by-user-controller"; + +describe('LoadTransactionByUserController', () => { + function makeSut() { + const loadTransactionByUserSpy = new LoadTransactionByUserSpy() + const validationSpy = new ValidationSpy(); + const sut = new LoadTransactionByUserController( + loadTransactionByUserSpy, + validationSpy + ) + + return { + sut, + loadTransactionByUserSpy, + validationSpy + } + } + describe('handle()', () => { + test('should call validation with correct params', async () => { + const { sut, validationSpy } = makeSut() + const request = { + page: faker.datatype.number(), + perPage: faker.datatype.number(), + userId: faker.datatype.number() + } + + await sut.handle(request) + expect(validationSpy.input).toEqual(request) + }) + + test('should return badRequest if validation returns an error', async () => { + const { sut, validationSpy } = makeSut() + const error = new Error('any_error') + validationSpy.error = error + const request = { + page: faker.datatype.number(), + perPage: faker.datatype.number(), + userId: faker.datatype.number() + } + + const response = await sut.handle(request) + expect (response).toEqual(badRequest(error)) + }) + + test('should return serverError if validation throws', async () => { + const { sut, validationSpy } = makeSut() + vitest.spyOn(validationSpy, 'validate').mockImplementationOnce(() => { + throw new Error('any_error') + }) + const request = { + page: faker.datatype.number(), + perPage: faker.datatype.number(), + userId: faker.datatype.number() + } + + const response = await sut.handle(request) + expect(response).toEqual(serverError(new Error('any_error'))) + }) + + test('should call loadTransactionByUserUseCase with correct params', async () => { + const { sut, loadTransactionByUserSpy } = makeSut() + const request = { + page: faker.datatype.number(), + perPage: faker.datatype.number(), + userId: faker.datatype.number() + } + + await sut.handle(request) + expect(loadTransactionByUserSpy.loadByUserParams).toEqual(request) + }); + + test('should return ok with loadTransactionByUserUseCase result', async () => { + const { sut, loadTransactionByUserSpy } = makeSut() + const request = { + page: faker.datatype.number(), + perPage: faker.datatype.number(), + userId: faker.datatype.number() + } + + const result = await sut.handle(request) + expect(result).toEqual(ok(loadTransactionByUserSpy.loadByUserResult)) + }); + }); +}); \ No newline at end of file From 30defa733de14f9063231a6509dd9e4eaf1f4d06 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 00:04:23 -0300 Subject: [PATCH 095/105] feat: implementa LoadTransaction --- .../main/factories/controllers/transaction/index.ts | 3 ++- .../load-transactions-by-user-controller-factory.ts | 11 +++++++++++ app/src/main/factories/usecases/transaction/index.ts | 3 ++- .../load-transactions-by-user-usecase-factory.ts | 9 +++++++++ .../main/factories/validators/transaction/index.ts | 3 ++- ...ansactions-by-user-controller-validator-factory.ts | 10 ++++++++++ app/src/main/routes/users-routes.ts | 3 ++- app/src/presentation/errors/missing-param-error.ts | 2 +- 8 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 app/src/main/factories/controllers/transaction/load-transactions-by-user-controller-factory.ts create mode 100644 app/src/main/factories/usecases/transaction/load-transactions-by-user-usecase-factory.ts create mode 100644 app/src/main/factories/validators/transaction/load-transactions-by-user-controller-validator-factory.ts diff --git a/app/src/main/factories/controllers/transaction/index.ts b/app/src/main/factories/controllers/transaction/index.ts index c17f6815..3325b4d4 100644 --- a/app/src/main/factories/controllers/transaction/index.ts +++ b/app/src/main/factories/controllers/transaction/index.ts @@ -1 +1,2 @@ -export * from './add-transaction-controller-factory' \ No newline at end of file +export * from './add-transaction-controller-factory' +export * from './load-transactions-by-user-controller-factory' \ No newline at end of file diff --git a/app/src/main/factories/controllers/transaction/load-transactions-by-user-controller-factory.ts b/app/src/main/factories/controllers/transaction/load-transactions-by-user-controller-factory.ts new file mode 100644 index 00000000..43ffdd75 --- /dev/null +++ b/app/src/main/factories/controllers/transaction/load-transactions-by-user-controller-factory.ts @@ -0,0 +1,11 @@ +import { LoadTransactionByUserController } from "@/presentation/controllers/transactions-controllers/load-transactions-by-user-controller" +import { Controller } from "@/presentation/protocols" +import { makeLoadTransactionsByUserUseCase } from "../../usecases/transaction/load-transactions-by-user-usecase-factory" +import { makeLoadTransactionsByUserControllerValidator } from "../../validators/transaction" + +export function makeLoadTransactionsByUserController(): Controller { + const loadTransactionByUserUseCase = makeLoadTransactionsByUserUseCase() + const validation = makeLoadTransactionsByUserControllerValidator() + + return new LoadTransactionByUserController(loadTransactionByUserUseCase, validation) +} \ No newline at end of file diff --git a/app/src/main/factories/usecases/transaction/index.ts b/app/src/main/factories/usecases/transaction/index.ts index 0a54e259..cc848c74 100644 --- a/app/src/main/factories/usecases/transaction/index.ts +++ b/app/src/main/factories/usecases/transaction/index.ts @@ -1 +1,2 @@ -export * from './add-transaction-usecase-factory' \ No newline at end of file +export * from './add-transaction-usecase-factory' +export * from './load-transactions-by-user-usecase-factory' \ No newline at end of file diff --git a/app/src/main/factories/usecases/transaction/load-transactions-by-user-usecase-factory.ts b/app/src/main/factories/usecases/transaction/load-transactions-by-user-usecase-factory.ts new file mode 100644 index 00000000..965e482e --- /dev/null +++ b/app/src/main/factories/usecases/transaction/load-transactions-by-user-usecase-factory.ts @@ -0,0 +1,9 @@ +import { DbLoadTransactionByUser } from "@/data/usecases/transactions/db-load-transaction-by-user"; +import { LoadTransactionByUser } from "@/domain/usecases/transactions"; +import { TransactionsMySqlReposiory } from "@/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository"; + +export function makeLoadTransactionsByUserUseCase(): LoadTransactionByUser { + return new DbLoadTransactionByUser( + new TransactionsMySqlReposiory(), + ) +} \ No newline at end of file diff --git a/app/src/main/factories/validators/transaction/index.ts b/app/src/main/factories/validators/transaction/index.ts index ccc1e5cb..cffb5e6f 100644 --- a/app/src/main/factories/validators/transaction/index.ts +++ b/app/src/main/factories/validators/transaction/index.ts @@ -1 +1,2 @@ -export * from './add-transaction-controller-validator-factory' \ No newline at end of file +export * from './add-transaction-controller-validator-factory' +export * from './load-transactions-by-user-controller-validator-factory' \ No newline at end of file diff --git a/app/src/main/factories/validators/transaction/load-transactions-by-user-controller-validator-factory.ts b/app/src/main/factories/validators/transaction/load-transactions-by-user-controller-validator-factory.ts new file mode 100644 index 00000000..cde6cec3 --- /dev/null +++ b/app/src/main/factories/validators/transaction/load-transactions-by-user-controller-validator-factory.ts @@ -0,0 +1,10 @@ +import { Validation } from "@/presentation/protocols"; +import { RequiredFieldValidation, ValidationComposite } from "@/validation/validators"; + +export function makeLoadTransactionsByUserControllerValidator(): Validation { + return new ValidationComposite([ + new RequiredFieldValidation('page'), + new RequiredFieldValidation('perPage'), + new RequiredFieldValidation('userId'), + ]) +} \ No newline at end of file diff --git a/app/src/main/routes/users-routes.ts b/app/src/main/routes/users-routes.ts index 8741c665..85848e4e 100644 --- a/app/src/main/routes/users-routes.ts +++ b/app/src/main/routes/users-routes.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ import { Router } from 'express' import { adaptRoute } from '../adapters/express/express-route-adapter' -import { makeAddTransactionController } from '../factories/controllers/transaction' +import { makeAddTransactionController, makeLoadTransactionsByUserController } from '../factories/controllers/transaction' import { makeAddUserController, makeLoadUsersController } from '../factories/controllers/user' import { makeDeleteUserController } from '../factories/controllers/user/delete-user-controller-factory' import { makeLoadUsersByIdController } from '../factories/controllers/user/load-user-by-id-controller-factory' @@ -12,5 +12,6 @@ export const usersRoutes = (router: Router): void => { router.post('/users', adaptRoute(makeAddUserController())) router.delete('/users/:id', adaptRoute(makeDeleteUserController())) + router.get('/users/:id/transactions', adaptRoute(makeLoadTransactionsByUserController())) router.post('/users/:from/transactions', adaptRoute(makeAddTransactionController())) } diff --git a/app/src/presentation/errors/missing-param-error.ts b/app/src/presentation/errors/missing-param-error.ts index 057729e2..314c66f1 100644 --- a/app/src/presentation/errors/missing-param-error.ts +++ b/app/src/presentation/errors/missing-param-error.ts @@ -3,7 +3,7 @@ import { ClientError } from "./client-error" export class MissingParamError extends ClientError { constructor (paramName: string) { super(`Missing param: ${paramName}`) - this.statusCode = 404 + this.statusCode = 400 this.name = 'MissingParamError' } } \ No newline at end of file From 93e99e8aa9929e6c2e6a11ef7bbc37f527986952 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 00:06:03 -0300 Subject: [PATCH 096/105] test: implementa LoadTransactionsByUser --- ...-user-controller-validator-factory.test.ts | 23 +++ app/src/main/routes/users-routes.spec.ts | 136 +++++++++++++++++- 2 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 app/src/main/factories/validators/transaction/load-transactions-by-user-controller-validator-factory.test.ts diff --git a/app/src/main/factories/validators/transaction/load-transactions-by-user-controller-validator-factory.test.ts b/app/src/main/factories/validators/transaction/load-transactions-by-user-controller-validator-factory.test.ts new file mode 100644 index 00000000..204b3883 --- /dev/null +++ b/app/src/main/factories/validators/transaction/load-transactions-by-user-controller-validator-factory.test.ts @@ -0,0 +1,23 @@ +import { RequiredFieldValidation, ValidationComposite } from '@/validation/validators' +import { Validation } from '@/presentation/protocols/validation' +import { describe, expect, test, vitest } from 'vitest' +import { makeLoadTransactionsByUserControllerValidator } from './load-transactions-by-user-controller-validator-factory' +import { AddTransactionController } from '@/presentation/controllers/transactions-controllers' + +vitest.mock('@/validation/validators/validation-composite') + +describe('AddTransactionControllerValidator Factory', () => { + test('Should call ValidationComposite with all validators', () => { + makeLoadTransactionsByUserControllerValidator() + const validations: Validation[] = [ + new RequiredFieldValidation('page'), + new RequiredFieldValidation('perPage'), + new RequiredFieldValidation('userId'), + ] + + + expect(ValidationComposite).toHaveBeenCalledWith([ + ...validations + ]) + }) +}) diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index 01f56a88..b0b3cd48 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -5,6 +5,9 @@ import request from 'supertest' import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' import app from '../config/app' import MockDate from 'mockdate' +import { faker } from '@faker-js/faker' +import TransactionSequelize from '@/infra/database/sequelize/models/Transaction' +import { mockAddTransaction } from '@/domain/tests/mock-transactions' describe('Users Routes', () => { beforeAll(async () => { @@ -18,6 +21,12 @@ describe('Users Routes', () => { afterAll(async () => { await truncate() }) + + async function makeUser() { + const user = mockAddUser() + const createdUser = await UsersSequelize.create(user) + return createdUser.toJSON() + } describe('POST /users', () => { test('should return 200 with a valid user', async () => { const body = mockAddUser() @@ -84,7 +93,7 @@ describe('Users Routes', () => { }) }) - describe('Delete /users/{id}', () => { + describe('DELETE /users/{id}', () => { test('should return 404 if the user does not exits', async () => { await request(app) .delete('/users/1') @@ -98,6 +107,129 @@ describe('Users Routes', () => { await request(app).delete(`/users/${id}`).expect(204) const usersExists = await UsersSequelize.findOne({ where: { id } }) expect(usersExists).toBeFalsy() - }); + }) + }) + + describe('POST /users/{id}/transactions', () => { + test('should create an transaction from an user to other', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + + const id = userFrom.getDataValue('id') + const body = { + amount: faker.datatype.number(), + description: faker.lorem.sentence(), + to: userTo.getDataValue('id'), + type: 'credit', + } + const res = await request(app) + .post(`/users/${id}/transactions`) + .send(body) + + expect(res.body.id).toBeTruthy() + const transaction = await TransactionSequelize.findOne({ + where: { id: res.body.id }, + }) + expect(transaction).toBeTruthy() + }) + + test('should return an transaction from an user to other', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + + const id = userFrom.getDataValue('id') + const body = { + amount: faker.datatype.number(), + description: faker.lorem.sentence(), + to: userTo.getDataValue('id'), + type: 'credit', + } + const res = await request(app) + .post(`/users/${id}/transactions`) + .send(body) + + expect(res.statusCode).toBe(200) + expect(res.body.amount).toBe(body.amount) + expect(res.body.description).toBe(body.description) + expect(res.body.to.id).toBe(body.to) + expect(res.body.type).toBe(body.type) + expect(res.body.from.id).toBe(id) + }) + }) + + describe('GET /users/{id}/transactions', () => { + test('should return the users transactions paginated', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + const transactions = await TransactionSequelize.bulkCreate( + [ + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + ].map(transaction => ({ ...transaction, from: idFrom, to: idTo })) + ) + + const res = await request(app) + .get(`/users/${idFrom}/transactions`) + .query({ page: 1, perPage: 3, userId: idTo }) + + expect(res.body.pagination).toEqual({ + page: '1', + perPage: '3', + total: 6, + totalPages: 2, + }) + }) + + test('should return the users transactions according to the page', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + const transactions = await TransactionSequelize.bulkCreate( + [ + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + ].map(transaction => ({ ...transaction, from: idFrom, to: idTo })) + ) + + const res = await request(app) + .get(`/users/${idFrom}/transactions`) + .query({ page: 1, perPage: 3, userId: idTo }) + + expect(res.body.data[0].id).toBe(transactions[0].getDataValue('id')) + }) + + test('should return the users transactions according to the page', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + const transactions = await TransactionSequelize.bulkCreate( + [ + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + ].map(transaction => ({ ...transaction, from: idFrom, to: idTo })) + ) + + const res = await request(app) + .get(`/users/${idFrom}/transactions`) + .query({ page: 2, perPage: 3, userId: idTo }) + + expect(res.body.data[0].id).toBe(transactions[3].getDataValue('id')) + }) }) }) From ce2b3899d36f927398939e1b52a21faf551bc99e Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 00:12:51 -0300 Subject: [PATCH 097/105] =?UTF-8?q?fix:=20arruma=20coers=C3=A3o=20de=20tip?= =?UTF-8?q?os?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/routes/users-routes.ts | 2 +- .../load-transactions-by-user-controller.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/routes/users-routes.ts b/app/src/main/routes/users-routes.ts index 85848e4e..b1fd75c8 100644 --- a/app/src/main/routes/users-routes.ts +++ b/app/src/main/routes/users-routes.ts @@ -12,6 +12,6 @@ export const usersRoutes = (router: Router): void => { router.post('/users', adaptRoute(makeAddUserController())) router.delete('/users/:id', adaptRoute(makeDeleteUserController())) - router.get('/users/:id/transactions', adaptRoute(makeLoadTransactionsByUserController())) + router.get('/users/:userId/transactions', adaptRoute(makeLoadTransactionsByUserController())) router.post('/users/:from/transactions', adaptRoute(makeAddTransactionController())) } diff --git a/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.ts b/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.ts index 463b7d36..f880903b 100644 --- a/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.ts +++ b/app/src/presentation/controllers/transactions-controllers/load-transactions-by-user-controller.ts @@ -16,7 +16,11 @@ export class LoadTransactionByUserController implements Controller { return badRequest(error) } - const result = await this.loadTransactionByUserUseCase.loadByUser(params) + const result = await this.loadTransactionByUserUseCase.loadByUser({ + page: parseInt(params.page.toString()), + perPage: parseInt(params.perPage.toString()), + userId: params.userId, + }) return ok(result) } catch (error) { return serverError(error) From 122dc98746265619d184b94ad5a2c19a89dfa9b2 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 00:25:24 -0300 Subject: [PATCH 098/105] refactor: adiciona rotas isoladas para /transactions --- app/src/main/config/routes.ts | 3 +- app/src/main/routes/index.ts | 3 +- .../main/routes/transactions-routes.spec.ts | 149 ++++++++++++++++++ app/src/main/routes/transactions-routes.ts | 10 ++ app/src/main/routes/users-routes.spec.ts | 6 +- 5 files changed, 166 insertions(+), 5 deletions(-) create mode 100644 app/src/main/routes/transactions-routes.spec.ts create mode 100644 app/src/main/routes/transactions-routes.ts diff --git a/app/src/main/config/routes.ts b/app/src/main/config/routes.ts index 30413217..4db7c737 100644 --- a/app/src/main/config/routes.ts +++ b/app/src/main/config/routes.ts @@ -1,8 +1,9 @@ import { Express, Router } from 'express' -import {usersRoutes} from '../routes/users-routes' +import { transactionsRoutes, usersRoutes } from '../routes' export function setupRoutes(app: Express) { const router = Router() usersRoutes(router) + transactionsRoutes(router) app.use(router) } \ No newline at end of file diff --git a/app/src/main/routes/index.ts b/app/src/main/routes/index.ts index 777eedad..5f957d09 100644 --- a/app/src/main/routes/index.ts +++ b/app/src/main/routes/index.ts @@ -1 +1,2 @@ -export * from './users-routes' \ No newline at end of file +export * from './users-routes' +export * from './transactions-routes' \ No newline at end of file diff --git a/app/src/main/routes/transactions-routes.spec.ts b/app/src/main/routes/transactions-routes.spec.ts new file mode 100644 index 00000000..9fa97b4d --- /dev/null +++ b/app/src/main/routes/transactions-routes.spec.ts @@ -0,0 +1,149 @@ +import { mockAddUser } from '@/domain/tests/mock-users' +import UsersSequelize from '@/infra/database/sequelize/models/User' +import { migrate, truncate } from '@/infra/database/sequelize/__tests__/utils' +import request from 'supertest' +import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest' +import app from '../config/app' +import MockDate from 'mockdate' +import { faker } from '@faker-js/faker' +import TransactionSequelize from '@/infra/database/sequelize/models/Transaction' +import { mockAddTransaction } from '@/domain/tests/mock-transactions' + +describe('Transactions Routes', () => { + beforeAll(async () => { + await migrate() + }) + + beforeEach(async () => { + await truncate() + }) + + afterAll(async () => { + await truncate() + }) + + describe('POST /transactions', () => { + test('should create an transaction', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + + const id = userFrom.getDataValue('id') + const body = { + amount: faker.datatype.number(), + description: faker.lorem.sentence(), + from: id, + to: userTo.getDataValue('id'), + type: 'credit', + } + const res = await request(app) + .post(`/transactions`) + .send(body) + + expect(res.body.id).toBeTruthy() + const transaction = await TransactionSequelize.findOne({ + where: { id: res.body.id }, + }) + expect(transaction).toBeTruthy() + }) + + test('should return an transaction from an user to other', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + + const id = userFrom.getDataValue('id') + const body = { + amount: faker.datatype.number(), + description: faker.lorem.sentence(), + from: id, + to: userTo.getDataValue('id'), + type: 'credit', + } + const res = await request(app) + .post(`/transactions`) + .send(body) + + expect(res.statusCode).toBe(200) + expect(res.body.amount).toBe(body.amount) + expect(res.body.description).toBe(body.description) + expect(res.body.to.id).toBe(body.to) + expect(res.body.type).toBe(body.type) + expect(res.body.from.id).toBe(id) + }) + }) + + describe('GET /transactions', () => { + test('should return the users transactions paginated according to the userId', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + await TransactionSequelize.bulkCreate( + [ + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + ].map(transaction => ({ ...transaction, from: idFrom, to: idTo })) + ) + + const res = await request(app) + .get(`/transactions`) + .query({ page: 1, perPage: 3, userId: idTo }) + + expect(res.body.pagination).toEqual({ + page: 1, + perPage: 3, + total: 6, + totalPages: 2, + }) + }) + + test('should return the users transactions according to the page', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + const transactions = await TransactionSequelize.bulkCreate( + [ + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + ].map(transaction => ({ ...transaction, from: idFrom, to: idTo })) + ) + + const res = await request(app) + .get(`/users/${idFrom}/transactions`) + .query({ page: 1, perPage: 3, userId: idTo }) + + expect(res.body.data[0].id).toBe(transactions[0].getDataValue('id')) + }) + + test('should return the users transactions according to the page', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + const transactions = await TransactionSequelize.bulkCreate( + [ + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + ].map(transaction => ({ ...transaction, from: idFrom, to: idTo })) + ) + + const res = await request(app) + .get(`/users/${idFrom}/transactions`) + .query({ page: 2, perPage: 3, userId: idTo }) + + expect(res.body.data[0].id).toBe(transactions[3].getDataValue('id')) + }) + }) +}) diff --git a/app/src/main/routes/transactions-routes.ts b/app/src/main/routes/transactions-routes.ts new file mode 100644 index 00000000..04cdc015 --- /dev/null +++ b/app/src/main/routes/transactions-routes.ts @@ -0,0 +1,10 @@ +/* eslint-disable @typescript-eslint/no-misused-promises */ +import { Router } from 'express' +import { adaptRoute } from '../adapters/express/express-route-adapter' +import { makeAddTransactionController, makeLoadTransactionsByUserController } from '../factories/controllers/transaction' + +export const transactionsRoutes = (router: Router): void => { + router.get('/transactions', adaptRoute(makeLoadTransactionsByUserController())) + router.post('/transactions', adaptRoute(makeAddTransactionController())) + router.delete('/transactions/:id') +} diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index b0b3cd48..6302b9cf 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -163,7 +163,7 @@ describe('Users Routes', () => { const userTo = await UsersSequelize.create(mockAddUser()) const idFrom = userFrom.getDataValue('id') const idTo = userTo.getDataValue('id') - const transactions = await TransactionSequelize.bulkCreate( + await TransactionSequelize.bulkCreate( [ mockAddTransaction(), mockAddTransaction(), @@ -179,8 +179,8 @@ describe('Users Routes', () => { .query({ page: 1, perPage: 3, userId: idTo }) expect(res.body.pagination).toEqual({ - page: '1', - perPage: '3', + page: 1, + perPage: 3, total: 6, totalPages: 2, }) From 921dc4a682931c514e9e835014211675c7b45b93 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 01:05:22 -0300 Subject: [PATCH 099/105] feat: implementa DELETE /transactions --- .../delete-transaction-by-id-repository.ts | 13 ++++++ .../db-delete-transaction-by-id.ts | 14 +++++++ .../transactions/delete-transaction-by-id.ts | 13 ++++++ app/src/domain/usecases/transactions/index.ts | 3 +- .../transactions-mysql.repository.ts | 14 ++++++- ...te-transaction-by-id-controller-factory.ts | 9 ++++ ...elete-transaction-by-id-usecase-factory.ts | 9 ++++ .../factories/usecases/transaction/index.ts | 3 +- .../main/routes/transactions-routes.spec.ts | 42 +++++++++++++++++++ app/src/main/routes/transactions-routes.ts | 3 +- .../delete-transaction-by-id-controller.ts | 31 ++++++++++++++ .../transactions-controllers/index.ts | 4 +- app/src/presentation/helpers/http-helper.ts | 4 +- 13 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 app/src/data/protocols/database/transactions/delete-transaction-by-id-repository.ts create mode 100644 app/src/data/usecases/transactions/db-delete-transaction-by-id.ts create mode 100644 app/src/domain/usecases/transactions/delete-transaction-by-id.ts create mode 100644 app/src/main/factories/controllers/transaction/delete-transaction-by-id-controller-factory.ts create mode 100644 app/src/main/factories/usecases/transaction/delete-transaction-by-id-usecase-factory.ts create mode 100644 app/src/presentation/controllers/transactions-controllers/delete-transaction-by-id-controller.ts diff --git a/app/src/data/protocols/database/transactions/delete-transaction-by-id-repository.ts b/app/src/data/protocols/database/transactions/delete-transaction-by-id-repository.ts new file mode 100644 index 00000000..72987bcd --- /dev/null +++ b/app/src/data/protocols/database/transactions/delete-transaction-by-id-repository.ts @@ -0,0 +1,13 @@ +import { DeleteTransactionById } from '@/domain/usecases/transactions' + +export interface DeleteTransactionByIdRepository { + deleteById: ( + params: DeleteTransactionByIdRepository.Params + ) => Promise +} + +export namespace DeleteTransactionByIdRepository { + export type Params = DeleteTransactionById.Params + + export type Result = DeleteTransactionById.Result +} diff --git a/app/src/data/usecases/transactions/db-delete-transaction-by-id.ts b/app/src/data/usecases/transactions/db-delete-transaction-by-id.ts new file mode 100644 index 00000000..0f1d7199 --- /dev/null +++ b/app/src/data/usecases/transactions/db-delete-transaction-by-id.ts @@ -0,0 +1,14 @@ +import { DeleteTransactionByIdRepository } from '@/data/protocols/database/transactions/delete-transaction-by-id-repository' +import { DeleteTransactionById } from '@/domain/usecases/transactions' + +export class DbDeleteTransactionById implements DeleteTransactionById { + constructor( + private readonly deleteTransactionByIdRepository: DeleteTransactionByIdRepository + ) {} + + async deleteById( + params: DeleteTransactionById.Params + ): Promise { + return await this.deleteTransactionByIdRepository.deleteById(params) + } +} diff --git a/app/src/domain/usecases/transactions/delete-transaction-by-id.ts b/app/src/domain/usecases/transactions/delete-transaction-by-id.ts new file mode 100644 index 00000000..be06ff29 --- /dev/null +++ b/app/src/domain/usecases/transactions/delete-transaction-by-id.ts @@ -0,0 +1,13 @@ +import { Transaction } from '@/domain/models' + +export interface DeleteTransactionById { + deleteById: (params: DeleteTransactionById.Params) => Promise +} + +export namespace DeleteTransactionById { + export type Params = { + id: number + } + + export type Result = boolean +} diff --git a/app/src/domain/usecases/transactions/index.ts b/app/src/domain/usecases/transactions/index.ts index 8817f983..d1148ec3 100644 --- a/app/src/domain/usecases/transactions/index.ts +++ b/app/src/domain/usecases/transactions/index.ts @@ -1,2 +1,3 @@ export * from './add-transaction' -export * from './load-transactions-by-user' \ No newline at end of file +export * from './load-transactions-by-user' +export * from './delete-transaction-by-id' \ No newline at end of file diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts index 65d4e53e..ef61c9d7 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts @@ -1,11 +1,12 @@ import { AddTransactionRepository } from '@/data/protocols/database/transactions/add-transaction-repository' +import { DeleteTransactionByIdRepository } from '@/data/protocols/database/transactions/delete-transaction-by-id-repository' import { LoadTransactionByUserRepository } from '@/data/protocols/database/transactions/load-transaction-by-user-repository' import { Op } from 'sequelize' import TransactionSequelize, { TransactionModelSequelize, } from '../models/Transaction' -export class TransactionsMySqlReposiory implements AddTransactionRepository, LoadTransactionByUserRepository { +export class TransactionsMySqlReposiory implements AddTransactionRepository, LoadTransactionByUserRepository,DeleteTransactionByIdRepository { async add( transaction: AddTransactionRepository.Params ): Promise { @@ -72,4 +73,15 @@ export class TransactionsMySqlReposiory implements AddTransactionRepository, Loa pagination } } + + async deleteById(params: DeleteTransactionByIdRepository.Params): Promise { + const result = await TransactionSequelize.destroy({ + + where: { + id: params.id + }, + }) + + return result > 0 + } } diff --git a/app/src/main/factories/controllers/transaction/delete-transaction-by-id-controller-factory.ts b/app/src/main/factories/controllers/transaction/delete-transaction-by-id-controller-factory.ts new file mode 100644 index 00000000..14b3bcb9 --- /dev/null +++ b/app/src/main/factories/controllers/transaction/delete-transaction-by-id-controller-factory.ts @@ -0,0 +1,9 @@ +import {DeleteTransactionByIdController } from "@/presentation/controllers/transactions-controllers" +import { Controller } from "@/presentation/protocols" +import { makeDeleteTransactionByIdUseCase } from "../../usecases/transaction" + +export function makeDeleteTransactionByIdController(): Controller { + const deleteTransactionByIdUseCase = makeDeleteTransactionByIdUseCase() + + return new DeleteTransactionByIdController(deleteTransactionByIdUseCase) +} \ No newline at end of file diff --git a/app/src/main/factories/usecases/transaction/delete-transaction-by-id-usecase-factory.ts b/app/src/main/factories/usecases/transaction/delete-transaction-by-id-usecase-factory.ts new file mode 100644 index 00000000..8676ee97 --- /dev/null +++ b/app/src/main/factories/usecases/transaction/delete-transaction-by-id-usecase-factory.ts @@ -0,0 +1,9 @@ +import { DbDeleteTransactionById } from "@/data/usecases/transactions/db-delete-transaction-by-id"; +import { DeleteTransactionById } from "@/domain/usecases/transactions"; +import { TransactionsMySqlReposiory } from "@/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository"; + +export function makeDeleteTransactionByIdUseCase(): DeleteTransactionById { + return new DbDeleteTransactionById( + new TransactionsMySqlReposiory(), + ) +} \ No newline at end of file diff --git a/app/src/main/factories/usecases/transaction/index.ts b/app/src/main/factories/usecases/transaction/index.ts index cc848c74..959e4506 100644 --- a/app/src/main/factories/usecases/transaction/index.ts +++ b/app/src/main/factories/usecases/transaction/index.ts @@ -1,2 +1,3 @@ export * from './add-transaction-usecase-factory' -export * from './load-transactions-by-user-usecase-factory' \ No newline at end of file +export * from './load-transactions-by-user-usecase-factory' +export * from './delete-transaction-by-id-usecase-factory' \ No newline at end of file diff --git a/app/src/main/routes/transactions-routes.spec.ts b/app/src/main/routes/transactions-routes.spec.ts index 9fa97b4d..c1fe1d6f 100644 --- a/app/src/main/routes/transactions-routes.spec.ts +++ b/app/src/main/routes/transactions-routes.spec.ts @@ -146,4 +146,46 @@ describe('Transactions Routes', () => { expect(res.body.data[0].id).toBe(transactions[3].getDataValue('id')) }) }) + + describe('DELETE /transactions/{id}', () => { + test('should return 404 if an unexisting user is provided', async () => { + const res = await request(app).delete('/transactions/1') + + expect(res.statusCode).toBe(404) + }); + + test('should delete the user provided', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + const transaction = await TransactionSequelize.create( + {...mockAddTransaction(), from: idFrom, to: idTo } + ) + + await request(app).delete( + `/transactions/${transaction.getDataValue('id')}` + ) + const transactionExits = await TransactionSequelize.findOne({ + where: { id: transaction.getDataValue('id') }, + }) + expect(transactionExits).toBeFalsy() + }); + + test('should delete the user provided', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + const transaction = await TransactionSequelize.create( + {...mockAddTransaction(), from: idFrom, to: idTo } + ) + + const res = await request(app).delete( + `/transactions/${transaction.getDataValue('id')}` + ) + + expect(res.statusCode).toBe(200) + }); + }); }) diff --git a/app/src/main/routes/transactions-routes.ts b/app/src/main/routes/transactions-routes.ts index 04cdc015..4cb4ab49 100644 --- a/app/src/main/routes/transactions-routes.ts +++ b/app/src/main/routes/transactions-routes.ts @@ -2,9 +2,10 @@ import { Router } from 'express' import { adaptRoute } from '../adapters/express/express-route-adapter' import { makeAddTransactionController, makeLoadTransactionsByUserController } from '../factories/controllers/transaction' +import { makeDeleteTransactionByIdController } from '../factories/controllers/transaction/delete-transaction-by-id-controller-factory' export const transactionsRoutes = (router: Router): void => { router.get('/transactions', adaptRoute(makeLoadTransactionsByUserController())) router.post('/transactions', adaptRoute(makeAddTransactionController())) - router.delete('/transactions/:id') + router.delete('/transactions/:id', adaptRoute(makeDeleteTransactionByIdController())) } diff --git a/app/src/presentation/controllers/transactions-controllers/delete-transaction-by-id-controller.ts b/app/src/presentation/controllers/transactions-controllers/delete-transaction-by-id-controller.ts new file mode 100644 index 00000000..8386e3b7 --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/delete-transaction-by-id-controller.ts @@ -0,0 +1,31 @@ +import { DeleteTransactionById } from '@/domain/usecases/transactions' +import { notFound, ok, serverError } from '@/presentation/helpers/http-helper' +import { Controller, HttpResponse } from '@/presentation/protocols' + +export class DeleteTransactionByIdController + implements Controller +{ + constructor( + private readonly deleteTransactionByIdUseCase: DeleteTransactionById + ) {} + + async handle( + request: DeleteTransactionByIdController.Request + ): Promise { + try { + const isDeleted = await this.deleteTransactionByIdUseCase.deleteById(request) + if(!isDeleted) { + return notFound('transaction', `Transaction ${request.id} does not exits`) + } + return ok({success: isDeleted}) + } catch (error) { + return serverError(error) + } + } +} + +export namespace DeleteTransactionByIdController { + export type Request = DeleteTransactionById.Params + + export type Result = HttpResponse +} diff --git a/app/src/presentation/controllers/transactions-controllers/index.ts b/app/src/presentation/controllers/transactions-controllers/index.ts index 19135917..aac0578a 100644 --- a/app/src/presentation/controllers/transactions-controllers/index.ts +++ b/app/src/presentation/controllers/transactions-controllers/index.ts @@ -1 +1,3 @@ -export * from './add-transaction-controller' \ No newline at end of file +export * from './add-transaction-controller' +export * from './load-transactions-by-user-controller' +export * from './delete-transaction-by-id-controller' \ No newline at end of file diff --git a/app/src/presentation/helpers/http-helper.ts b/app/src/presentation/helpers/http-helper.ts index d5531437..171a5670 100644 --- a/app/src/presentation/helpers/http-helper.ts +++ b/app/src/presentation/helpers/http-helper.ts @@ -29,7 +29,7 @@ export const serverError = ( body: error, }) -export const notFound = (item: string): HttpResponse => ({ +export const notFound = (item: string, details?:string): HttpResponse => ({ statusCode: 404, - body: new NotFoundError(item), + body: new NotFoundError(item, details), }) From 03ccfdde48c779e008dfeb405ca2ad194de45a4a Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 01:05:28 -0300 Subject: [PATCH 100/105] test: implementa DELETE /transactions --- app/src/data/test/mock-transactions.ts | 10 +++ .../db-delete-transaction-by-id.test.ts | 63 +++++++++++++++++++ app/src/domain/tests/mock-transactions.ts | 14 ++++- .../transactions-mysql.repository.test.ts | 20 ++++++ .../main/routes/transactions-routes.spec.ts | 50 +++++++-------- ...elete-transaction-by-id-controller.test.ts | 63 +++++++++++++++++++ 6 files changed, 194 insertions(+), 26 deletions(-) create mode 100644 app/src/data/usecases/transactions/db-delete-transaction-by-id.test.ts create mode 100644 app/src/presentation/controllers/transactions-controllers/delete-transaction-by-id-controller.test.ts diff --git a/app/src/data/test/mock-transactions.ts b/app/src/data/test/mock-transactions.ts index 5306f73a..49282bd9 100644 --- a/app/src/data/test/mock-transactions.ts +++ b/app/src/data/test/mock-transactions.ts @@ -1,6 +1,7 @@ import { mockTransaction } from '@/domain/tests/mock-transactions' import { faker } from '@faker-js/faker' import { AddTransactionRepository } from '../protocols/database/transactions/add-transaction-repository' +import { DeleteTransactionByIdRepository } from '../protocols/database/transactions/delete-transaction-by-id-repository' import { LoadTransactionByUserRepository } from '../protocols/database/transactions/load-transaction-by-user-repository' export class AddTransactionRepositorySpy implements AddTransactionRepository { @@ -36,4 +37,13 @@ export class LoadTransactionByUserRepositorySpy implements LoadTransactionByUser this.loadByUserParams = params return this.loadByUserResult } +} + +export class DeleteTransactionByIdRepositorySpy implements DeleteTransactionByIdRepository { + deleteByIdParams: DeleteTransactionByIdRepository.Params + deleteByIdResult = true + async deleteById(params: DeleteTransactionByIdRepository.Params): Promise { + this.deleteByIdParams = params + return Promise.resolve(this.deleteByIdResult) + } } \ No newline at end of file diff --git a/app/src/data/usecases/transactions/db-delete-transaction-by-id.test.ts b/app/src/data/usecases/transactions/db-delete-transaction-by-id.test.ts new file mode 100644 index 00000000..cd209e36 --- /dev/null +++ b/app/src/data/usecases/transactions/db-delete-transaction-by-id.test.ts @@ -0,0 +1,63 @@ +import { DeleteTransactionByIdRepositorySpy } from "@/data/test/mock-transactions"; +import { faker } from "@faker-js/faker"; +import { describe, expect, test, vitest } from "vitest"; +import { DbDeleteTransactionById } from "./db-delete-transaction-by-id"; + +describe('DbDeleteTransactionById', () => { + function makeSut() { + const deleteTransactionByIdRepositorySpy = new DeleteTransactionByIdRepositorySpy() + const sut = new DbDeleteTransactionById( + deleteTransactionByIdRepositorySpy + ) + + return { + sut, + deleteTransactionByIdRepositorySpy + } + } + describe('deleteById()', () => { + test('should call loadTransactionByUserRepository with correct params', async () => { + const { sut, deleteTransactionByIdRepositorySpy } = makeSut() + const params = { + id: faker.datatype.number(), + } + + await sut.deleteById(params) + expect(deleteTransactionByIdRepositorySpy.deleteByIdParams).toEqual(params) + }); + + test('should return true on success', async () => { + const { sut } = makeSut() + const params = { + id: faker.datatype.number(), + } + + const result = await sut.deleteById(params) + expect(result).toBe(true) + }) + + test('should return false on fails', async () => { + const { sut, deleteTransactionByIdRepositorySpy } = makeSut() + deleteTransactionByIdRepositorySpy.deleteByIdResult = false + const params = { + id: faker.datatype.number(), + } + + const result = await sut.deleteById(params) + expect(result).toBe(false) + }); + + test('should throw if deleteTransactionById throws', async () => { + const { sut, deleteTransactionByIdRepositorySpy } = makeSut() + vitest.spyOn(deleteTransactionByIdRepositorySpy, 'deleteById').mockImplementationOnce(() => { + throw new Error() + }) + + const params = { + id: faker.datatype.number(), + } + + await expect(sut.deleteById(params)).rejects.toThrow() + }); + }); +}); \ No newline at end of file diff --git a/app/src/domain/tests/mock-transactions.ts b/app/src/domain/tests/mock-transactions.ts index ce0b6b7a..7a9c1ed7 100644 --- a/app/src/domain/tests/mock-transactions.ts +++ b/app/src/domain/tests/mock-transactions.ts @@ -1,6 +1,6 @@ import { faker } from "@faker-js/faker"; import { AddTransactionModel, Transaction } from "../models"; -import { AddTransaction, LoadTransactionByUser } from "../usecases/transactions"; +import { AddTransaction, DeleteTransactionById, LoadTransactionByUser } from "../usecases/transactions"; import { mockPagination } from "./mock-pagination"; import { mockUser } from "./mock-users"; @@ -50,4 +50,16 @@ export class LoadTransactionByUserSpy implements LoadTransactionByUser { this.loadByUserParams = params return new Promise((resolve) => resolve(this.loadByUserResult)) } +} + +export class DeleteTransactionByIdSpy implements DeleteTransactionById { + deleteByIdResult: DeleteTransactionById.Result + deleteByIdParams: DeleteTransactionById.Params + constructor() { + this.deleteByIdResult = true + } + async deleteById(params: DeleteTransactionById.Params): Promise { + this.deleteByIdParams = params + return new Promise((resolve) => resolve(this.deleteByIdResult)) + } } \ No newline at end of file diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts index a6665f6b..4897e8dc 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts @@ -202,4 +202,24 @@ describe('TransactionsMySqlRepository', () => { expect(transactionsOfUserOne.data[0].from.id).toEqual(userTwo.id) }); }); + + describe('deleteById()', () => { + test('should return true if the transaction was deleted', async () => { + const sut = makeSut() + const transaction = await makeTransaction() + const transactionExists = await TransactionSequelize.findByPk(transaction.id) + expect(transactionExists).toBeTruthy() + const result = await sut.deleteById({id: transaction.id}) + const transactionAfterDelete = await TransactionSequelize.findByPk(transaction.id) + + expect(result).toBe(true) + expect(transactionAfterDelete).toBeFalsy() + }) + + test('should return false if the transaction was not deleted', async () => { + const sut = makeSut() + const deleted = await sut.deleteById({id: 1}) + expect(deleted).toBe(false) + }) + }); }) diff --git a/app/src/main/routes/transactions-routes.spec.ts b/app/src/main/routes/transactions-routes.spec.ts index c1fe1d6f..56003911 100644 --- a/app/src/main/routes/transactions-routes.spec.ts +++ b/app/src/main/routes/transactions-routes.spec.ts @@ -35,9 +35,7 @@ describe('Transactions Routes', () => { to: userTo.getDataValue('id'), type: 'credit', } - const res = await request(app) - .post(`/transactions`) - .send(body) + const res = await request(app).post(`/transactions`).send(body) expect(res.body.id).toBeTruthy() const transaction = await TransactionSequelize.findOne({ @@ -58,9 +56,7 @@ describe('Transactions Routes', () => { to: userTo.getDataValue('id'), type: 'credit', } - const res = await request(app) - .post(`/transactions`) - .send(body) + const res = await request(app).post(`/transactions`).send(body) expect(res.statusCode).toBe(200) expect(res.body.amount).toBe(body.amount) @@ -77,7 +73,7 @@ describe('Transactions Routes', () => { const userTo = await UsersSequelize.create(mockAddUser()) const idFrom = userFrom.getDataValue('id') const idTo = userTo.getDataValue('id') - await TransactionSequelize.bulkCreate( + await TransactionSequelize.bulkCreate( [ mockAddTransaction(), mockAddTransaction(), @@ -152,40 +148,44 @@ describe('Transactions Routes', () => { const res = await request(app).delete('/transactions/1') expect(res.statusCode).toBe(404) - }); + }) test('should delete the user provided', async () => { const userFrom = await UsersSequelize.create(mockAddUser()) const userTo = await UsersSequelize.create(mockAddUser()) const idFrom = userFrom.getDataValue('id') const idTo = userTo.getDataValue('id') - const transaction = await TransactionSequelize.create( - {...mockAddTransaction(), from: idFrom, to: idTo } - ) + const transaction = await TransactionSequelize.create({ + ...mockAddTransaction(), + from: idFrom, + to: idTo, + }) - await request(app).delete( + await request(app).delete( `/transactions/${transaction.getDataValue('id')}` ) - const transactionExits = await TransactionSequelize.findOne({ - where: { id: transaction.getDataValue('id') }, - }) - expect(transactionExits).toBeFalsy() - }); + const transactionExits = await TransactionSequelize.findOne({ + where: { id: transaction.getDataValue('id') }, + }) + expect(transactionExits).toBeFalsy() + }) test('should delete the user provided', async () => { const userFrom = await UsersSequelize.create(mockAddUser()) const userTo = await UsersSequelize.create(mockAddUser()) const idFrom = userFrom.getDataValue('id') const idTo = userTo.getDataValue('id') - const transaction = await TransactionSequelize.create( - {...mockAddTransaction(), from: idFrom, to: idTo } - ) + const transaction = await TransactionSequelize.create({ + ...mockAddTransaction(), + from: idFrom, + to: idTo, + }) - const res = await request(app).delete( + const res = await request(app).delete( `/transactions/${transaction.getDataValue('id')}` ) - - expect(res.statusCode).toBe(200) - }); - }); + + expect(res.statusCode).toBe(200) + }) + }) }) diff --git a/app/src/presentation/controllers/transactions-controllers/delete-transaction-by-id-controller.test.ts b/app/src/presentation/controllers/transactions-controllers/delete-transaction-by-id-controller.test.ts new file mode 100644 index 00000000..ae7d00bc --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/delete-transaction-by-id-controller.test.ts @@ -0,0 +1,63 @@ +import { DeleteTransactionByIdSpy } from '@/domain/tests/mock-transactions' +import { notFound, ok, serverError } from '@/presentation/helpers/http-helper' +import { faker } from '@faker-js/faker' +import { describe, expect, test, vitest } from 'vitest' +import { DeleteTransactionByIdController } from './delete-transaction-by-id-controller' + +describe('DeleteTransactionByIdController', () => { + function makeSut() { + const deleteTransactionByIdSpy = new DeleteTransactionByIdSpy() + const sut = new DeleteTransactionByIdController(deleteTransactionByIdSpy) + return { + sut, + deleteTransactionByIdSpy, + } + } + describe('handle()', () => { + test('should call deleteTransactionByIdUseCase with correct id', async () => { + const { sut, deleteTransactionByIdSpy } = makeSut() + const request = { + id: faker.datatype.number(), + } + await sut.handle(request) + expect(deleteTransactionByIdSpy.deleteByIdParams).toEqual({ + id: request.id, + }) + }) + + test('should return NotFound if deleteTransactionByIdUseCase returns false', async () => { + const { sut, deleteTransactionByIdSpy } = makeSut() + deleteTransactionByIdSpy.deleteByIdResult = false + const request = { + id: faker.datatype.number(), + } + const result = await sut.handle(request) + expect(result).toEqual( + notFound('transaction', `Transaction ${request.id} does not exits`) + ) + }) + + test('should return ok with success on success', async () => { + const { sut } = makeSut() + const request = { + id: faker.datatype.number(), + } + const result = await sut.handle(request) + expect(result).toEqual(ok({ success: true })) + }) + + test('should return server error if deleteTransactionByIdUseCase throws', async () => { + const { sut, deleteTransactionByIdSpy } = makeSut() + const mockedError = new Error('mocked error') + vitest + .spyOn(deleteTransactionByIdSpy, 'deleteById') + .mockRejectedValueOnce(mockedError) + const request = { + id: faker.datatype.number(), + } + + const result = await sut.handle(request) + expect(result).toEqual(serverError(mockedError)) + }) + }) +}) From b50e47f0a7c4a1d219d21e37a153ead43cc2572e Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 02:34:20 -0300 Subject: [PATCH 101/105] =?UTF-8?q?feat:=20inicia=20cra=C3=A7=C3=A3o=20do?= =?UTF-8?q?=20endpoint=20para=20exportar=20transa=C3=A7=C3=B5es=20em=20CSV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../load-transactions-repository.ts | 13 +++ app/src/data/protocols/utils/csv-parser.ts | 3 + app/src/data/protocols/utils/index.ts | 3 +- .../transactions/db-load-transactions.ts | 17 ++++ app/src/domain/tests/mock-transactions.ts | 45 ++++++--- app/src/domain/usecases/transactions/index.ts | 3 +- .../transactions/load-transactions.ts | 16 +++ .../transactions-mysql.repository.ts | 98 ++++++++++++++----- .../load-transactions-csv-controller.ts | 27 +++++ 9 files changed, 187 insertions(+), 38 deletions(-) create mode 100644 app/src/data/protocols/database/transactions/load-transactions-repository.ts create mode 100644 app/src/data/protocols/utils/csv-parser.ts create mode 100644 app/src/data/usecases/transactions/db-load-transactions.ts create mode 100644 app/src/domain/usecases/transactions/load-transactions.ts create mode 100644 app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.ts diff --git a/app/src/data/protocols/database/transactions/load-transactions-repository.ts b/app/src/data/protocols/database/transactions/load-transactions-repository.ts new file mode 100644 index 00000000..462c0dcc --- /dev/null +++ b/app/src/data/protocols/database/transactions/load-transactions-repository.ts @@ -0,0 +1,13 @@ +import { LoadTransactions } from '@/domain/usecases/transactions' + +export interface LoadTransactionsRepository { + load: ( + params: LoadTransactionsRepository.Params + ) => Promise +} + +export namespace LoadTransactionsRepository { + export type Params = LoadTransactions.Params + + export type Result = LoadTransactions.Result +} diff --git a/app/src/data/protocols/utils/csv-parser.ts b/app/src/data/protocols/utils/csv-parser.ts new file mode 100644 index 00000000..1a4851df --- /dev/null +++ b/app/src/data/protocols/utils/csv-parser.ts @@ -0,0 +1,3 @@ +export interface CsvParser { + parse: (object: Object) => Promise +} diff --git a/app/src/data/protocols/utils/index.ts b/app/src/data/protocols/utils/index.ts index d5a7902f..d53d7e9b 100644 --- a/app/src/data/protocols/utils/index.ts +++ b/app/src/data/protocols/utils/index.ts @@ -1 +1,2 @@ -export * from './date-formatter' \ No newline at end of file +export * from './date-formatter' +export * from './csv-parser' \ No newline at end of file diff --git a/app/src/data/usecases/transactions/db-load-transactions.ts b/app/src/data/usecases/transactions/db-load-transactions.ts new file mode 100644 index 00000000..5ec92747 --- /dev/null +++ b/app/src/data/usecases/transactions/db-load-transactions.ts @@ -0,0 +1,17 @@ +import { LoadTransactionsRepository } from '@/data/protocols/database/transactions/load-transactions-repository' +import { LoadTransactions } from '@/domain/usecases/transactions' + +export class DbLoadTransactions implements LoadTransactions { + constructor( + private readonly loadTransactionsRepository: LoadTransactionsRepository + ) {} + + async load( + params: LoadTransactions.Params + ): Promise { + const transactions = await this.loadTransactionsRepository.load( + params + ) + return transactions + } +} diff --git a/app/src/domain/tests/mock-transactions.ts b/app/src/domain/tests/mock-transactions.ts index 7a9c1ed7..f2e90b03 100644 --- a/app/src/domain/tests/mock-transactions.ts +++ b/app/src/domain/tests/mock-transactions.ts @@ -1,8 +1,13 @@ -import { faker } from "@faker-js/faker"; -import { AddTransactionModel, Transaction } from "../models"; -import { AddTransaction, DeleteTransactionById, LoadTransactionByUser } from "../usecases/transactions"; -import { mockPagination } from "./mock-pagination"; -import { mockUser } from "./mock-users"; +import { faker } from '@faker-js/faker' +import { AddTransactionModel, Transaction } from '../models' +import { + AddTransaction, + DeleteTransactionById, + LoadTransactionByUser, + LoadTransactions, +} from '../usecases/transactions' +import { mockPagination } from './mock-pagination' +import { mockUser } from './mock-users' export function mockTransaction(): Transaction { return { @@ -36,7 +41,7 @@ export class AddTransactionSpy implements AddTransaction { } async add(params: AddTransaction.Params): Promise { this.addParams = params - return new Promise((resolve) => resolve(this.addResult)) + return new Promise(resolve => resolve(this.addResult)) } } @@ -46,9 +51,25 @@ export class LoadTransactionByUserSpy implements LoadTransactionByUser { constructor() { this.loadByUserResult = mockPagination([mockTransaction()]) } - async loadByUser(params: LoadTransactionByUser.Params): Promise { + async loadByUser( + params: LoadTransactionByUser.Params + ): Promise { this.loadByUserParams = params - return new Promise((resolve) => resolve(this.loadByUserResult)) + return new Promise(resolve => resolve(this.loadByUserResult)) + } +} + +export class LoadTransactionsSpy implements LoadTransactions { + loadResult: LoadTransactions.Result + loadParams: LoadTransactions.Params + constructor() { + this.loadResult = [mockTransaction()] + } + async load( + params: LoadTransactions.Params + ): Promise { + this.loadParams = params + return new Promise(resolve => resolve(this.loadResult)) } } @@ -58,8 +79,10 @@ export class DeleteTransactionByIdSpy implements DeleteTransactionById { constructor() { this.deleteByIdResult = true } - async deleteById(params: DeleteTransactionById.Params): Promise { + async deleteById( + params: DeleteTransactionById.Params + ): Promise { this.deleteByIdParams = params - return new Promise((resolve) => resolve(this.deleteByIdResult)) + return new Promise(resolve => resolve(this.deleteByIdResult)) } -} \ No newline at end of file +} diff --git a/app/src/domain/usecases/transactions/index.ts b/app/src/domain/usecases/transactions/index.ts index d1148ec3..a0f9cd03 100644 --- a/app/src/domain/usecases/transactions/index.ts +++ b/app/src/domain/usecases/transactions/index.ts @@ -1,3 +1,4 @@ export * from './add-transaction' export * from './load-transactions-by-user' -export * from './delete-transaction-by-id' \ No newline at end of file +export * from './delete-transaction-by-id' +export * from './load-transactions' \ No newline at end of file diff --git a/app/src/domain/usecases/transactions/load-transactions.ts b/app/src/domain/usecases/transactions/load-transactions.ts new file mode 100644 index 00000000..c7aa561f --- /dev/null +++ b/app/src/domain/usecases/transactions/load-transactions.ts @@ -0,0 +1,16 @@ +import { Transaction } from '@/domain/models' + +export interface LoadTransactions { + load: ( + params: LoadTransactions.Params + ) => Promise +} + +export namespace LoadTransactions { + export type Params = { + lastDays?: number + monthAndYear?: string + } + + export type Result = Transaction[] +} diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts index ef61c9d7..d16f22a9 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.ts @@ -1,36 +1,46 @@ import { AddTransactionRepository } from '@/data/protocols/database/transactions/add-transaction-repository' import { DeleteTransactionByIdRepository } from '@/data/protocols/database/transactions/delete-transaction-by-id-repository' import { LoadTransactionByUserRepository } from '@/data/protocols/database/transactions/load-transaction-by-user-repository' +import { LoadTransactionsRepository } from '@/data/protocols/database/transactions/load-transactions-repository' +import { LoadTransactions } from '@/domain/usecases/transactions' import { Op } from 'sequelize' import TransactionSequelize, { TransactionModelSequelize, } from '../models/Transaction' -export class TransactionsMySqlReposiory implements AddTransactionRepository, LoadTransactionByUserRepository,DeleteTransactionByIdRepository { +export class TransactionsMySqlReposiory + implements + AddTransactionRepository, + LoadTransactionByUserRepository, + DeleteTransactionByIdRepository, + LoadTransactionsRepository +{ async add( transaction: AddTransactionRepository.Params ): Promise { - const newTransaction = (await TransactionSequelize.create(transaction)).toJSON() - + const newTransaction = ( + await TransactionSequelize.create(transaction) + ).toJSON() + + const insertedTransaction = ( + await TransactionSequelize.findOne({ + where: { + id: newTransaction.id, + }, + include: { + all: true, + }, + }) + ).toJSON() - const insertedTransaction = (await TransactionSequelize.findOne({ - where: { - id: newTransaction.id, - }, - include: { - all: true - - } - })).toJSON() - return this.formatTransaction(insertedTransaction) } private formatTransaction( transaction: TransactionModelSequelize ): AddTransactionRepository.Result { - const { From, To, ChargebackFrom, ...prunedTransaction} = transaction - + const { From, To, ChargebackFrom, ...prunedTransaction } = transaction + const newTransaction: AddTransactionRepository.Result = { ...prunedTransaction, from: transaction.From, @@ -38,11 +48,12 @@ export class TransactionsMySqlReposiory implements AddTransactionRepository, Loa chargebackFrom: transaction.ChargebackFrom, } - return newTransaction } - async loadByUser(params: LoadTransactionByUserRepository.Params): Promise { + async loadByUser( + params: LoadTransactionByUserRepository.Params + ): Promise { const { page, perPage, userId } = params const offset = (page - 1) * perPage @@ -51,37 +62,74 @@ export class TransactionsMySqlReposiory implements AddTransactionRepository, Loa [Op.or]: { from: userId, to: userId, - } + }, }, offset, limit: perPage, include: { all: true, - } + }, }) - const data = transactions.rows.map(transaction => this.formatTransaction(transaction.toJSON())) + const data = transactions.rows.map(transaction => + this.formatTransaction(transaction.toJSON()) + ) const pagination = { page, perPage, total: transactions.count, - totalPages: Math.ceil(transactions.count / perPage) + totalPages: Math.ceil(transactions.count / perPage), } return { data, - pagination + pagination, } } - async deleteById(params: DeleteTransactionByIdRepository.Params): Promise { + async deleteById( + params: DeleteTransactionByIdRepository.Params + ): Promise { const result = await TransactionSequelize.destroy({ - where: { - id: params.id + id: params.id, }, }) return result > 0 } + + async load (params: LoadTransactions.Params = {}): Promise { + const { lastDays, monthAndYear } = params + + const where = {} + + if (lastDays) { + const date = new Date() + date.setDate(date.getDate() - lastDays) + where['createdAt'] = { + [Op.gte]: date, + } + } else if (monthAndYear) { + const [month, abbreviatedYear] = monthAndYear.split('/').map(Number) + const year = Number(`20${abbreviatedYear}`) + where['createdAt'] = { + [Op.gte]: new Date(year, month - 1, 1), + [Op.lte]: new Date(year, month, 0), + } + } + + const transactions = await TransactionSequelize.findAndCountAll({ + where, + include: { + all: true, + }, + }) + + const data = transactions.rows.map(transaction => + this.formatTransaction(transaction.toJSON()) + ) + + return data + } } diff --git a/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.ts b/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.ts new file mode 100644 index 00000000..6c3052fe --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.ts @@ -0,0 +1,27 @@ +import { CsvParser } from '@/data/protocols/utils' +import { LoadTransactions } from '@/domain/usecases/transactions' +import { ok, serverError } from '@/presentation/helpers/http-helper' +import { Controller, HttpResponse } from '@/presentation/protocols' + +export class LoadTransactionsCsvController implements Controller { + constructor( + private readonly loadTransactionsUseCase: LoadTransactions, + private readonly csvParser: CsvParser + ) {} + async handle( + params: LoadTransactionsCsvController.Request + ): Promise { + try { + const transactions = await this.loadTransactionsUseCase.load(params) + const csv = await this.csvParser.parse(transactions) + return ok(csv) + } catch (error) { + return serverError(error) + } + } +} + +export namespace LoadTransactionsCsvController { + export type Request = LoadTransactions.Params + export type Response = HttpResponse +} \ No newline at end of file From 723eff7927795ddab956df69e62e162abb210422 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 02:34:25 -0300 Subject: [PATCH 102/105] =?UTF-8?q?test:=20inicia=20cra=C3=A7=C3=A3o=20do?= =?UTF-8?q?=20endpoint=20para=20exportar=20transa=C3=A7=C3=B5es=20em=20CSV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/data/test/mock-csv-parser.ts | 11 ++ app/src/data/test/mock-transactions.ts | 21 +++ .../db-load-transaction-by-user.test.ts | 2 +- .../db-load-transactions.test .ts | 58 +++++++ .../transactions-mysql.repository.test.ts | 159 ++++++++++++++---- .../load-transactions-csv-controller.test.ts | 61 +++++++ 6 files changed, 281 insertions(+), 31 deletions(-) create mode 100644 app/src/data/test/mock-csv-parser.ts create mode 100644 app/src/data/usecases/transactions/db-load-transactions.test .ts create mode 100644 app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.test.ts diff --git a/app/src/data/test/mock-csv-parser.ts b/app/src/data/test/mock-csv-parser.ts new file mode 100644 index 00000000..6012c1e3 --- /dev/null +++ b/app/src/data/test/mock-csv-parser.ts @@ -0,0 +1,11 @@ +import { faker } from "@faker-js/faker"; +import { CsvParser, DateFormatter } from "../protocols/utils"; + +export class CsvParserSpy implements CsvParser { + input: Object + result: string = faker.lorem.words() + async parse(obj: Object): Promise { + this.input = obj + return this.result + } +} \ No newline at end of file diff --git a/app/src/data/test/mock-transactions.ts b/app/src/data/test/mock-transactions.ts index 49282bd9..344a2e42 100644 --- a/app/src/data/test/mock-transactions.ts +++ b/app/src/data/test/mock-transactions.ts @@ -3,6 +3,7 @@ import { faker } from '@faker-js/faker' import { AddTransactionRepository } from '../protocols/database/transactions/add-transaction-repository' import { DeleteTransactionByIdRepository } from '../protocols/database/transactions/delete-transaction-by-id-repository' import { LoadTransactionByUserRepository } from '../protocols/database/transactions/load-transaction-by-user-repository' +import { LoadTransactionsRepository } from '../protocols/database/transactions/load-transactions-repository' export class AddTransactionRepositorySpy implements AddTransactionRepository { addParams: AddTransactionRepository.Params @@ -39,6 +40,26 @@ export class LoadTransactionByUserRepositorySpy implements LoadTransactionByUser } } +export class LoadTransactionsRepositorySpy implements LoadTransactionsRepository { + loadParams: LoadTransactionsRepository.Params + loadResult: LoadTransactionsRepository.Result + constructor() { + this.loadResult = { + data: [mockTransaction()], + pagination: { + page: faker.datatype.number(), + perPage: faker.datatype.number(), + total: faker.datatype.number(), + totalPages: faker.datatype.number() + } + } + } + async load(params: LoadTransactionsRepository.Params): Promise { + this.loadParams = params + return this.loadResult + } +} + export class DeleteTransactionByIdRepositorySpy implements DeleteTransactionByIdRepository { deleteByIdParams: DeleteTransactionByIdRepository.Params deleteByIdResult = true diff --git a/app/src/data/usecases/transactions/db-load-transaction-by-user.test.ts b/app/src/data/usecases/transactions/db-load-transaction-by-user.test.ts index c9e99e8f..193d8b26 100644 --- a/app/src/data/usecases/transactions/db-load-transaction-by-user.test.ts +++ b/app/src/data/usecases/transactions/db-load-transaction-by-user.test.ts @@ -15,7 +15,7 @@ describe('DbLoadTransactionByUser', () => { loadTransactionByUserRepositorySpy } } - describe('lodByUser()', () => { + describe('loadByUser()', () => { test('should call loadTransactionByUserRepository with correct params', async () => { const { sut, loadTransactionByUserRepositorySpy } = makeSut() const params = { diff --git a/app/src/data/usecases/transactions/db-load-transactions.test .ts b/app/src/data/usecases/transactions/db-load-transactions.test .ts new file mode 100644 index 00000000..70845e15 --- /dev/null +++ b/app/src/data/usecases/transactions/db-load-transactions.test .ts @@ -0,0 +1,58 @@ +import { LoadTransactionsRepositorySpy } from '@/data/test/mock-transactions' +import { faker } from '@faker-js/faker' +import { describe, expect, test, vitest } from 'vitest' +import { DbLoadTransactions } from './db-load-transactions' + +describe('DbLoadTransactions', () => { + function makeSut() { + const loadTransactionsRepositorySpy = new LoadTransactionsRepositorySpy() + const sut = new DbLoadTransactions(loadTransactionsRepositorySpy) + + return { + sut, + loadTransactionsRepositorySpy, + } + } + describe('load()', () => { + test('should call loadTransactionsRepository with correct params', async () => { + const { sut, loadTransactionsRepositorySpy } = makeSut() + const params = { + userId: faker.datatype.number(), + page: faker.datatype.number(), + perPage: faker.datatype.number(), + } + + await sut.load(params) + expect(loadTransactionsRepositorySpy.load).toEqual(params) + }) + + test("should return user's transaction paginated", async () => { + const someDate = faker.date.recent() + const monthAndYear = `${ + someDate.getMonth() + 1 + }/${someDate.getFullYear()}` + const { sut, loadTransactionsRepositorySpy } = makeSut() + const result = await sut.load({ + lastDays: faker.datatype.number(), + monthAndYear, + page: faker.datatype.number(), + perPage: faker.datatype.number(), + }) + expect(result).toEqual(loadTransactionsRepositorySpy.loadResult) + }) + + test('should throw if loadTransactionsRepository throws', async () => { + const { sut, loadTransactionsRepositorySpy } = makeSut() + const mockedError = new Error('some_error') + vitest + .spyOn(loadTransactionsRepositorySpy, 'load') + .mockRejectedValueOnce(mockedError) + const promise = sut.load({ + lastDays: faker.datatype.number(), + page: faker.datatype.number(), + perPage: faker.datatype.number(), + }) + await expect(promise).rejects.toThrow(mockedError) + }) + }) +}) diff --git a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts index 4897e8dc..b03c2e7d 100644 --- a/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts +++ b/app/src/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository.test.ts @@ -22,7 +22,11 @@ describe('TransactionsMySqlRepository', () => { const to = await makeUser() const from = await makeUser() const rawTransactionDb = ( - await TransactionSequelize.create({...transaction, to: to.id, from: from.id}) + await TransactionSequelize.create({ + ...transaction, + to: to.id, + from: from.id, + }) ).toJSON() const { From, ChargebackFrom, To, ...transactionDb } = ( @@ -85,7 +89,7 @@ describe('TransactionsMySqlRepository', () => { const to = await makeUser() const from = await makeUser() const mockedChargebackTransaction = await makeTransaction() - + const mockedTransaction = mockAddTransaction() mockedTransaction.to = to.id mockedTransaction.from = from.id @@ -98,8 +102,10 @@ describe('TransactionsMySqlRepository', () => { expect(transaction.type).toBe(mockedTransaction.type) expect(transaction.to.id).toEqual(to.id) expect(transaction.from.id).toEqual(from.id) - expect(transaction.chargebackFrom.id).toEqual(mockedChargebackTransaction.id) - + expect(transaction.chargebackFrom.id).toEqual( + mockedChargebackTransaction.id + ) + const transactionExists = await TransactionSequelize.findByPk( transaction.id ) @@ -124,7 +130,7 @@ describe('TransactionsMySqlRepository', () => { perPage: 10, total: 0, totalPages: 0, - } + }, }) }) @@ -142,7 +148,7 @@ describe('TransactionsMySqlRepository', () => { transactionThree.from = userOne.id transactionThree.to = userTwo.id - const [transactionOneInserted] =await TransactionSequelize.bulkCreate([ + const [transactionOneInserted] = await TransactionSequelize.bulkCreate([ transactionOne, transactionTwo, transactionThree, @@ -154,17 +160,19 @@ describe('TransactionsMySqlRepository', () => { }) expect(transactionsOfUserOne.pagination).toEqual({ - page: 1, - perPage: 10, - total: 3, - totalPages: 1, + page: 1, + perPage: 10, + total: 3, + totalPages: 1, }) - expect(transactionsOfUserOne.data[0].id).toBe(transactionOneInserted.getDataValue('id')) + expect(transactionsOfUserOne.data[0].id).toBe( + transactionOneInserted.getDataValue('id') + ) expect(transactionsOfUserOne.data[0].to.id).toEqual(userOne.id) expect(transactionsOfUserOne.data[0].from.id).toEqual(userTwo.id) - }); - + }) + test('should change the page correctly', async () => { const sut = makeSut() const userOne = await makeUser() @@ -179,11 +187,9 @@ describe('TransactionsMySqlRepository', () => { transactionThree.from = userOne.id transactionThree.to = userTwo.id - const [_,transactionTwoInserted] =await TransactionSequelize.bulkCreate([ - transactionOne, - transactionTwo, - transactionThree, - ]) + const [_, transactionTwoInserted] = await TransactionSequelize.bulkCreate( + [transactionOne, transactionTwo, transactionThree] + ) const transactionsOfUserOne = await sut.loadByUser({ userId: userOne.id, page: 2, @@ -191,26 +197,32 @@ describe('TransactionsMySqlRepository', () => { }) expect(transactionsOfUserOne.pagination).toEqual({ - page: 2, - perPage: 1, - total: 3, - totalPages: 3, + page: 2, + perPage: 1, + total: 3, + totalPages: 3, }) - expect(transactionsOfUserOne.data[0].id).toBe(transactionTwoInserted.getDataValue('id')) + expect(transactionsOfUserOne.data[0].id).toBe( + transactionTwoInserted.getDataValue('id') + ) expect(transactionsOfUserOne.data[0].to.id).toEqual(userOne.id) expect(transactionsOfUserOne.data[0].from.id).toEqual(userTwo.id) - }); - }); + }) + }) describe('deleteById()', () => { test('should return true if the transaction was deleted', async () => { const sut = makeSut() const transaction = await makeTransaction() - const transactionExists = await TransactionSequelize.findByPk(transaction.id) + const transactionExists = await TransactionSequelize.findByPk( + transaction.id + ) expect(transactionExists).toBeTruthy() - const result = await sut.deleteById({id: transaction.id}) - const transactionAfterDelete = await TransactionSequelize.findByPk(transaction.id) + const result = await sut.deleteById({ id: transaction.id }) + const transactionAfterDelete = await TransactionSequelize.findByPk( + transaction.id + ) expect(result).toBe(true) expect(transactionAfterDelete).toBeFalsy() @@ -218,8 +230,95 @@ describe('TransactionsMySqlRepository', () => { test('should return false if the transaction was not deleted', async () => { const sut = makeSut() - const deleted = await sut.deleteById({id: 1}) + const deleted = await sut.deleteById({ id: 1 }) expect(deleted).toBe(false) }) - }); + }) + + describe('load()', () => { + test('should return an empty array no transactions are found', async () => { + const sut = makeSut() + const transactions = await sut.load() + expect(transactions).toEqual([]) + }) + + test('should filter only the transactions of the lastDays provided', async () => { + const sut = makeSut() + const userOne = await makeUser() + const userTwo = await makeUser() + const transactionOne = mockAddTransaction() + transactionOne.to = userOne.id + transactionOne.from = userTwo.id + const transactionTwo = mockAddTransaction() + transactionTwo.to = userOne.id + transactionTwo.from = userTwo.id + const transactionThree = mockAddTransaction() + transactionThree.from = userOne.id + transactionThree.to = userTwo.id + + const [insertedTransactionOne] = await TransactionSequelize.bulkCreate([ + transactionOne, + transactionTwo, + transactionThree, + ]) + + await TransactionSequelize.update( + { + createdAt: new Date('2020-01-01'), + }, + { + where: { + id: insertedTransactionOne.getDataValue('id'), + }, + } + ) + + const transactions = await sut.load({ + lastDays: 1, + }) + + expect(transactions.length).toBe(2) + }) + + test('should filter only the transactions of the monthAndYear provided', async () => { + const sut = makeSut() + const userOne = await makeUser() + const userTwo = await makeUser() + const transactionOne = mockAddTransaction() + transactionOne.to = userOne.id + transactionOne.from = userTwo.id + const transactionTwo = mockAddTransaction() + transactionTwo.to = userOne.id + transactionTwo.from = userTwo.id + const transactionThree = mockAddTransaction() + transactionThree.from = userOne.id + transactionThree.to = userTwo.id + const month = 1 + const year = 20 + const monthAndYear = `${month}/${year}` + + const [insertedTransactionOne] = await TransactionSequelize.bulkCreate([ + transactionOne, + transactionTwo, + transactionThree, + ]) + + await TransactionSequelize.update( + { + createdAt: new Date(2020, 0, 1), + }, + { + where: { + id: insertedTransactionOne.getDataValue('id'), + }, + } + ) + + const transactions = await sut.load({ + monthAndYear, + }) + + expect(transactions[0].id).toBe(insertedTransactionOne.getDataValue('id')) + }) + }) }) diff --git a/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.test.ts b/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.test.ts new file mode 100644 index 00000000..32ea57b6 --- /dev/null +++ b/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.test.ts @@ -0,0 +1,61 @@ +import { CsvParserSpy } from '@/data/test/mock-csv-parser' +import { LoadTransactionsSpy } from '@/domain/tests/mock-transactions' +import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' +import { faker } from '@faker-js/faker' +import { describe, expect, test, vitest } from 'vitest' +import { LoadTransactionsCsvController } from './load-transactions-csv-controller' + +describe('LoadTransactionsCsvController', () => { + function makeSut() { + const loadTransactions = new LoadTransactionsSpy() + const csvParserSpy = new CsvParserSpy() + const sut = new LoadTransactionsCsvController(loadTransactions, csvParserSpy) + + return { + sut, + loadTransactions, + csvParserSpy, + } + } + describe('handle()', () => { + test('should call loadTransactionsUseCase with correct params', async () => { + const { sut, loadTransactions } = makeSut() + const request = { + lastDays: faker.datatype.number(), + } + + await sut.handle(request) + expect(loadTransactions.loadParams).toEqual(request) + }) + + test('should return 500 if loadTransactionsUseCase throws', async () => { + const { sut, loadTransactions } = makeSut() + vitest.spyOn(loadTransactions, 'load').mockRejectedValueOnce(new Error()) + + const response = await sut.handle({}) + expect(response).toEqual(serverError(new Error())) + }) + + test('should call csvParser with correct params', async () => { + const { sut, loadTransactions, csvParserSpy } = makeSut() + + await sut.handle({}) + expect(csvParserSpy.input).toEqual(loadTransactions.loadResult) + }); + + test('should return 500 if csvParser throws', async () => { + const { sut, csvParserSpy } = makeSut() + vitest.spyOn(csvParserSpy, 'parse').mockRejectedValueOnce(new Error()) + + const response = await sut.handle({}) + expect(response).toEqual(serverError(new Error())) + }) + + test('should return 200 if csvParser succeeds', async () => { + const { sut, csvParserSpy } = makeSut() + + const response = await sut.handle({}) + expect(response).toEqual(ok(csvParserSpy.result)) + }) + }) +}) From cefc8e34f42e746acbe62b40544ff6689adbfcb5 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 16:02:17 -0300 Subject: [PATCH 103/105] feat: implementa LoadTransactionsCSVController --- app/package-lock.json | 85 +++++++++++++++++++ app/package.json | 2 + app/src/data/test/mock-csv-parser.ts | 4 +- app/src/data/usecases/transactions/index.ts | 4 + .../csv-parser/json-to-csv-adapter.test.ts | 75 ++++++++++++++++ .../utils/csv-parser/json-to-csv-adapter.ts | 15 ++++ .../adapters/express/express-route-adapter.ts | 31 +++++-- .../load-transactions-csv-controller.ts | 22 +++++ .../factories/usecases/transaction/index.ts | 3 +- .../load-transactions-usecase-factory.ts | 9 ++ .../main/routes/transactions-routes.spec.ts | 28 ++++++ app/src/main/routes/transactions-routes.ts | 2 + app/src/main/routes/users-routes.spec.ts | 6 +- .../transactions-controllers/index.ts | 3 +- .../load-transactions-csv-controller.test.ts | 10 ++- .../load-transactions-csv-controller.ts | 26 +++++- .../delete-user-controller.ts | 2 + app/src/presentation/helpers/file-response.ts | 27 ++++++ .../presentation/protocols/file-response.ts | 7 ++ app/vitest.config.ts | 2 +- 20 files changed, 343 insertions(+), 20 deletions(-) create mode 100644 app/src/data/usecases/transactions/index.ts create mode 100644 app/src/infra/utils/csv-parser/json-to-csv-adapter.test.ts create mode 100644 app/src/infra/utils/csv-parser/json-to-csv-adapter.ts create mode 100644 app/src/main/factories/controllers/transaction/load-transactions-csv-controller.ts create mode 100644 app/src/main/factories/usecases/transaction/load-transactions-usecase-factory.ts create mode 100644 app/src/presentation/helpers/file-response.ts create mode 100644 app/src/presentation/protocols/file-response.ts diff --git a/app/package-lock.json b/app/package-lock.json index 9148085c..3dd50e90 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -12,6 +12,7 @@ "cross-env": "^7.0.3", "dotenv": "^16.0.3", "express": "^4.18.2", + "json2csv": "^5.0.7", "moment": "^2.29.4", "mysql2": "^2.3.3", "sequelize": "^6.25.1", @@ -21,6 +22,7 @@ "devDependencies": { "@faker-js/faker": "^7.6.0", "@types/express": "^4.17.14", + "@types/json2csv": "^5.0.3", "@types/node": "^18.11.0", "@types/supertest": "^2.0.12", "@vitest/coverage-istanbul": "^0.24.3", @@ -652,6 +654,15 @@ "@types/range-parser": "*" } }, + "node_modules/@types/json2csv": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/json2csv/-/json2csv-5.0.3.tgz", + "integrity": "sha512-ZJEv6SzhPhgpBpxZU4n/TZekbZqI4EcyXXRwms1lAITG2kIAtj85PfNYafUOY1zy8bWs5ujaub0GU4copaA0sw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2860,6 +2871,31 @@ "node": ">=4" } }, + "node_modules/json2csv": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.7.tgz", + "integrity": "sha512-YRZbUnyaJZLZUJSRi2G/MqahCyRv9n/ds+4oIetjDF3jWQA7AG7iSeKTiZiCNqtMZM7HDyt0e/W6lEnoGEmMGA==", + "dependencies": { + "commander": "^6.1.0", + "jsonparse": "^1.3.1", + "lodash.get": "^4.4.2" + }, + "bin": { + "json2csv": "bin/json2csv.js" + }, + "engines": { + "node": ">= 10", + "npm": ">= 6.13.0" + } + }, + "node_modules/json2csv/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -2883,6 +2919,14 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] + }, "node_modules/local-pkg": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", @@ -2900,6 +2944,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -5697,6 +5746,15 @@ "@types/range-parser": "*" } }, + "@types/json2csv": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/json2csv/-/json2csv-5.0.3.tgz", + "integrity": "sha512-ZJEv6SzhPhgpBpxZU4n/TZekbZqI4EcyXXRwms1lAITG2kIAtj85PfNYafUOY1zy8bWs5ujaub0GU4copaA0sw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -7347,6 +7405,23 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json2csv": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.7.tgz", + "integrity": "sha512-YRZbUnyaJZLZUJSRi2G/MqahCyRv9n/ds+4oIetjDF3jWQA7AG7iSeKTiZiCNqtMZM7HDyt0e/W6lEnoGEmMGA==", + "requires": { + "commander": "^6.1.0", + "jsonparse": "^1.3.1", + "lodash.get": "^4.4.2" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==" + } + } + }, "json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -7362,6 +7437,11 @@ "universalify": "^2.0.0" } }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" + }, "local-pkg": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", @@ -7373,6 +7453,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", diff --git a/app/package.json b/app/package.json index d79bb92e..06e7589e 100644 --- a/app/package.json +++ b/app/package.json @@ -16,6 +16,7 @@ "devDependencies": { "@faker-js/faker": "^7.6.0", "@types/express": "^4.17.14", + "@types/json2csv": "^5.0.3", "@types/node": "^18.11.0", "@types/supertest": "^2.0.12", "@vitest/coverage-istanbul": "^0.24.3", @@ -37,6 +38,7 @@ "cross-env": "^7.0.3", "dotenv": "^16.0.3", "express": "^4.18.2", + "json2csv": "^5.0.7", "moment": "^2.29.4", "mysql2": "^2.3.3", "sequelize": "^6.25.1", diff --git a/app/src/data/test/mock-csv-parser.ts b/app/src/data/test/mock-csv-parser.ts index 6012c1e3..21716452 100644 --- a/app/src/data/test/mock-csv-parser.ts +++ b/app/src/data/test/mock-csv-parser.ts @@ -2,10 +2,10 @@ import { faker } from "@faker-js/faker"; import { CsvParser, DateFormatter } from "../protocols/utils"; export class CsvParserSpy implements CsvParser { - input: Object + input: any[] = [] result: string = faker.lorem.words() async parse(obj: Object): Promise { - this.input = obj + this.input.push(obj) return this.result } } \ No newline at end of file diff --git a/app/src/data/usecases/transactions/index.ts b/app/src/data/usecases/transactions/index.ts new file mode 100644 index 00000000..0ea877d8 --- /dev/null +++ b/app/src/data/usecases/transactions/index.ts @@ -0,0 +1,4 @@ +export * from './db-add-transaction' +export * from './db-load-transaction-by-user' +export * from './db-load-transactions' +export * from './db-add-transaction' \ No newline at end of file diff --git a/app/src/infra/utils/csv-parser/json-to-csv-adapter.test.ts b/app/src/infra/utils/csv-parser/json-to-csv-adapter.test.ts new file mode 100644 index 00000000..fa31b26d --- /dev/null +++ b/app/src/infra/utils/csv-parser/json-to-csv-adapter.test.ts @@ -0,0 +1,75 @@ +import { describe, expect, test, vitest } from 'vitest' +import jsonToCsv from 'json2csv' +import { JsonToCSVAdapter } from './json-to-csv-adapter' +import { faker } from '@faker-js/faker' + +const MOCKED_VALUE = faker.lorem.text() +const PUSH_FUNCTION = vitest.fn() +vitest.mock('json2csv', () => ({ + default: { + AsyncParser: vitest.fn().mockImplementation(() => ({ + input: { + push: PUSH_FUNCTION, + }, + promise: vitest.fn().mockResolvedValue(MOCKED_VALUE), + })), + }, +})) + +describe('JsonToCSVAdapter', () => { + describe('parse()', () => { + test('should call AsyncParser with correct params', async () => { + const fields = [ + { + label: 'any_label', + value: 'any_key', + }, + { + label: 'any_label', + value: 'any_value', + }, + ] + const sut = new JsonToCSVAdapter(fields) + await sut.parse(JSON.stringify({ any_key: 'any_value' })) + expect(jsonToCsv.AsyncParser).toHaveBeenCalledWith({ + fields, + defaultValue: '', + }) + }) + + test('should call input.push with the data', async () => { + const fields = [ + { + label: 'any_label', + value: 'any_key', + }, + { + label: 'any_label', + value: 'any_value', + }, + ] + const sut = new JsonToCSVAdapter(fields) + const data = JSON.stringify({ any_key: 'any_value' }) + await sut.parse(data) + expect(PUSH_FUNCTION.mock.calls[0][0]).toEqual(Buffer.from(data)) + expect(PUSH_FUNCTION.mock.calls[1][0]).toEqual(null) + }); + + test('should return valid data', async () => { + const fields = [ + { + label: 'any_label', + value: 'any_key', + }, + { + label: 'any_label', + value: 'any_value', + }, + ] + const sut = new JsonToCSVAdapter(fields) + const data = JSON.stringify({ any_key: 'any_value' }) + const result = await sut.parse(data) + expect(result).toEqual(MOCKED_VALUE) + }); + }) +}) diff --git a/app/src/infra/utils/csv-parser/json-to-csv-adapter.ts b/app/src/infra/utils/csv-parser/json-to-csv-adapter.ts new file mode 100644 index 00000000..07453589 --- /dev/null +++ b/app/src/infra/utils/csv-parser/json-to-csv-adapter.ts @@ -0,0 +1,15 @@ +import { CsvParser } from '@/data/protocols/utils' +import jsonToCsv ,{ FieldInfo } from 'json2csv' +export class JsonToCSVAdapter implements CsvParser { + constructor(private readonly options: FieldInfo[]) {} + + async parse(json: string): Promise { + const json2csv = new jsonToCsv.AsyncParser({ + fields: this.options, + defaultValue: '', + }) + json2csv.input.push(Buffer.from(json)) + json2csv.input.push(null) + return await json2csv.promise() + } +} diff --git a/app/src/main/adapters/express/express-route-adapter.ts b/app/src/main/adapters/express/express-route-adapter.ts index fdba75f3..3f1e0a22 100644 --- a/app/src/main/adapters/express/express-route-adapter.ts +++ b/app/src/main/adapters/express/express-route-adapter.ts @@ -1,27 +1,44 @@ import { Request, Response } from 'express' import { Controller } from '@/presentation/protocols' +import { FileResponseGenerator } from '@/presentation/helpers/file-response' +import { PassThrough } from 'stream' -export function adaptRoute (controller: Controller) { +export function adaptRoute(controller: Controller) { return async function (req: Request, res: Response): Promise { const httpRequest: any = { ...(req.body || {}), ...(req.params || {}), - ...(req.query || {}) + ...(req.query || {}), } try { const httpResponse = await controller.handle(httpRequest) + const isFile = httpResponse.body?.data instanceof Buffer if (httpResponse.statusCode >= 200 && httpResponse.statusCode <= 299) { - res.status(httpResponse.statusCode).json(httpResponse.body) - return - } + if (isFile) { + handleFile(httpResponse.body, res) + return + } else { + res.status(httpResponse.statusCode).json(httpResponse.body) + return + } + } res.status(httpResponse.statusCode).json({ - error: httpResponse.body.message + error: httpResponse.body.message, }) } catch (error) { res.status(500).json({ - error: error.message + error: error.message, }) } } } + +export function handleFile(file: FileResponseGenerator.Response, res: Response) { + const readStream = new PassThrough() + readStream.end(file.data) + + res.set('Content-disposition', `attachment; filename=${file.name}.${file.ext}`) + res.set('Content-Type', file.mimetype) + readStream.pipe(res) +} \ No newline at end of file diff --git a/app/src/main/factories/controllers/transaction/load-transactions-csv-controller.ts b/app/src/main/factories/controllers/transaction/load-transactions-csv-controller.ts new file mode 100644 index 00000000..34191483 --- /dev/null +++ b/app/src/main/factories/controllers/transaction/load-transactions-csv-controller.ts @@ -0,0 +1,22 @@ +import { JsonToCSVAdapter } from "@/infra/utils/csv-parser/json-to-csv-adapter" +import { LoadTransactionsCsvController } from "@/presentation/controllers/transactions-controllers" +import { Controller } from "@/presentation/protocols" +import { makeLoadTransactionsUseCase } from "../../usecases/transaction" + +export function makeLoadTransactionsCsvController(): Controller { + const loadTransactionsUseCase = makeLoadTransactionsUseCase() + const jsonToCSVAdaptar = new JsonToCSVAdapter([ + { label: 'ID da transação', value: 'id' }, + { label: 'Descrição', value: 'description' }, + { label: 'Valor', value: 'amount' }, + { label: 'Tipo', value: 'type' }, + { label: 'Pagante', value: 'from.name' }, + { label: 'Recebedor', value: 'to.name' }, + { label: 'Estorno de', value: 'chargebackFrom.id' }, + { label: 'Data', value: 'createdAt' }, + ]) + return new LoadTransactionsCsvController( + loadTransactionsUseCase, + jsonToCSVAdaptar + ) +} \ No newline at end of file diff --git a/app/src/main/factories/usecases/transaction/index.ts b/app/src/main/factories/usecases/transaction/index.ts index 959e4506..a0dc69ed 100644 --- a/app/src/main/factories/usecases/transaction/index.ts +++ b/app/src/main/factories/usecases/transaction/index.ts @@ -1,3 +1,4 @@ export * from './add-transaction-usecase-factory' export * from './load-transactions-by-user-usecase-factory' -export * from './delete-transaction-by-id-usecase-factory' \ No newline at end of file +export * from './delete-transaction-by-id-usecase-factory' +export * from './load-transactions-usecase-factory' \ No newline at end of file diff --git a/app/src/main/factories/usecases/transaction/load-transactions-usecase-factory.ts b/app/src/main/factories/usecases/transaction/load-transactions-usecase-factory.ts new file mode 100644 index 00000000..743a16d8 --- /dev/null +++ b/app/src/main/factories/usecases/transaction/load-transactions-usecase-factory.ts @@ -0,0 +1,9 @@ +import { DbLoadTransactions } from "@/data/usecases/transactions"; +import { LoadTransactions } from "@/domain/usecases/transactions"; +import { TransactionsMySqlReposiory } from "@/infra/database/sequelize/TransactionsMySqlRepository/transactions-mysql.repository"; + +export function makeLoadTransactionsUseCase(): LoadTransactions { + return new DbLoadTransactions( + new TransactionsMySqlReposiory(), + ) +} \ No newline at end of file diff --git a/app/src/main/routes/transactions-routes.spec.ts b/app/src/main/routes/transactions-routes.spec.ts index 56003911..ee7c17bf 100644 --- a/app/src/main/routes/transactions-routes.spec.ts +++ b/app/src/main/routes/transactions-routes.spec.ts @@ -188,4 +188,32 @@ describe('Transactions Routes', () => { expect(res.statusCode).toBe(200) }) }) + + describe('GET /transactions/csv', () => { + test('should return a csv file according to the transactions', async () => { + const userFrom = await UsersSequelize.create(mockAddUser()) + const userTo = await UsersSequelize.create(mockAddUser()) + const idFrom = userFrom.getDataValue('id') + const idTo = userTo.getDataValue('id') + await TransactionSequelize.bulkCreate( + [ + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + mockAddTransaction(), + ].map(transaction => ({ ...transaction, from: idFrom, to: idTo })) + ) + + const res = await request(app) + .get(`/transactions/csv`) + .query({ userId: idTo }) + + expect(res.statusCode).toBe(200) + expect(res.header['content-type']).toBe('text/csv; charset=utf-8') + }) + + + }); }) diff --git a/app/src/main/routes/transactions-routes.ts b/app/src/main/routes/transactions-routes.ts index 4cb4ab49..36d3aa30 100644 --- a/app/src/main/routes/transactions-routes.ts +++ b/app/src/main/routes/transactions-routes.ts @@ -3,9 +3,11 @@ import { Router } from 'express' import { adaptRoute } from '../adapters/express/express-route-adapter' import { makeAddTransactionController, makeLoadTransactionsByUserController } from '../factories/controllers/transaction' import { makeDeleteTransactionByIdController } from '../factories/controllers/transaction/delete-transaction-by-id-controller-factory' +import { makeLoadTransactionsCsvController } from '../factories/controllers/transaction/load-transactions-csv-controller' export const transactionsRoutes = (router: Router): void => { router.get('/transactions', adaptRoute(makeLoadTransactionsByUserController())) + router.get('/transactions/csv', adaptRoute(makeLoadTransactionsCsvController())) router.post('/transactions', adaptRoute(makeAddTransactionController())) router.delete('/transactions/:id', adaptRoute(makeDeleteTransactionByIdController())) } diff --git a/app/src/main/routes/users-routes.spec.ts b/app/src/main/routes/users-routes.spec.ts index 6302b9cf..e39539f2 100644 --- a/app/src/main/routes/users-routes.spec.ts +++ b/app/src/main/routes/users-routes.spec.ts @@ -104,9 +104,11 @@ describe('Users Routes', () => { test('should delete an user according to the id', async () => { const user = await UsersSequelize.create(mockAddUser()) const id = user.getDataValue('id') - await request(app).delete(`/users/${id}`).expect(204) const usersExists = await UsersSequelize.findOne({ where: { id } }) - expect(usersExists).toBeFalsy() + expect(usersExists).toBeTruthy() + await request(app).delete(`/users/${id}`).expect(204) + const usersAfterDelete = await UsersSequelize.findOne({ where: { id } }) + expect(usersAfterDelete).toBeFalsy() }) }) diff --git a/app/src/presentation/controllers/transactions-controllers/index.ts b/app/src/presentation/controllers/transactions-controllers/index.ts index aac0578a..fcefe6ff 100644 --- a/app/src/presentation/controllers/transactions-controllers/index.ts +++ b/app/src/presentation/controllers/transactions-controllers/index.ts @@ -1,3 +1,4 @@ export * from './add-transaction-controller' export * from './load-transactions-by-user-controller' -export * from './delete-transaction-by-id-controller' \ No newline at end of file +export * from './delete-transaction-by-id-controller' +export * from './load-transactions-csv-controller' \ No newline at end of file diff --git a/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.test.ts b/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.test.ts index 32ea57b6..e92ec4c5 100644 --- a/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.test.ts +++ b/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.test.ts @@ -1,5 +1,6 @@ import { CsvParserSpy } from '@/data/test/mock-csv-parser' import { LoadTransactionsSpy } from '@/domain/tests/mock-transactions' +import { FileResponseGenerator } from '@/presentation/helpers/file-response' import { badRequest, ok, serverError } from '@/presentation/helpers/http-helper' import { faker } from '@faker-js/faker' import { describe, expect, test, vitest } from 'vitest' @@ -40,7 +41,7 @@ describe('LoadTransactionsCsvController', () => { const { sut, loadTransactions, csvParserSpy } = makeSut() await sut.handle({}) - expect(csvParserSpy.input).toEqual(loadTransactions.loadResult) + expect(csvParserSpy.input.length).toBe(loadTransactions.loadResult.length) }); test('should return 500 if csvParser throws', async () => { @@ -55,7 +56,12 @@ describe('LoadTransactionsCsvController', () => { const { sut, csvParserSpy } = makeSut() const response = await sut.handle({}) - expect(response).toEqual(ok(csvParserSpy.result)) + expect(response).toEqual(ok(new FileResponseGenerator().generate({ + data: csvParserSpy.result, + name: 'transactions', + ext: 'csv', + mimetype: 'text/csv', + }))) }) }) }) diff --git a/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.ts b/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.ts index 6c3052fe..52f3d544 100644 --- a/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.ts +++ b/app/src/presentation/controllers/transactions-controllers/load-transactions-csv-controller.ts @@ -1,7 +1,9 @@ import { CsvParser } from '@/data/protocols/utils' import { LoadTransactions } from '@/domain/usecases/transactions' +import { FileResponseGenerator } from '@/presentation/helpers/file-response' import { ok, serverError } from '@/presentation/helpers/http-helper' import { Controller, HttpResponse } from '@/presentation/protocols' +import { FileResponse } from '@/presentation/protocols/file-response' export class LoadTransactionsCsvController implements Controller { constructor( @@ -9,12 +11,28 @@ export class LoadTransactionsCsvController implements Controller { private readonly csvParser: CsvParser ) {} async handle( - params: LoadTransactionsCsvController.Request + params?: LoadTransactionsCsvController.Request ): Promise { try { const transactions = await this.loadTransactionsUseCase.load(params) - const csv = await this.csvParser.parse(transactions) - return ok(csv) + const csv = (await Promise.all( + transactions.map(async (transaction) => { + return await this.csvParser.parse(JSON.stringify(transaction)) + }) + )).join('\n') + let name = 'transactions' + + if(params?.lastDays) { + name += `-last${params.lastDays}days` + } else if(params?.monthAndYear) { + name += `-${params.monthAndYear}` + } + return ok(new FileResponseGenerator().generate({ + data: csv, + name, + ext: 'csv', + mimetype: 'text/csv', + })) } catch (error) { return serverError(error) } @@ -23,5 +41,5 @@ export class LoadTransactionsCsvController implements Controller { export namespace LoadTransactionsCsvController { export type Request = LoadTransactions.Params - export type Response = HttpResponse + export type Response = HttpResponse } \ No newline at end of file diff --git a/app/src/presentation/controllers/users-controller/delete-user-controller.ts b/app/src/presentation/controllers/users-controller/delete-user-controller.ts index f1d44aa0..34a6c030 100644 --- a/app/src/presentation/controllers/users-controller/delete-user-controller.ts +++ b/app/src/presentation/controllers/users-controller/delete-user-controller.ts @@ -14,6 +14,8 @@ export class DeleteUserController implements Controller { }) return noContent() } catch (error) { + console.error('ERRO AO APAGAR USUÁRIO', error); + return serverError(error) } } diff --git a/app/src/presentation/helpers/file-response.ts b/app/src/presentation/helpers/file-response.ts new file mode 100644 index 00000000..9f57761d --- /dev/null +++ b/app/src/presentation/helpers/file-response.ts @@ -0,0 +1,27 @@ +import { FileResponse } from '../protocols/file-response' + +export class FileResponseGenerator { + generate( + request: FileResponseGenerator.Request + ): FileResponseGenerator.Response { + const { data, ...info } = request + const buffer = Buffer.from(data) + + return { + data: buffer, + ...info, + } + } +} + +export namespace FileResponseGenerator { + export type Request = { + data: string + name: string + ext: string + mimetype?: string + size?: number + } + + export type Response = FileResponse +} diff --git a/app/src/presentation/protocols/file-response.ts b/app/src/presentation/protocols/file-response.ts new file mode 100644 index 00000000..8c0e53e3 --- /dev/null +++ b/app/src/presentation/protocols/file-response.ts @@ -0,0 +1,7 @@ +export type FileResponse = { + data: Buffer + ext: string + name: string + mimetype?: string + size?: number +} \ No newline at end of file diff --git a/app/vitest.config.ts b/app/vitest.config.ts index e3b5e349..9317cb4f 100644 --- a/app/vitest.config.ts +++ b/app/vitest.config.ts @@ -6,7 +6,7 @@ export default defineConfig({ coverage: { include: ['src/**/*.ts'], provider: 'istanbul' - } + }, }, plugins: [tsconfigPaths()], }) From 574415a50058b2c7411b9430ac9b43a83e590def Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 16:40:35 -0300 Subject: [PATCH 104/105] =?UTF-8?q?docs:=20cria=20documenta=C3=A7=C3=A3o?= =?UTF-8?q?=20utilizando=20o=20Insomnia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/.env.example | 3 +- app/README.md | 66 ++++++++++++++++++ .../docs/backend_challenge_2022-10-20.json | 1 + app/src/main/docs/html/bundle.css | 15 ++++ app/src/main/docs/html/bundle.css.map | 36 ++++++++++ app/src/main/docs/html/bundle.js | 9 +++ app/src/main/docs/html/bundle.js.map | 1 + app/src/main/docs/html/favicon.ico | Bin 0 -> 33310 bytes app/src/main/docs/html/index.html | 17 +++++ app/src/main/docs/html/insomnia.json | 1 + app/src/main/docs/html/logo.png | Bin 0 -> 1957 bytes 11 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 app/README.md create mode 100644 app/src/main/docs/backend_challenge_2022-10-20.json create mode 100644 app/src/main/docs/html/bundle.css create mode 100644 app/src/main/docs/html/bundle.css.map create mode 100644 app/src/main/docs/html/bundle.js create mode 100644 app/src/main/docs/html/bundle.js.map create mode 100644 app/src/main/docs/html/favicon.ico create mode 100644 app/src/main/docs/html/index.html create mode 100644 app/src/main/docs/html/insomnia.json create mode 100644 app/src/main/docs/html/logo.png diff --git a/app/.env.example b/app/.env.example index 45d559ac..2ea73fd7 100644 --- a/app/.env.example +++ b/app/.env.example @@ -6,4 +6,5 @@ DB_HOST= DB_PORT= DB_USER= DB_PASS= -DB_NAME= \ No newline at end of file +DB_NAME= +DB_DIALECT \ No newline at end of file diff --git a/app/README.md b/app/README.md new file mode 100644 index 00000000..9c059422 --- /dev/null +++ b/app/README.md @@ -0,0 +1,66 @@ +# Desafio Back-End + +# Como executar o projeto +>### Configurações de ambiente +>```bash +># Copie o .env.example para .env +>cp .env.example .env +>``` + +>Depois, coloque as suas variáveis de ambiente: +>```bash +># Ambiente que o NODE está rodando +>NODE_ENV= +> +># Porta que a aplicação rodará (o padrão é a 3000) +>PORT= +> +># Dados do banco de dados +>DB_HOST= +>DB_PORT= +>DB_USER= +>DB_PASS= +>DB_NAME= +>DB_DIALECT= # O padrão é sqlite:memory +>``` + +>### Rode as migrations +>```bash +># Cria o banco de dados +>npx sequelize db:create +> +># Cria as tableas +>npx sequelize db:migrate +>``` + +>### Iniciar o servidor +> ```bash +> # Entre na pasta do projeto +> cd app +> +> # Instale as dependências +> npm install +> +> # Execute a aplicação utilizando +> npm run start +> +> ``` + +# Testes automatizados +A aplicação está com mais de `90%` de cobertura de testes, para conseguir rodar ps testes, os comandos são: +``` bash +# Testes unitários +npm run test:unit + +# Testes de integração +npm run test:integration + +# Todos os testes +npm run test + +# Gerar cobertura de testes +npm run test:coverage +``` + +# Documentação da API +A documentação se encontra na url: `http://localhost:3000/` \ No newline at end of file diff --git a/app/src/main/docs/backend_challenge_2022-10-20.json b/app/src/main/docs/backend_challenge_2022-10-20.json new file mode 100644 index 00000000..cfec23ea --- /dev/null +++ b/app/src/main/docs/backend_challenge_2022-10-20.json @@ -0,0 +1 @@ +{"_type":"export","__export_format":4,"__export_date":"2022-10-20T19:06:47.174Z","__export_source":"insomnia.desktop.app:v2022.6.0","resources":[{"_id":"req_1a7b1ee2f01f4ce2a1621855a3c3351a","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666292507799,"created":1666185103116,"url":"{{baseUrl}}/users/1/transactions","name":"Create User Transaction","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"amount\": 1500,\n\t\"type\": \"debt\",\n\t\"to\": 2\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1666185103116,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_a052e33ed66e4d98834b4bf6cd760389","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666114938461,"created":1666114938461,"name":"Users","description":"","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1666114938461,"_type":"request_group"},{"_id":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","parentId":null,"modified":1666114932310,"created":1666114932310,"name":"BackendChallenge","description":"","scope":"collection","_type":"workspace"},{"_id":"req_f37c3f6499564ea491356edb40740fdc","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666235521765,"created":1666188017345,"url":"{{baseUrl}}/users/1/transactions","name":"Get User Transactions","description":"","method":"GET","body":{},"parameters":[{"id":"pair_0a074b65359146829f9f4feb765b4ba5","name":"page","value":"2","description":""},{"id":"pair_8e4a6d20f778413c90342aabc8318576","name":"perPage","value":"3","description":""}],"headers":[],"authentication":{},"metaSortKey":-1666150021495,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_ce08a86a916b47bbb07b8be9a06b91bf","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666186702358,"created":1666114939874,"url":"{{baseUrl}}/users","name":"Get Users","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1666114939874,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_33367c55d2064f56952a51330682d298","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666123446983,"created":1666123443230,"url":"{{baseUrl}}/users/1","name":"Delete User","description":"","method":"DELETE","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1665817526841.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_9022a9bb05cc45c288bb68601e7b1b7c","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666115032037,"created":1666115028820,"url":"{{baseUrl}}/users/1","name":"Get Users By Id","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1665520113809,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_cf3fb2462edc49b0b3f087a7420a7eea","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666292513172,"created":1666115039543,"url":"{{baseUrl}}/users","name":"Create User","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"name\": \"João Teixeira Ais\",\n\t\"email\": \"joaoteixeiraais@gmail.com\",\n\t\"birthDay\": \"2003-08-26\",\n\t\"password\": \"123321\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1665222700776.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_7c7d33b661bb4542be9eddc0713f95fe","parentId":"fld_1d2b2c2bc6204adb9659454b69e60852","modified":1666292501589,"created":1666236236507,"url":"{{baseUrl}}/transactions","name":"Post Transactions","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"amount\": 1500,\n\t\"type\": \"chargeback\",\n\t\"to\": 2,\n\t\"from\": 1,\n\t \"chargebackFrom\": 1\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1666185103116,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_1d2b2c2bc6204adb9659454b69e60852","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666236236484,"created":1666236236484,"name":"Trasactions","description":"","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1664568081339.5,"_type":"request_group"},{"_id":"req_3bec4a7a6bfe4d42a355f6ba992b641c","parentId":"fld_1d2b2c2bc6204adb9659454b69e60852","modified":1666292497072,"created":1666236236507,"url":"{{baseUrl}}/transactions","name":"Get Transactions","description":"","method":"GET","body":{},"parameters":[{"id":"pair_0a074b65359146829f9f4feb765b4ba5","name":"page","value":"2","description":""},{"id":"pair_8e4a6d20f778413c90342aabc8318576","name":"perPage","value":"3","description":""},{"id":"pair_2f5d823bb1c744179297554bc6356419","name":"userId","value":"1","description":""}],"headers":[],"authentication":{},"metaSortKey":-1666150021495,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_8ae68353e95c4081ad2a743afd848478","parentId":"fld_1d2b2c2bc6204adb9659454b69e60852","modified":1666292155112,"created":1666292152246,"url":"{{baseUrl}}/transactions/csv","name":"Get Transactions CSV","description":"","method":"GET","body":{},"parameters":[{"id":"pair_0a074b65359146829f9f4feb765b4ba5","name":"page","value":"2","description":""},{"id":"pair_8e4a6d20f778413c90342aabc8318576","name":"perPage","value":"3","description":""},{"id":"pair_2f5d823bb1c744179297554bc6356419","name":"userId","value":"1","description":""}],"headers":[],"authentication":{},"metaSortKey":-1666132480684.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_3ccb4c4d6d9247644c2c79a62f41d4e744699ee0","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666114952084,"created":1666114932313,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1666114932313,"_type":"environment"},{"_id":"jar_3ccb4c4d6d9247644c2c79a62f41d4e744699ee0","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666114932314,"created":1666114932314,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_74154c8af1f24d998cc4b26b0897a649","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666114932311,"created":1666114932311,"fileName":"BackendChallenge","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_c7a84395678a441fb7da3e2c70536328","parentId":"env_3ccb4c4d6d9247644c2c79a62f41d4e744699ee0","modified":1666114984073,"created":1666114954031,"name":"localhost","data":{"baseUrl":"http://localhost:3000"},"dataPropertyOrder":{"&":["baseUrl"]},"color":"#04d755","isPrivate":false,"metaSortKey":1666114954031,"_type":"environment"}]} \ No newline at end of file diff --git a/app/src/main/docs/html/bundle.css b/app/src/main/docs/html/bundle.css new file mode 100644 index 00000000..5160caab --- /dev/null +++ b/app/src/main/docs/html/bundle.css @@ -0,0 +1,15 @@ +.item.svelte-u114qp{cursor:default;height:var(--height, 42px);line-height:var(--height, 42px);padding:var(--itemPadding, 0 20px);color:var(--itemColor, inherit);text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.groupHeader.svelte-u114qp{text-transform:var(--groupTitleTextTransform, uppercase)}.groupItem.svelte-u114qp{padding-left:var(--groupItemPaddingLeft, 40px)}.item.svelte-u114qp:active{background:var(--itemActiveBackground, #b9daff)}.item.active.svelte-u114qp{background:var(--itemIsActiveBG, #007aff);color:var(--itemIsActiveColor, #fff)}.item.first.svelte-u114qp{border-radius:var(--itemFirstBorderRadius, 4px 4px 0 0)}.item.hover.svelte-u114qp:not(.active){background:var(--itemHoverBG, #e7f2ff)} +.listContainer.svelte-1rmpqnb{box-shadow:var(--listShadow, 0 2px 3px 0 rgba(44, 62, 80, 0.24));border-radius:var(--listBorderRadius, 4px);max-height:var(--listMaxHeight, 250px);overflow-y:auto;background:var(--listBackground, #fff)}.virtualList.svelte-1rmpqnb{height:var(--virtualListHeight, 200px)}.listGroupTitle.svelte-1rmpqnb{color:var(--groupTitleColor, #8f8f8f);cursor:default;font-size:var(--groupTitleFontSize, 12px);font-weight:var(--groupTitleFontWeight, 600);height:var(--height, 42px);line-height:var(--height, 42px);padding:var(--groupTitlePadding, 0 20px);text-overflow:ellipsis;overflow-x:hidden;white-space:nowrap;text-transform:var(--groupTitleTextTransform, uppercase)}.empty.svelte-1rmpqnb{text-align:var(--listEmptyTextAlign, center);padding:var(--listEmptyPadding, 20px 0);color:var(--listEmptyColor, #78848F)} +.multiSelectItem.svelte-1k6n0vy.svelte-1k6n0vy{background:var(--multiItemBG, #EBEDEF);margin:var(--multiItemMargin, 5px 5px 0 0);border-radius:var(--multiItemBorderRadius, 16px);height:var(--multiItemHeight, 32px);line-height:var(--multiItemHeight, 32px);display:flex;cursor:default;padding:var(--multiItemPadding, 0 10px 0 15px);max-width:100%}.multiSelectItem_label.svelte-1k6n0vy.svelte-1k6n0vy{margin:var(--multiLabelMargin, 0 5px 0 0);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.multiSelectItem.svelte-1k6n0vy.svelte-1k6n0vy:hover,.multiSelectItem.active.svelte-1k6n0vy.svelte-1k6n0vy{background-color:var(--multiItemActiveBG, #006FFF);color:var(--multiItemActiveColor, #fff)}.multiSelectItem.disabled.svelte-1k6n0vy.svelte-1k6n0vy:hover{background:var(--multiItemDisabledHoverBg, #EBEDEF);color:var(--multiItemDisabledHoverColor, #C1C6CC)}.multiSelectItem_clear.svelte-1k6n0vy.svelte-1k6n0vy{border-radius:var(--multiClearRadius, 50%);background:var(--multiClearBG, #52616F);min-width:var(--multiClearWidth, 16px);max-width:var(--multiClearWidth, 16px);height:var(--multiClearHeight, 16px);position:relative;top:var(--multiClearTop, 8px);text-align:var(--multiClearTextAlign, center);padding:var(--multiClearPadding, 1px)}.multiSelectItem_clear.svelte-1k6n0vy.svelte-1k6n0vy:hover,.active.svelte-1k6n0vy .multiSelectItem_clear.svelte-1k6n0vy{background:var(--multiClearHoverBG, #fff)}.multiSelectItem_clear.svelte-1k6n0vy:hover svg.svelte-1k6n0vy,.active.svelte-1k6n0vy .multiSelectItem_clear svg.svelte-1k6n0vy{fill:var(--multiClearHoverFill, #006FFF)}.multiSelectItem_clear.svelte-1k6n0vy svg.svelte-1k6n0vy{fill:var(--multiClearFill, #EBEDEF);vertical-align:top} +.selectContainer.svelte-l63srs.svelte-l63srs{--padding:0 16px;border:var(--border, 1px solid #d8dbdf);border-radius:var(--borderRadius, 3px);height:var(--height, 42px);position:relative;display:flex;align-items:center;padding:var(--padding);background:var(--background, #fff)}.selectContainer.svelte-l63srs input.svelte-l63srs{cursor:default;border:none;color:var(--inputColor, #3f4f5f);height:var(--height, 42px);line-height:var(--height, 42px);padding:var(--inputPadding, var(--padding));width:100%;background:transparent;font-size:var(--inputFontSize, 14px);letter-spacing:var(--inputLetterSpacing, -0.08px);position:absolute;left:var(--inputLeft, 0)}.selectContainer.svelte-l63srs input.svelte-l63srs::placeholder{color:var(--placeholderColor, #78848f);opacity:var(--placeholderOpacity, 1)}.selectContainer.svelte-l63srs input.svelte-l63srs:focus{outline:none}.selectContainer.svelte-l63srs.svelte-l63srs:hover{border-color:var(--borderHoverColor, #b2b8bf)}.selectContainer.focused.svelte-l63srs.svelte-l63srs{border-color:var(--borderFocusColor, #006fe8)}.selectContainer.disabled.svelte-l63srs.svelte-l63srs{background:var(--disabledBackground, #ebedef);border-color:var(--disabledBorderColor, #ebedef);color:var(--disabledColor, #c1c6cc)}.selectContainer.disabled.svelte-l63srs input.svelte-l63srs::placeholder{color:var(--disabledPlaceholderColor, #c1c6cc);opacity:var(--disabledPlaceholderOpacity, 1)}.selectedItem.svelte-l63srs.svelte-l63srs{line-height:var(--height, 42px);height:var(--height, 42px);overflow-x:hidden;padding:var(--selectedItemPadding, 0 20px 0 0)}.selectedItem.svelte-l63srs.svelte-l63srs:focus{outline:none}.clearSelect.svelte-l63srs.svelte-l63srs{position:absolute;right:var(--clearSelectRight, 10px);top:var(--clearSelectTop, 11px);bottom:var(--clearSelectBottom, 11px);width:var(--clearSelectWidth, 20px);color:var(--clearSelectColor, #c5cacf);flex:none !important}.clearSelect.svelte-l63srs.svelte-l63srs:hover{color:var(--clearSelectHoverColor, #2c3e50)}.selectContainer.focused.svelte-l63srs .clearSelect.svelte-l63srs{color:var(--clearSelectFocusColor, #3f4f5f)}.indicator.svelte-l63srs.svelte-l63srs{position:absolute;right:var(--indicatorRight, 10px);top:var(--indicatorTop, 11px);width:var(--indicatorWidth, 20px);height:var(--indicatorHeight, 20px);color:var(--indicatorColor, #c5cacf)}.indicator.svelte-l63srs svg.svelte-l63srs{display:inline-block;fill:var(--indicatorFill, currentcolor);line-height:1;stroke:var(--indicatorStroke, currentcolor);stroke-width:0}.spinner.svelte-l63srs.svelte-l63srs{position:absolute;right:var(--spinnerRight, 10px);top:var(--spinnerLeft, 11px);width:var(--spinnerWidth, 20px);height:var(--spinnerHeight, 20px);color:var(--spinnerColor, #51ce6c);animation:svelte-l63srs-rotate 0.75s linear infinite}.spinner_icon.svelte-l63srs.svelte-l63srs{display:block;height:100%;transform-origin:center center;width:100%;position:absolute;top:0;bottom:0;left:0;right:0;margin:auto;-webkit-transform:none}.spinner_path.svelte-l63srs.svelte-l63srs{stroke-dasharray:90;stroke-linecap:round}.multiSelect.svelte-l63srs.svelte-l63srs{display:flex;padding:var(--multiSelectPadding, 0 35px 0 16px);height:auto;flex-wrap:wrap;align-items:stretch}.multiSelect.svelte-l63srs>.svelte-l63srs{flex:1 1 50px}.selectContainer.multiSelect.svelte-l63srs input.svelte-l63srs{padding:var(--multiSelectInputPadding, 0);position:relative;margin:var(--multiSelectInputMargin, 0)}.hasError.svelte-l63srs.svelte-l63srs{border:var(--errorBorder, 1px solid #ff2d55);background:var(--errorBackground, #fff)}@keyframes svelte-l63srs-rotate{100%{transform:rotate(360deg)}} +.selection.svelte-17yna57{text-overflow:ellipsis;overflow-x:hidden;white-space:nowrap} +svelte-virtual-list-viewport.svelte-8nn5yg{position:relative;overflow-y:auto;-webkit-overflow-scrolling:touch;display:block}svelte-virtual-list-contents.svelte-8nn5yg,svelte-virtual-list-row.svelte-8nn5yg{display:block}svelte-virtual-list-row.svelte-8nn5yg{overflow:hidden} +.hljs{display:block;overflow-x:auto;padding:0.5em;background:#272822;color:#ddd}.hljs-tag,.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-strong,.hljs-name{color:#f92672}.hljs-code{color:#66d9ef}.hljs-class .hljs-title{color:white}.hljs-attribute,.hljs-symbol,.hljs-regexp,.hljs-link{color:#bf79db}.hljs-string,.hljs-bullet,.hljs-subst,.hljs-title,.hljs-section,.hljs-emphasis,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-addition,.hljs-variable,.hljs-template-tag,.hljs-template-variable{color:#a6e22e}.hljs-comment,.hljs-quote,.hljs-deletion,.hljs-meta{color:#75715e}.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-doctag,.hljs-title,.hljs-section,.hljs-type,.hljs-selector-id{font-weight:bold}html,body{position:relative;width:100%}body{color:#333;margin:0;box-sizing:border-box;font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif}h1{font-size:36px}h1,h2,h3,h4{font-weight:normal;margin:0;padding:10px 0}hr{border:none;display:block;height:1px;background:#e7e7e7}a{color:#0064c8;text-decoration:none}a:hover{text-decoration:underline}label{display:block}input,button,select,textarea{font-family:inherit;font-size:inherit;padding:0.4em;margin:0 0 0.5em 0;box-sizing:border-box;border:1px solid #ccc;border-radius:2px}input:disabled{color:#ccc}input[type="range"]{height:0}button{color:#333;background-color:#f4f4f4;outline:none}button:active{background-color:#ddd}button:focus{background-color:#666}.row{display:flex;height:100%}.left,.right{box-sizing:border-box;padding:10px 15px;flex:1;min-width:50%}.left{transition-duration:.2s;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-property:min-width;will-change:transform}.right{background:#232323;color:#fff;max-width:0}.wrapper.hide-right .left{min-width:100%}.sidebar-list-link{display:block;padding:5px 15px;margin-bottom:5px;text-decoration:none;color:#222;border-top-left-radius:5px;border-bottom-left-radius:5px}.sidebar-list-link:hover{background:rgba(0, 0, 0, 0.05);text-decoration:none}.sidebar-list-link.expanded{background:rgba(0, 0, 0, 0.1)}.sidebar-list-link::before,.sidebar-list-link span,.sidebar-list-link strong{display:inline-block;vertical-align:middle}.sidebar-list-link::before{margin-right:7px}.sidebar-list-link strong{font-size:11px;margin-right:5px}.sidebar-list-link strong.get{color:#7d69cb}.sidebar-list-link strong.post{color:#59a210}.sidebar-list-link strong.put{color:#ff9a1f}.sidebar-list-link strong.patch{color:#d07502}.sidebar-list-link strong.delete{color:#d04444}.sidebar-list-link strong.options,.sidebar-list-link strong.head{color:#1c90b4}.request-title{font-weight:600}.request-title strong{display:inline-block;padding:5px 8px;text-transform:uppercase;color:#fff;border-radius:3px;margin-right:10px;font-size:17px;background:#1c90b4}.request-title strong.get{background:#7d69cb}.request-title strong.post{background:#59a210}.request-title strong.put{background:#ff9a1f}.request-title strong.patch{background:#d07502}.request-title strong.delete{background:#d04444}.hljs{padding:0;background:transparent}.description{overflow-x:auto}.description code,.description pre{background:#eee;text-shadow:0 1px #fff;padding:0 .3em;white-space:pre-wrap;overflow-wrap:break-word}.description pre{padding:10px 15px}.description pre code{padding:0}.language-selector .selectContainer{transition:background 150ms linear}.language-selector .selectContainer:hover{background:#454545}.language-selector .selectContainer *{cursor:pointer !important}.table pre{margin:0;background:#efefef;padding:10px;white-space:pre-wrap;overflow-wrap:break-word}.tables .table:last-child{border-bottom:none !important}.hamburger-toggler{display:none}.example-toggler{margin-right:32px;font-size:1.7em;position:relative;color:#6a57d5;bottom:2px}.example-toggler.inactive{color:#c9c9c9}.env-variable{font-weight:bold;color:white;margin:0 1px;background-color:#414141;padding:2px 6px;border-radius:3px}table{background:#fff;border:solid 1px #ddd;margin-bottom:1.25rem;width:100%;border-collapse:collapse}table thead,table tfoot{background:#f5f5f5}table th,table td{color:#222222;padding:0.5rem}table tr:nth-of-type(even){background:#F9F9F9}@media only screen and (max-width: 1000px){aside{display:none}.content{margin-left:0 !important}.row{display:block}.left,.right{width:auto;max-width:100%}.right{padding:0}.language-selector{padding:10px}.language-selector select{margin:0}header .environment span{display:none}header .title{font-size:18px !important}header .logo{margin-left:0 !important;padding:0 !important}header .environment{padding:0 5px !important}header .run,header .example-toggler{display:none !important}.hamburger-toggler{display:inline-block;padding:15px}}header{box-sizing:border-box;position:fixed;top:0;left:0;right:0;border-bottom:1px solid #dedede;background:#fff;z-index:10000;display:flex;justify-content:space-between;height:60px;overflow:hidden}header .header-left,header .header-right{display:flex;align-items:center;flex-wrap:wrap}header .title{padding:0 10px;margin:0;font-size:22px;font-weight:600;display:inline-block;vertical-align:middle}header .hamburger-toggler{vertical-align:middle;font-size:22px;color:#000}header .logo{display:inline-block;vertical-align:middle;padding:0 5px;margin-left:30px;width:48px;height:48px}header .logo img{width:100%;height:100%}header .environment{font-size:13px;padding:0 30px;display:inline-block;vertical-align:middle}header .environment select{margin-bottom:0}header .run{display:inline-block;vertical-align:middle}.wrapper{margin-top:60px} +.error-page.svelte-19j2wr5{width:760px;margin:60px auto 0}@media only screen and ( max-width: 760px ){.error-page.svelte-19j2wr5{width:auto;padding:15px}} +.content.svelte-1jbhgwi{margin-left:260px;overflow-x:hidden}.language-selector.svelte-1jbhgwi{text-align:center}.language-selector.svelte-1jbhgwi{--background:#555;--color:#fff;--listBackground:#343434;--itemHoverBG:#121212;--itemIsActiveBG:#6a57d5;--listMaxHeight:auto;--border:none} +aside.svelte-dekk65{background:#f6f6f6;width:260px;position:fixed;top:60px;left:0;bottom:0;overflow:auto;text-overflow:clip;white-space:nowrap;z-index:10001}aside.visible.svelte-dekk65{display:block} +.anchor.svelte-1suc8s6.svelte-1suc8s6{display:block;position:relative;top:-60px;visibility:hidden;height:0}pre.url.svelte-1suc8s6.svelte-1suc8s6{padding:8px;background:#e9e9e9;border:1px solid #d4d4d4;border-radius:2px;overflow-x:auto}.code-example.svelte-1suc8s6 .header.svelte-1suc8s6{display:flex;justify-content:space-between;background:#404040;color:#fff;font-size:14px;font-weight:600}.code-example.svelte-1suc8s6 .header .title.svelte-1suc8s6,.code-example.svelte-1suc8s6 .header .copy a.svelte-1suc8s6{padding:8px 15px}.code-example.svelte-1suc8s6 .header .copy a.svelte-1suc8s6{display:inline-block;text-decoration:none !important;color:#fff;background:#333}.code-example.svelte-1suc8s6 pre.svelte-1suc8s6{padding:10px 15px;border:1px solid #404040;border-top:0;margin:0;white-space:pre-wrap;overflow-x:auto}.example-response.svelte-1suc8s6.svelte-1suc8s6{margin-top:25px}.example-response.default.svelte-1suc8s6 .header.svelte-1suc8s6{background:#675bc0}.example-response.default.svelte-1suc8s6 pre.svelte-1suc8s6{border-color:#675bc0}.example-response.info.svelte-1suc8s6 .header.svelte-1suc8s6{background:#3949ab}.example-response.info.svelte-1suc8s6 pre.svelte-1suc8s6{border-color:#3949ab}.example-response.success.svelte-1suc8s6 .header.svelte-1suc8s6{background:#43a047}.example-response.success.svelte-1suc8s6 pre.svelte-1suc8s6{border-color:#43a047}.example-response.redirect.svelte-1suc8s6 .header.svelte-1suc8s6{background:#6d4c41}.example-response.redirect.svelte-1suc8s6 pre.svelte-1suc8s6{border-color:#6d4c41}.example-response.client-error.svelte-1suc8s6 .header.svelte-1suc8s6{background:#fb8c00}.example-response.client-error.svelte-1suc8s6 pre.svelte-1suc8s6{border-color:#fb8c00}.example-response.server-error.svelte-1suc8s6 .header.svelte-1suc8s6{background:#e53935}.example-response.server-error.svelte-1suc8s6 pre.svelte-1suc8s6{border-color:#e53935} +.table.svelte-t9o7qk.svelte-t9o7qk{padding:10px 0;border-bottom:1px solid #cdcdcd;margin-bottom:20px}.table.svelte-t9o7qk .header.svelte-t9o7qk{font-size:18px;font-weight:600;margin-bottom:10px}.table.svelte-t9o7qk .header span.svelte-t9o7qk,.table.svelte-t9o7qk .header .note.svelte-t9o7qk{display:inline-block;vertical-align:middle}.table.svelte-t9o7qk .header .note.svelte-t9o7qk{font-size:12px;margin-left:5px;padding:3px 5px;background:#ababab;border-radius:3px;color:#fff}.table.svelte-t9o7qk .row.svelte-t9o7qk{display:flex;justify-content:space-between;font-size:13px}.table.svelte-t9o7qk .row .name.svelte-t9o7qk,.table.svelte-t9o7qk .row .value.svelte-t9o7qk{padding:10px 0;overflow-wrap:break-word}.table.svelte-t9o7qk .row .name.svelte-t9o7qk{font-weight:600;min-width:25%}.table.svelte-t9o7qk .row .value.svelte-t9o7qk{width:75%}.table.svelte-t9o7qk .row.description.svelte-t9o7qk{color:#787878;margin-bottom:10px} +.sidebar-list-link.svelte-7lkbuh::before{font-family:FontAwesome;content:"\f07b"}.sidebar-list-link.expanded.svelte-7lkbuh::before{content:"\f07c"}ul.svelte-7lkbuh{list-style-type:none;padding-inline-start:15px;font-size:12px} + +/*# sourceMappingURL=bundle.css.map */ \ No newline at end of file diff --git a/app/src/main/docs/html/bundle.css.map b/app/src/main/docs/html/bundle.css.map new file mode 100644 index 00000000..28f1701f --- /dev/null +++ b/app/src/main/docs/html/bundle.css.map @@ -0,0 +1,36 @@ +{ + "version": 3, + "file": "bundle.css", + "sources": [ + "Item.svelte", + "List.svelte", + "MultiSelection.svelte", + "Select.svelte", + "Selection.svelte", + "VirtualList.svelte", + "App.svelte", + "ErrorPage.svelte", + "Content.svelte", + "Sidebar.svelte", + "Request.svelte", + "Table.svelte", + "Group.svelte" + ], + "sourcesContent": [ + "\n\n\n\n\n\n
\n {@html getOptionLabel(item, filterText)}\n
\n", + "\n\n\n\n{#if isVirtualList}\n
\n\n \n\n
handleHover(i)}\" on:click=\"{event => handleClick({item, i, event})}\"\n class=\"listItem\">\n \n
\n\n
\n
\n{/if}\n\n{#if !isVirtualList}\n
\n {#each items as item, i}\n {#if item.isGroupHeader && !item.isSelectable}\n
{getGroupHeaderLabel(item)}
\n { :else }\n handleHover(i)}\"\n on:click=\"{event => handleClick({item, i, event})}\"\n class=\"listItem\"\n >\n \n
\n {/if}\n {:else}\n {#if !hideEmptyState}\n
{noOptionsMessage}
\n {/if}\n {/each}\n\n{/if}\n\n\n", + "\n\n{#each selectedValue as value, i}\n
multiFullItemClearable ? handleClear(i, event) : {}}>\n
\n {@html getSelectionLabel(value)}\n
\n {#if !isDisabled && !multiFullItemClearable}\n
handleClear(i, event)}\">\n \n \n \n
\n {/if}\n
\n{/each}\n\n\n\n\n", + "\n\n\n\n\n\n\n\n {#if Icon}\n \n {/if}\n\n {#if isMulti && selectedValue && selectedValue.length > 0}\n \n {/if}\n\n {#if isDisabled}\n \n {:else}\n \n {/if}\n\n {#if !isMulti && showSelectedItem}\n
\n \n
\n {/if}\n\n {#if showSelectedItem && isClearable && !isDisabled && !isWaiting}\n
\n \n
\n {/if}\n\n {#if showIndicator || (showChevron && !selectedValue || (!isSearchable && !isDisabled && !isWaiting && ((showSelectedItem && !isClearable) || !showSelectedItem)))}\n
\n {#if indicatorSvg}\n {@html indicatorSvg}\n {:else}\n \n \n \n {/if}\n
\n {/if}\n\n {#if isWaiting}\n
\n \n \n \n
\n {/if}\n\n", + "\n\n\n\n
\n {@html getSelectionLabel(item)}\n
\n", + "\n\n\n\n\n\t\n\t\t{#each visible as row (row.index)}\n\t\t\t\n\t\t\t\tMissing template\n\t\t\t\n\t\t{/each}\n\t\n\n", + "\n\n\n\n\n {config.workspace.name}\n\n\n
\n
\n \n \n \n\n
\n {config.workspace.name}\n
\n\n

{config.workspace.name}

\n
\n
\n
\n \n \"Run\n \n
\n
\n \n \n
\n \n \n \n
\n
\n\n
\n \n \n
\n", + "\n Uh-oh!\n\n\n
\n

Uh-oh!

\n

\n It looks like it's not possible to retrieve the contents of the API documentation\n at the moment. If you're the owner of this site, make sure that your\n Insomnia JSON file is accessible.\n

\n

\n The developer console of your browser might have more things to say about this error.\n

\n
\n\n\n", + "\n\n
\n
\n
\n

{workspace.name}

\n {#if description}\n
{@html description}
\n {/if}\n
\n
\n
\n \n
\n
\n
\n \n
\n\n\n", + "\n\n\n\n\n", + "\n\n
\n
\n
 
\n

{request.method} {reqData.name}\n

\n
{@html reqData.url}
\n\n {#if description}\n
{@html description}
\n {/if}\n\n
\n\n {#if request.parameters && request.parameters.length}\n \n {/if}\n\n {#if (request.headers && request.headers.length) || (request.authentication && request.authentication.type)}\n
\n {/if}\n\n {#if request.body && (request.body.text || request.body.params)}\n
\n {/if}\n\n \n\n
\n \n
\n
\n
\n
Example request:
\n \n
\n
{@html exampleHTML}
\n
\n {#if reqData.exampleResponses && reqData.exampleResponses.length}\n {#each reqData.exampleResponses as example}\n {#if example.value}\n
\n
\n
Example\n response{ example.code && example.code.length ? ` - ${example.code}` : '' }:\n
\n
\n
{@html hljs.highlightAuto(example.value).value}
\n
\n {/if}\n {/each}\n {/if}\n
\n\n\n\n", + "\n\n
\n
\n {data.title}\n {#if data.note}\n {data.note}\n {/if}\n
\n\n {#if data.text}\n
{@html data.text}
\n {/if}\n\n {#if data.rows && data.rows.length}\n {#each data.rows as row}\n
\n
{row.name}
\n
{@html row.value}
\n
\n {#if row.description}\n
\n {@html row.description}\n
\n {/if}\n {/each}\n {/if}\n
\n\n\n", + "\n\n{#if !root}\n\n {name}\n\n{/if}\n\n{#if expanded}\n
    \n {#each children as child}\n
  • \n {/each}\n {#each requests as request}\n
  • \n {/each}\n
\n{/if}\n\n\n" + ], + "names": [], + "mappings": "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" +} \ No newline at end of file diff --git a/app/src/main/docs/html/bundle.js b/app/src/main/docs/html/bundle.js new file mode 100644 index 00000000..bbeda705 --- /dev/null +++ b/app/src/main/docs/html/bundle.js @@ -0,0 +1,9 @@ +var app=function(){"use strict";function e(){}function t(e,t){for(const n in t)e[n]=t[n];return e}function n(e){return e()}function r(){return Object.create(null)}function a(e){e.forEach(n)}function i(e){return"function"==typeof e}function o(e,t){return e!=e?t==t:e!==t||e&&"object"==typeof e||"function"==typeof e}function s(e,n,r,a){return e[1]&&a?t(r.ctx.slice(),e[1](a(n))):r.ctx}function l(e,t,n,r,a,i,o){const l=function(e,t,n,r){if(e[2]&&r){const a=e[2](r(n));if(void 0===t.dirty)return a;if("object"==typeof a){const e=[],n=Math.max(t.dirty.length,a.length);for(let r=0;re.removeEventListener(t,n,r)}function v(e,t,n){null==n?e.removeAttribute(t):e.getAttribute(t)!==n&&e.setAttribute(t,n)}function y(e,t){const n=Object.getOwnPropertyDescriptors(e.__proto__);for(const r in t)null==t[r]?e.removeAttribute(r):"style"===r?e.style.cssText=t[r]:"__value"===r?e.value=e[r]=t[r]:n[r]&&n[r].set?e[r]=t[r]:v(e,r,t[r])}function k(e,t,n){t in e?e[t]="boolean"==typeof e[t]&&""===n||n:v(e,t,n)}function $(e,t){t=""+t,e.wholeText!==t&&(e.data=t)}function E(e,t){e.value=null==t?"":t}function x(e,t,n,r){e.style.setProperty(t,n,r?"important":"")}function S(e,t){for(let n=0;n{const r=e.$$.callbacks[t];if(r){const a=function(e,t){const n=document.createEvent("CustomEvent");return n.initCustomEvent(e,!1,!1,t),n}(t,n);r.slice().forEach(t=>{t.call(e,a)})}}}const H=[],z=[],B=[],q=[],D=Promise.resolve();let U=!1;function F(){U||(U=!0,D.then(J))}function G(){return F(),D}function V(e){B.push(e)}let W=!1;const K=new Set;function J(){if(!W){W=!0;do{for(let e=0;e{Q.delete(e),r&&(n&&e.d(1),r())}),e.o(t)}}function re(e,t){ne(e,1,1,()=>{t.delete(e.key)})}function ae(e,t){const n={},r={},a={$$scope:1};let i=e.length;for(;i--;){const o=e[i],s=t[i];if(s){for(const e in o)e in s||(r[e]=1);for(const e in s)a[e]||(n[e]=s[e],a[e]=1);e[i]=s}else for(const e in o)a[e]=1}for(const e in r)e in n||(n[e]=void 0);return n}function ie(e){return"object"==typeof e&&null!==e?e:{}}function oe(e){e&&e.c()}function se(e,t,r,o){const{fragment:s,on_mount:l,on_destroy:c,after_update:u}=e.$$;s&&s.m(t,r),o||V(()=>{const t=l.map(n).filter(i);c?c.push(...t):a(t),e.$$.on_mount=[]}),u.forEach(V)}function le(e,t){const n=e.$$;null!==n.fragment&&(a(n.on_destroy),n.fragment&&n.fragment.d(t),n.on_destroy=n.fragment=null,n.ctx=[])}function ce(t,n,i,o,s,l,c=[-1]){const u=A;T(t);const d=t.$$={fragment:null,ctx:null,props:l,update:e,not_equal:s,bound:r(),on_mount:[],on_destroy:[],on_disconnect:[],before_update:[],after_update:[],context:new Map(u?u.$$.context:n.context||[]),callbacks:r(),dirty:c,skip_bound:!1};let h=!1;if(d.ctx=i?i(t,n.props||{},(e,n,...r)=>{const a=r.length?r[0]:n;return d.ctx&&s(d.ctx[e],d.ctx[e]=a)&&(!d.skip_bound&&d.bound[e]&&d.bound[e](a),h&&function(e,t){-1===e.$$.dirty[0]&&(H.push(e),F(),e.$$.dirty.fill(0)),e.$$.dirty[t/31|0]|=1<{const e=n.indexOf(t);-1!==e&&n.splice(e,1)}}$set(e){var t;this.$$set&&(t=e,0!==Object.keys(t).length)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}function de(t){let n,r,a,i,o,s,l,c,h=t[0].method+"",f=t[0].name+"";return{c(){n=g("a"),r=g("strong"),a=m(h),o=b(),s=g("span"),l=m(f),v(r,"class",i=t[0].method.toLowerCase()),v(n,"href",c="#"+t[0]._id),v(n,"class","sidebar-list-link name")},m(e,t){d(e,n,t),u(n,r),u(r,a),u(n,o),u(n,s),u(s,l)},p(e,[t]){1&t&&h!==(h=e[0].method+"")&&$(a,h),1&t&&i!==(i=e[0].method.toLowerCase())&&v(r,"class",i),1&t&&f!==(f=e[0].name+"")&&$(l,f),1&t&&c!==(c="#"+e[0]._id)&&v(n,"href",c)},i:e,o:e,d(e){e&&p(n)}}}function pe(e,t,n){let{request:r}=t;return e.$$set=e=>{"request"in e&&n(0,r=e.request)},[r]}class he extends ue{constructor(e){super(),ce(this,e,pe,de,o,{request:0})}}function ge(e,t,n){const r=e.slice();return r[6]=t[n],r}function fe(e,t,n){const r=e.slice();return r[9]=t[n],r}function me(e){let t,n,r,a,i;return{c(){t=g("a"),n=g("span"),r=m(e[2]),v(t,"href","javascript:;"),v(t,"class","sidebar-list-link name svelte-7lkbuh"),M(t,"expanded",e[0])},m(o,s){d(o,t,s),u(t,n),u(n,r),a||(i=w(t,"click",e[5]),a=!0)},p(e,n){4&n&&$(r,e[2]),1&n&&M(t,"expanded",e[0])},d(e){e&&p(t),a=!1,i()}}}function be(e){let t,n,r,a=e[3],i=[];for(let t=0;tne(i[e],1,1,()=>{i[e]=null});let s=e[4],l=[];for(let t=0;tne(l[e],1,1,()=>{l[e]=null});return{c(){t=g("ul");for(let e=0;e{i=null}),ee())},i(e){r||(te(i),r=!0)},o(e){ne(i),r=!1},d(e){a&&a.d(e),e&&p(t),i&&i.d(e),e&&p(n)}}}function ye(e,t,n){let{root:r=!1}=t,{expanded:a=!1}=t,{name:i}=t,{children:o}=t,{requests:s}=t;return e.$$set=e=>{"root"in e&&n(1,r=e.root),"expanded"in e&&n(0,a=e.expanded),"name"in e&&n(2,i=e.name),"children"in e&&n(3,o=e.children),"requests"in e&&n(4,s=e.requests)},[a,r,i,o,s,function(){n(0,a=!a)}]}class ke extends ue{constructor(e){super(),ce(this,e,ye,ve,o,{root:1,expanded:0,name:2,children:3,requests:4})}}function $e(e){let t,n,r;return n=new ke({props:{name:e[2].name,children:e[1],requests:e[0],root:!0,expanded:!0}}),{c(){t=g("aside"),oe(n.$$.fragment),v(t,"class","svelte-dekk65"),M(t,"visible",e[3])},m(e,a){d(e,t,a),se(n,t,null),r=!0},p(e,[r]){const a={};4&r&&(a.name=e[2].name),2&r&&(a.children=e[1]),1&r&&(a.requests=e[0]),n.$set(a),8&r&&M(t,"visible",e[3])},i(e){r||(te(n.$$.fragment,e),r=!0)},o(e){ne(n.$$.fragment,e),r=!1},d(e){e&&p(t),le(n)}}}function Ee(e,t,n){let{requests:r}=t,{groups:a}=t,{workspace:i}=t,{visible:o}=t;return e.$$set=e=>{"requests"in e&&n(0,r=e.requests),"groups"in e&&n(1,a=e.groups),"workspace"in e&&n(2,i=e.workspace),"visible"in e&&n(3,o=e.visible)},[r,a,i,o]}class xe extends ue{constructor(e){super(),ce(this,e,Ee,$e,o,{requests:0,groups:1,workspace:2,visible:3})}}function Se(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((function(t){var n=e[t];"object"!=typeof n||Object.isFrozen(n)||Se(n)})),e}var Ce=Se,Ae=Se;Ce.default=Ae;class Le{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function Me(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function je(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t];return t.forEach((function(e){for(const t in e)n[t]=e[t]})),n}const Te=e=>!!e.kind;class Ie{constructor(e,t){this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){this.buffer+=Me(e)}openNode(e){if(!Te(e))return;let t=e.kind;e.sublanguage||(t=`${this.classPrefix}${t}`),this.span(t)}closeNode(e){Te(e)&&(this.buffer+="")}value(){return this.buffer}span(e){this.buffer+=``}}class Ne{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const t={kind:e,children:[]};this.add(t),this.stack.push(t)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t),t.children.forEach(t=>this._walk(e,t)),e.closeNode(t)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{Ne._collapse(e)}))}}class Oe extends Ne{constructor(e){super(),this.options=e}addKeyword(e,t){""!==e&&(this.openNode(t),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,t){const n=e.root;n.kind=t,n.sublanguage=!0,this.add(n)}toHTML(){return new Ie(this,this.options).value()}finalize(){return!0}}function Pe(e){return e?"string"==typeof e?e:e.source:null}const Re=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;const He="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",ze={begin:"\\\\[\\s\\S]",relevance:0},Be={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[ze]},qe={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[ze]},De={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},Ue=function(e,t,n={}){const r=je({className:"comment",begin:e,end:t,contains:[]},n);return r.contains.push(De),r.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),r},Fe=Ue("//","$"),Ge=Ue("/\\*","\\*/"),Ve=Ue("#","$"),We={className:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},Ke={className:"number",begin:He,relevance:0},Je={className:"number",begin:"\\b(0b[01]+)",relevance:0},Ze={className:"number",begin:"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},Qe={begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[ze,{begin:/\[/,end:/\]/,relevance:0,contains:[ze]}]}]},Xe={className:"title",begin:"[a-zA-Z]\\w*",relevance:0},Ye={className:"title",begin:"[a-zA-Z_]\\w*",relevance:0},et={begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0};var tt=Object.freeze({__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:"[a-zA-Z]\\w*",UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:He,BINARY_NUMBER_RE:"\\b(0b[01]+)",RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map(e=>Pe(e)).join("")}(t,/.*\b/,e.binary,/\b.*/)),je({className:"meta",begin:t,end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)},BACKSLASH_ESCAPE:ze,APOS_STRING_MODE:Be,QUOTE_STRING_MODE:qe,PHRASAL_WORDS_MODE:De,COMMENT:Ue,C_LINE_COMMENT_MODE:Fe,C_BLOCK_COMMENT_MODE:Ge,HASH_COMMENT_MODE:Ve,NUMBER_MODE:We,C_NUMBER_MODE:Ke,BINARY_NUMBER_MODE:Je,CSS_NUMBER_MODE:Ze,REGEXP_MODE:Qe,TITLE_MODE:Xe,UNDERSCORE_TITLE_MODE:Ye,METHOD_GUARD:et,END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{t.data._beginMatch!==e[1]&&t.ignoreMatch()}})}});function nt(e,t){"."===e.input[e.index-1]&&t.ignoreMatch()}function rt(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=nt,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,void 0===e.relevance&&(e.relevance=0))}function at(e,t){Array.isArray(e.illegal)&&(e.illegal=function(...e){return"("+e.map(e=>Pe(e)).join("|")+")"}(...e.illegal))}function it(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function ot(e,t){void 0===e.relevance&&(e.relevance=1)}const st=["of","and","for","in","not","or","if","then","parent","list","value"];function lt(e,t){return t?Number(t):function(e){return st.includes(e.toLowerCase())}(e)?0:1}function ct(e,{plugins:t}){function n(t,n){return new RegExp(Pe(t),"m"+(e.case_insensitive?"i":"")+(n?"g":""))}class r{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,t){t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),this.matchAt+=function(e){return new RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map(e=>e[1]);this.matcherRe=n(function(e,t="|"){let n=0;return e.map(e=>{n+=1;const t=n;let r=Pe(e),a="";for(;r.length>0;){const e=Re.exec(r);if(!e){a+=r;break}a+=r.substring(0,e.index),r=r.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?a+="\\"+String(Number(e[1])+t):(a+=e[0],"("===e[0]&&n++)}return a}).map(e=>`(${e})`).join(t)}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const t=this.matcherRe.exec(e);if(!t)return null;const n=t.findIndex((e,t)=>t>0&&void 0!==e),r=this.matchIndexes[n];return t.splice(0,n),Object.assign(t,r)}}class a{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const t=new r;return this.rules.slice(e).forEach(([e,n])=>t.addRule(e,n)),t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex;let n=t.exec(e);if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}return n&&(this.regexIndex+=n.position+1,this.regexIndex===this.count&&this.considerAll()),n}}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=je(e.classNameAliases||{}),function t(r,i){const o=r;if(r.isCompiled)return o;[it].forEach(e=>e(r,i)),e.compilerExtensions.forEach(e=>e(r,i)),r.__beforeBegin=null,[rt,at,ot].forEach(e=>e(r,i)),r.isCompiled=!0;let s=null;if("object"==typeof r.keywords&&(s=r.keywords.$pattern,delete r.keywords.$pattern),r.keywords&&(r.keywords=function e(t,n,r="keyword"){const a={};return"string"==typeof t?i(r,t.split(" ")):Array.isArray(t)?i(r,t):Object.keys(t).forEach((function(r){Object.assign(a,e(t[r],n,r))})),a;function i(e,t){n&&(t=t.map(e=>e.toLowerCase())),t.forEach((function(t){const n=t.split("|");a[n[0]]=[e,lt(n[0],n[1])]}))}}(r.keywords,e.case_insensitive)),r.lexemes&&s)throw new Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return s=s||r.lexemes||/\w+/,o.keywordPatternRe=n(s,!0),i&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(r.begin),r.endSameAsBegin&&(r.end=r.begin),r.end||r.endsWithParent||(r.end=/\B|\b/),r.end&&(o.endRe=n(r.end)),o.terminatorEnd=Pe(r.end)||"",r.endsWithParent&&i.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+i.terminatorEnd)),r.illegal&&(o.illegalRe=n(r.illegal)),r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((function(e){return function(e){e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((function(t){return je(e,{variants:null},t)})));if(e.cachedVariants)return e.cachedVariants;if(function e(t){return!!t&&(t.endsWithParent||e(t.starts))}(e))return je(e,{starts:e.starts?je(e.starts):null});if(Object.isFrozen(e))return je(e);return e}("self"===e?r:e)}))),r.contains.forEach((function(e){t(e,o)})),r.starts&&t(r.starts,i),o.matcher=function(e){const t=new a;return e.contains.forEach(e=>t.addRule(e.begin,{rule:e,type:"begin"})),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end"}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t}(o),o}(e)}function ut(e){const t={props:["language","code","autodetect"],data:function(){return{detectedLanguage:"",unknownLanguage:!1}},computed:{className(){return this.unknownLanguage?"":"hljs "+this.detectedLanguage},highlighted(){if(!this.autoDetect&&!e.getLanguage(this.language))return console.warn(`The language "${this.language}" you specified could not be found.`),this.unknownLanguage=!0,Me(this.code);let t={};return this.autoDetect?(t=e.highlightAuto(this.code),this.detectedLanguage=t.language):(t=e.highlight(this.language,this.code,this.ignoreIllegals),this.detectedLanguage=this.language),t.value},autoDetect(){return!this.language||(e=this.autodetect,Boolean(e||""===e));var e},ignoreIllegals:()=>!0},render(e){return e("pre",{},[e("code",{class:this.className,domProps:{innerHTML:this.highlighted}})])}};return{Component:t,VuePlugin:{install(e){e.component("highlightjs",t)}}}}const dt={"after:highlightElement":({el:e,result:t,text:n})=>{const r=ht(e);if(!r.length)return;const a=document.createElement("div");a.innerHTML=t.value,t.value=function(e,t,n){let r=0,a="";const i=[];function o(){return e.length&&t.length?e[0].offset!==t[0].offset?e[0].offset"}function l(e){a+=""}function c(e){("start"===e.event?s:l)(e.node)}for(;e.length||t.length;){let t=o();if(a+=Me(n.substring(r,t[0].offset)),r=t[0].offset,t===e){i.reverse().forEach(l);do{c(t.splice(0,1)[0]),t=o()}while(t===e&&t.length&&t[0].offset===r);i.reverse().forEach(s)}else"start"===t[0].event?i.push(t[0].node):i.pop(),c(t.splice(0,1)[0])}return a+Me(n.substr(r))}(r,ht(a),n)}};function pt(e){return e.nodeName.toLowerCase()}function ht(e){const t=[];return function e(n,r){for(let a=n.firstChild;a;a=a.nextSibling)3===a.nodeType?r+=a.nodeValue.length:1===a.nodeType&&(t.push({event:"start",offset:r,node:a}),r=e(a,r),pt(a).match(/br|hr|img|input/)||t.push({event:"stop",offset:r,node:a}));return r}(e,0),t}const gt={},ft=e=>{console.error(e)},mt=(e,...t)=>{console.log("WARN: "+e,...t)},bt=(e,t)=>{gt[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),gt[`${e}/${t}`]=!0)},_t=Me,wt=je,vt=Symbol("nomatch");var yt=function(e){const t=Object.create(null),n=Object.create(null),r=[];let a=!0;const i=/(^(<[^>]+>|\t|)+|\n)/gm,o="Could not find the language '{}', did you forget to load/include a language module?",s={disableAutodetect:!0,name:"Plain text",contains:[]};let l={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:Oe};function c(e){return l.noHighlightRe.test(e)}function u(e,t,n,r){let a="",i="";"object"==typeof t?(a=e,n=t.ignoreIllegals,i=t.language,r=void 0):(bt("10.7.0","highlight(lang, code, ...args) has been deprecated."),bt("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),i=e,a=t);const o={code:a,language:i};$("before:highlight",o);const s=o.result?o.result:d(o.language,o.code,n,r);return s.code=o.code,$("after:highlight",s),s}function d(e,n,i,s){function c(e,t){const n=w.case_insensitive?t[0].toLowerCase():t[0];return Object.prototype.hasOwnProperty.call(e.keywords,n)&&e.keywords[n]}function u(){null!=$.subLanguage?function(){if(""===S)return;let e=null;if("string"==typeof $.subLanguage){if(!t[$.subLanguage])return void x.addText(S);e=d($.subLanguage,S,!0,E[$.subLanguage]),E[$.subLanguage]=e.top}else e=p(S,$.subLanguage.length?$.subLanguage:null);$.relevance>0&&(C+=e.relevance),x.addSublanguage(e.emitter,e.language)}():function(){if(!$.keywords)return void x.addText(S);let e=0;$.keywordPatternRe.lastIndex=0;let t=$.keywordPatternRe.exec(S),n="";for(;t;){n+=S.substring(e,t.index);const r=c($,t);if(r){const[e,a]=r;if(x.addText(n),n="",C+=a,e.startsWith("_"))n+=t[0];else{const n=w.classNameAliases[e]||e;x.addKeyword(t[0],n)}}else n+=t[0];e=$.keywordPatternRe.lastIndex,t=$.keywordPatternRe.exec(S)}n+=S.substr(e),x.addText(n)}(),S=""}function h(e){return e.className&&x.openNode(w.classNameAliases[e.className]||e.className),$=Object.create(e,{parent:{value:$}}),$}function g(e){return 0===$.matcher.regexIndex?(S+=e[0],1):(M=!0,0)}function f(e){const t=e[0],n=e.rule,r=new Le(n),a=[n.__beforeBegin,n["on:begin"]];for(const n of a)if(n&&(n(e,r),r.isMatchIgnored))return g(t);return n&&n.endSameAsBegin&&(n.endRe=new RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),n.skip?S+=t:(n.excludeBegin&&(S+=t),u(),n.returnBegin||n.excludeBegin||(S=t)),h(n),n.returnBegin?0:t.length}function m(e){const t=e[0],r=n.substr(e.index),a=function e(t,n,r){let a=function(e,t){const n=e&&e.exec(t);return n&&0===n.index}(t.endRe,r);if(a){if(t["on:end"]){const e=new Le(t);t["on:end"](n,e),e.isMatchIgnored&&(a=!1)}if(a){for(;t.endsParent&&t.parent;)t=t.parent;return t}}if(t.endsWithParent)return e(t.parent,n,r)}($,e,r);if(!a)return vt;const i=$;i.skip?S+=t:(i.returnEnd||i.excludeEnd||(S+=t),u(),i.excludeEnd&&(S=t));do{$.className&&x.closeNode(),$.skip||$.subLanguage||(C+=$.relevance),$=$.parent}while($!==a.parent);return a.starts&&(a.endSameAsBegin&&(a.starts.endRe=a.endRe),h(a.starts)),i.returnEnd?0:t.length}let b={};function _(t,r){const o=r&&r[0];if(S+=t,null==o)return u(),0;if("begin"===b.type&&"end"===r.type&&b.index===r.index&&""===o){if(S+=n.slice(r.index,r.index+1),!a){const t=new Error("0 width match regex");throw t.languageName=e,t.badRule=b.rule,t}return 1}if(b=r,"begin"===r.type)return f(r);if("illegal"===r.type&&!i){const e=new Error('Illegal lexeme "'+o+'" for mode "'+($.className||"")+'"');throw e.mode=$,e}if("end"===r.type){const e=m(r);if(e!==vt)return e}if("illegal"===r.type&&""===o)return 1;if(L>1e5&&L>3*r.index){throw new Error("potential infinite loop, way more iterations than matches")}return S+=o,o.length}const w=v(e);if(!w)throw ft(o.replace("{}",e)),new Error('Unknown language: "'+e+'"');const y=ct(w,{plugins:r});let k="",$=s||y;const E={},x=new l.__emitter(l);!function(){const e=[];for(let t=$;t!==w;t=t.parent)t.className&&e.unshift(t.className);e.forEach(e=>x.openNode(e))}();let S="",C=0,A=0,L=0,M=!1;try{for($.matcher.considerAll();;){L++,M?M=!1:$.matcher.considerAll(),$.matcher.lastIndex=A;const e=$.matcher.exec(n);if(!e)break;const t=_(n.substring(A,e.index),e);A=e.index+t}return _(n.substr(A)),x.closeAllNodes(),x.finalize(),k=x.toHTML(),{relevance:Math.floor(C),value:k,language:e,illegal:!1,emitter:x,top:$}}catch(t){if(t.message&&t.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:t.message,context:n.slice(A-100,A+100),mode:t.mode},sofar:k,relevance:0,value:_t(n),emitter:x};if(a)return{illegal:!1,relevance:0,value:_t(n),emitter:x,language:e,top:$,errorRaised:t};throw t}}function p(e,n){n=n||l.languages||Object.keys(t);const r=function(e){const t={relevance:0,emitter:new l.__emitter(l),value:_t(e),illegal:!1,top:s};return t.emitter.addText(e),t}(e),a=n.filter(v).filter(k).map(t=>d(t,e,!1));a.unshift(r);const i=a.sort((e,t)=>{if(e.relevance!==t.relevance)return t.relevance-e.relevance;if(e.language&&t.language){if(v(e.language).supersetOf===t.language)return 1;if(v(t.language).supersetOf===e.language)return-1}return 0}),[o,c]=i,u=o;return u.second_best=c,u}const h={"before:highlightElement":({el:e})=>{l.useBR&&(e.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"))},"after:highlightElement":({result:e})=>{l.useBR&&(e.value=e.value.replace(/\n/g,"
"))}},g=/^(<[^>]+>|\t)+/gm,f={"after:highlightElement":({result:e})=>{l.tabReplace&&(e.value=e.value.replace(g,e=>e.replace(/\t/g,l.tabReplace)))}};function m(e){let t=null;const r=function(e){let t=e.className+" ";t+=e.parentNode?e.parentNode.className:"";const n=l.languageDetectRe.exec(t);if(n){const t=v(n[1]);return t||(mt(o.replace("{}",n[1])),mt("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"}return t.split(/\s+/).find(e=>c(e)||v(e))}(e);if(c(r))return;$("before:highlightElement",{el:e,language:r}),t=e;const a=t.textContent,i=r?u(a,{language:r,ignoreIllegals:!0}):p(a);$("after:highlightElement",{el:e,result:i,text:a}),e.innerHTML=i.value,function(e,t,r){const a=t?n[t]:r;e.classList.add("hljs"),a&&e.classList.add(a)}(e,r,i.language),e.result={language:i.language,re:i.relevance,relavance:i.relevance},i.second_best&&(e.second_best={language:i.second_best.language,re:i.second_best.relevance,relavance:i.second_best.relevance})}const b=()=>{if(b.called)return;b.called=!0,bt("10.6.0","initHighlighting() is deprecated. Use highlightAll() instead.");document.querySelectorAll("pre code").forEach(m)};let _=!1;function w(){if("loading"===document.readyState)return void(_=!0);document.querySelectorAll("pre code").forEach(m)}function v(e){return e=(e||"").toLowerCase(),t[e]||t[n[e]]}function y(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach(e=>{n[e.toLowerCase()]=t})}function k(e){const t=v(e);return t&&!t.disableAutodetect}function $(e,t){const n=e;r.forEach((function(e){e[n]&&e[n](t)}))}"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(function(){_&&w()}),!1),Object.assign(e,{highlight:u,highlightAuto:p,highlightAll:w,fixMarkup:function(e){return bt("10.2.0","fixMarkup will be removed entirely in v11.0"),bt("10.2.0","Please see https://github.com/highlightjs/highlight.js/issues/2534"),t=e,l.tabReplace||l.useBR?t.replace(i,e=>"\n"===e?l.useBR?"
":e:l.tabReplace?e.replace(/\t/g,l.tabReplace):e):t;var t},highlightElement:m,highlightBlock:function(e){return bt("10.7.0","highlightBlock will be removed entirely in v12.0"),bt("10.7.0","Please use highlightElement now."),m(e)},configure:function(e){e.useBR&&(bt("10.3.0","'useBR' will be removed entirely in v11.0"),bt("10.3.0","Please see https://github.com/highlightjs/highlight.js/issues/2559")),l=wt(l,e)},initHighlighting:b,initHighlightingOnLoad:function(){bt("10.6.0","initHighlightingOnLoad() is deprecated. Use highlightAll() instead."),_=!0},registerLanguage:function(n,r){let i=null;try{i=r(e)}catch(e){if(ft("Language definition for '{}' could not be registered.".replace("{}",n)),!a)throw e;ft(e),i=s}i.name||(i.name=n),t[n]=i,i.rawDefinition=r.bind(null,e),i.aliases&&y(i.aliases,{languageName:n})},unregisterLanguage:function(e){delete t[e];for(const t of Object.keys(n))n[t]===e&&delete n[t]},listLanguages:function(){return Object.keys(t)},getLanguage:v,registerAliases:y,requireLanguage:function(e){bt("10.4.0","requireLanguage will be removed entirely in v11."),bt("10.4.0","Please see https://github.com/highlightjs/highlight.js/pull/2844");const t=v(e);if(t)return t;throw new Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:k,inherit:wt,addPlugin:function(e){!function(e){e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{e["before:highlightBlock"](Object.assign({block:t.el},t))}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{e["after:highlightBlock"](Object.assign({block:t.el},t))})}(e),r.push(e)},vuePlugin:ut(e).VuePlugin}),e.debugMode=function(){a=!1},e.safeMode=function(){a=!0},e.versionString="10.7.2";for(const e in tt)"object"==typeof tt[e]&&Ce(tt[e]);return Object.assign(e,tt),e.addPlugin(h),e.addPlugin(dt),e.addPlugin(f),e}({});const kt=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],$t=["true","false","null","undefined","NaN","Infinity"],Et=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer","BigInt64Array","BigUint64Array","BigInt"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function xt(e){return St("(?=",e,")")}function St(...e){return e.map(e=>{return(t=e)?"string"==typeof t?t:t.source:null;var t}).join("")}var Ct=function(e){const t="[A-Za-z$_][0-9A-Za-z$_]*",n="<>",r="",a={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,t)=>{const n=e[0].length+e.index,r=e.input[n];"<"!==r?">"===r&&(((e,{after:t})=>{const n="",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i,contains:f}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:n,end:r},{begin:a.begin,"on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[{;]/,excludeEnd:!0,keywords:i,contains:["self",e.inherit(e.TITLE_MODE,{begin:t}),m],illegal:/%/},{beginKeywords:"while if switch catch for"},{className:"function",begin:e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,contains:[m,e.inherit(e.TITLE_MODE,{begin:t})]},{variants:[{begin:"\\."+t},{begin:"\\$"+t}],relevance:0},{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"[\]]/,contains:[{beginKeywords:"extends"},e.UNDERSCORE_TITLE_MODE]},{begin:/\b(?=constructor)/,end:/[{;]/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:t}),"self",m]},{begin:"(get|set)\\s+(?="+t+"\\()",end:/\{/,keywords:"get set",contains:[e.inherit(e.TITLE_MODE,{begin:t}),{begin:/\(\)/},m]},{begin:/\$[(.]/}]}};function At(e){return function(...e){return e.map(e=>{return(t=e)?"string"==typeof t?t:t.source:null;var t}).join("")}("(?=",e,")")}var Lt=function(e){const t={$pattern:/[A-Za-z]\w+|__\w+__/,keyword:["and","as","assert","async","await","break","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"],literal:["__debug__","Ellipsis","False","None","NotImplemented","True"],type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"]},n={className:"meta",begin:/^(>>>|\.\.\.) /},r={className:"subst",begin:/\{/,end:/\}/,keywords:t,illegal:/#/},a={begin:/\{\{/,relevance:0},i={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,n],relevance:10},{begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,n],relevance:10},{begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,n,a,r]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,n,a,r]},{begin:/([uU]|[rR])'/,end:/'/,relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/,end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,a,r]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,a,r]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},o="[0-9](_?[0-9])*",s=`(\\b(${o}))?\\.(${o})|\\b(${o})\\.`,l={className:"number",relevance:0,variants:[{begin:`(\\b(${o})|(${s}))[eE][+-]?(${o})[jJ]?\\b`},{begin:`(${s})[jJ]?`},{begin:"\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?\\b"},{begin:"\\b0[bB](_?[01])+[lL]?\\b"},{begin:"\\b0[oO](_?[0-7])+[lL]?\\b"},{begin:"\\b0[xX](_?[0-9a-fA-F])+[lL]?\\b"},{begin:`\\b(${o})[jJ]\\b`}]},c={className:"comment",begin:At(/# type:/),end:/$/,keywords:t,contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},u={className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:["self",n,l,i,e.HASH_COMMENT_MODE]}]};return r.contains=[i,l,n],{name:"Python",aliases:["py","gyp","ipython"],keywords:t,illegal:/(<\/|->|\?)|=>/,contains:[n,l,{begin:/\bself\b/},{beginKeywords:"if",relevance:0},i,c,e.HASH_COMMENT_MODE,{variants:[{className:"function",beginKeywords:"def"},{className:"class",beginKeywords:"class"}],end:/:/,illegal:/[${=;\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,u,{begin:/->/,endsWithParent:!0,keywords:t}]},{className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[l,u,i]}]}};function Mt(...e){return e.map(e=>{return(t=e)?"string"==typeof t?t:t.source:null;var t}).join("")}var jt=function(e){const t={},n={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{className:"variable",variants:[{begin:Mt(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},n]});const r={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},a={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},i={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,t,r]};r.contains.push(i);const o={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t]},s=e.SHEBANG({binary:`(${["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"].join("|")})`,relevance:10}),l={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b[a-z._-]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp"},contains:[s,e.SHEBANG(),l,o,e.HASH_COMMENT_MODE,a,i,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},t]}};function Tt(...e){return e.map(e=>{return(t=e)?"string"==typeof t?t:t.source:null;var t}).join("")}var It=function(e){const t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",n={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor __FILE__",built_in:"proc lambda",literal:"true false nil"},r={className:"doctag",begin:"@[A-Za-z]+"},a={begin:"#<",end:">"},i=[e.COMMENT("#","$",{contains:[r]}),e.COMMENT("^=begin","^=end",{contains:[r],relevance:10}),e.COMMENT("^__END__","\\n$")],o={className:"subst",begin:/#\{/,end:/\}/,keywords:n},s={className:"string",contains:[e.BACKSLASH_ESCAPE,o],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{begin:/%[qQwWx]?\//,end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{begin:/<<[-~]?'?(\w+)\n(?:[^\n]*\n)*?\s*\1\b/,returnBegin:!0,contains:[{begin:/<<[-~]?'?/},e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,o]})]}]},l={className:"number",relevance:0,variants:[{begin:"\\b([1-9](_?[0-9])*|0)(\\.([0-9](_?[0-9])*))?([eE][+-]?([0-9](_?[0-9])*)|r)?i?\\b"},{begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{begin:"\\b0(_?[0-7])+r?i?\\b"}]},c={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:n},u=[s,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE,relevance:0}]}].concat(i)},{className:"function",begin:Tt(/def\s+/,(d=t+"\\s*(\\(|;|$)",Tt("(?=",d,")"))),relevance:0,keywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:t}),c].concat(i)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[s,{begin:t}],relevance:0},l,{className:"variable",begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{className:"params",begin:/\|/,end:/\|/,relevance:0,keywords:n},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,o],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(a,i),relevance:0}].concat(a,i);var d;o.contains=u,c.contains=u;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:u}},{className:"meta",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])",starts:{end:"$",contains:u}}];return i.unshift(a),{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:n,illegal:/\/\*/,contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(i).concat(u)}};var Nt=function(e){const t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{name:"Go",aliases:["golang"],keywords:t,illegal:"/}]},r={className:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]},a=e.inherit(e.APOS_STRING_MODE,{illegal:null}),i=e.inherit(e.QUOTE_STRING_MODE,{illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(r)}),o=e.END_SAME_AS_BEGIN({begin:/<<<[ \t]*(\w+)\n/,end:/[ \t]*(\w+)\b/,contains:e.QUOTE_STRING_MODE.contains.concat(r)}),s={className:"string",contains:[e.BACKSLASH_ESCAPE,n],variants:[e.inherit(a,{begin:"b'",end:"'"}),e.inherit(i,{begin:'b"',end:'"'}),i,a,o]},l={className:"number",variants:[{begin:"\\b0b[01]+(?:_[01]+)*\\b"},{begin:"\\b0o[0-7]+(?:_[0-7]+)*\\b"},{begin:"\\b0x[\\da-f]+(?:_[\\da-f]+)*\\b"},{begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:e[+-]?\\d+)?"}],relevance:0},c={keyword:"__CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ die echo exit include include_once print require require_once array abstract and as binary bool boolean break callable case catch class clone const continue declare default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile enum eval extends final finally float for foreach from global goto if implements instanceof insteadof int integer interface isset iterable list match|0 mixed new object or private protected public real return string switch throw trait try unset use var void while xor yield",literal:"false null true",built_in:"Error|0 AppendIterator ArgumentCountError ArithmeticError ArrayIterator ArrayObject AssertionError BadFunctionCallException BadMethodCallException CachingIterator CallbackFilterIterator CompileError Countable DirectoryIterator DivisionByZeroError DomainException EmptyIterator ErrorException Exception FilesystemIterator FilterIterator GlobIterator InfiniteIterator InvalidArgumentException IteratorIterator LengthException LimitIterator LogicException MultipleIterator NoRewindIterator OutOfBoundsException OutOfRangeException OuterIterator OverflowException ParentIterator ParseError RangeException RecursiveArrayIterator RecursiveCachingIterator RecursiveCallbackFilterIterator RecursiveDirectoryIterator RecursiveFilterIterator RecursiveIterator RecursiveIteratorIterator RecursiveRegexIterator RecursiveTreeIterator RegexIterator RuntimeException SeekableIterator SplDoublyLinkedList SplFileInfo SplFileObject SplFixedArray SplHeap SplMaxHeap SplMinHeap SplObjectStorage SplObserver SplObserver SplPriorityQueue SplQueue SplStack SplSubject SplSubject SplTempFileObject TypeError UnderflowException UnexpectedValueException UnhandledMatchError ArrayAccess Closure Generator Iterator IteratorAggregate Serializable Stringable Throwable Traversable WeakReference WeakMap Directory __PHP_Incomplete_Class parent php_user_filter self static stdClass"};return{aliases:["php3","php4","php5","php6","php7","php8"],case_insensitive:!0,keywords:c,contains:[e.HASH_COMMENT_MODE,e.COMMENT("//","$",{contains:[n]}),e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler"}),n,{className:"keyword",begin:/\$this\b/},t,{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/,excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use"},e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{className:"params",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:c,contains:["self",t,e.C_BLOCK_COMMENT_MODE,s,l]}]},{className:"class",variants:[{beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait",illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",relevance:0,end:";",contains:[e.UNDERSCORE_TITLE_MODE]},s,l]}};yt.registerLanguage("javascript",Ct),yt.registerLanguage("node",Ct),yt.registerLanguage("python",Lt),yt.registerLanguage("curl",jt),yt.registerLanguage("ruby",It),yt.registerLanguage("go",Nt),yt.registerLanguage("php",Ot);var Pt="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function Rt(e,t){return e(t={exports:{}},t.exports),t.exports}var Ht,zt=Rt((function(e,t){ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +var n;n=function(){return function(){var e={134:function(e,t,n){n.d(t,{default:function(){return w}});var r=n(279),a=n.n(r),i=n(370),o=n.n(i),s=n(817),l=n.n(s);function c(e){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function u(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"createFakeElement",value:function(){var e="rtl"===document.documentElement.getAttribute("dir");this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var t=window.pageYOffset||document.documentElement.scrollTop;return this.fakeElem.style.top="".concat(t,"px"),this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.fakeElem}},{key:"selectFake",value:function(){var e=this,t=this.createFakeElement();this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.container.appendChild(t),this.selectedText=l()(t),this.copyText(),this.removeFake()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=l()(this.target),this.copyText()}},{key:"copyText",value:function(){var e;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),document.activeElement.blur(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(e){if(void 0!==e){if(!e||"object"!==c(e)||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function(){return this._target}}])&&u(t.prototype,n),r&&u(t,r),e}();function p(e){return(p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function h(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof e?[e]:e,n=!!document.queryCommandSupported;return t.forEach((function(e){n=n&&!!document.queryCommandSupported(e)})),n}}],(n=[{key:"resolveOptions",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===p(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=o()(e,"click",(function(e){return t.onClick(e)}))}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new d({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(e){return _("action",e)}},{key:"defaultTarget",value:function(e){var t=_("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return _("text",e)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}])&&h(t.prototype,n),r&&h(t,r),i}(a())},828:function(e){if("undefined"!=typeof Element&&!Element.prototype.matches){var t=Element.prototype;t.matches=t.matchesSelector||t.mozMatchesSelector||t.msMatchesSelector||t.oMatchesSelector||t.webkitMatchesSelector}e.exports=function(e,t){for(;e&&9!==e.nodeType;){if("function"==typeof e.matches&&e.matches(t))return e;e=e.parentNode}}},438:function(e,t,n){var r=n(828);function a(e,t,n,r,a){var o=i.apply(this,arguments);return e.addEventListener(n,o,a),{destroy:function(){e.removeEventListener(n,o,a)}}}function i(e,t,n,a){return function(n){n.delegateTarget=r(n.target,t),n.delegateTarget&&a.call(e,n)}}e.exports=function(e,t,n,r,i){return"function"==typeof e.addEventListener?a.apply(null,arguments):"function"==typeof n?a.bind(null,document).apply(null,arguments):("string"==typeof e&&(e=document.querySelectorAll(e)),Array.prototype.map.call(e,(function(e){return a(e,t,n,r,i)})))}},879:function(e,t){t.node=function(e){return void 0!==e&&e instanceof HTMLElement&&1===e.nodeType},t.nodeList=function(e){var n=Object.prototype.toString.call(e);return void 0!==e&&("[object NodeList]"===n||"[object HTMLCollection]"===n)&&"length"in e&&(0===e.length||t.node(e[0]))},t.string=function(e){return"string"==typeof e||e instanceof String},t.fn=function(e){return"[object Function]"===Object.prototype.toString.call(e)}},370:function(e,t,n){var r=n(879),a=n(438);e.exports=function(e,t,n){if(!e&&!t&&!n)throw new Error("Missing required arguments");if(!r.string(t))throw new TypeError("Second argument must be a String");if(!r.fn(n))throw new TypeError("Third argument must be a Function");if(r.node(e))return function(e,t,n){return e.addEventListener(t,n),{destroy:function(){e.removeEventListener(t,n)}}}(e,t,n);if(r.nodeList(e))return function(e,t,n){return Array.prototype.forEach.call(e,(function(e){e.addEventListener(t,n)})),{destroy:function(){Array.prototype.forEach.call(e,(function(e){e.removeEventListener(t,n)}))}}}(e,t,n);if(r.string(e))return function(e,t,n){return a(document.body,e,t,n)}(e,t,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}},817:function(e){e.exports=function(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var n=e.hasAttribute("readonly");n||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),n||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var r=window.getSelection(),a=document.createRange();a.selectNodeContents(e),r.removeAllRanges(),r.addRange(a),t=r.toString()}return t}},279:function(e){function t(){}t.prototype={on:function(e,t,n){var r=this.e||(this.e={});return(r[e]||(r[e]=[])).push({fn:t,ctx:n}),this},once:function(e,t,n){var r=this;function a(){r.off(e,a),t.apply(n,arguments)}return a._=t,this.on(e,a,n)},emit:function(e){for(var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),r=0,a=n.length;r (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,description:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,description:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",description:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,description:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,description:"Open all links in new windows",type:"boolean"},backslashEscapesHTMLTags:{defaultValue:!1,description:"Support for HTML Tag escaping. ex:
foo
",type:"boolean"},emoji:{defaultValue:!1,description:"Enable emoji support. Ex: `this is a :smile: emoji`",type:"boolean"},underline:{defaultValue:!1,description:"Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `` and ``",type:"boolean"},completeHTMLDocument:{defaultValue:!1,description:"Outputs a complete html document, including ``, `` and `` tags",type:"boolean"},metadata:{defaultValue:!1,description:"Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).",type:"boolean"},splitAdjacentBlockquotes:{defaultValue:!1,description:"Split adjacent blockquote blocks",type:"boolean"}};if(!1===e)return JSON.parse(JSON.stringify(t));var n={};for(var r in t)t.hasOwnProperty(r)&&(n[r]=t[r].defaultValue);return n}var n={},r={},a={},i=t(!0),o="vanilla",s={github:{omitExtraWLInCodeBlocks:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,disableForced4SpacesIndentedSublists:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghCompatibleHeaderId:!0,ghMentions:!0,backslashEscapesHTMLTags:!0,emoji:!0,splitAdjacentBlockquotes:!0},original:{noHeaderId:!0,ghCodeBlocks:!1},ghost:{omitExtraWLInCodeBlocks:!0,parseImgDimensions:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,smoothLivePreview:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghMentions:!1,encodeEmails:!0},vanilla:t(!0),allOn:function(){var e=t(!0),n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=!0);return n}()};function l(e,t){var r=t?"Error in "+t+" extension->":"Error in unnamed extension",a={valid:!0,error:""};n.helper.isArray(e)||(e=[e]);for(var i=0;i").replace(/&/g,"&")};var u=function(e,t,n,r){var a,i,o,s,l,c=r||"",u=c.indexOf("g")>-1,d=new RegExp(t+"|"+n,"g"+c.replace(/g/g,"")),p=new RegExp(t,c.replace(/g/g,"")),h=[];do{for(a=0;o=d.exec(e);)if(p.test(o[0]))a++||(s=(i=d.lastIndex)-o[0].length);else if(a&&!--a){l=o.index+o[0].length;var g={left:{start:s,end:i},match:{start:i,end:o.index},right:{start:o.index,end:l},wholeMatch:{start:s,end:l}};if(h.push(g),!u)return h}}while(a&&(d.lastIndex=i));return h};n.helper.matchRecursiveRegExp=function(e,t,n,r){for(var a=u(e,t,n,r),i=[],o=0;o0){var d=[];0!==s[0].wholeMatch.start&&d.push(e.slice(0,s[0].wholeMatch.start));for(var p=0;p=0?a+(r||0):a},n.helper.splitAtIndex=function(e,t){if(!n.helper.isString(e))throw"InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";return[e.substring(0,t),e.substring(t)]},n.helper.encodeEmailAddress=function(e){var t=[function(e){return"&#"+e.charCodeAt(0)+";"},function(e){return"&#x"+e.charCodeAt(0).toString(16)+";"},function(e){return e}];return e=e.replace(/./g,(function(e){if("@"===e)e=t[Math.floor(2*Math.random())](e);else{var n=Math.random();e=n>.9?t[2](e):n>.45?t[1](e):t[0](e)}return e}))},n.helper.padEnd=function(e,t,n){return t>>=0,n=String(n||" "),e.length>t?String(e):((t-=e.length)>n.length&&(n+=n.repeat(t/n.length)),String(e)+n.slice(0,t))},"undefined"==typeof console&&(console={warn:function(e){alert(e)},log:function(e){alert(e)},error:function(e){throw e}}),n.helper.regexes={asteriskDashAndColon:/([*_:~])/g},n.helper.emojis={"+1":"👍","-1":"👎",100:"💯",1234:"🔢","1st_place_medal":"🥇","2nd_place_medal":"🥈","3rd_place_medal":"🥉","8ball":"🎱",a:"🅰️",ab:"🆎",abc:"🔤",abcd:"🔡",accept:"🉑",aerial_tramway:"🚡",airplane:"✈️",alarm_clock:"⏰",alembic:"⚗️",alien:"👽",ambulance:"🚑",amphora:"🏺",anchor:"⚓️",angel:"👼",anger:"💢",angry:"😠",anguished:"😧",ant:"🐜",apple:"🍎",aquarius:"♒️",aries:"♈️",arrow_backward:"◀️",arrow_double_down:"⏬",arrow_double_up:"⏫",arrow_down:"⬇️",arrow_down_small:"🔽",arrow_forward:"▶️",arrow_heading_down:"⤵️",arrow_heading_up:"⤴️",arrow_left:"⬅️",arrow_lower_left:"↙️",arrow_lower_right:"↘️",arrow_right:"➡️",arrow_right_hook:"↪️",arrow_up:"⬆️",arrow_up_down:"↕️",arrow_up_small:"🔼",arrow_upper_left:"↖️",arrow_upper_right:"↗️",arrows_clockwise:"🔃",arrows_counterclockwise:"🔄",art:"🎨",articulated_lorry:"🚛",artificial_satellite:"🛰",astonished:"😲",athletic_shoe:"👟",atm:"🏧",atom_symbol:"⚛️",avocado:"🥑",b:"🅱️",baby:"👶",baby_bottle:"🍼",baby_chick:"🐤",baby_symbol:"🚼",back:"🔙",bacon:"🥓",badminton:"🏸",baggage_claim:"🛄",baguette_bread:"🥖",balance_scale:"⚖️",balloon:"🎈",ballot_box:"🗳",ballot_box_with_check:"☑️",bamboo:"🎍",banana:"🍌",bangbang:"‼️",bank:"🏦",bar_chart:"📊",barber:"💈",baseball:"⚾️",basketball:"🏀",basketball_man:"⛹️",basketball_woman:"⛹️‍♀️",bat:"🦇",bath:"🛀",bathtub:"🛁",battery:"🔋",beach_umbrella:"🏖",bear:"🐻",bed:"🛏",bee:"🐝",beer:"🍺",beers:"🍻",beetle:"🐞",beginner:"🔰",bell:"🔔",bellhop_bell:"🛎",bento:"🍱",biking_man:"🚴",bike:"🚲",biking_woman:"🚴‍♀️",bikini:"👙",biohazard:"☣️",bird:"🐦",birthday:"🎂",black_circle:"⚫️",black_flag:"🏴",black_heart:"🖤",black_joker:"🃏",black_large_square:"⬛️",black_medium_small_square:"◾️",black_medium_square:"◼️",black_nib:"✒️",black_small_square:"▪️",black_square_button:"🔲",blonde_man:"👱",blonde_woman:"👱‍♀️",blossom:"🌼",blowfish:"🐡",blue_book:"📘",blue_car:"🚙",blue_heart:"💙",blush:"😊",boar:"🐗",boat:"⛵️",bomb:"💣",book:"📖",bookmark:"🔖",bookmark_tabs:"📑",books:"📚",boom:"💥",boot:"👢",bouquet:"💐",bowing_man:"🙇",bow_and_arrow:"🏹",bowing_woman:"🙇‍♀️",bowling:"🎳",boxing_glove:"🥊",boy:"👦",bread:"🍞",bride_with_veil:"👰",bridge_at_night:"🌉",briefcase:"💼",broken_heart:"💔",bug:"🐛",building_construction:"🏗",bulb:"💡",bullettrain_front:"🚅",bullettrain_side:"🚄",burrito:"🌯",bus:"🚌",business_suit_levitating:"🕴",busstop:"🚏",bust_in_silhouette:"👤",busts_in_silhouette:"👥",butterfly:"🦋",cactus:"🌵",cake:"🍰",calendar:"📆",call_me_hand:"🤙",calling:"📲",camel:"🐫",camera:"📷",camera_flash:"📸",camping:"🏕",cancer:"♋️",candle:"🕯",candy:"🍬",canoe:"🛶",capital_abcd:"🔠",capricorn:"♑️",car:"🚗",card_file_box:"🗃",card_index:"📇",card_index_dividers:"🗂",carousel_horse:"🎠",carrot:"🥕",cat:"🐱",cat2:"🐈",cd:"💿",chains:"⛓",champagne:"🍾",chart:"💹",chart_with_downwards_trend:"📉",chart_with_upwards_trend:"📈",checkered_flag:"🏁",cheese:"🧀",cherries:"🍒",cherry_blossom:"🌸",chestnut:"🌰",chicken:"🐔",children_crossing:"🚸",chipmunk:"🐿",chocolate_bar:"🍫",christmas_tree:"🎄",church:"⛪️",cinema:"🎦",circus_tent:"🎪",city_sunrise:"🌇",city_sunset:"🌆",cityscape:"🏙",cl:"🆑",clamp:"🗜",clap:"👏",clapper:"🎬",classical_building:"🏛",clinking_glasses:"🥂",clipboard:"📋",clock1:"🕐",clock10:"🕙",clock1030:"🕥",clock11:"🕚",clock1130:"🕦",clock12:"🕛",clock1230:"🕧",clock130:"🕜",clock2:"🕑",clock230:"🕝",clock3:"🕒",clock330:"🕞",clock4:"🕓",clock430:"🕟",clock5:"🕔",clock530:"🕠",clock6:"🕕",clock630:"🕡",clock7:"🕖",clock730:"🕢",clock8:"🕗",clock830:"🕣",clock9:"🕘",clock930:"🕤",closed_book:"📕",closed_lock_with_key:"🔐",closed_umbrella:"🌂",cloud:"☁️",cloud_with_lightning:"🌩",cloud_with_lightning_and_rain:"⛈",cloud_with_rain:"🌧",cloud_with_snow:"🌨",clown_face:"🤡",clubs:"♣️",cocktail:"🍸",coffee:"☕️",coffin:"⚰️",cold_sweat:"😰",comet:"☄️",computer:"💻",computer_mouse:"🖱",confetti_ball:"🎊",confounded:"😖",confused:"😕",congratulations:"㊗️",construction:"🚧",construction_worker_man:"👷",construction_worker_woman:"👷‍♀️",control_knobs:"🎛",convenience_store:"🏪",cookie:"🍪",cool:"🆒",policeman:"👮",copyright:"©️",corn:"🌽",couch_and_lamp:"🛋",couple:"👫",couple_with_heart_woman_man:"💑",couple_with_heart_man_man:"👨‍❤️‍👨",couple_with_heart_woman_woman:"👩‍❤️‍👩",couplekiss_man_man:"👨‍❤️‍💋‍👨",couplekiss_man_woman:"💏",couplekiss_woman_woman:"👩‍❤️‍💋‍👩",cow:"🐮",cow2:"🐄",cowboy_hat_face:"🤠",crab:"🦀",crayon:"🖍",credit_card:"💳",crescent_moon:"🌙",cricket:"🏏",crocodile:"🐊",croissant:"🥐",crossed_fingers:"🤞",crossed_flags:"🎌",crossed_swords:"⚔️",crown:"👑",cry:"😢",crying_cat_face:"😿",crystal_ball:"🔮",cucumber:"🥒",cupid:"💘",curly_loop:"➰",currency_exchange:"💱",curry:"🍛",custard:"🍮",customs:"🛃",cyclone:"🌀",dagger:"🗡",dancer:"💃",dancing_women:"👯",dancing_men:"👯‍♂️",dango:"🍡",dark_sunglasses:"🕶",dart:"🎯",dash:"💨",date:"📅",deciduous_tree:"🌳",deer:"🦌",department_store:"🏬",derelict_house:"🏚",desert:"🏜",desert_island:"🏝",desktop_computer:"🖥",male_detective:"🕵️",diamond_shape_with_a_dot_inside:"💠",diamonds:"♦️",disappointed:"😞",disappointed_relieved:"😥",dizzy:"💫",dizzy_face:"😵",do_not_litter:"🚯",dog:"🐶",dog2:"🐕",dollar:"💵",dolls:"🎎",dolphin:"🐬",door:"🚪",doughnut:"🍩",dove:"🕊",dragon:"🐉",dragon_face:"🐲",dress:"👗",dromedary_camel:"🐪",drooling_face:"🤤",droplet:"💧",drum:"🥁",duck:"🦆",dvd:"📀","e-mail":"📧",eagle:"🦅",ear:"👂",ear_of_rice:"🌾",earth_africa:"🌍",earth_americas:"🌎",earth_asia:"🌏",egg:"🥚",eggplant:"🍆",eight_pointed_black_star:"✴️",eight_spoked_asterisk:"✳️",electric_plug:"🔌",elephant:"🐘",email:"✉️",end:"🔚",envelope_with_arrow:"📩",euro:"💶",european_castle:"🏰",european_post_office:"🏤",evergreen_tree:"🌲",exclamation:"❗️",expressionless:"😑",eye:"👁",eye_speech_bubble:"👁‍🗨",eyeglasses:"👓",eyes:"👀",face_with_head_bandage:"🤕",face_with_thermometer:"🤒",fist_oncoming:"👊",factory:"🏭",fallen_leaf:"🍂",family_man_woman_boy:"👪",family_man_boy:"👨‍👦",family_man_boy_boy:"👨‍👦‍👦",family_man_girl:"👨‍👧",family_man_girl_boy:"👨‍👧‍👦",family_man_girl_girl:"👨‍👧‍👧",family_man_man_boy:"👨‍👨‍👦",family_man_man_boy_boy:"👨‍👨‍👦‍👦",family_man_man_girl:"👨‍👨‍👧",family_man_man_girl_boy:"👨‍👨‍👧‍👦",family_man_man_girl_girl:"👨‍👨‍👧‍👧",family_man_woman_boy_boy:"👨‍👩‍👦‍👦",family_man_woman_girl:"👨‍👩‍👧",family_man_woman_girl_boy:"👨‍👩‍👧‍👦",family_man_woman_girl_girl:"👨‍👩‍👧‍👧",family_woman_boy:"👩‍👦",family_woman_boy_boy:"👩‍👦‍👦",family_woman_girl:"👩‍👧",family_woman_girl_boy:"👩‍👧‍👦",family_woman_girl_girl:"👩‍👧‍👧",family_woman_woman_boy:"👩‍👩‍👦",family_woman_woman_boy_boy:"👩‍👩‍👦‍👦",family_woman_woman_girl:"👩‍👩‍👧",family_woman_woman_girl_boy:"👩‍👩‍👧‍👦",family_woman_woman_girl_girl:"👩‍👩‍👧‍👧",fast_forward:"⏩",fax:"📠",fearful:"😨",feet:"🐾",female_detective:"🕵️‍♀️",ferris_wheel:"🎡",ferry:"⛴",field_hockey:"🏑",file_cabinet:"🗄",file_folder:"📁",film_projector:"📽",film_strip:"🎞",fire:"🔥",fire_engine:"🚒",fireworks:"🎆",first_quarter_moon:"🌓",first_quarter_moon_with_face:"🌛",fish:"🐟",fish_cake:"🍥",fishing_pole_and_fish:"🎣",fist_raised:"✊",fist_left:"🤛",fist_right:"🤜",flags:"🎏",flashlight:"🔦",fleur_de_lis:"⚜️",flight_arrival:"🛬",flight_departure:"🛫",floppy_disk:"💾",flower_playing_cards:"🎴",flushed:"😳",fog:"🌫",foggy:"🌁",football:"🏈",footprints:"👣",fork_and_knife:"🍴",fountain:"⛲️",fountain_pen:"🖋",four_leaf_clover:"🍀",fox_face:"🦊",framed_picture:"🖼",free:"🆓",fried_egg:"🍳",fried_shrimp:"🍤",fries:"🍟",frog:"🐸",frowning:"😦",frowning_face:"☹️",frowning_man:"🙍‍♂️",frowning_woman:"🙍",middle_finger:"🖕",fuelpump:"⛽️",full_moon:"🌕",full_moon_with_face:"🌝",funeral_urn:"⚱️",game_die:"🎲",gear:"⚙️",gem:"💎",gemini:"♊️",ghost:"👻",gift:"🎁",gift_heart:"💝",girl:"👧",globe_with_meridians:"🌐",goal_net:"🥅",goat:"🐐",golf:"⛳️",golfing_man:"🏌️",golfing_woman:"🏌️‍♀️",gorilla:"🦍",grapes:"🍇",green_apple:"🍏",green_book:"📗",green_heart:"💚",green_salad:"🥗",grey_exclamation:"❕",grey_question:"❔",grimacing:"😬",grin:"😁",grinning:"😀",guardsman:"💂",guardswoman:"💂‍♀️",guitar:"🎸",gun:"🔫",haircut_woman:"💇",haircut_man:"💇‍♂️",hamburger:"🍔",hammer:"🔨",hammer_and_pick:"⚒",hammer_and_wrench:"🛠",hamster:"🐹",hand:"✋",handbag:"👜",handshake:"🤝",hankey:"💩",hatched_chick:"🐥",hatching_chick:"🐣",headphones:"🎧",hear_no_evil:"🙉",heart:"❤️",heart_decoration:"💟",heart_eyes:"😍",heart_eyes_cat:"😻",heartbeat:"💓",heartpulse:"💗",hearts:"♥️",heavy_check_mark:"✔️",heavy_division_sign:"➗",heavy_dollar_sign:"💲",heavy_heart_exclamation:"❣️",heavy_minus_sign:"➖",heavy_multiplication_x:"✖️",heavy_plus_sign:"➕",helicopter:"🚁",herb:"🌿",hibiscus:"🌺",high_brightness:"🔆",high_heel:"👠",hocho:"🔪",hole:"🕳",honey_pot:"🍯",horse:"🐴",horse_racing:"🏇",hospital:"🏥",hot_pepper:"🌶",hotdog:"🌭",hotel:"🏨",hotsprings:"♨️",hourglass:"⌛️",hourglass_flowing_sand:"⏳",house:"🏠",house_with_garden:"🏡",houses:"🏘",hugs:"🤗",hushed:"😯",ice_cream:"🍨",ice_hockey:"🏒",ice_skate:"⛸",icecream:"🍦",id:"🆔",ideograph_advantage:"🉐",imp:"👿",inbox_tray:"📥",incoming_envelope:"📨",tipping_hand_woman:"💁",information_source:"ℹ️",innocent:"😇",interrobang:"⁉️",iphone:"📱",izakaya_lantern:"🏮",jack_o_lantern:"🎃",japan:"🗾",japanese_castle:"🏯",japanese_goblin:"👺",japanese_ogre:"👹",jeans:"👖",joy:"😂",joy_cat:"😹",joystick:"🕹",kaaba:"🕋",key:"🔑",keyboard:"⌨️",keycap_ten:"🔟",kick_scooter:"🛴",kimono:"👘",kiss:"💋",kissing:"😗",kissing_cat:"😽",kissing_closed_eyes:"😚",kissing_heart:"😘",kissing_smiling_eyes:"😙",kiwi_fruit:"🥝",koala:"🐨",koko:"🈁",label:"🏷",large_blue_circle:"🔵",large_blue_diamond:"🔷",large_orange_diamond:"🔶",last_quarter_moon:"🌗",last_quarter_moon_with_face:"🌜",latin_cross:"✝️",laughing:"😆",leaves:"🍃",ledger:"📒",left_luggage:"🛅",left_right_arrow:"↔️",leftwards_arrow_with_hook:"↩️",lemon:"🍋",leo:"♌️",leopard:"🐆",level_slider:"🎚",libra:"♎️",light_rail:"🚈",link:"🔗",lion:"🦁",lips:"👄",lipstick:"💄",lizard:"🦎",lock:"🔒",lock_with_ink_pen:"🔏",lollipop:"🍭",loop:"➿",loud_sound:"🔊",loudspeaker:"📢",love_hotel:"🏩",love_letter:"💌",low_brightness:"🔅",lying_face:"🤥",m:"Ⓜ️",mag:"🔍",mag_right:"🔎",mahjong:"🀄️",mailbox:"📫",mailbox_closed:"📪",mailbox_with_mail:"📬",mailbox_with_no_mail:"📭",man:"👨",man_artist:"👨‍🎨",man_astronaut:"👨‍🚀",man_cartwheeling:"🤸‍♂️",man_cook:"👨‍🍳",man_dancing:"🕺",man_facepalming:"🤦‍♂️",man_factory_worker:"👨‍🏭",man_farmer:"👨‍🌾",man_firefighter:"👨‍🚒",man_health_worker:"👨‍⚕️",man_in_tuxedo:"🤵",man_judge:"👨‍⚖️",man_juggling:"🤹‍♂️",man_mechanic:"👨‍🔧",man_office_worker:"👨‍💼",man_pilot:"👨‍✈️",man_playing_handball:"🤾‍♂️",man_playing_water_polo:"🤽‍♂️",man_scientist:"👨‍🔬",man_shrugging:"🤷‍♂️",man_singer:"👨‍🎤",man_student:"👨‍🎓",man_teacher:"👨‍🏫",man_technologist:"👨‍💻",man_with_gua_pi_mao:"👲",man_with_turban:"👳",tangerine:"🍊",mans_shoe:"👞",mantelpiece_clock:"🕰",maple_leaf:"🍁",martial_arts_uniform:"🥋",mask:"😷",massage_woman:"💆",massage_man:"💆‍♂️",meat_on_bone:"🍖",medal_military:"🎖",medal_sports:"🏅",mega:"📣",melon:"🍈",memo:"📝",men_wrestling:"🤼‍♂️",menorah:"🕎",mens:"🚹",metal:"🤘",metro:"🚇",microphone:"🎤",microscope:"🔬",milk_glass:"🥛",milky_way:"🌌",minibus:"🚐",minidisc:"💽",mobile_phone_off:"📴",money_mouth_face:"🤑",money_with_wings:"💸",moneybag:"💰",monkey:"🐒",monkey_face:"🐵",monorail:"🚝",moon:"🌔",mortar_board:"🎓",mosque:"🕌",motor_boat:"🛥",motor_scooter:"🛵",motorcycle:"🏍",motorway:"🛣",mount_fuji:"🗻",mountain:"⛰",mountain_biking_man:"🚵",mountain_biking_woman:"🚵‍♀️",mountain_cableway:"🚠",mountain_railway:"🚞",mountain_snow:"🏔",mouse:"🐭",mouse2:"🐁",movie_camera:"🎥",moyai:"🗿",mrs_claus:"🤶",muscle:"💪",mushroom:"🍄",musical_keyboard:"🎹",musical_note:"🎵",musical_score:"🎼",mute:"🔇",nail_care:"💅",name_badge:"📛",national_park:"🏞",nauseated_face:"🤢",necktie:"👔",negative_squared_cross_mark:"❎",nerd_face:"🤓",neutral_face:"😐",new:"🆕",new_moon:"🌑",new_moon_with_face:"🌚",newspaper:"📰",newspaper_roll:"🗞",next_track_button:"⏭",ng:"🆖",no_good_man:"🙅‍♂️",no_good_woman:"🙅",night_with_stars:"🌃",no_bell:"🔕",no_bicycles:"🚳",no_entry:"⛔️",no_entry_sign:"🚫",no_mobile_phones:"📵",no_mouth:"😶",no_pedestrians:"🚷",no_smoking:"🚭","non-potable_water":"🚱",nose:"👃",notebook:"📓",notebook_with_decorative_cover:"📔",notes:"🎶",nut_and_bolt:"🔩",o:"⭕️",o2:"🅾️",ocean:"🌊",octopus:"🐙",oden:"🍢",office:"🏢",oil_drum:"🛢",ok:"🆗",ok_hand:"👌",ok_man:"🙆‍♂️",ok_woman:"🙆",old_key:"🗝",older_man:"👴",older_woman:"👵",om:"🕉",on:"🔛",oncoming_automobile:"🚘",oncoming_bus:"🚍",oncoming_police_car:"🚔",oncoming_taxi:"🚖",open_file_folder:"📂",open_hands:"👐",open_mouth:"😮",open_umbrella:"☂️",ophiuchus:"⛎",orange_book:"📙",orthodox_cross:"☦️",outbox_tray:"📤",owl:"🦉",ox:"🐂",package:"📦",page_facing_up:"📄",page_with_curl:"📃",pager:"📟",paintbrush:"🖌",palm_tree:"🌴",pancakes:"🥞",panda_face:"🐼",paperclip:"📎",paperclips:"🖇",parasol_on_ground:"⛱",parking:"🅿️",part_alternation_mark:"〽️",partly_sunny:"⛅️",passenger_ship:"🛳",passport_control:"🛂",pause_button:"⏸",peace_symbol:"☮️",peach:"🍑",peanuts:"🥜",pear:"🍐",pen:"🖊",pencil2:"✏️",penguin:"🐧",pensive:"😔",performing_arts:"🎭",persevere:"😣",person_fencing:"🤺",pouting_woman:"🙎",phone:"☎️",pick:"⛏",pig:"🐷",pig2:"🐖",pig_nose:"🐽",pill:"💊",pineapple:"🍍",ping_pong:"🏓",pisces:"♓️",pizza:"🍕",place_of_worship:"🛐",plate_with_cutlery:"🍽",play_or_pause_button:"⏯",point_down:"👇",point_left:"👈",point_right:"👉",point_up:"☝️",point_up_2:"👆",police_car:"🚓",policewoman:"👮‍♀️",poodle:"🐩",popcorn:"🍿",post_office:"🏣",postal_horn:"📯",postbox:"📮",potable_water:"🚰",potato:"🥔",pouch:"👝",poultry_leg:"🍗",pound:"💷",rage:"😡",pouting_cat:"😾",pouting_man:"🙎‍♂️",pray:"🙏",prayer_beads:"📿",pregnant_woman:"🤰",previous_track_button:"⏮",prince:"🤴",princess:"👸",printer:"🖨",purple_heart:"💜",purse:"👛",pushpin:"📌",put_litter_in_its_place:"🚮",question:"❓",rabbit:"🐰",rabbit2:"🐇",racehorse:"🐎",racing_car:"🏎",radio:"📻",radio_button:"🔘",radioactive:"☢️",railway_car:"🚃",railway_track:"🛤",rainbow:"🌈",rainbow_flag:"🏳️‍🌈",raised_back_of_hand:"🤚",raised_hand_with_fingers_splayed:"🖐",raised_hands:"🙌",raising_hand_woman:"🙋",raising_hand_man:"🙋‍♂️",ram:"🐏",ramen:"🍜",rat:"🐀",record_button:"⏺",recycle:"♻️",red_circle:"🔴",registered:"®️",relaxed:"☺️",relieved:"😌",reminder_ribbon:"🎗",repeat:"🔁",repeat_one:"🔂",rescue_worker_helmet:"⛑",restroom:"🚻",revolving_hearts:"💞",rewind:"⏪",rhinoceros:"🦏",ribbon:"🎀",rice:"🍚",rice_ball:"🍙",rice_cracker:"🍘",rice_scene:"🎑",right_anger_bubble:"🗯",ring:"💍",robot:"🤖",rocket:"🚀",rofl:"🤣",roll_eyes:"🙄",roller_coaster:"🎢",rooster:"🐓",rose:"🌹",rosette:"🏵",rotating_light:"🚨",round_pushpin:"📍",rowing_man:"🚣",rowing_woman:"🚣‍♀️",rugby_football:"🏉",running_man:"🏃",running_shirt_with_sash:"🎽",running_woman:"🏃‍♀️",sa:"🈂️",sagittarius:"♐️",sake:"🍶",sandal:"👡",santa:"🎅",satellite:"📡",saxophone:"🎷",school:"🏫",school_satchel:"🎒",scissors:"✂️",scorpion:"🦂",scorpius:"♏️",scream:"😱",scream_cat:"🙀",scroll:"📜",seat:"💺",secret:"㊙️",see_no_evil:"🙈",seedling:"🌱",selfie:"🤳",shallow_pan_of_food:"🥘",shamrock:"☘️",shark:"🦈",shaved_ice:"🍧",sheep:"🐑",shell:"🐚",shield:"🛡",shinto_shrine:"⛩",ship:"🚢",shirt:"👕",shopping:"🛍",shopping_cart:"🛒",shower:"🚿",shrimp:"🦐",signal_strength:"📶",six_pointed_star:"🔯",ski:"🎿",skier:"⛷",skull:"💀",skull_and_crossbones:"☠️",sleeping:"😴",sleeping_bed:"🛌",sleepy:"😪",slightly_frowning_face:"🙁",slightly_smiling_face:"🙂",slot_machine:"🎰",small_airplane:"🛩",small_blue_diamond:"🔹",small_orange_diamond:"🔸",small_red_triangle:"🔺",small_red_triangle_down:"🔻",smile:"😄",smile_cat:"😸",smiley:"😃",smiley_cat:"😺",smiling_imp:"😈",smirk:"😏",smirk_cat:"😼",smoking:"🚬",snail:"🐌",snake:"🐍",sneezing_face:"🤧",snowboarder:"🏂",snowflake:"❄️",snowman:"⛄️",snowman_with_snow:"☃️",sob:"😭",soccer:"⚽️",soon:"🔜",sos:"🆘",sound:"🔉",space_invader:"👾",spades:"♠️",spaghetti:"🍝",sparkle:"❇️",sparkler:"🎇",sparkles:"✨",sparkling_heart:"💖",speak_no_evil:"🙊",speaker:"🔈",speaking_head:"🗣",speech_balloon:"💬",speedboat:"🚤",spider:"🕷",spider_web:"🕸",spiral_calendar:"🗓",spiral_notepad:"🗒",spoon:"🥄",squid:"🦑",stadium:"🏟",star:"⭐️",star2:"🌟",star_and_crescent:"☪️",star_of_david:"✡️",stars:"🌠",station:"🚉",statue_of_liberty:"🗽",steam_locomotive:"🚂",stew:"🍲",stop_button:"⏹",stop_sign:"🛑",stopwatch:"⏱",straight_ruler:"📏",strawberry:"🍓",stuck_out_tongue:"😛",stuck_out_tongue_closed_eyes:"😝",stuck_out_tongue_winking_eye:"😜",studio_microphone:"🎙",stuffed_flatbread:"🥙",sun_behind_large_cloud:"🌥",sun_behind_rain_cloud:"🌦",sun_behind_small_cloud:"🌤",sun_with_face:"🌞",sunflower:"🌻",sunglasses:"😎",sunny:"☀️",sunrise:"🌅",sunrise_over_mountains:"🌄",surfing_man:"🏄",surfing_woman:"🏄‍♀️",sushi:"🍣",suspension_railway:"🚟",sweat:"😓",sweat_drops:"💦",sweat_smile:"😅",sweet_potato:"🍠",swimming_man:"🏊",swimming_woman:"🏊‍♀️",symbols:"🔣",synagogue:"🕍",syringe:"💉",taco:"🌮",tada:"🎉",tanabata_tree:"🎋",taurus:"♉️",taxi:"🚕",tea:"🍵",telephone_receiver:"📞",telescope:"🔭",tennis:"🎾",tent:"⛺️",thermometer:"🌡",thinking:"🤔",thought_balloon:"💭",ticket:"🎫",tickets:"🎟",tiger:"🐯",tiger2:"🐅",timer_clock:"⏲",tipping_hand_man:"💁‍♂️",tired_face:"😫",tm:"™️",toilet:"🚽",tokyo_tower:"🗼",tomato:"🍅",tongue:"👅",top:"🔝",tophat:"🎩",tornado:"🌪",trackball:"🖲",tractor:"🚜",traffic_light:"🚥",train:"🚋",train2:"🚆",tram:"🚊",triangular_flag_on_post:"🚩",triangular_ruler:"📐",trident:"🔱",triumph:"😤",trolleybus:"🚎",trophy:"🏆",tropical_drink:"🍹",tropical_fish:"🐠",truck:"🚚",trumpet:"🎺",tulip:"🌷",tumbler_glass:"🥃",turkey:"🦃",turtle:"🐢",tv:"📺",twisted_rightwards_arrows:"🔀",two_hearts:"💕",two_men_holding_hands:"👬",two_women_holding_hands:"👭",u5272:"🈹",u5408:"🈴",u55b6:"🈺",u6307:"🈯️",u6708:"🈷️",u6709:"🈶",u6e80:"🈵",u7121:"🈚️",u7533:"🈸",u7981:"🈲",u7a7a:"🈳",umbrella:"☔️",unamused:"😒",underage:"🔞",unicorn:"🦄",unlock:"🔓",up:"🆙",upside_down_face:"🙃",v:"✌️",vertical_traffic_light:"🚦",vhs:"📼",vibration_mode:"📳",video_camera:"📹",video_game:"🎮",violin:"🎻",virgo:"♍️",volcano:"🌋",volleyball:"🏐",vs:"🆚",vulcan_salute:"🖖",walking_man:"🚶",walking_woman:"🚶‍♀️",waning_crescent_moon:"🌘",waning_gibbous_moon:"🌖",warning:"⚠️",wastebasket:"🗑",watch:"⌚️",water_buffalo:"🐃",watermelon:"🍉",wave:"👋",wavy_dash:"〰️",waxing_crescent_moon:"🌒",wc:"🚾",weary:"😩",wedding:"💒",weight_lifting_man:"🏋️",weight_lifting_woman:"🏋️‍♀️",whale:"🐳",whale2:"🐋",wheel_of_dharma:"☸️",wheelchair:"♿️",white_check_mark:"✅",white_circle:"⚪️",white_flag:"🏳️",white_flower:"💮",white_large_square:"⬜️",white_medium_small_square:"◽️",white_medium_square:"◻️",white_small_square:"▫️",white_square_button:"🔳",wilted_flower:"🥀",wind_chime:"🎐",wind_face:"🌬",wine_glass:"🍷",wink:"😉",wolf:"🐺",woman:"👩",woman_artist:"👩‍🎨",woman_astronaut:"👩‍🚀",woman_cartwheeling:"🤸‍♀️",woman_cook:"👩‍🍳",woman_facepalming:"🤦‍♀️",woman_factory_worker:"👩‍🏭",woman_farmer:"👩‍🌾",woman_firefighter:"👩‍🚒",woman_health_worker:"👩‍⚕️",woman_judge:"👩‍⚖️",woman_juggling:"🤹‍♀️",woman_mechanic:"👩‍🔧",woman_office_worker:"👩‍💼",woman_pilot:"👩‍✈️",woman_playing_handball:"🤾‍♀️",woman_playing_water_polo:"🤽‍♀️",woman_scientist:"👩‍🔬",woman_shrugging:"🤷‍♀️",woman_singer:"👩‍🎤",woman_student:"👩‍🎓",woman_teacher:"👩‍🏫",woman_technologist:"👩‍💻",woman_with_turban:"👳‍♀️",womans_clothes:"👚",womans_hat:"👒",women_wrestling:"🤼‍♀️",womens:"🚺",world_map:"🗺",worried:"😟",wrench:"🔧",writing_hand:"✍️",x:"❌",yellow_heart:"💛",yen:"💴",yin_yang:"☯️",yum:"😋",zap:"⚡️",zipper_mouth_face:"🤐",zzz:"💤",octocat:':octocat:',showdown:"S"},n.Converter=function(e){var t={},r=[],c=[],u={},d=o,p={parsed:{},raw:"",format:""};function h(e,t){if(t=t||null,n.helper.isString(e)){if(t=e=n.helper.stdExtName(e),n.extensions[e])return console.warn("DEPRECATION WARNING: "+e+" is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!"),void function(e,t){"function"==typeof e&&(e=e(new n.Converter));n.helper.isArray(e)||(e=[e]);var a=l(e,t);if(!a.valid)throw Error(a.error);for(var i=0;i[ \t]+¨NBSP;<"),!t){if(!window||!window.document)throw new Error("HTMLParser is undefined. If in a webworker or nodejs environment, you need to provide a WHATWG DOM and HTML such as JSDOM");t=window.document}var r=t.createElement("div");r.innerHTML=e;var a={preList:function(e){for(var t=e.querySelectorAll("pre"),r=[],a=0;a'}else r.push(t[a].innerHTML),t[a].innerHTML="",t[a].setAttribute("prenum",a.toString());return r}(r)};!function e(t){for(var n=0;n? ?(['"].*['"])?\)$/m)>-1)o="";else if(!o){if(i||(i=a.toLowerCase().replace(/ ?\n/g," ")),o="#"+i,n.helper.isUndefined(r.gUrls[i]))return e;o=r.gUrls[i],n.helper.isUndefined(r.gTitles[i])||(c=r.gTitles[i])}var u='"};return e=(e=(e=(e=(e=r.converter._dispatch("anchors.before",e,t,r)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g,a)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,a)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]??(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,a)).replace(/\[([^\[\]]+)]()()()()()/g,a),t.ghMentions&&(e=e.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gim,(function(e,r,a,i,o){if("\\"===a)return r+i;if(!n.helper.isString(t.ghMentionsLink))throw new Error("ghMentionsLink option must be a string");var s=t.ghMentionsLink.replace(/\{u}/g,o),l="";return t.openLinksInNewWindow&&(l=' rel="noopener noreferrer" target="¨E95Eblank"'),r+'"+i+""}))),e=r.converter._dispatch("anchors.after",e,t,r)}));var d=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,p=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,h=/()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,g=/(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gim,f=/<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,m=function(e){return function(t,r,a,i,o,s,l){var c=a=a.replace(n.helper.regexes.asteriskDashAndColon,n.helper.escapeCharactersCallback),u="",d="",p=r||"",h=l||"";return/^www\./i.test(a)&&(a=a.replace(/^www\./i,"http://www.")),e.excludeTrailingPunctuationFromURLs&&s&&(u=s),e.openLinksInNewWindow&&(d=' rel="noopener noreferrer" target="¨E95Eblank"'),p+'"+c+""+u+h}},b=function(e,t){return function(r,a,i){var o="mailto:";return a=a||"",i=n.subParser("unescapeSpecialChars")(i,e,t),e.encodeEmails?(o=n.helper.encodeEmailAddress(o+i),i=n.helper.encodeEmailAddress(i)):o+=i,a+''+i+""}};n.subParser("autoLinks",(function(e,t,n){return e=(e=(e=n.converter._dispatch("autoLinks.before",e,t,n)).replace(h,m(t))).replace(f,b(t,n)),e=n.converter._dispatch("autoLinks.after",e,t,n)})),n.subParser("simplifiedAutoLinks",(function(e,t,n){return t.simplifiedAutoLink?(e=n.converter._dispatch("simplifiedAutoLinks.before",e,t,n),e=(e=t.excludeTrailingPunctuationFromURLs?e.replace(p,m(t)):e.replace(d,m(t))).replace(g,b(t,n)),e=n.converter._dispatch("simplifiedAutoLinks.after",e,t,n)):e})),n.subParser("blockGamut",(function(e,t,r){return e=r.converter._dispatch("blockGamut.before",e,t,r),e=n.subParser("blockQuotes")(e,t,r),e=n.subParser("headers")(e,t,r),e=n.subParser("horizontalRule")(e,t,r),e=n.subParser("lists")(e,t,r),e=n.subParser("codeBlocks")(e,t,r),e=n.subParser("tables")(e,t,r),e=n.subParser("hashHTMLBlocks")(e,t,r),e=n.subParser("paragraphs")(e,t,r),e=r.converter._dispatch("blockGamut.after",e,t,r)})),n.subParser("blockQuotes",(function(e,t,r){e=r.converter._dispatch("blockQuotes.before",e,t,r),e+="\n\n";var a=/(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;return t.splitAdjacentBlockquotes&&(a=/^ {0,3}>[\s\S]*?(?:\n\n)/gm),e=e.replace(a,(function(e){return e=(e=(e=e.replace(/^[ \t]*>[ \t]?/gm,"")).replace(/¨0/g,"")).replace(/^[ \t]+$/gm,""),e=n.subParser("githubCodeBlocks")(e,t,r),e=(e=(e=n.subParser("blockGamut")(e,t,r)).replace(/(^|\n)/g,"$1 ")).replace(/(\s*
[^\r]+?<\/pre>)/gm,(function(e,t){var n=t;return n=(n=n.replace(/^  /gm,"¨0")).replace(/¨0/g,"")})),n.subParser("hashBlock")("
\n"+e+"\n
",t,r)})),e=r.converter._dispatch("blockQuotes.after",e,t,r)})),n.subParser("codeBlocks",(function(e,t,r){e=r.converter._dispatch("codeBlocks.before",e,t,r);return e=(e=(e+="¨0").replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g,(function(e,a,i){var o=a,s=i,l="\n";return o=n.subParser("outdent")(o,t,r),o=n.subParser("encodeCode")(o,t,r),o=(o=(o=n.subParser("detab")(o,t,r)).replace(/^\n+/g,"")).replace(/\n+$/g,""),t.omitExtraWLInCodeBlocks&&(l=""),o="
"+o+l+"
",n.subParser("hashBlock")(o,t,r)+s}))).replace(/¨0/,""),e=r.converter._dispatch("codeBlocks.after",e,t,r)})),n.subParser("codeSpans",(function(e,t,r){return void 0===(e=r.converter._dispatch("codeSpans.before",e,t,r))&&(e=""),e=e.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,(function(e,a,i,o){var s=o;return s=(s=s.replace(/^([ \t]*)/g,"")).replace(/[ \t]*$/g,""),s=a+""+(s=n.subParser("encodeCode")(s,t,r))+"",s=n.subParser("hashHTMLSpans")(s,t,r)})),e=r.converter._dispatch("codeSpans.after",e,t,r)})),n.subParser("completeHTMLDocument",(function(e,t,n){if(!t.completeHTMLDocument)return e;e=n.converter._dispatch("completeHTMLDocument.before",e,t,n);var r="html",a="\n",i="",o='\n',s="",l="";for(var c in void 0!==n.metadata.parsed.doctype&&(a="\n","html"!==(r=n.metadata.parsed.doctype.toString().toLowerCase())&&"html5"!==r||(o='')),n.metadata.parsed)if(n.metadata.parsed.hasOwnProperty(c))switch(c.toLowerCase()){case"doctype":break;case"title":i=""+n.metadata.parsed.title+"\n";break;case"charset":o="html"===r||"html5"===r?'\n':'\n';break;case"language":case"lang":s=' lang="'+n.metadata.parsed[c]+'"',l+='\n';break;default:l+='\n'}return e=a+"\n\n"+i+o+l+"\n\n"+e.trim()+"\n\n",e=n.converter._dispatch("completeHTMLDocument.after",e,t,n)})),n.subParser("detab",(function(e,t,n){return e=(e=(e=(e=(e=(e=n.converter._dispatch("detab.before",e,t,n)).replace(/\t(?=\t)/g," ")).replace(/\t/g,"¨A¨B")).replace(/¨B(.+?)¨A/g,(function(e,t){for(var n=t,r=4-n.length%4,a=0;a/g,">"),e=n.converter._dispatch("encodeAmpsAndAngles.after",e,t,n)})),n.subParser("encodeBackslashEscapes",(function(e,t,r){return e=(e=(e=r.converter._dispatch("encodeBackslashEscapes.before",e,t,r)).replace(/\\(\\)/g,n.helper.escapeCharactersCallback)).replace(/\\([`*_{}\[\]()>#+.!~=|-])/g,n.helper.escapeCharactersCallback),e=r.converter._dispatch("encodeBackslashEscapes.after",e,t,r)})),n.subParser("encodeCode",(function(e,t,r){return e=(e=r.converter._dispatch("encodeCode.before",e,t,r)).replace(/&/g,"&").replace(//g,">").replace(/([*_{}\[\]\\=~-])/g,n.helper.escapeCharactersCallback),e=r.converter._dispatch("encodeCode.after",e,t,r)})),n.subParser("escapeSpecialCharsWithinTagAttributes",(function(e,t,r){return e=(e=(e=r.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before",e,t,r)).replace(/<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,(function(e){return e.replace(/(.)<\/?code>(?=.)/g,"$1`").replace(/([\\`*_~=|])/g,n.helper.escapeCharactersCallback)}))).replace(/-]|-[^>])(?:[^-]|-[^-])*)--)>/gi,(function(e){return e.replace(/([\\`*_~=|])/g,n.helper.escapeCharactersCallback)})),e=r.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after",e,t,r)})),n.subParser("githubCodeBlocks",(function(e,t,r){return t.ghCodeBlocks?(e=r.converter._dispatch("githubCodeBlocks.before",e,t,r),e=(e=(e+="¨0").replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g,(function(e,a,i,o){var s=t.omitExtraWLInCodeBlocks?"":"\n";return o=n.subParser("encodeCode")(o,t,r),o="
"+(o=(o=(o=n.subParser("detab")(o,t,r)).replace(/^\n+/g,"")).replace(/\n+$/g,""))+s+"
",o=n.subParser("hashBlock")(o,t,r),"\n\n¨G"+(r.ghCodeBlocks.push({text:e,codeblock:o})-1)+"G\n\n"}))).replace(/¨0/,""),r.converter._dispatch("githubCodeBlocks.after",e,t,r)):e})),n.subParser("hashBlock",(function(e,t,n){return e=(e=n.converter._dispatch("hashBlock.before",e,t,n)).replace(/(^\n+|\n+$)/g,""),e="\n\n¨K"+(n.gHtmlBlocks.push(e)-1)+"K\n\n",e=n.converter._dispatch("hashBlock.after",e,t,n)})),n.subParser("hashCodeTags",(function(e,t,r){e=r.converter._dispatch("hashCodeTags.before",e,t,r);return e=n.helper.replaceRecursiveRegExp(e,(function(e,a,i,o){var s=i+n.subParser("encodeCode")(a,t,r)+o;return"¨C"+(r.gHtmlSpans.push(s)-1)+"C"}),"]*>","","gim"),e=r.converter._dispatch("hashCodeTags.after",e,t,r)})),n.subParser("hashElement",(function(e,t,n){return function(e,t){var r=t;return r=(r=(r=r.replace(/\n\n/g,"\n")).replace(/^\n/,"")).replace(/\n+$/g,""),r="\n\n¨K"+(n.gHtmlBlocks.push(r)-1)+"K\n\n"}})),n.subParser("hashHTMLBlocks",(function(e,t,r){e=r.converter._dispatch("hashHTMLBlocks.before",e,t,r);var a=["pre","div","h1","h2","h3","h4","h5","h6","blockquote","table","dl","ol","ul","script","noscript","form","fieldset","iframe","math","style","section","header","footer","nav","article","aside","address","audio","canvas","figure","hgroup","output","video","p"],i=function(e,t,n,a){var i=e;return-1!==n.search(/\bmarkdown\b/)&&(i=n+r.converter.makeHtml(t)+a),"\n\n¨K"+(r.gHtmlBlocks.push(i)-1)+"K\n\n"};t.backslashEscapesHTMLTags&&(e=e.replace(/\\<(\/?[^>]+?)>/g,(function(e,t){return"<"+t+">"})));for(var o=0;o]*>)","im"),c="<"+a[o]+"\\b[^>]*>",u="";-1!==(s=n.helper.regexIndexOf(e,l));){var d=n.helper.splitAtIndex(e,s),p=n.helper.replaceRecursiveRegExp(d[1],i,c,u,"im");if(p===d[1])break;e=d[0].concat(p)}return e=e.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,n.subParser("hashElement")(e,t,r)),e=(e=n.helper.replaceRecursiveRegExp(e,(function(e){return"\n\n¨K"+(r.gHtmlBlocks.push(e)-1)+"K\n\n"}),"^ {0,3}\x3c!--","--\x3e","gm")).replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,n.subParser("hashElement")(e,t,r)),e=r.converter._dispatch("hashHTMLBlocks.after",e,t,r)})),n.subParser("hashHTMLSpans",(function(e,t,n){function r(e){return"¨C"+(n.gHtmlSpans.push(e)-1)+"C"}return e=(e=(e=(e=(e=n.converter._dispatch("hashHTMLSpans.before",e,t,n)).replace(/<[^>]+?\/>/gi,(function(e){return r(e)}))).replace(/<([^>]+?)>[\s\S]*?<\/\1>/g,(function(e){return r(e)}))).replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g,(function(e){return r(e)}))).replace(/<[^>]+?>/gi,(function(e){return r(e)})),e=n.converter._dispatch("hashHTMLSpans.after",e,t,n)})),n.subParser("unhashHTMLSpans",(function(e,t,n){e=n.converter._dispatch("unhashHTMLSpans.before",e,t,n);for(var r=0;r]*>\\s*]*>","^ {0,3}\\s*
","gim"),e=r.converter._dispatch("hashPreCodeTags.after",e,t,r)})),n.subParser("headers",(function(e,t,r){e=r.converter._dispatch("headers.before",e,t,r);var a=isNaN(parseInt(t.headerLevelStart))?1:parseInt(t.headerLevelStart),i=t.smoothLivePreview?/^(.+)[ \t]*\n={2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n=+[ \t]*\n+/gm,o=t.smoothLivePreview?/^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n-+[ \t]*\n+/gm;e=(e=e.replace(i,(function(e,i){var o=n.subParser("spanGamut")(i,t,r),s=t.noHeaderId?"":' id="'+l(i)+'"',c=""+o+"";return n.subParser("hashBlock")(c,t,r)}))).replace(o,(function(e,i){var o=n.subParser("spanGamut")(i,t,r),s=t.noHeaderId?"":' id="'+l(i)+'"',c=a+1,u=""+o+"";return n.subParser("hashBlock")(u,t,r)}));var s=t.requireSpaceBeforeHeadingText?/^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm:/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;function l(e){var a,i;if(t.customizedHeaderId){var o=e.match(/\{([^{]+?)}\s*$/);o&&o[1]&&(e=o[1])}return a=e,i=n.helper.isString(t.prefixHeaderId)?t.prefixHeaderId:!0===t.prefixHeaderId?"section-":"",t.rawPrefixHeaderId||(a=i+a),a=t.ghCompatibleHeaderId?a.replace(/ /g,"-").replace(/&/g,"").replace(/¨T/g,"").replace(/¨D/g,"").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g,"").toLowerCase():t.rawHeaderId?a.replace(/ /g,"-").replace(/&/g,"&").replace(/¨T/g,"¨").replace(/¨D/g,"$").replace(/["']/g,"-").toLowerCase():a.replace(/[^\w]/g,"").toLowerCase(),t.rawPrefixHeaderId&&(a=i+a),r.hashLinkCounts[a]?a=a+"-"+r.hashLinkCounts[a]++:r.hashLinkCounts[a]=1,a}return e=e.replace(s,(function(e,i,o){var s=o;t.customizedHeaderId&&(s=o.replace(/\s?\{([^{]+?)}\s*$/,""));var c=n.subParser("spanGamut")(s,t,r),u=t.noHeaderId?"":' id="'+l(o)+'"',d=a-1+i.length,p=""+c+"";return n.subParser("hashBlock")(p,t,r)})),e=r.converter._dispatch("headers.after",e,t,r)})),n.subParser("horizontalRule",(function(e,t,r){e=r.converter._dispatch("horizontalRule.before",e,t,r);var a=n.subParser("hashBlock")("
",t,r);return e=(e=(e=e.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm,a)).replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm,a)).replace(/^ {0,2}( ?_){3,}[ \t]*$/gm,a),e=r.converter._dispatch("horizontalRule.after",e,t,r)})),n.subParser("images",(function(e,t,r){function a(e,t,a,i,o,s,l,c){var u=r.gUrls,d=r.gTitles,p=r.gDimensions;if(a=a.toLowerCase(),c||(c=""),e.search(/\(? ?(['"].*['"])?\)$/m)>-1)i="";else if(""===i||null===i){if(""!==a&&null!==a||(a=t.toLowerCase().replace(/ ?\n/g," ")),i="#"+a,n.helper.isUndefined(u[a]))return e;i=u[a],n.helper.isUndefined(d[a])||(c=d[a]),n.helper.isUndefined(p[a])||(o=p[a].width,s=p[a].height)}t=t.replace(/"/g,""").replace(n.helper.regexes.asteriskDashAndColon,n.helper.escapeCharactersCallback);var h=''+t+'"}return e=(e=(e=(e=(e=(e=r.converter._dispatch("images.before",e,t,r)).replace(/!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,a)).replace(/!\[([^\]]*?)][ \t]*()\([ \t]??(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,(function(e,t,n,r,i,o,s,l){return a(e,t,n,r=r.replace(/\s/g,""),i,o,s,l)}))).replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,a)).replace(/!\[([^\]]*?)][ \t]*()\([ \t]??(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,a)).replace(/!\[([^\[\]]+)]()()()()()/g,a),e=r.converter._dispatch("images.after",e,t,r)})),n.subParser("italicsAndBold",(function(e,t,n){function r(e,t,n){return t+e+n}return e=n.converter._dispatch("italicsAndBold.before",e,t,n),e=t.literalMidWordUnderscores?(e=(e=e.replace(/\b___(\S[\s\S]*?)___\b/g,(function(e,t){return r(t,"","")}))).replace(/\b__(\S[\s\S]*?)__\b/g,(function(e,t){return r(t,"","")}))).replace(/\b_(\S[\s\S]*?)_\b/g,(function(e,t){return r(t,"","")})):(e=(e=e.replace(/___(\S[\s\S]*?)___/g,(function(e,t){return/\S$/.test(t)?r(t,"",""):e}))).replace(/__(\S[\s\S]*?)__/g,(function(e,t){return/\S$/.test(t)?r(t,"",""):e}))).replace(/_([^\s_][\s\S]*?)_/g,(function(e,t){return/\S$/.test(t)?r(t,"",""):e})),e=t.literalMidWordAsterisks?(e=(e=e.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g,(function(e,t,n){return r(n,t+"","")}))).replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g,(function(e,t,n){return r(n,t+"","")}))).replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g,(function(e,t,n){return r(n,t+"","")})):(e=(e=e.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g,(function(e,t){return/\S$/.test(t)?r(t,"",""):e}))).replace(/\*\*(\S[\s\S]*?)\*\*/g,(function(e,t){return/\S$/.test(t)?r(t,"",""):e}))).replace(/\*([^\s*][\s\S]*?)\*/g,(function(e,t){return/\S$/.test(t)?r(t,"",""):e})),e=n.converter._dispatch("italicsAndBold.after",e,t,n)})),n.subParser("lists",(function(e,t,r){function a(e,a){r.gListLevel++,e=e.replace(/\n{2,}$/,"\n");var i=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,o=/\n[ \t]*\n(?!¨0)/.test(e+="¨0");return t.disableForced4SpacesIndentedSublists&&(i=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm),e=(e=e.replace(i,(function(e,a,i,s,l,c,u){u=u&&""!==u.trim();var d=n.subParser("outdent")(l,t,r),p="";return c&&t.tasklists&&(p=' class="task-list-item" style="list-style-type: none;"',d=d.replace(/^[ \t]*\[(x|X| )?]/m,(function(){var e='-1?(d=n.subParser("githubCodeBlocks")(d,t,r),d=n.subParser("blockGamut")(d,t,r)):(d=(d=n.subParser("lists")(d,t,r)).replace(/\n$/,""),d=(d=n.subParser("hashHTMLBlocks")(d,t,r)).replace(/\n\n+/g,"\n\n"),d=o?n.subParser("paragraphs")(d,t,r):n.subParser("spanGamut")(d,t,r)),d=""+(d=d.replace("¨A",""))+"\n"}))).replace(/¨0/g,""),r.gListLevel--,a&&(e=e.replace(/\s+$/,"")),e}function i(e,t){if("ol"===t){var n=e.match(/^ *(\d+)\./);if(n&&"1"!==n[1])return' start="'+n[1]+'"'}return""}function o(e,n,r){var o=t.disableForced4SpacesIndentedSublists?/^ ?\d+\.[ \t]/gm:/^ {0,3}\d+\.[ \t]/gm,s=t.disableForced4SpacesIndentedSublists?/^ ?[*+-][ \t]/gm:/^ {0,3}[*+-][ \t]/gm,l="ul"===n?o:s,c="";if(-1!==e.search(l))!function t(u){var d=u.search(l),p=i(e,n);-1!==d?(c+="\n\n<"+n+p+">\n"+a(u.slice(0,d),!!r)+"\n",l="ul"===(n="ul"===n?"ol":"ul")?o:s,t(u.slice(d))):c+="\n\n<"+n+p+">\n"+a(u,!!r)+"\n"}(e);else{var u=i(e,n);c="\n\n<"+n+u+">\n"+a(e,!!r)+"\n"}return c}return e=r.converter._dispatch("lists.before",e,t,r),e+="¨0",e=(e=r.gListLevel?e.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,(function(e,t,n){return o(t,n.search(/[*+-]/g)>-1?"ul":"ol",!0)})):e.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,(function(e,t,n,r){return o(n,r.search(/[*+-]/g)>-1?"ul":"ol",!1)}))).replace(/¨0/,""),e=r.converter._dispatch("lists.after",e,t,r)})),n.subParser("metadata",(function(e,t,n){if(!t.metadata)return e;function r(e){n.metadata.raw=e,(e=(e=e.replace(/&/g,"&").replace(/"/g,""")).replace(/\n {4}/g," ")).replace(/^([\S ]+): +([\s\S]+?)$/gm,(function(e,t,r){return n.metadata.parsed[t]=r,""}))}return e=(e=(e=(e=n.converter._dispatch("metadata.before",e,t,n)).replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/,(function(e,t,n){return r(n),"¨M"}))).replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/,(function(e,t,a){return t&&(n.metadata.format=t),r(a),"¨M"}))).replace(/¨M/g,""),e=n.converter._dispatch("metadata.after",e,t,n)})),n.subParser("outdent",(function(e,t,n){return e=(e=(e=n.converter._dispatch("outdent.before",e,t,n)).replace(/^(\t|[ ]{1,4})/gm,"¨0")).replace(/¨0/g,""),e=n.converter._dispatch("outdent.after",e,t,n)})),n.subParser("paragraphs",(function(e,t,r){for(var a=(e=(e=(e=r.converter._dispatch("paragraphs.before",e,t,r)).replace(/^\n+/g,"")).replace(/\n+$/g,"")).split(/\n{2,}/g),i=[],o=a.length,s=0;s=0?i.push(l):l.search(/\S/)>=0&&(l=(l=n.subParser("spanGamut")(l,t,r)).replace(/^([ \t]*)/g,"

"),l+="

",i.push(l))}for(o=i.length,s=0;s]*>\s*]*>/.test(u)&&(d=!0)}i[s]=u}return e=(e=(e=i.join("\n")).replace(/^\n+/g,"")).replace(/\n+$/g,""),r.converter._dispatch("paragraphs.after",e,t,r)})),n.subParser("runExtension",(function(e,t,n,r){if(e.filter)t=e.filter(t,r.converter,n);else if(e.regex){var a=e.regex;a instanceof RegExp||(a=new RegExp(a,"g")),t=t.replace(a,e.replace)}return t})),n.subParser("spanGamut",(function(e,t,r){return e=r.converter._dispatch("spanGamut.before",e,t,r),e=n.subParser("codeSpans")(e,t,r),e=n.subParser("escapeSpecialCharsWithinTagAttributes")(e,t,r),e=n.subParser("encodeBackslashEscapes")(e,t,r),e=n.subParser("images")(e,t,r),e=n.subParser("anchors")(e,t,r),e=n.subParser("autoLinks")(e,t,r),e=n.subParser("simplifiedAutoLinks")(e,t,r),e=n.subParser("emoji")(e,t,r),e=n.subParser("underline")(e,t,r),e=n.subParser("italicsAndBold")(e,t,r),e=n.subParser("strikethrough")(e,t,r),e=n.subParser("ellipsis")(e,t,r),e=n.subParser("hashHTMLSpans")(e,t,r),e=n.subParser("encodeAmpsAndAngles")(e,t,r),t.simpleLineBreaks?/\n\n¨K/.test(e)||(e=e.replace(/\n+/g,"
\n")):e=e.replace(/ +\n/g,"
\n"),e=r.converter._dispatch("spanGamut.after",e,t,r)})),n.subParser("strikethrough",(function(e,t,r){return t.strikethrough&&(e=(e=r.converter._dispatch("strikethrough.before",e,t,r)).replace(/(?:~){2}([\s\S]+?)(?:~){2}/g,(function(e,a){return function(e){return t.simplifiedAutoLink&&(e=n.subParser("simplifiedAutoLinks")(e,t,r)),""+e+""}(a)})),e=r.converter._dispatch("strikethrough.after",e,t,r)),e})),n.subParser("stripLinkDefinitions",(function(e,t,r){var a=function(e,a,i,o,s,l,c){return a=a.toLowerCase(),i.match(/^data:.+?\/.+?;base64,/)?r.gUrls[a]=i.replace(/\s/g,""):r.gUrls[a]=n.subParser("encodeAmpsAndAngles")(i,t,r),l?l+c:(c&&(r.gTitles[a]=c.replace(/"|'/g,""")),t.parseImgDimensions&&o&&s&&(r.gDimensions[a]={width:o,height:s}),"")};return e=(e=(e=(e+="¨0").replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm,a)).replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,a)).replace(/¨0/,"")})),n.subParser("tables",(function(e,t,r){if(!t.tables)return e;function a(e,a){return""+n.subParser("spanGamut")(e,t,r)+"\n"}function i(e){var i,o=e.split("\n");for(i=0;i"+(l=n.subParser("spanGamut")(l,t,r))+"\n"));for(i=0;i\n\n
\n",a=0;a\n";for(var i=0;i\n"}return n+="\n
\n"}(g,m)}return e=(e=(e=(e=r.converter._dispatch("tables.before",e,t,r)).replace(/\\(\|)/g,n.helper.escapeCharactersCallback)).replace(/^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,i)).replace(/^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm,i),e=r.converter._dispatch("tables.after",e,t,r)})),n.subParser("underline",(function(e,t,r){return t.underline?(e=r.converter._dispatch("underline.before",e,t,r),e=(e=t.literalMidWordUnderscores?(e=e.replace(/\b___(\S[\s\S]*?)___\b/g,(function(e,t){return""+t+""}))).replace(/\b__(\S[\s\S]*?)__\b/g,(function(e,t){return""+t+""})):(e=e.replace(/___(\S[\s\S]*?)___/g,(function(e,t){return/\S$/.test(t)?""+t+"":e}))).replace(/__(\S[\s\S]*?)__/g,(function(e,t){return/\S$/.test(t)?""+t+"":e}))).replace(/(_)/g,n.helper.escapeCharactersCallback),e=r.converter._dispatch("underline.after",e,t,r)):e})),n.subParser("unescapeSpecialChars",(function(e,t,n){return e=(e=n.converter._dispatch("unescapeSpecialChars.before",e,t,n)).replace(/¨E(\d+)E/g,(function(e,t){var n=parseInt(t);return String.fromCharCode(n)})),e=n.converter._dispatch("unescapeSpecialChars.after",e,t,n)})),n.subParser("makeMarkdown.blockquote",(function(e,t){var r="";if(e.hasChildNodes())for(var a=e.childNodes,i=a.length,o=0;o ")})),n.subParser("makeMarkdown.codeBlock",(function(e,t){var n=e.getAttribute("language"),r=e.getAttribute("precodenum");return"```"+n+"\n"+t.preList[r]+"\n```"})),n.subParser("makeMarkdown.codeSpan",(function(e){return"`"+e.innerHTML+"`"})),n.subParser("makeMarkdown.emphasis",(function(e,t){var r="";if(e.hasChildNodes()){r+="*";for(var a=e.childNodes,i=a.length,o=0;o",e.hasAttribute("width")&&e.hasAttribute("height")&&(t+=" ="+e.getAttribute("width")+"x"+e.getAttribute("height")),e.hasAttribute("title")&&(t+=' "'+e.getAttribute("title")+'"'),t+=")"),t})),n.subParser("makeMarkdown.links",(function(e,t){var r="";if(e.hasChildNodes()&&e.hasAttribute("href")){var a=e.childNodes,i=a.length;r="[";for(var o=0;o",e.hasAttribute("title")&&(r+=' "'+e.getAttribute("title")+'"'),r+=")"}return r})),n.subParser("makeMarkdown.list",(function(e,t,r){var a="";if(!e.hasChildNodes())return"";for(var i=e.childNodes,o=i.length,s=e.getAttribute("start")||1,l=0;l"+t.preList[n]+""})),n.subParser("makeMarkdown.strikethrough",(function(e,t){var r="";if(e.hasChildNodes()){r+="~~";for(var a=e.childNodes,i=a.length,o=0;otr>th"),l=e.querySelectorAll("tbody>tr");for(r=0;rg&&(g=f)}for(r=0;r/g,"\\$1>")).replace(/^#/gm,"\\#")).replace(/^(\s*)([-=]{3,})(\s*)$/,"$1\\$2$3")).replace(/^( {0,3}\d+)\./gm,"$1\\.")).replace(/^( {0,3})([+-])/gm,"$1\\$2")).replace(/]([\s]*)\(/g,"\\]$1\\(")).replace(/^ {0,3}\[([\S \t]*?)]:/gm,"\\[$1]:")}));e.exports?e.exports=n:this.showdown=n}).call(Pt)}));function Dt(e){switch(e.type){case"basic":return function(e=null,t=null){return{name:"Authorization",value:"Basic "+btoa(`${e||""}:${t||""}`)}}(e.username,e.password);case"bearer":return t=e.token,{name:"Authorization",value:`${e.prefix||"Bearer"} ${t}`};case"oauth1":return function(e){const{callback:t,consumerKey:n,nonce:r,signatureMethod:a,timestamp:i,tokenKey:o}=e;return{name:"Authorization",value:`OAuth oauth_callback="${t}",\noauth_consumer_key="${n}",\noauth_nonce="${r||"{{oauth_nonce}}"}",\noauth_signature="{{oauth_signature}}",\noauth_signature_method="${a}",\noauth_timestamp="${i||1103493600}",\noauth_token="${o}",\noauth_version="1.0"`.split("\n").join(" ")}}(e);case"oauth2":return{name:"Authorization",value:'OAuth {{params}}, oauth_version="2.0"'};case"hawk":return{name:"Authorization",value:`Hawk id="${e.id}", ts="1103493600", nonce="{{hawk_nonce}}", mac="{{hawk_mac}}"`};case"ntlm":return{name:"Authorization",value:"NTLM {{ntlm_token}}"};case"asap":return{name:"Authorization",value:"Bearer {{jwt_token}}"};default:return{name:"Authorization",value:"{{authorization}}"}}var t}function Ut(e,t){const n=t.parameters;return n&&n.length?(e+="?",e+=n.filter(e=>!e.disabled).map(e=>`${encodeURIComponent(e.name)}=${encodeURIComponent(e.value)}`).join("&")):e}function Ft(e){return JSON.stringify(e).slice(1,-1)}function Gt(e,t){let n=`curl "${Ut(e,t)}" \\\n`;return t.headers.forEach(e=>{n+=` -H '${e.name}: ${e.value||""}' \\\n`}),t.authHeader&&(n+=` -H '${t.authHeader.name}: ${Ft(t.authHeader.value||"")}' \\\n`),n+=` -X ${t.method} \\\n`,t.cookies&&t.cookies.length&&t.cookies.forEach(e=>{n+=` -b '${e.key}'='${e.value}' \\\n`}),t.body&&t.body.params&&t.body.params.length&&t.body.params.forEach(e=>{if(null===e.value)return!1;e.value.indexOf("'")>=0&&e.value.indexOf('"')>=0?n+=` -F "${e.name}=${e.value.replace('"','\\"')}"`:e.value.indexOf("'")>=0?n+=` -F "${e.name}=${e.value}"`:(e.value.indexOf('"'),n+=` -F '${e.name}=${e.value}'`),n+=" \\\n"}),t.body&&t.body.text&&(n+=` -d '${t.body.text.replace(/\t/g," ")}' \\\n`),n.slice(0,-2)}function Vt(e,t){let n="",r=!1;t.body&&"multipart/form-data"===t.body.mimeType&&(r=!0,n+="const form = new FormData();\n",t.body.params.forEach(e=>{n+=`form.append("${e.name}", "${e.value}");\n`}),n+="\n"),n+=`fetch("${Ut(e,t)}", `;const a={method:t.method};var i,o;return t.headers&&t.headers.length&&(a.headers={},t.headers.forEach(e=>{a.headers[e.name]=e.value})),t.authHeader&&(a.headers||(a.headers={}),a.headers[t.authHeader.name]=t.authHeader.value),t.cookies&&t.cookies.length&&(a.headers||(a.headers={}),a.headers.cookie=t.cookies.map(e=>`${encodeURIComponent(e.key)}=${encodeURIComponent(e.value)}`).join("; ")),!r&&t.body&&"multipart/form-data"!==t.body.mimeType&&(a.body=(i=t.body.mimeType,o=t.body,"application/json"===i&&o.text?JSON.parse(o.text):"application/x-www-form-urlencoded"===i?o.params.map(e=>`${encodeURIComponent(e.name)}=${encodeURIComponent(e.value)}`).join("&"):o.text)),r&&(a.body="{{formVariable}}"),n+=JSON.stringify(a,null,2),r&&(n=n.replace('"{{formVariable}}"',"form")),n+=")\n .then(response => console.log(response))\n",n+=" .catch(err => console.error(err));",n}function Wt(e,t){let n="import requests\n\n";if(n+=`url = '${e}'\n`,t.parameters&&t.parameters.length){const e={};t.parameters.forEach(t=>{e[t.name]=t.value}),n+=`querystring = ${JSON.stringify(e)}\n`}const r={};t.authHeader&&(r[t.authHeader.name]=t.authHeader.value),t.headers&&t.headers.length&&t.headers.forEach(e=>{r[e.name]=e.value}),t.cookies&&t.cookies.length&&(r.cookie=t.cookies.map(e=>`${encodeURIComponent(e.key)}=${encodeURIComponent(e.value)}`).join("; ")),r&&(n+=`headers = ${JSON.stringify(r,null,2)}\n`);const a=function(e){const t=e.mimeType;if("application/x-www-form-urlencoded"===t)return"payload = "+e.params.map(e=>`${encodeURIComponent(e.name)}=${encodeURIComponent(e.value)}`).join("&");if("multipart/form-data"===t){const t={},n={};return e.params.forEach(e=>{"file"===e.type?n[e.name]=e.value:t[e.name]=e.value}),`payload = ${JSON.stringify(t,null,2)}\n\nfiles = ${JSON.stringify(n,null,2)}`}return"application/json"===t&&e.text?"payload = "+JSON.stringify(JSON.parse(e.text),null,2):e.text?`payload = '${e.text}'`:null}(t.body);return a&&(n+=a+"\n"),n+=`\nresponse = requests.request('${t.method}', url, ${a?"data = payload, ":""}headers=headers, files=files)\n`,n+="print(response.text)",n}function Kt(e){const t=e.mimeType;if("application/x-www-form-urlencoded"===t)return e.params.map(e=>`${encodeURIComponent(e.name)}=${encodeURIComponent(e.value)}`).join("&");if("multipart/form-data"===t){const t="-----011000010111000001101001";return`"${Ft(e.params.map(e=>`${t}\nContent-Disposition: form-data; name="${e.name}"\n\n${e.value}`).join("\n"))}\n${t}--"`}return JSON.stringify(e.text)}function Jt(e,t){const n=(e=Ut(e,t)).startsWith("https://");let r="require 'uri'\nrequire 'net/http'\n";if(n&&(r+="require 'openssl'\n"),r+=`\nurl = URI("${e}")\n\nhttp = Net::HTTP.new(url.host, url.port)\n`,n&&(r+="http.use_ssl = true\nhttp.verify_mode = OpenSSL::SSL::VERIFY_NONE\n"),r+=`\nrequest = Net::HTTP::${function(e){switch(e){case"GET":return"Get";case"POST":return"Post";case"PATCH":return"Patch";case"PUT":return"Put";case"DELETE":return"Delete";default:return"{{METHOD}}"}}(t.method)}.new(url)\n`,t.cookies&&t.cookies.length){const e=[];t.cookies.forEach(t=>e.push(`${encodeURIComponent(t.key)}=${encodeURIComponent(t.value)}`)),r+=`request["cookie"] = '${e.join("; ")}'\n`}if(t.headers&&t.headers.length&&t.headers.forEach(e=>{r+=`request["${e.name}"] = ${JSON.stringify(e.value)}\n`}),t.authHeader&&(r+=`request["${t.authHeader.name}"] = ${JSON.stringify(t.authHeader.value)}\n`),t.body){const e=Kt(t.body);e&&(r+=`request.body = ${e}\n`)}return r+="\nresponse = http.request(request)\nputs response.read_body",r}function Zt(e,t){let n=" "${Ut(e,t)}"`,"CURLOPT_RETURNTRANSFER => true",'CURLOPT_ENCODING => ""',"CURLOPT_MAXREDIRS => 10","CURLOPT_TIMEOUT => 30","CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1",`CURLOPT_CUSTOMREQUEST => "${t.method}"`],a=Kt(t.body);if(a&&r.push("CURLOPT_POSTFIELDS => "+a),t.cookies&&t.cookies.length){const e=[];t.cookies.forEach(t=>e.push(`${encodeURIComponent(t.key)}=${encodeURIComponent(t.value)}`)),r.push(`CURLOPT_COOKIE => '${e.join("; ")}'`)}const i=[];return t.headers&&t.headers.length&&t.headers.forEach(e=>i.push(`${e.name}: ${Ft(e.value)}`)),t.authHeader&&i.push(`${t.authHeader.name}: ${t.authHeader.value}`),i.length&&r.push(`CURLOPTS_HTTPHEADER => array(\n ${i.join(",\n ")}\n )`),n+=r.join(",\n ")+'\n));\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo "cURL Error #:" . $err;\n} else {\n echo $response;\n}',n}function Qt(e,t){const n=t.body&&function(e){const t=e.mimeType;if("application/x-www-form-urlencoded"===t)return'"'+e.params.map(e=>`${encodeURIComponent(e.name)}=${encodeURIComponent(e.value)}`).join("&")+'"';if("multipart/form-data"===t){const t="-----011000010111000001101001",n=e.params.map(e=>`${t}\nContent-Disposition: form-data; name="${e.name}"\n\n${e.value}`).join("\n");return`"${escape(n)}\n${t}--"`}return JSON.stringify(e.text)}(t.body);let r=`package main\n\nimport (\n "fmt"${n?'\n"strings"':""}\n "net/http"\n "io/ioutil"\n)\n\nfunc main() {\n\n `;if(r+=`url := "${Ut(e,t)}"\n`,n&&(r+=` payload := strings.NewReader(${n})\n`),r+=` req, _ := http.NewRequest("${t.method}" url, ${n?"payload":"nil"})\n\n`,t.cookies&&t.cookies.length){const e=[];t.cookies.forEach(t=>e.push(`${encodeURIComponent(t.key)}=${encodeURIComponent(t.value)}`)),r+=` req.Header.Add("cookie", ${JSON.stringify(e.join(";"))})\n`}return t.headers.forEach(e=>{r+=` req.Header.Add("${e.name}", ${JSON.stringify(e.value)})\n`}),t.authHeader&&(r+=` req.Header.Add("${t.authHeader.name}", ${JSON.stringify(t.authHeader.value)})\n`),r+=" res, _ := http.DefaultClient.Do(req)\n\n defer res.Body.Close()\n body, _ := ioutil.ReadAll(res.Body)\n\n fmt.Println(res)\n fmt.Println(string(body))\n\n}",r}class Xt{constructor(e,t,n){this.request=e,this.url=t,this.cookiejars=n,this.code=null,this.request.cookies=this.appendCookies(),this.request.authentication&&this.request.authentication.type&&(this.request.authHeader=Dt(this.request.authentication))}generate(e){switch(e){case"curl":this.code=Gt;break;case"javascript":this.code=Vt;break;case"python":this.code=Wt;break;case"node":return"const fetch = require('node-fetch');\n\n"+Vt(this.url,this.request);case"ruby":this.code=Jt;break;case"php":this.code=Zt;break;case"golang":this.code=Qt;break;default:return"Not implemented yet..."}return this.code(this.url,this.request)}appendCookies(){const e=[];return this.cookiejars.forEach(t=>{t.cookies&&t.cookies.length&&t.cookies.forEach(t=>{this.url&&this.url.includes(t.domain)&&("/"===t.path||this.url.includes(t.path))&&e.push({key:t.key,value:t.value})})}),e}}function Yt(e){return e?e.replace(/{{\s*(_.)?([a-zA-Z0-9_]+)\s*}}/g,'$2'):""}class en{constructor(e){this.body=e,this.mime=e.mimeType}__parseJSON(){if(!this.body.text)return;let e;this.body.text=this.body.text.replace(new RegExp("{{.*}}","g"),'"!!Missing declaration in environment!!"');try{e=JSON.stringify(JSON.parse(this.body.text),null,2)}catch(t){console.warn("Failed to parse JSON body (expect incorrect tokenization):",this.body.text),e=this.body.text}return{type:"plain",note:"json",text:`
${e}
`}}__parseMultipart(){return{type:"array",note:"formdata",rows:this.body.params.map(e=>({name:e.name,value:e.value,description:e.description}))}}__parsePlain(){return{type:"plain",note:"raw",text:`
${this.body.text}
`}}parse(){switch(this.mime){case"application/json":return this.__parseJSON();case"multipart/form-data":case"application/x-www-form-urlencoded":return this.__parseMultipart();default:return this.__parsePlain()}}}class tn{constructor(e){this.req=e}params(){const e=[];return this.req.parameters.forEach(t=>{e.push({name:t.name,value:t.value,description:t.description})}),{title:"Parameters",rows:e}}headers(){const e=[];if(this.req.headers.forEach(t=>{e.push({name:t.name,value:Yt(t.value||""),description:t.description})}),this.req.authentication&&this.req.authentication.type){const t=Dt(this.req.authentication);e.push({name:t.name,value:`
${Yt(t.value)}
`})}return{title:"Headers",rows:e}}body(){const e=new en(this.req.body).parse();switch(e.type){case"array":return{title:"Body",note:e.note,rows:e.rows};case"plain":return{title:"Body",note:e.note,text:e.text}}}}function nn(e,t,n){const r=e.slice();return r[1]=t[n],r}function rn(e){let t,n,r=e[0].note+"";return{c(){t=g("span"),n=m(r),v(t,"class","note svelte-t9o7qk")},m(e,r){d(e,t,r),u(t,n)},p(e,t){1&t&&r!==(r=e[0].note+"")&&$(n,r)},d(e){e&&p(t)}}}function an(e){let t,n=e[0].text+"";return{c(){t=g("div"),v(t,"class","raw-data")},m(e,r){d(e,t,r),t.innerHTML=n},p(e,r){1&r&&n!==(n=e[0].text+"")&&(t.innerHTML=n)},d(e){e&&p(t)}}}function on(e){let t,n=e[0].rows,r=[];for(let t=0;t{"data"in e&&n(0,r=e.data)},[r]}class dn extends ue{constructor(e){super(),ce(this,e,un,cn,o,{data:0})}}function pn(e,t,n){const r=e.slice();return r[17]=t[n],r}function hn(e){let t;return{c(){t=g("div"),v(t,"class","description")},m(n,r){d(n,t,r),t.innerHTML=e[7]},p(e,n){128&n&&(t.innerHTML=e[7])},d(e){e&&p(t)}}}function gn(e){let t,n;return t=new dn({props:{data:e[5].params()}}),{c(){oe(t.$$.fragment)},m(e,r){se(t,e,r),n=!0},p(e,n){const r={};32&n&&(r.data=e[5].params()),t.$set(r)},i(e){n||(te(t.$$.fragment,e),n=!0)},o(e){ne(t.$$.fragment,e),n=!1},d(e){le(t,e)}}}function fn(e){let t,n;return t=new dn({props:{data:e[5].headers()}}),{c(){oe(t.$$.fragment)},m(e,r){se(t,e,r),n=!0},p(e,n){const r={};32&n&&(r.data=e[5].headers()),t.$set(r)},i(e){n||(te(t.$$.fragment,e),n=!0)},o(e){ne(t.$$.fragment,e),n=!1},d(e){le(t,e)}}}function mn(e){let t,n;return t=new dn({props:{data:e[5].body()}}),{c(){oe(t.$$.fragment)},m(e,r){se(t,e,r),n=!0},p(e,n){const r={};32&n&&(r.data=e[5].body()),t.$set(r)},i(e){n||(te(t.$$.fragment,e),n=!0)},o(e){ne(t.$$.fragment,e),n=!1},d(e){le(t,e)}}}function bn(e){let t,n=e[3].exampleResponses,r=[];for(let t=0;t{K=null}),ee()),e[0].headers&&e[0].headers.length||e[0].authentication&&e[0].authentication.type?J?(J.p(e,t),1&t&&te(J,1)):(J=fn(e),J.c(),te(J,1),J.m(S,A)):J&&(Y(),ne(J,1,1,()=>{J=null}),ee()),e[0].body&&(e[0].body.text||e[0].body.params)?Z?(Z.p(e,t),1&t&&te(Z,1)):(Z=mn(e),Z.c(),te(Z,1),Z.m(S,null)):Z&&(Y(),ne(Z,1,1,()=>{Z=null}),ee()),(!U||16&t)&&$(z,e[4]),(!U||64&t)&&(q.innerHTML=e[6]),e[3].exampleResponses&&e[3].exampleResponses.length?Q?Q.p(e,t):(Q=bn(e),Q.c(),Q.m(T,null)):Q&&(Q.d(1),Q=null)},i(e){U||(te(K),te(J),te(Z),U=!0)},o(e){ne(K),ne(J),ne(Z),U=!1},d(n){n&&p(t),W&&W.d(),K&&K.d(),J&&J.d(),Z&&Z.d(),e[14](null),e[15](null),Q&&Q.d()}}}function yn(e){if(!e)return"default";switch(e[0]){case"1":return"info";case"2":return"success";case"3":return"redirect";case"4":return"client-error";case"5":return"server-error";default:return"default"}}function kn(e,t,n){let r,a,i,o,s,l;const c=new qt.Converter({simplifiedAutoLink:!0,openLinksInNewWindow:!0,excludeTrailingPunctuationFromURLs:!0,tables:!0});let u,d,{request:p}=t,{env:h}=t,{language:g=null}=t,{cookiejars:f}=t,m="Copy to clipboard";const b=document.createElement("code");return e.$$set=e=>{"request"in e&&n(0,p=e.request),"env"in e&&n(8,h=e.env),"language"in e&&n(9,g=e.language),"cookiejars"in e&&n(10,f=e.cookiejars)},e.$$.update=()=>{1&e.$$.dirty&&n(5,r=new tn(p)),1&e.$$.dirty&&n(3,a={method:p.method,url:Yt(p.url),name:p.name,description:p.description,exampleResponses:p.exampleResponses}),1537&e.$$.dirty&&n(12,i=((e,t,n,r)=>new Xt(e,t,r).generate(n))(p,p.url,g,f)),512&e.$$.dirty&&n(11,b.className=g,b),4096&e.$$.dirty&&n(11,b.textContent=i,b),2048&e.$$.dirty&&yt.highlightBlock(b),2048&e.$$.dirty&&n(6,o=b.outerHTML),6&e.$$.dirty&&n(13,s=u&&new Bt(u,{target:()=>d})),8192&e.$$.dirty&&s&&s.on("success",(function(){n(4,m="Copied!"),setTimeout(()=>n(4,m="Copy to Clipboard"),5e3)})),8192&e.$$.dirty&&s&&s.on("error",(function(e){console.error(e),n(4,m="Failed to copy :("),setTimeout(()=>n(4,m="Copy to Clipboard"),5e3)})),8&e.$$.dirty&&n(7,l=a.description&&c.makeHtml(a.description))},[p,u,d,a,m,r,o,l,h,g,f,b,i,s,function(e){z[e?"unshift":"push"](()=>{u=e,n(1,u)})},function(e){z[e?"unshift":"push"](()=>{d=e,n(2,d)})}]}class $n extends ue{constructor(e){super(),ce(this,e,kn,vn,o,{request:0,env:8,language:9,cookiejars:10})}}function En(e,t){return e?(Object.keys(t.data).forEach(n=>{e=e.replace(new RegExp("{{(\\s*(_.)?"+n+"\\s*)}}","g"),t.data[n])}),e):null}function xn(e){let t;return{c(){t=g("div"),v(t,"class","description")},m(n,r){d(n,t,r),t.innerHTML=e[1]},p(e,n){2&n&&(t.innerHTML=e[1])},d(e){e&&p(t)}}}function Sn(t){let n,r,a,i,o,s,l,c,h,f=t[0].name+"",_=t[1]&&xn(t);return{c(){n=g("div"),r=g("div"),a=g("h2"),i=m(f),o=b(),_&&_.c(),s=b(),l=g("hr"),c=b(),h=g("div"),v(r,"class","left"),v(h,"class","right"),v(n,"class","row")},m(e,t){d(e,n,t),u(n,r),u(r,a),u(a,i),u(r,o),_&&_.m(r,null),u(r,s),u(r,l),u(n,c),u(n,h)},p(e,[t]){1&t&&f!==(f=e[0].name+"")&&$(i,f),e[1]?_?_.p(e,t):(_=xn(e),_.c(),_.m(r,s)):_&&(_.d(1),_=null)},i:e,o:e,d(e){e&&p(n),_&&_.d()}}}function Cn(e,t,n){let r,a;const i=new qt.Converter({simplifiedAutoLink:!0,openLinksInNewWindow:!0,excludeTrailingPunctuationFromURLs:!0,tables:!0});let{group:o}=t,{env:s}=t;return e.$$set=e=>{"group"in e&&n(2,o=e.group),"env"in e&&n(3,s=e.env)},e.$$.update=()=>{12&e.$$.dirty&&n(0,r={name:En(o.name,s),description:En(o.description,s)}),1&e.$$.dirty&&n(1,a=r.description&&i.makeHtml(r.description))},[r,a,o,s]}class An extends ue{constructor(e){super(),ce(this,e,Cn,Sn,o,{group:2,env:3})}}function Ln(e,t,n){const r=e.slice();return r[4]=t[n],r}function Mn(e){let t,n,r,a;return t=new An({props:{group:e[4],env:e[1]}}),r=new On({props:{content:[...e[4].requests,...e[4].children],env:e[1],language:e[2],cookiejars:e[3]}}),{c(){oe(t.$$.fragment),n=b(),oe(r.$$.fragment)},m(e,i){se(t,e,i),d(e,n,i),se(r,e,i),a=!0},p(e,n){const a={};1&n&&(a.group=e[4]),2&n&&(a.env=e[1]),t.$set(a);const i={};1&n&&(i.content=[...e[4].requests,...e[4].children]),2&n&&(i.env=e[1]),4&n&&(i.language=e[2]),8&n&&(i.cookiejars=e[3]),r.$set(i)},i(e){a||(te(t.$$.fragment,e),te(r.$$.fragment,e),a=!0)},o(e){ne(t.$$.fragment,e),ne(r.$$.fragment,e),a=!1},d(e){le(t,e),e&&p(n),le(r,e)}}}function jn(e){let t,n;return t=new $n({props:{request:e[4],env:e[1],language:e[2],cookiejars:e[3]}}),{c(){oe(t.$$.fragment)},m(e,r){se(t,e,r),n=!0},p(e,n){const r={};1&n&&(r.request=e[4]),2&n&&(r.env=e[1]),4&n&&(r.language=e[2]),8&n&&(r.cookiejars=e[3]),t.$set(r)},i(e){n||(te(t.$$.fragment,e),n=!0)},o(e){ne(t.$$.fragment,e),n=!1},d(e){le(t,e)}}}function Tn(e){let t,n,r,a;const i=[jn,Mn],o=[];function s(e,t){return"request"===e[4]._type?0:1}return t=s(e),n=o[t]=i[t](e),{c(){n.c(),r=_()},m(e,n){o[t].m(e,n),d(e,r,n),a=!0},p(e,a){let l=t;t=s(e),t===l?o[t].p(e,a):(Y(),ne(o[l],1,1,()=>{o[l]=null}),ee(),n=o[t],n?n.p(e,a):(n=o[t]=i[t](e),n.c()),te(n,1),n.m(r.parentNode,r))},i(e){a||(te(n),a=!0)},o(e){ne(n),a=!1},d(e){o[t].d(e),e&&p(r)}}}function In(e){let t,n,r=e[0],a=[];for(let t=0;tne(a[e],1,1,()=>{a[e]=null});return{c(){for(let e=0;e{"content"in e&&n(0,r=e.content),"env"in e&&n(1,a=e.env),"language"in e&&n(2,i=e.language),"cookiejars"in e&&n(3,o=e.cookiejars)},[r,a,i,o]}class On extends ue{constructor(e){super(),ce(this,e,Nn,In,o,{content:0,env:1,language:2,cookiejars:3})}}function Pn(t){let n,r,a=t[0](t[1],t[2])+"";return{c(){n=g("div"),v(n,"class",r="item "+t[3]+" svelte-u114qp")},m(e,t){d(e,n,t),n.innerHTML=a},p(e,[t]){7&t&&a!==(a=e[0](e[1],e[2])+"")&&(n.innerHTML=a),8&t&&r!==(r="item "+e[3]+" svelte-u114qp")&&v(n,"class",r)},i:e,o:e,d(e){e&&p(n)}}}function Rn(e,t,n){let{isActive:r=!1}=t,{isFirst:a=!1}=t,{isHover:i=!1}=t,{getOptionLabel:o}=t,{item:s}=t,{filterText:l=""}=t,c="";return e.$$set=e=>{"isActive"in e&&n(4,r=e.isActive),"isFirst"in e&&n(5,a=e.isFirst),"isHover"in e&&n(6,i=e.isHover),"getOptionLabel"in e&&n(0,o=e.getOptionLabel),"item"in e&&n(1,s=e.item),"filterText"in e&&n(2,l=e.filterText)},e.$$.update=()=>{if(114&e.$$.dirty){const e=[];r&&e.push("active"),a&&e.push("first"),i&&e.push("hover"),s.isGroupHeader&&e.push("groupHeader"),s.isGroupItem&&e.push("groupItem"),n(3,c=e.join(" "))}},[o,s,l,c,r,a,i]}class Hn extends ue{constructor(e){super(),ce(this,e,Rn,Pn,o,{isActive:4,isFirst:5,isHover:6,getOptionLabel:0,item:1,filterText:2})}}function zn(e,t,n){const r=e.slice();return r[23]=t[n],r}const Bn=e=>({item:32&e,i:32&e,hoverItemIndex:2&e}),qn=e=>({item:e[23].data,i:e[23].index,hoverItemIndex:e[1]});function Dn(e,t){let n,r,a;const i=t[15].default,o=function(e,t,n,r){if(e){const a=s(e,t,n,r);return e[0](a)}}(i,t,t[14],qn),c=o||function(e){let t;return{c(){t=m("Missing template")},m(e,n){d(e,t,n)},d(e){e&&p(t)}}}();return{key:e,first:null,c(){n=g("svelte-virtual-list-row"),c&&c.c(),r=b(),k(n,"class","svelte-8nn5yg"),this.first=n},m(e,t){d(e,n,t),c&&c.m(n,null),u(n,r),a=!0},p(e,n){t=e,o&&o.p&&(!a||16418&n)&&l(o,i,t,t[14],n,Bn,qn)},i(e){a||(te(c,e),a=!0)},o(e){ne(c,e),a=!1},d(e){e&&p(n),c&&c.d(e)}}}function Un(e){let t,n,r,a,i,o,s=[],l=new Map,c=e[5];const h=e=>e[23].index;for(let t=0;te[18].call(t))},m(l,c){d(l,t,c),u(t,n);for(let e=0;e{e.source===n.contentWindow&&t()})):(n.src="about:blank",n.onload=()=>{a=w(n.contentWindow,"resize",t)}),u(e,n),()=>{(r||a&&n.contentWindow)&&a(),p(n)}}(t,e[18].bind(t)),a=!0,i||(o=w(t,"scroll",e[8]),i=!0)},p(e,[r]){16418&r&&(c=e[5],Y(),s=function(e,t,n,r,a,i,o,s,l,c,u,d){let p=e.length,h=i.length,g=p;const f={};for(;g--;)f[e[g].key]=g;const m=[],b=new Map,_=new Map;for(g=h;g--;){const e=d(a,i,g),s=n(e);let l=o.get(s);l?r&&l.p(e,t):(l=c(s,e),l.c()),b.set(s,m[g]=l),s in f&&_.set(s,Math.abs(g-f[s]))}const w=new Set,v=new Set;function y(e){te(e,1),e.m(s,u),o.set(e.key,e),u=e.first,h--}for(;p&&h;){const t=m[h-1],n=e[p-1],r=t.key,a=n.key;t===n?(u=t.first,p--,h--):b.has(a)?!o.has(r)||w.has(r)?y(t):v.has(a)?p--:_.get(r)>_.get(a)?(v.add(r),y(t)):(w.add(a),p--):(l(n,o),p--)}for(;p--;){const t=e[p];b.has(t.key)||l(t,o)}for(;h;)y(m[h-1]);return m}(s,r,h,1,e,c,l,n,re,Dn,null,zn),ee()),(!a||64&r)&&x(n,"padding-top",e[6]+"px"),(!a||128&r)&&x(n,"padding-bottom",e[7]+"px"),(!a||1&r)&&x(t,"height",e[0])},i(e){if(!a){for(let e=0;e{r=i.getElementsByTagName("svelte-virtual-list-row"),n(13,s=!0)}),e.$$set=e=>{"items"in e&&n(11,d=e.items),"height"in e&&n(0,p=e.height),"itemHeight"in e&&n(12,h=e.itemHeight),"hoverItemIndex"in e&&n(1,g=e.hoverItemIndex),"start"in e&&n(9,f=e.start),"end"in e&&n(10,m=e.end),"$$scope"in e&&n(14,u=e.$$scope)},e.$$.update=()=>{3584&e.$$.dirty&&n(5,o=d.slice(f,m).map((e,t)=>({index:t+f,data:e}))),14340&e.$$.dirty&&s&&async function(e,t,i){const{scrollTop:o}=a;await G();let s=w-o,c=f;for(;se){n(9,f=i),n(6,w=o);break}o+=t,i+=1}for(;ie+_)););n(10,m=i);const s=d.length-m;for(l=o/m;i{i=e,n(4,i)})},function(e){z[e?"unshift":"push"](()=>{a=e,n(3,a)})},function(){_=this.offsetHeight,n(2,_)}]}class Gn extends ue{constructor(e){super(),ce(this,e,Fn,Un,o,{items:11,height:0,itemHeight:12,hoverItemIndex:1,start:9,end:10})}}function Vn(e,t,n){const r=e.slice();return r[34]=t[n],r[36]=n,r}function Wn(e){let t,n,r;return n=new Gn({props:{items:e[4],itemHeight:e[7],$$slots:{default:[Kn,({item:e,i:t})=>({34:e,36:t}),({item:e,i:t})=>[0,(e?8:0)|(t?32:0)]]},$$scope:{ctx:e}}}),{c(){t=g("div"),oe(n.$$.fragment),v(t,"class","listContainer virtualList svelte-1rmpqnb")},m(a,i){d(a,t,i),se(n,t,null),e[20](t),r=!0},p(e,t){const r={};16&t[0]&&(r.items=e[4]),128&t[0]&&(r.itemHeight=e[7]),4918&t[0]|104&t[1]&&(r.$$scope={dirty:t,ctx:e}),n.$set(r)},i(e){r||(te(n.$$.fragment,e),r=!0)},o(e){ne(n.$$.fragment,e),r=!1},d(r){r&&p(t),le(n),e[20](null)}}}function Kn(e){let t,n,r,i,o;var s=e[2];function l(e){return{props:{item:e[34],filterText:e[12],getOptionLabel:e[5],isFirst:rr(e[36]),isActive:nr(e[34],e[8],e[9]),isHover:ar(e[1],e[34],e[36],e[4])}}}function c(){return e[18](e[36])}function u(...t){return e[19](e[34],e[36],...t)}return s&&(n=new s(l(e))),{c(){t=g("div"),n&&oe(n.$$.fragment),v(t,"class","listItem")},m(e,a){d(e,t,a),n&&se(n,t,null),r=!0,i||(o=[w(t,"mouseover",c),w(t,"click",u)],i=!0)},p(r,a){e=r;const i={};if(8&a[1]&&(i.item=e[34]),4096&a[0]&&(i.filterText=e[12]),32&a[0]&&(i.getOptionLabel=e[5]),32&a[1]&&(i.isFirst=rr(e[36])),768&a[0]|8&a[1]&&(i.isActive=nr(e[34],e[8],e[9])),18&a[0]|40&a[1]&&(i.isHover=ar(e[1],e[34],e[36],e[4])),s!==(s=e[2])){if(n){Y();const e=n;ne(e.$$.fragment,1,0,()=>{le(e,1)}),ee()}s?(n=new s(l(e)),oe(n.$$.fragment),te(n.$$.fragment,1),se(n,t,null)):n=null}else s&&n.$set(i)},i(e){r||(n&&te(n.$$.fragment,e),r=!0)},o(e){n&&ne(n.$$.fragment,e),r=!1},d(e){e&&p(t),n&&le(n),i=!1,a(o)}}}function Jn(e){let t,n,r=e[4],a=[];for(let t=0;tne(a[e],1,1,()=>{a[e]=null});let o=null;return r.length||(o=Zn(e)),{c(){t=g("div");for(let e=0;e{le(e,1)}),ee()}l?(n=new l(c(e)),oe(n.$$.fragment),te(n.$$.fragment,1),se(n,t,r)):n=null}else l&&n.$set(o)},i(e){i||(n&&te(n.$$.fragment,e),i=!0)},o(e){n&&ne(n.$$.fragment,e),i=!1},d(e){e&&p(t),n&&le(n),o=!1,a(s)}}}function Yn(t){let n,r,a=t[6](t[34])+"";return{c(){n=g("div"),r=m(a),v(n,"class","listGroupTitle svelte-1rmpqnb")},m(e,t){d(e,n,t),u(n,r)},p(e,t){80&t[0]&&a!==(a=e[6](e[34])+"")&&$(r,a)},i:e,o:e,d(e){e&&p(n)}}}function er(e){let t,n,r,a;const i=[Yn,Xn],o=[];function s(e,t){return e[34].isGroupHeader&&!e[34].isSelectable?0:1}return t=s(e),n=o[t]=i[t](e),{c(){n.c(),r=_()},m(e,n){o[t].m(e,n),d(e,r,n),a=!0},p(e,a){let l=t;t=s(e),t===l?o[t].p(e,a):(Y(),ne(o[l],1,1,()=>{o[l]=null}),ee(),n=o[t],n?n.p(e,a):(n=o[t]=i[t](e),n.c()),te(n,1),n.m(r.parentNode,r))},i(e){a||(te(n),a=!0)},o(e){ne(n),a=!1},d(e){o[t].d(e),e&&p(r)}}}function tr(e){let t,n,r,a,i,o=e[3]&&Wn(e),s=!e[3]&&Jn(e);return{c(){o&&o.c(),t=b(),s&&s.c(),n=_()},m(l,c){o&&o.m(l,c),d(l,t,c),s&&s.m(l,c),d(l,n,c),r=!0,a||(i=w(window,"keydown",e[15]),a=!0)},p(e,r){e[3]?o?(o.p(e,r),8&r[0]&&te(o,1)):(o=Wn(e),o.c(),te(o,1),o.m(t.parentNode,t)):o&&(Y(),ne(o,1,1,()=>{o=null}),ee()),e[3]?s&&(Y(),ne(s,1,1,()=>{s=null}),ee()):s?(s.p(e,r),8&r[0]&&te(s,1)):(s=Jn(e),s.c(),te(s,1),s.m(n.parentNode,n))},i(e){r||(te(o),te(s),r=!0)},o(e){ne(o),ne(s),r=!1},d(e){o&&o.d(e),e&&p(t),s&&s.d(e),e&&p(n),a=!1,i()}}}function nr(e,t,n){return t&&t[n]===e[n]}function rr(e){return 0===e}function ar(e,t,n,r){return e===n||1===r.length}function ir(e,t,n){const r=R();let a,{container:i}=t,{Item:o=Hn}=t,{isVirtualList:s=!1}=t,{items:l=[]}=t,{getOptionLabel:c=((e,t)=>{if(e)return e.isCreator?`Create "${t}"`:e.label})}=t,{getGroupHeaderLabel:u=(e=>e.label)}=t,{itemHeight:d=40}=t,{hoverItemIndex:p=0}=t,{selectedValue:h}=t,{optionIdentifier:g="value"}=t,{hideEmptyState:f=!1}=t,{noOptionsMessage:m="No options"}=t,{isMulti:b=!1}=t,{activeItemIndex:_=0}=t,{filterText:w=""}=t,v=0,y=!1;function k(e){e.isCreator||r("itemSelected",e)}function $(e){y||n(1,p=e)}function E(e){const{item:t,i:a,event:i}=e;if(i.stopPropagation(),h&&!b&&h[g]===t[g])return x();t.isCreator?r("itemCreated",w):(n(16,_=a),n(1,p=a),k(t))}function x(){r("closeList")}async function S(e){if(s)return;let t=!0;for(;t;)e>0&&p===l.length-1?n(1,p=0):n(1,e<0&&0===p?p=l.length-1:p+=e),t=l[p].isGroupHeader&&!l[p].isSelectable;await G(),C("hover")}function C(e){if(s||!i)return;let t;const r=i.querySelector(".listItem ."+e);r&&(t=i.getBoundingClientRect().bottom-r.getBoundingClientRect().bottom),n(0,i.scrollTop-=t,i)}O(()=>{if(l.length>0&&!b&&h){const e=l.findIndex(e=>e[g]===h[g]);e&&n(1,p=e)}C("active"),i.addEventListener("scroll",()=>{clearTimeout(v),v=setTimeout(()=>{y=!1},100)},!1)}),P(()=>{}),N(()=>{l!==a&&l.length>0&&n(1,p=0),a=l});return e.$$set=e=>{"container"in e&&n(0,i=e.container),"Item"in e&&n(2,o=e.Item),"isVirtualList"in e&&n(3,s=e.isVirtualList),"items"in e&&n(4,l=e.items),"getOptionLabel"in e&&n(5,c=e.getOptionLabel),"getGroupHeaderLabel"in e&&n(6,u=e.getGroupHeaderLabel),"itemHeight"in e&&n(7,d=e.itemHeight),"hoverItemIndex"in e&&n(1,p=e.hoverItemIndex),"selectedValue"in e&&n(8,h=e.selectedValue),"optionIdentifier"in e&&n(9,g=e.optionIdentifier),"hideEmptyState"in e&&n(10,f=e.hideEmptyState),"noOptionsMessage"in e&&n(11,m=e.noOptionsMessage),"isMulti"in e&&n(17,b=e.isMulti),"activeItemIndex"in e&&n(16,_=e.activeItemIndex),"filterText"in e&&n(12,w=e.filterText)},[i,p,o,s,l,c,u,d,h,g,f,m,w,$,E,function(e){switch(e.key){case"ArrowDown":e.preventDefault(),l.length&&S(1);break;case"ArrowUp":e.preventDefault(),l.length&&S(-1);break;case"Enter":if(e.preventDefault(),0===l.length)break;const t=l[p];if(h&&!b&&h[g]===t[g]){x();break}t.isCreator?r("itemCreated",w):(n(16,_=p),k(l[p]));break;case"Tab":if(e.preventDefault(),0===l.length)break;if(h&&h[g]===l[p][g])return x();n(16,_=p),k(l[p])}},_,b,e=>$(e),(e,t,n)=>E({item:e,i:t,event:n}),function(e){z[e?"unshift":"push"](()=>{i=e,n(0,i)})},e=>$(e),(e,t,n)=>E({item:e,i:t,event:n}),function(e){z[e?"unshift":"push"](()=>{i=e,n(0,i)})}]}class or extends ue{constructor(e){super(),ce(this,e,ir,tr,o,{container:0,Item:2,isVirtualList:3,items:4,getOptionLabel:5,getGroupHeaderLabel:6,itemHeight:7,hoverItemIndex:1,selectedValue:8,optionIdentifier:9,hideEmptyState:10,noOptionsMessage:11,isMulti:17,activeItemIndex:16,filterText:12},[-1,-1])}}function sr(t){let n,r=t[0](t[1])+"";return{c(){n=g("div"),v(n,"class","selection svelte-17yna57")},m(e,t){d(e,n,t),n.innerHTML=r},p(e,[t]){3&t&&r!==(r=e[0](e[1])+"")&&(n.innerHTML=r)},i:e,o:e,d(e){e&&p(n)}}}function lr(e,t,n){let{getSelectionLabel:r}=t,{item:a}=t;return e.$$set=e=>{"getSelectionLabel"in e&&n(0,r=e.getSelectionLabel),"item"in e&&n(1,a=e.item)},[r,a]}class cr extends ue{constructor(e){super(),ce(this,e,lr,sr,o,{getSelectionLabel:0,item:1})}}function ur(e,t,n){const r=e.slice();return r[9]=t[n],r[11]=n,r}function dr(e){let t,n,r;function a(...t){return e[6](e[11],...t)}return{c(){t=g("div"),t.innerHTML='',v(t,"class","multiSelectItem_clear svelte-1k6n0vy")},m(e,i){d(e,t,i),n||(r=w(t,"click",a),n=!0)},p(t,n){e=t},d(e){e&&p(t),n=!1,r()}}}function pr(e){let t,n,r,a,i,o,s,l=e[4](e[9])+"",c=!e[2]&&!e[3]&&dr(e);function h(...t){return e[7](e[11],...t)}return{c(){t=g("div"),n=g("div"),r=b(),c&&c.c(),a=b(),v(n,"class","multiSelectItem_label svelte-1k6n0vy"),v(t,"class",i="multiSelectItem "+(e[1]===e[11]?"active":"")+" "+(e[2]?"disabled":"")+" svelte-1k6n0vy")},m(e,i){d(e,t,i),u(t,n),n.innerHTML=l,u(t,r),c&&c.m(t,null),u(t,a),o||(s=w(t,"click",h),o=!0)},p(r,o){e=r,17&o&&l!==(l=e[4](e[9])+"")&&(n.innerHTML=l),e[2]||e[3]?c&&(c.d(1),c=null):c?c.p(e,o):(c=dr(e),c.c(),c.m(t,a)),6&o&&i!==(i="multiSelectItem "+(e[1]===e[11]?"active":"")+" "+(e[2]?"disabled":"")+" svelte-1k6n0vy")&&v(t,"class",i)},d(e){e&&p(t),c&&c.d(),o=!1,s()}}}function hr(t){let n,r=t[0],a=[];for(let e=0;e{"selectedValue"in e&&n(0,a=e.selectedValue),"activeSelectedValue"in e&&n(1,i=e.activeSelectedValue),"isDisabled"in e&&n(2,o=e.isDisabled),"multiFullItemClearable"in e&&n(3,s=e.multiFullItemClearable),"getSelectionLabel"in e&&n(4,l=e.getSelectionLabel)},[a,i,o,s,l,c,(e,t)=>c(e,t),(e,t)=>s?c(e,t):{}]}class fr extends ue{constructor(e){super(),ce(this,e,gr,hr,o,{selectedValue:0,activeSelectedValue:1,isDisabled:2,multiFullItemClearable:3,getSelectionLabel:4})}}function mr(t){let n,r;return{c(){n=f("svg"),r=f("path"),v(r,"fill","currentColor"),v(r,"d","M34.923,37.251L24,26.328L13.077,37.251L9.436,33.61l10.923-10.923L9.436,11.765l3.641-3.641L24,19.047L34.923,8.124\n l3.641,3.641L27.641,22.688L38.564,33.61L34.923,37.251z"),v(n,"width","100%"),v(n,"height","100%"),v(n,"viewBox","-2 -2 50 50"),v(n,"focusable","false"),v(n,"role","presentation")},m(e,t){d(e,n,t),u(n,r)},p:e,i:e,o:e,d(e){e&&p(n)}}}class br extends ue{constructor(e){super(),ce(this,e,null,mr,o,{})}}function _r(e){let n,r,a;const i=[e[18]];var o=e[17];function s(e){let n={};for(let e=0;e{le(e,1)}),ee()}o?(n=new o(s()),oe(n.$$.fragment),te(n.$$.fragment,1),se(n,r.parentNode,r)):n=null}else o&&n.$set(a)},i(e){a||(n&&te(n.$$.fragment,e),a=!0)},o(e){n&&ne(n.$$.fragment,e),a=!1},d(e){e&&p(r),n&&le(n,e)}}}function wr(e){let t,n,r;var a=e[7];function i(e){return{props:{selectedValue:e[0],getSelectionLabel:e[13],activeSelectedValue:e[25],isDisabled:e[10],multiFullItemClearable:e[9]}}}return a&&(t=new a(i(e)),t.$on("multiItemClear",e[29]),t.$on("focus",e[32])),{c(){t&&oe(t.$$.fragment),n=_()},m(e,a){t&&se(t,e,a),d(e,n,a),r=!0},p(e,r){const o={};if(1&r[0]&&(o.selectedValue=e[0]),8192&r[0]&&(o.getSelectionLabel=e[13]),33554432&r[0]&&(o.activeSelectedValue=e[25]),1024&r[0]&&(o.isDisabled=e[10]),512&r[0]&&(o.multiFullItemClearable=e[9]),a!==(a=e[7])){if(t){Y();const e=t;ne(e.$$.fragment,1,0,()=>{le(e,1)}),ee()}a?(t=new a(i(e)),t.$on("multiItemClear",e[29]),t.$on("focus",e[32]),oe(t.$$.fragment),te(t.$$.fragment,1),se(t,n.parentNode,n)):t=null}else a&&t.$set(o)},i(e){r||(t&&te(t.$$.fragment,e),r=!0)},o(e){t&&ne(t.$$.fragment,e),r=!1},d(e){e&&p(n),t&&le(t,e)}}}function vr(e){let n,r,i,o=[e[26],{placeholder:e[28]},{style:e[15]}],s={};for(let e=0;e{le(e,1)}),ee()}o?(n=new o(s(e)),oe(n.$$.fragment),te(n.$$.fragment,1),se(n,t,null)):n=null}else o&&n.$set(a)},i(e){r||(n&&te(n.$$.fragment,e),r=!0)},o(e){n&&ne(n.$$.fragment,e),r=!1},d(e){e&&p(t),n&&le(n),a=!1,i()}}}function $r(e){let t,n,r,a,i;var o=e[23];return o&&(n=new o({})),{c(){t=g("div"),n&&oe(n.$$.fragment),v(t,"class","clearSelect svelte-l63srs")},m(o,s){var l;d(o,t,s),n&&se(n,t,null),r=!0,a||(i=w(t,"click",(l=e[24],function(e){return e.preventDefault(),l.call(this,e)})),a=!0)},p(e,r){if(o!==(o=e[23])){if(n){Y();const e=n;ne(e.$$.fragment,1,0,()=>{le(e,1)}),ee()}o?(n=new o({}),oe(n.$$.fragment),te(n.$$.fragment,1),se(n,t,null)):n=null}},i(e){r||(n&&te(n.$$.fragment,e),r=!0)},o(e){n&&ne(n.$$.fragment,e),r=!1},d(e){e&&p(t),n&&le(n),a=!1,i()}}}function Er(e){let t;function n(e,t){return e[22]?Sr:xr}let r=n(e),a=r(e);return{c(){t=g("div"),a.c(),v(t,"class","indicator svelte-l63srs")},m(e,n){d(e,t,n),a.m(t,null)},p(e,i){r===(r=n(e))&&a?a.p(e,i):(a.d(1),a=r(e),a&&(a.c(),a.m(t,null)))},d(e){e&&p(t),a.d()}}}function xr(t){let n,r;return{c(){n=f("svg"),r=f("path"),v(r,"d","M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747\n 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0\n 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502\n 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0\n 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"),v(n,"width","100%"),v(n,"height","100%"),v(n,"viewBox","0 0 20 20"),v(n,"focusable","false"),v(n,"class","svelte-l63srs")},m(e,t){d(e,n,t),u(n,r)},p:e,d(e){e&&p(n)}}}function Sr(e){let t,n;return{c(){n=_(),t=new j(n)},m(r,a){t.m(e[22],r,a),d(r,n,a)},p(e,n){4194304&n[0]&&t.p(e[22])},d(e){e&&p(n),e&&t.d()}}}function Cr(e){let t;return{c(){t=g("div"),t.innerHTML='',v(t,"class","spinner svelte-l63srs")},m(e,n){d(e,t,n)},d(e){e&&p(t)}}}function Ar(e){let t,n,r,i,o,s,l,c,h,f,m,_=e[17]&&_r(e),y=e[8]&&e[0]&&e[0].length>0&&wr(e);function k(e,t){return e[10]?yr:vr}let $=k(e),E=$(e),x=!e[8]&&e[27]&&kr(e),S=e[27]&&e[16]&&!e[10]&&!e[5]&&$r(e),C=(e[20]||e[19]&&!e[0]||!e[14]&&!e[10]&&!e[5]&&(e[27]&&!e[16]||!e[27]))&&Er(e),A=e[5]&&Cr();return{c(){t=g("div"),_&&_.c(),n=b(),y&&y.c(),r=b(),E.c(),i=b(),x&&x.c(),o=b(),S&&S.c(),s=b(),C&&C.c(),l=b(),A&&A.c(),v(t,"class",c="selectContainer "+e[21]+" svelte-l63srs"),v(t,"style",e[12]),M(t,"hasError",e[11]),M(t,"multiSelect",e[8]),M(t,"disabled",e[10]),M(t,"focused",e[4])},m(a,c){d(a,t,c),_&&_.m(t,null),u(t,n),y&&y.m(t,null),u(t,r),E.m(t,null),u(t,i),x&&x.m(t,null),u(t,o),S&&S.m(t,null),u(t,s),C&&C.m(t,null),u(t,l),A&&A.m(t,null),e[65](t),h=!0,f||(m=[w(window,"click",e[33]),w(window,"keydown",e[31]),w(window,"resize",e[30]),w(t,"click",e[34])],f=!0)},p(e,a){e[17]?_?(_.p(e,a),131072&a[0]&&te(_,1)):(_=_r(e),_.c(),te(_,1),_.m(t,n)):_&&(Y(),ne(_,1,1,()=>{_=null}),ee()),e[8]&&e[0]&&e[0].length>0?y?(y.p(e,a),257&a[0]&&te(y,1)):(y=wr(e),y.c(),te(y,1),y.m(t,r)):y&&(Y(),ne(y,1,1,()=>{y=null}),ee()),$===($=k(e))&&E?E.p(e,a):(E.d(1),E=$(e),E&&(E.c(),E.m(t,i))),!e[8]&&e[27]?x?(x.p(e,a),134217984&a[0]&&te(x,1)):(x=kr(e),x.c(),te(x,1),x.m(t,o)):x&&(Y(),ne(x,1,1,()=>{x=null}),ee()),e[27]&&e[16]&&!e[10]&&!e[5]?S?(S.p(e,a),134284320&a[0]&&te(S,1)):(S=$r(e),S.c(),te(S,1),S.m(t,s)):S&&(Y(),ne(S,1,1,()=>{S=null}),ee()),e[20]||e[19]&&!e[0]||!e[14]&&!e[10]&&!e[5]&&(e[27]&&!e[16]||!e[27])?C?C.p(e,a):(C=Er(e),C.c(),C.m(t,l)):C&&(C.d(1),C=null),e[5]?A||(A=Cr(),A.c(),A.m(t,null)):A&&(A.d(1),A=null),(!h||2097152&a[0]&&c!==(c="selectContainer "+e[21]+" svelte-l63srs"))&&v(t,"class",c),(!h||4096&a[0])&&v(t,"style",e[12]),2099200&a[0]&&M(t,"hasError",e[11]),2097408&a[0]&&M(t,"multiSelect",e[8]),2098176&a[0]&&M(t,"disabled",e[10]),2097168&a[0]&&M(t,"focused",e[4])},i(e){h||(te(_),te(y),te(x),te(S),h=!0)},o(e){ne(_),ne(y),ne(x),ne(S),h=!1},d(n){n&&p(t),_&&_.d(),y&&y.d(),E.d(),x&&x.d(),S&&S.d(),C&&C.d(),A&&A.d(),e[65](null),f=!1,a(m)}}}function Lr(e,t,n){let r,a;const i=R();let o,s,l,c,u,d,p,h,{container:g}=t,{input:f}=t,{Item:m=Hn}=t,{Selection:b=cr}=t,{MultiSelection:_=fr}=t,{isMulti:w=!1}=t,{multiFullItemClearable:v=!1}=t,{isDisabled:y=!1}=t,{isCreatable:k=!1}=t,{isFocused:$=!1}=t,{selectedValue:E}=t,{filterText:x=""}=t,{placeholder:S="Select..."}=t,{items:C=[]}=t,{itemFilter:A=((e,t,n)=>e.toLowerCase().includes(t.toLowerCase()))}=t,{groupBy:L}=t,{groupFilter:M=(e=>e)}=t,{isGroupHeaderSelectable:j=!1}=t,{getGroupHeaderLabel:T=(e=>e.label)}=t,{getOptionLabel:I=((e,t)=>e.isCreator?`Create "${t}"`:e.label)}=t,{optionIdentifier:H="value"}=t,{loadOptions:B}=t,{hasError:q=!1}=t,{containerStyles:D=""}=t,{getSelectionLabel:U=(e=>{if(e)return e.label})}=t,{createGroupHeaderItem:F=(e=>({value:e,label:e}))}=t,{createItem:V=(e=>({value:e,label:e}))}=t,{isSearchable:W=!0}=t,{inputStyles:K=""}=t,{isClearable:J=!0}=t,{isWaiting:Z=!1}=t,{listPlacement:Q="auto"}=t,{listOpen:X=!1}=t,{list:Y}=t,{isVirtualList:ee=!1}=t,{loadOptionsInterval:te=300}=t,{noOptionsMessage:ne="No options"}=t,{hideEmptyState:re=!1}=t,{filteredItems:ae=[]}=t,{inputAttributes:ie={}}=t,{listAutoWidth:oe=!0}=t,{itemHeight:se=40}=t,{Icon:le}=t,{iconProps:ce={}}=t,{showChevron:ue=!1}=t,{showIndicator:de=!1}=t,{containerClasses:pe=""}=t,{indicatorSvg:he}=t,{ClearIcon:ge=br}=t;async function fe(){await G(),n(1,x="")}let me=!1;const be=function(e,t,n){let r;return function(){let a=this,i=arguments,o=function(){r=null,n||e.apply(a,i)},s=n&&!r;clearTimeout(r),r=setTimeout(o,t),s&&e.apply(a,i)}}(async()=>{me=!0,n(5,Z=!0);let e=await B(x).catch(e=>{console.warn("svelte-select loadOptions error :>> ",e),i("error",{type:"loadOptions",details:e})});e&&!e.cancelled&&(e?(n(35,C=[...e]),i("loaded",{items:C})):n(35,C=[]),n(5,Z=!1),n(4,$=!0),n(37,X=!0))},te);let _e={};function we(){let e=!0;if(E){const t=[],r=[];E.forEach(n=>{t.includes(n[H])?e=!1:(t.push(n[H]),r.push(n))}),e||n(0,E=r)}return e}function ve(e){let t=e?e[H]:E[H];return C.find(e=>e[H]===t)}async function ye(e){if(await G(),X)return Y?Y.$set({items:e}):void(B&&me&&e.length>0&&Se())}function ke(e){const{detail:t}=e,r=E[t?t.i:E.length-1];1===E.length?n(0,E=void 0):n(0,E=E.filter(e=>e!==r)),i("clear",r),$e()}async function $e(){if(await G(),!o||!g)return;const{top:e,height:t,width:n}=g.getBoundingClientRect();o.style["min-width"]=n+"px",o.style.width=""+(oe?"auto":"100%"),o.style.left="0","top"===Q?o.style.bottom=t+5+"px":o.style.top=t+5+"px",o=o,"auto"===Q&&function(e){const t=e.getBoundingClientRect(),n={};return n.top=t.top<0,n.left=t.left<0,n.bottom=t.bottom>(window.innerHeight||document.documentElement.clientHeight),n.right=t.right>(window.innerWidth||document.documentElement.clientWidth),n.any=n.top||n.left||n.bottom||n.right,n}(o).bottom&&(o.style.top="",o.style.bottom=t+5+"px"),o.style.visibility=""}function Ee(){n(4,$=!0),f&&f.focus()}function xe(){fe(),n(25,s=void 0),Y&&(Y.$destroy(),n(36,Y=void 0),o&&(o.parentNode&&o.parentNode.removeChild(o),o=void 0,n(36,Y),o=o))}async function Se(){if(await G(),o&&Y)return;const e={Item:m,filterText:x,optionIdentifier:H,noOptionsMessage:ne,hideEmptyState:re,isVirtualList:ee,selectedValue:E,isMulti:w,getGroupHeaderLabel:T,items:ae,itemHeight:se};I&&(e.getOptionLabel=I),o=document.createElement("div"),Object.assign(o.style,{position:"absolute","z-index":2,visibility:"hidden"}),n(36,Y),o=o,g&&g.appendChild(o),n(36,Y=new or({target:o,props:e})),Y.$on("itemSelected",e=>{const{detail:t}=e;if(t){const e=Object.assign({},t);e.isGroupHeader&&!e.isSelectable||(n(0,E=w?E?E.concat([e]):[e]:e),fe(),n(0,E),n(48,H),n(8,w),setTimeout(()=>{n(37,X=!1),n(25,s=void 0)}))}}),Y.$on("itemCreated",e=>{const{detail:t}=e;w?(n(0,E=E||[]),n(0,E=[...E,V(t)])):n(0,E=V(t)),i("itemCreated",t),n(1,x=""),n(37,X=!1),n(25,s=void 0),fe()}),Y.$on("closeList",()=>{n(37,X=!1)}),n(36,Y),o=o,$e()}return N(()=>{if(w&&E&&E.length>1&&we(),!w&&E&&c!==E&&(c&&JSON.stringify(E[H])===JSON.stringify(c[H])||i("select",E)),w&&JSON.stringify(E)!==JSON.stringify(c)&&we()&&i("select",E),g&&X!==u&&(X?Se():xe()),x!==d&&(x.length>0?(n(4,$=!0),n(37,X=!0),B?be():(Se(),n(37,X=!0),w&&n(25,s=void 0))):ye([]),Y&&Y.$set({filterText:x})),$!==p&&($||X?Ee():(fe(),f&&f.blur())),h!==ae){let e=[...ae];if(k&&x){const t=V(x);t.isCreator=!0;const n=e.find(e=>e[H]===t[H]);let r;E&&(w?r=E.find(e=>e[H]===t[H]):E[H]===t[H]&&(r=E)),n||r||(e=[...e,t])}ye(e)}c=E,u=X,d=x,p=$,h=ae}),O(()=>{$&&f.focus(),X&&Se(),C&&C.length>0&&n(60,l=JSON.stringify(C))}),P(()=>{xe()}),e.$$set=e=>{"container"in e&&n(2,g=e.container),"input"in e&&n(3,f=e.input),"Item"in e&&n(39,m=e.Item),"Selection"in e&&n(6,b=e.Selection),"MultiSelection"in e&&n(7,_=e.MultiSelection),"isMulti"in e&&n(8,w=e.isMulti),"multiFullItemClearable"in e&&n(9,v=e.multiFullItemClearable),"isDisabled"in e&&n(10,y=e.isDisabled),"isCreatable"in e&&n(40,k=e.isCreatable),"isFocused"in e&&n(4,$=e.isFocused),"selectedValue"in e&&n(0,E=e.selectedValue),"filterText"in e&&n(1,x=e.filterText),"placeholder"in e&&n(41,S=e.placeholder),"items"in e&&n(35,C=e.items),"itemFilter"in e&&n(42,A=e.itemFilter),"groupBy"in e&&n(43,L=e.groupBy),"groupFilter"in e&&n(44,M=e.groupFilter),"isGroupHeaderSelectable"in e&&n(45,j=e.isGroupHeaderSelectable),"getGroupHeaderLabel"in e&&n(46,T=e.getGroupHeaderLabel),"getOptionLabel"in e&&n(47,I=e.getOptionLabel),"optionIdentifier"in e&&n(48,H=e.optionIdentifier),"loadOptions"in e&&n(49,B=e.loadOptions),"hasError"in e&&n(11,q=e.hasError),"containerStyles"in e&&n(12,D=e.containerStyles),"getSelectionLabel"in e&&n(13,U=e.getSelectionLabel),"createGroupHeaderItem"in e&&n(50,F=e.createGroupHeaderItem),"createItem"in e&&n(51,V=e.createItem),"isSearchable"in e&&n(14,W=e.isSearchable),"inputStyles"in e&&n(15,K=e.inputStyles),"isClearable"in e&&n(16,J=e.isClearable),"isWaiting"in e&&n(5,Z=e.isWaiting),"listPlacement"in e&&n(52,Q=e.listPlacement),"listOpen"in e&&n(37,X=e.listOpen),"list"in e&&n(36,Y=e.list),"isVirtualList"in e&&n(53,ee=e.isVirtualList),"loadOptionsInterval"in e&&n(54,te=e.loadOptionsInterval),"noOptionsMessage"in e&&n(55,ne=e.noOptionsMessage),"hideEmptyState"in e&&n(56,re=e.hideEmptyState),"filteredItems"in e&&n(38,ae=e.filteredItems),"inputAttributes"in e&&n(57,ie=e.inputAttributes),"listAutoWidth"in e&&n(58,oe=e.listAutoWidth),"itemHeight"in e&&n(59,se=e.itemHeight),"Icon"in e&&n(17,le=e.Icon),"iconProps"in e&&n(18,ce=e.iconProps),"showChevron"in e&&n(19,ue=e.showChevron),"showIndicator"in e&&n(20,de=e.showIndicator),"containerClasses"in e&&n(21,pe=e.containerClasses),"indicatorSvg"in e&&n(22,he=e.indicatorSvg),"ClearIcon"in e&&n(23,ge=e.ClearIcon)},e.$$.update=()=>{if(e.$$.dirty[0],16&e.$$.dirty[1]&&function(e){e&&0!==e.length&&!e.some(e=>"object"!=typeof e)&&E&&(w?!E.some(e=>!e||!e[H]):E[H])&&(Array.isArray(E)?n(0,E=E.map(e=>ve(e)||e)):n(0,E=ve()||E))}(C),257&e.$$.dirty[0]|131072&e.$$.dirty[1]&&("string"==typeof E?n(0,E={[H]:E,label:E}):w&&Array.isArray(E)&&E.length>0&&n(0,E=E.map(e=>"string"==typeof e?{value:e,label:e}:e))),16777248&e.$$.dirty[1]&&ne&&Y&&Y.$set({noOptionsMessage:ne}),3&e.$$.dirty[0]&&n(27,r=E&&0===x.length),1&e.$$.dirty[0]|1024&e.$$.dirty[1]&&n(28,a=E?"":S),16384&e.$$.dirty[0]|67108864&e.$$.dirty[1]&&(n(26,_e=Object.assign({autocomplete:"off",autocorrect:"off",spellcheck:!1},ie)),W||n(26,_e.readonly=!0,_e)),259&e.$$.dirty[0]|537884688&e.$$.dirty[1]){let e,t=C;if(C&&C.length>0&&"object"!=typeof C[0]&&(t=C.map((e,t)=>({index:t,value:e,label:e}))),B&&0===x.length&&l?(e=JSON.parse(l),t=JSON.parse(l)):e=B?0===x.length?[]:t:t.filter(e=>{let t=!0;return w&&E&&(t=!E.some(t=>t[H]===e[H])),!!t&&(x.length<1||A(I(e,x),x,e))}),L){const t=[],r={};e.forEach(e=>{const n=L(e);t.includes(n)||(t.push(n),r[n]=[],n&&r[n].push(Object.assign(F(n,e),{id:n,isGroupHeader:!0,isSelectable:j}))),r[n].push(Object.assign({isGroupItem:!!n},e))});const a=[];M(t).forEach(e=>{a.push(...r[e])}),n(38,ae=a)}else n(38,ae=e)}},[E,x,g,f,$,Z,b,_,w,v,y,q,D,U,W,K,J,le,ce,ue,de,pe,he,ge,function(){n(0,E=void 0),n(37,X=!1),i("clear",E),Ee()},s,_e,r,a,ke,$e,function(e){if($)switch(e.key){case"ArrowDown":case"ArrowUp":e.preventDefault(),n(37,X=!0),n(25,s=void 0);break;case"Tab":X||n(4,$=!1);break;case"Backspace":if(!w||x.length>0)return;if(w&&E&&E.length>0){if(ke(void 0!==s?s:E.length-1),0===s||void 0===s)break;n(25,s=E.length>s?s-1:void 0)}break;case"ArrowLeft":if(Y&&Y.$set({hoverItemIndex:-1}),!w||x.length>0)return;void 0===s?n(25,s=E.length-1):E.length>s&&0!==s&&n(25,s-=1);break;case"ArrowRight":if(Y&&Y.$set({hoverItemIndex:-1}),!w||x.length>0||void 0===s)return;s===E.length-1?n(25,s=void 0):s0?e.path[0]:e.target;g.contains(t)||(n(4,$=!1),n(37,X=!1),n(25,s=void 0),f&&f.blur())},function(){y||(n(4,$=!0),n(37,X=!X))},C,Y,X,ae,m,k,S,A,L,M,j,T,I,H,B,F,V,Q,ee,te,ne,re,ie,oe,se,l,function(e){z[e?"unshift":"push"](()=>{f=e,n(3,f)})},function(){x=this.value,n(1,x)},function(e){z[e?"unshift":"push"](()=>{f=e,n(3,f)})},function(){x=this.value,n(1,x)},function(e){z[e?"unshift":"push"](()=>{g=e,n(2,g)})}]}class Mr extends ue{constructor(e){super(),ce(this,e,Lr,Ar,o,{container:2,input:3,Item:39,Selection:6,MultiSelection:7,isMulti:8,multiFullItemClearable:9,isDisabled:10,isCreatable:40,isFocused:4,selectedValue:0,filterText:1,placeholder:41,items:35,itemFilter:42,groupBy:43,groupFilter:44,isGroupHeaderSelectable:45,getGroupHeaderLabel:46,getOptionLabel:47,optionIdentifier:48,loadOptions:49,hasError:11,containerStyles:12,getSelectionLabel:13,createGroupHeaderItem:50,createItem:51,isSearchable:14,inputStyles:15,isClearable:16,isWaiting:5,listPlacement:52,listOpen:37,list:36,isVirtualList:53,loadOptionsInterval:54,noOptionsMessage:55,hideEmptyState:56,filteredItems:38,inputAttributes:57,listAutoWidth:58,itemHeight:59,Icon:17,iconProps:18,showChevron:19,showIndicator:20,containerClasses:21,indicatorSvg:22,ClearIcon:23,handleClear:24},[-1,-1,-1])}get handleClear(){return this.$$.ctx[24]}}function jr(e){let t;return{c(){t=g("div"),v(t,"class","description")},m(n,r){d(n,t,r),t.innerHTML=e[5]},p(e,n){32&n&&(t.innerHTML=e[5])},d(e){e&&p(t)}}}function Tr(e){let t,n,r,a,i,o,s,l,c,h,f,_,w,y,k=e[1].name+"",E=e[5]&&jr(e);function x(t){e[10](t)}let S={items:e[7],isClearable:!1,isSearchable:!1};return void 0!==e[3]&&(S.selectedValue=e[3]),h=new Mr({props:S}),z.push(()=>function(e,t,n){const r=e.$$.props[t];void 0!==r&&(e.$$.bound[r]=n,n(e.$$.ctx[r]))}(h,"selectedValue",x)),w=new On({props:{content:e[4],env:e[0],language:e[6],cookiejars:e[2]}}),{c(){t=g("section"),n=g("div"),r=g("div"),a=g("h1"),i=m(k),o=b(),E&&E.c(),s=b(),l=g("div"),c=g("div"),oe(h.$$.fragment),_=b(),oe(w.$$.fragment),v(r,"class","left"),v(c,"class","language-selector svelte-1jbhgwi"),v(l,"class","right"),v(n,"class","row"),v(t,"class","content svelte-1jbhgwi")},m(e,p){d(e,t,p),u(t,n),u(n,r),u(r,a),u(a,i),u(r,o),E&&E.m(r,null),u(n,s),u(n,l),u(l,c),se(h,c,null),u(t,_),se(w,t,null),y=!0},p(e,[t]){(!y||2&t)&&k!==(k=e[1].name+"")&&$(i,k),e[5]?E?E.p(e,t):(E=jr(e),E.c(),E.m(r,null)):E&&(E.d(1),E=null);const n={};var a;!f&&8&t&&(f=!0,n.selectedValue=e[3],a=()=>f=!1,q.push(a)),h.$set(n);const o={};16&t&&(o.content=e[4]),1&t&&(o.env=e[0]),64&t&&(o.language=e[6]),4&t&&(o.cookiejars=e[2]),w.$set(o)},i(e){y||(te(h.$$.fragment,e),te(w.$$.fragment,e),y=!0)},o(e){ne(h.$$.fragment,e),ne(w.$$.fragment,e),y=!1},d(e){e&&p(t),E&&E.d(),le(h),le(w)}}}function Ir(e,t,n){let r,a,i;const o=new qt.Converter({simplifiedAutoLink:!0,openLinksInNewWindow:!0,excludeTrailingPunctuationFromURLs:!0,tables:!0}),s=[{value:"curl",label:"cURL"},{value:"javascript",label:"JavaScript/Deno (fetch)"},{value:"python",label:"Python (requests)"},{value:"node",label:"Node.js (node-fetch)"},{value:"ruby",label:"Ruby"},{value:"php",label:"PHP"},{value:"golang",label:"Go"}];let{env:l}=t,{groups:c}=t,{requests:u}=t,{workspace:d}=t,{cookiejars:p}=t,h=s[0];return e.$$set=e=>{"env"in e&&n(0,l=e.env),"groups"in e&&n(8,c=e.groups),"requests"in e&&n(9,u=e.requests),"workspace"in e&&n(1,d=e.workspace),"cookiejars"in e&&n(2,p=e.cookiejars)},e.$$.update=()=>{768&e.$$.dirty&&n(4,r=[...c,...u]),3&e.$$.dirty&&n(5,a=d.description&&o.makeHtml(En(d.description,l))),8&e.$$.dirty&&n(6,i=h.value)},[l,d,p,h,r,a,i,s,c,u,function(e){h=e,n(3,h)}]}class Nr extends ue{constructor(e){super(),ce(this,e,Ir,Tr,o,{env:0,groups:8,requests:9,workspace:1,cookiejars:2})}}function Or(e,t){let n=e;return"object"==typeof n&&(n=JSON.parse(JSON.stringify(e)),function e(t,n){Object.keys(t).forEach(r=>{if(null!==t[r])switch(typeof t[r]){case"object":e(t[r],n);break;case"string":t[r]=En(t[r],n)}})}(n,t)),n}function Pr(e,t,n){const r=e.slice();return r[13]=t[n],r[15]=n,r}function Rr(e){let t,n,r,a=e[13].name+"";return{c(){t=g("option"),n=m(a),t.__value=r=e[15],t.value=t.__value},m(e,r){d(e,t,r),u(t,n)},p(e,t){1&t&&a!==(a=e[13].name+"")&&$(n,a)},d(e){e&&p(t)}}}function Hr(e){let t,n,r,i,o,s,l,c,f,_,y,k,E,C,A,L,j,T,I,N,O,P,R,H,z,B,q,D,U,F,G,W,K,J,Z=e[0].workspace.name+"";document.title=t=e[0].workspace.name;let Q=e[0].environments,X=[];for(let t=0;t
\", \"gi\")\n * returns: [\"test\"]\n */\nshowdown.helper.matchRecursiveRegExp = function (str, left, right, flags) {\n 'use strict';\n\n var matchPos = rgxFindMatchPos (str, left, right, flags),\n results = [];\n\n for (var i = 0; i < matchPos.length; ++i) {\n results.push([\n str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),\n str.slice(matchPos[i].match.start, matchPos[i].match.end),\n str.slice(matchPos[i].left.start, matchPos[i].left.end),\n str.slice(matchPos[i].right.start, matchPos[i].right.end)\n ]);\n }\n return results;\n};\n\n/**\n *\n * @param {string} str\n * @param {string|function} replacement\n * @param {string} left\n * @param {string} right\n * @param {string} flags\n * @returns {string}\n */\nshowdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) {\n 'use strict';\n\n if (!showdown.helper.isFunction(replacement)) {\n var repStr = replacement;\n replacement = function () {\n return repStr;\n };\n }\n\n var matchPos = rgxFindMatchPos(str, left, right, flags),\n finalStr = str,\n lng = matchPos.length;\n\n if (lng > 0) {\n var bits = [];\n if (matchPos[0].wholeMatch.start !== 0) {\n bits.push(str.slice(0, matchPos[0].wholeMatch.start));\n }\n for (var i = 0; i < lng; ++i) {\n bits.push(\n replacement(\n str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),\n str.slice(matchPos[i].match.start, matchPos[i].match.end),\n str.slice(matchPos[i].left.start, matchPos[i].left.end),\n str.slice(matchPos[i].right.start, matchPos[i].right.end)\n )\n );\n if (i < lng - 1) {\n bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start));\n }\n }\n if (matchPos[lng - 1].wholeMatch.end < str.length) {\n bits.push(str.slice(matchPos[lng - 1].wholeMatch.end));\n }\n finalStr = bits.join('');\n }\n return finalStr;\n};\n\n/**\n * Returns the index within the passed String object of the first occurrence of the specified regex,\n * starting the search at fromIndex. Returns -1 if the value is not found.\n *\n * @param {string} str string to search\n * @param {RegExp} regex Regular expression to search\n * @param {int} [fromIndex = 0] Index to start the search\n * @returns {Number}\n * @throws InvalidArgumentError\n */\nshowdown.helper.regexIndexOf = function (str, regex, fromIndex) {\n 'use strict';\n if (!showdown.helper.isString(str)) {\n throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';\n }\n if (regex instanceof RegExp === false) {\n throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp';\n }\n var indexOf = str.substring(fromIndex || 0).search(regex);\n return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf;\n};\n\n/**\n * Splits the passed string object at the defined index, and returns an array composed of the two substrings\n * @param {string} str string to split\n * @param {int} index index to split string at\n * @returns {[string,string]}\n * @throws InvalidArgumentError\n */\nshowdown.helper.splitAtIndex = function (str, index) {\n 'use strict';\n if (!showdown.helper.isString(str)) {\n throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';\n }\n return [str.substring(0, index), str.substring(index)];\n};\n\n/**\n * Obfuscate an e-mail address through the use of Character Entities,\n * transforming ASCII characters into their equivalent decimal or hex entities.\n *\n * Since it has a random component, subsequent calls to this function produce different results\n *\n * @param {string} mail\n * @returns {string}\n */\nshowdown.helper.encodeEmailAddress = function (mail) {\n 'use strict';\n var encode = [\n function (ch) {\n return '&#' + ch.charCodeAt(0) + ';';\n },\n function (ch) {\n return '&#x' + ch.charCodeAt(0).toString(16) + ';';\n },\n function (ch) {\n return ch;\n }\n ];\n\n mail = mail.replace(/./g, function (ch) {\n if (ch === '@') {\n // this *must* be encoded. I insist.\n ch = encode[Math.floor(Math.random() * 2)](ch);\n } else {\n var r = Math.random();\n // roughly 10% raw, 45% hex, 45% dec\n ch = (\n r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch)\n );\n }\n return ch;\n });\n\n return mail;\n};\n\n/**\n *\n * @param str\n * @param targetLength\n * @param padString\n * @returns {string}\n */\nshowdown.helper.padEnd = function padEnd (str, targetLength, padString) {\n 'use strict';\n /*jshint bitwise: false*/\n // eslint-disable-next-line space-infix-ops\n targetLength = targetLength>>0; //floor if number or convert non-number to 0;\n /*jshint bitwise: true*/\n padString = String(padString || ' ');\n if (str.length > targetLength) {\n return String(str);\n } else {\n targetLength = targetLength - str.length;\n if (targetLength > padString.length) {\n padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed\n }\n return String(str) + padString.slice(0,targetLength);\n }\n};\n\n/**\n * POLYFILLS\n */\n// use this instead of builtin is undefined for IE8 compatibility\nif (typeof console === 'undefined') {\n console = {\n warn: function (msg) {\n 'use strict';\n alert(msg);\n },\n log: function (msg) {\n 'use strict';\n alert(msg);\n },\n error: function (msg) {\n 'use strict';\n throw msg;\n }\n };\n}\n\n/**\n * Common regexes.\n * We declare some common regexes to improve performance\n */\nshowdown.helper.regexes = {\n asteriskDashAndColon: /([*_:~])/g\n};\n\n/**\n * EMOJIS LIST\n */\nshowdown.helper.emojis = {\n '+1':'\\ud83d\\udc4d',\n '-1':'\\ud83d\\udc4e',\n '100':'\\ud83d\\udcaf',\n '1234':'\\ud83d\\udd22',\n '1st_place_medal':'\\ud83e\\udd47',\n '2nd_place_medal':'\\ud83e\\udd48',\n '3rd_place_medal':'\\ud83e\\udd49',\n '8ball':'\\ud83c\\udfb1',\n 'a':'\\ud83c\\udd70\\ufe0f',\n 'ab':'\\ud83c\\udd8e',\n 'abc':'\\ud83d\\udd24',\n 'abcd':'\\ud83d\\udd21',\n 'accept':'\\ud83c\\ude51',\n 'aerial_tramway':'\\ud83d\\udea1',\n 'airplane':'\\u2708\\ufe0f',\n 'alarm_clock':'\\u23f0',\n 'alembic':'\\u2697\\ufe0f',\n 'alien':'\\ud83d\\udc7d',\n 'ambulance':'\\ud83d\\ude91',\n 'amphora':'\\ud83c\\udffa',\n 'anchor':'\\u2693\\ufe0f',\n 'angel':'\\ud83d\\udc7c',\n 'anger':'\\ud83d\\udca2',\n 'angry':'\\ud83d\\ude20',\n 'anguished':'\\ud83d\\ude27',\n 'ant':'\\ud83d\\udc1c',\n 'apple':'\\ud83c\\udf4e',\n 'aquarius':'\\u2652\\ufe0f',\n 'aries':'\\u2648\\ufe0f',\n 'arrow_backward':'\\u25c0\\ufe0f',\n 'arrow_double_down':'\\u23ec',\n 'arrow_double_up':'\\u23eb',\n 'arrow_down':'\\u2b07\\ufe0f',\n 'arrow_down_small':'\\ud83d\\udd3d',\n 'arrow_forward':'\\u25b6\\ufe0f',\n 'arrow_heading_down':'\\u2935\\ufe0f',\n 'arrow_heading_up':'\\u2934\\ufe0f',\n 'arrow_left':'\\u2b05\\ufe0f',\n 'arrow_lower_left':'\\u2199\\ufe0f',\n 'arrow_lower_right':'\\u2198\\ufe0f',\n 'arrow_right':'\\u27a1\\ufe0f',\n 'arrow_right_hook':'\\u21aa\\ufe0f',\n 'arrow_up':'\\u2b06\\ufe0f',\n 'arrow_up_down':'\\u2195\\ufe0f',\n 'arrow_up_small':'\\ud83d\\udd3c',\n 'arrow_upper_left':'\\u2196\\ufe0f',\n 'arrow_upper_right':'\\u2197\\ufe0f',\n 'arrows_clockwise':'\\ud83d\\udd03',\n 'arrows_counterclockwise':'\\ud83d\\udd04',\n 'art':'\\ud83c\\udfa8',\n 'articulated_lorry':'\\ud83d\\ude9b',\n 'artificial_satellite':'\\ud83d\\udef0',\n 'astonished':'\\ud83d\\ude32',\n 'athletic_shoe':'\\ud83d\\udc5f',\n 'atm':'\\ud83c\\udfe7',\n 'atom_symbol':'\\u269b\\ufe0f',\n 'avocado':'\\ud83e\\udd51',\n 'b':'\\ud83c\\udd71\\ufe0f',\n 'baby':'\\ud83d\\udc76',\n 'baby_bottle':'\\ud83c\\udf7c',\n 'baby_chick':'\\ud83d\\udc24',\n 'baby_symbol':'\\ud83d\\udebc',\n 'back':'\\ud83d\\udd19',\n 'bacon':'\\ud83e\\udd53',\n 'badminton':'\\ud83c\\udff8',\n 'baggage_claim':'\\ud83d\\udec4',\n 'baguette_bread':'\\ud83e\\udd56',\n 'balance_scale':'\\u2696\\ufe0f',\n 'balloon':'\\ud83c\\udf88',\n 'ballot_box':'\\ud83d\\uddf3',\n 'ballot_box_with_check':'\\u2611\\ufe0f',\n 'bamboo':'\\ud83c\\udf8d',\n 'banana':'\\ud83c\\udf4c',\n 'bangbang':'\\u203c\\ufe0f',\n 'bank':'\\ud83c\\udfe6',\n 'bar_chart':'\\ud83d\\udcca',\n 'barber':'\\ud83d\\udc88',\n 'baseball':'\\u26be\\ufe0f',\n 'basketball':'\\ud83c\\udfc0',\n 'basketball_man':'\\u26f9\\ufe0f',\n 'basketball_woman':'\\u26f9\\ufe0f‍\\u2640\\ufe0f',\n 'bat':'\\ud83e\\udd87',\n 'bath':'\\ud83d\\udec0',\n 'bathtub':'\\ud83d\\udec1',\n 'battery':'\\ud83d\\udd0b',\n 'beach_umbrella':'\\ud83c\\udfd6',\n 'bear':'\\ud83d\\udc3b',\n 'bed':'\\ud83d\\udecf',\n 'bee':'\\ud83d\\udc1d',\n 'beer':'\\ud83c\\udf7a',\n 'beers':'\\ud83c\\udf7b',\n 'beetle':'\\ud83d\\udc1e',\n 'beginner':'\\ud83d\\udd30',\n 'bell':'\\ud83d\\udd14',\n 'bellhop_bell':'\\ud83d\\udece',\n 'bento':'\\ud83c\\udf71',\n 'biking_man':'\\ud83d\\udeb4',\n 'bike':'\\ud83d\\udeb2',\n 'biking_woman':'\\ud83d\\udeb4‍\\u2640\\ufe0f',\n 'bikini':'\\ud83d\\udc59',\n 'biohazard':'\\u2623\\ufe0f',\n 'bird':'\\ud83d\\udc26',\n 'birthday':'\\ud83c\\udf82',\n 'black_circle':'\\u26ab\\ufe0f',\n 'black_flag':'\\ud83c\\udff4',\n 'black_heart':'\\ud83d\\udda4',\n 'black_joker':'\\ud83c\\udccf',\n 'black_large_square':'\\u2b1b\\ufe0f',\n 'black_medium_small_square':'\\u25fe\\ufe0f',\n 'black_medium_square':'\\u25fc\\ufe0f',\n 'black_nib':'\\u2712\\ufe0f',\n 'black_small_square':'\\u25aa\\ufe0f',\n 'black_square_button':'\\ud83d\\udd32',\n 'blonde_man':'\\ud83d\\udc71',\n 'blonde_woman':'\\ud83d\\udc71‍\\u2640\\ufe0f',\n 'blossom':'\\ud83c\\udf3c',\n 'blowfish':'\\ud83d\\udc21',\n 'blue_book':'\\ud83d\\udcd8',\n 'blue_car':'\\ud83d\\ude99',\n 'blue_heart':'\\ud83d\\udc99',\n 'blush':'\\ud83d\\ude0a',\n 'boar':'\\ud83d\\udc17',\n 'boat':'\\u26f5\\ufe0f',\n 'bomb':'\\ud83d\\udca3',\n 'book':'\\ud83d\\udcd6',\n 'bookmark':'\\ud83d\\udd16',\n 'bookmark_tabs':'\\ud83d\\udcd1',\n 'books':'\\ud83d\\udcda',\n 'boom':'\\ud83d\\udca5',\n 'boot':'\\ud83d\\udc62',\n 'bouquet':'\\ud83d\\udc90',\n 'bowing_man':'\\ud83d\\ude47',\n 'bow_and_arrow':'\\ud83c\\udff9',\n 'bowing_woman':'\\ud83d\\ude47‍\\u2640\\ufe0f',\n 'bowling':'\\ud83c\\udfb3',\n 'boxing_glove':'\\ud83e\\udd4a',\n 'boy':'\\ud83d\\udc66',\n 'bread':'\\ud83c\\udf5e',\n 'bride_with_veil':'\\ud83d\\udc70',\n 'bridge_at_night':'\\ud83c\\udf09',\n 'briefcase':'\\ud83d\\udcbc',\n 'broken_heart':'\\ud83d\\udc94',\n 'bug':'\\ud83d\\udc1b',\n 'building_construction':'\\ud83c\\udfd7',\n 'bulb':'\\ud83d\\udca1',\n 'bullettrain_front':'\\ud83d\\ude85',\n 'bullettrain_side':'\\ud83d\\ude84',\n 'burrito':'\\ud83c\\udf2f',\n 'bus':'\\ud83d\\ude8c',\n 'business_suit_levitating':'\\ud83d\\udd74',\n 'busstop':'\\ud83d\\ude8f',\n 'bust_in_silhouette':'\\ud83d\\udc64',\n 'busts_in_silhouette':'\\ud83d\\udc65',\n 'butterfly':'\\ud83e\\udd8b',\n 'cactus':'\\ud83c\\udf35',\n 'cake':'\\ud83c\\udf70',\n 'calendar':'\\ud83d\\udcc6',\n 'call_me_hand':'\\ud83e\\udd19',\n 'calling':'\\ud83d\\udcf2',\n 'camel':'\\ud83d\\udc2b',\n 'camera':'\\ud83d\\udcf7',\n 'camera_flash':'\\ud83d\\udcf8',\n 'camping':'\\ud83c\\udfd5',\n 'cancer':'\\u264b\\ufe0f',\n 'candle':'\\ud83d\\udd6f',\n 'candy':'\\ud83c\\udf6c',\n 'canoe':'\\ud83d\\udef6',\n 'capital_abcd':'\\ud83d\\udd20',\n 'capricorn':'\\u2651\\ufe0f',\n 'car':'\\ud83d\\ude97',\n 'card_file_box':'\\ud83d\\uddc3',\n 'card_index':'\\ud83d\\udcc7',\n 'card_index_dividers':'\\ud83d\\uddc2',\n 'carousel_horse':'\\ud83c\\udfa0',\n 'carrot':'\\ud83e\\udd55',\n 'cat':'\\ud83d\\udc31',\n 'cat2':'\\ud83d\\udc08',\n 'cd':'\\ud83d\\udcbf',\n 'chains':'\\u26d3',\n 'champagne':'\\ud83c\\udf7e',\n 'chart':'\\ud83d\\udcb9',\n 'chart_with_downwards_trend':'\\ud83d\\udcc9',\n 'chart_with_upwards_trend':'\\ud83d\\udcc8',\n 'checkered_flag':'\\ud83c\\udfc1',\n 'cheese':'\\ud83e\\uddc0',\n 'cherries':'\\ud83c\\udf52',\n 'cherry_blossom':'\\ud83c\\udf38',\n 'chestnut':'\\ud83c\\udf30',\n 'chicken':'\\ud83d\\udc14',\n 'children_crossing':'\\ud83d\\udeb8',\n 'chipmunk':'\\ud83d\\udc3f',\n 'chocolate_bar':'\\ud83c\\udf6b',\n 'christmas_tree':'\\ud83c\\udf84',\n 'church':'\\u26ea\\ufe0f',\n 'cinema':'\\ud83c\\udfa6',\n 'circus_tent':'\\ud83c\\udfaa',\n 'city_sunrise':'\\ud83c\\udf07',\n 'city_sunset':'\\ud83c\\udf06',\n 'cityscape':'\\ud83c\\udfd9',\n 'cl':'\\ud83c\\udd91',\n 'clamp':'\\ud83d\\udddc',\n 'clap':'\\ud83d\\udc4f',\n 'clapper':'\\ud83c\\udfac',\n 'classical_building':'\\ud83c\\udfdb',\n 'clinking_glasses':'\\ud83e\\udd42',\n 'clipboard':'\\ud83d\\udccb',\n 'clock1':'\\ud83d\\udd50',\n 'clock10':'\\ud83d\\udd59',\n 'clock1030':'\\ud83d\\udd65',\n 'clock11':'\\ud83d\\udd5a',\n 'clock1130':'\\ud83d\\udd66',\n 'clock12':'\\ud83d\\udd5b',\n 'clock1230':'\\ud83d\\udd67',\n 'clock130':'\\ud83d\\udd5c',\n 'clock2':'\\ud83d\\udd51',\n 'clock230':'\\ud83d\\udd5d',\n 'clock3':'\\ud83d\\udd52',\n 'clock330':'\\ud83d\\udd5e',\n 'clock4':'\\ud83d\\udd53',\n 'clock430':'\\ud83d\\udd5f',\n 'clock5':'\\ud83d\\udd54',\n 'clock530':'\\ud83d\\udd60',\n 'clock6':'\\ud83d\\udd55',\n 'clock630':'\\ud83d\\udd61',\n 'clock7':'\\ud83d\\udd56',\n 'clock730':'\\ud83d\\udd62',\n 'clock8':'\\ud83d\\udd57',\n 'clock830':'\\ud83d\\udd63',\n 'clock9':'\\ud83d\\udd58',\n 'clock930':'\\ud83d\\udd64',\n 'closed_book':'\\ud83d\\udcd5',\n 'closed_lock_with_key':'\\ud83d\\udd10',\n 'closed_umbrella':'\\ud83c\\udf02',\n 'cloud':'\\u2601\\ufe0f',\n 'cloud_with_lightning':'\\ud83c\\udf29',\n 'cloud_with_lightning_and_rain':'\\u26c8',\n 'cloud_with_rain':'\\ud83c\\udf27',\n 'cloud_with_snow':'\\ud83c\\udf28',\n 'clown_face':'\\ud83e\\udd21',\n 'clubs':'\\u2663\\ufe0f',\n 'cocktail':'\\ud83c\\udf78',\n 'coffee':'\\u2615\\ufe0f',\n 'coffin':'\\u26b0\\ufe0f',\n 'cold_sweat':'\\ud83d\\ude30',\n 'comet':'\\u2604\\ufe0f',\n 'computer':'\\ud83d\\udcbb',\n 'computer_mouse':'\\ud83d\\uddb1',\n 'confetti_ball':'\\ud83c\\udf8a',\n 'confounded':'\\ud83d\\ude16',\n 'confused':'\\ud83d\\ude15',\n 'congratulations':'\\u3297\\ufe0f',\n 'construction':'\\ud83d\\udea7',\n 'construction_worker_man':'\\ud83d\\udc77',\n 'construction_worker_woman':'\\ud83d\\udc77‍\\u2640\\ufe0f',\n 'control_knobs':'\\ud83c\\udf9b',\n 'convenience_store':'\\ud83c\\udfea',\n 'cookie':'\\ud83c\\udf6a',\n 'cool':'\\ud83c\\udd92',\n 'policeman':'\\ud83d\\udc6e',\n 'copyright':'\\u00a9\\ufe0f',\n 'corn':'\\ud83c\\udf3d',\n 'couch_and_lamp':'\\ud83d\\udecb',\n 'couple':'\\ud83d\\udc6b',\n 'couple_with_heart_woman_man':'\\ud83d\\udc91',\n 'couple_with_heart_man_man':'\\ud83d\\udc68‍\\u2764\\ufe0f‍\\ud83d\\udc68',\n 'couple_with_heart_woman_woman':'\\ud83d\\udc69‍\\u2764\\ufe0f‍\\ud83d\\udc69',\n 'couplekiss_man_man':'\\ud83d\\udc68‍\\u2764\\ufe0f‍\\ud83d\\udc8b‍\\ud83d\\udc68',\n 'couplekiss_man_woman':'\\ud83d\\udc8f',\n 'couplekiss_woman_woman':'\\ud83d\\udc69‍\\u2764\\ufe0f‍\\ud83d\\udc8b‍\\ud83d\\udc69',\n 'cow':'\\ud83d\\udc2e',\n 'cow2':'\\ud83d\\udc04',\n 'cowboy_hat_face':'\\ud83e\\udd20',\n 'crab':'\\ud83e\\udd80',\n 'crayon':'\\ud83d\\udd8d',\n 'credit_card':'\\ud83d\\udcb3',\n 'crescent_moon':'\\ud83c\\udf19',\n 'cricket':'\\ud83c\\udfcf',\n 'crocodile':'\\ud83d\\udc0a',\n 'croissant':'\\ud83e\\udd50',\n 'crossed_fingers':'\\ud83e\\udd1e',\n 'crossed_flags':'\\ud83c\\udf8c',\n 'crossed_swords':'\\u2694\\ufe0f',\n 'crown':'\\ud83d\\udc51',\n 'cry':'\\ud83d\\ude22',\n 'crying_cat_face':'\\ud83d\\ude3f',\n 'crystal_ball':'\\ud83d\\udd2e',\n 'cucumber':'\\ud83e\\udd52',\n 'cupid':'\\ud83d\\udc98',\n 'curly_loop':'\\u27b0',\n 'currency_exchange':'\\ud83d\\udcb1',\n 'curry':'\\ud83c\\udf5b',\n 'custard':'\\ud83c\\udf6e',\n 'customs':'\\ud83d\\udec3',\n 'cyclone':'\\ud83c\\udf00',\n 'dagger':'\\ud83d\\udde1',\n 'dancer':'\\ud83d\\udc83',\n 'dancing_women':'\\ud83d\\udc6f',\n 'dancing_men':'\\ud83d\\udc6f‍\\u2642\\ufe0f',\n 'dango':'\\ud83c\\udf61',\n 'dark_sunglasses':'\\ud83d\\udd76',\n 'dart':'\\ud83c\\udfaf',\n 'dash':'\\ud83d\\udca8',\n 'date':'\\ud83d\\udcc5',\n 'deciduous_tree':'\\ud83c\\udf33',\n 'deer':'\\ud83e\\udd8c',\n 'department_store':'\\ud83c\\udfec',\n 'derelict_house':'\\ud83c\\udfda',\n 'desert':'\\ud83c\\udfdc',\n 'desert_island':'\\ud83c\\udfdd',\n 'desktop_computer':'\\ud83d\\udda5',\n 'male_detective':'\\ud83d\\udd75\\ufe0f',\n 'diamond_shape_with_a_dot_inside':'\\ud83d\\udca0',\n 'diamonds':'\\u2666\\ufe0f',\n 'disappointed':'\\ud83d\\ude1e',\n 'disappointed_relieved':'\\ud83d\\ude25',\n 'dizzy':'\\ud83d\\udcab',\n 'dizzy_face':'\\ud83d\\ude35',\n 'do_not_litter':'\\ud83d\\udeaf',\n 'dog':'\\ud83d\\udc36',\n 'dog2':'\\ud83d\\udc15',\n 'dollar':'\\ud83d\\udcb5',\n 'dolls':'\\ud83c\\udf8e',\n 'dolphin':'\\ud83d\\udc2c',\n 'door':'\\ud83d\\udeaa',\n 'doughnut':'\\ud83c\\udf69',\n 'dove':'\\ud83d\\udd4a',\n 'dragon':'\\ud83d\\udc09',\n 'dragon_face':'\\ud83d\\udc32',\n 'dress':'\\ud83d\\udc57',\n 'dromedary_camel':'\\ud83d\\udc2a',\n 'drooling_face':'\\ud83e\\udd24',\n 'droplet':'\\ud83d\\udca7',\n 'drum':'\\ud83e\\udd41',\n 'duck':'\\ud83e\\udd86',\n 'dvd':'\\ud83d\\udcc0',\n 'e-mail':'\\ud83d\\udce7',\n 'eagle':'\\ud83e\\udd85',\n 'ear':'\\ud83d\\udc42',\n 'ear_of_rice':'\\ud83c\\udf3e',\n 'earth_africa':'\\ud83c\\udf0d',\n 'earth_americas':'\\ud83c\\udf0e',\n 'earth_asia':'\\ud83c\\udf0f',\n 'egg':'\\ud83e\\udd5a',\n 'eggplant':'\\ud83c\\udf46',\n 'eight_pointed_black_star':'\\u2734\\ufe0f',\n 'eight_spoked_asterisk':'\\u2733\\ufe0f',\n 'electric_plug':'\\ud83d\\udd0c',\n 'elephant':'\\ud83d\\udc18',\n 'email':'\\u2709\\ufe0f',\n 'end':'\\ud83d\\udd1a',\n 'envelope_with_arrow':'\\ud83d\\udce9',\n 'euro':'\\ud83d\\udcb6',\n 'european_castle':'\\ud83c\\udff0',\n 'european_post_office':'\\ud83c\\udfe4',\n 'evergreen_tree':'\\ud83c\\udf32',\n 'exclamation':'\\u2757\\ufe0f',\n 'expressionless':'\\ud83d\\ude11',\n 'eye':'\\ud83d\\udc41',\n 'eye_speech_bubble':'\\ud83d\\udc41‍\\ud83d\\udde8',\n 'eyeglasses':'\\ud83d\\udc53',\n 'eyes':'\\ud83d\\udc40',\n 'face_with_head_bandage':'\\ud83e\\udd15',\n 'face_with_thermometer':'\\ud83e\\udd12',\n 'fist_oncoming':'\\ud83d\\udc4a',\n 'factory':'\\ud83c\\udfed',\n 'fallen_leaf':'\\ud83c\\udf42',\n 'family_man_woman_boy':'\\ud83d\\udc6a',\n 'family_man_boy':'\\ud83d\\udc68‍\\ud83d\\udc66',\n 'family_man_boy_boy':'\\ud83d\\udc68‍\\ud83d\\udc66‍\\ud83d\\udc66',\n 'family_man_girl':'\\ud83d\\udc68‍\\ud83d\\udc67',\n 'family_man_girl_boy':'\\ud83d\\udc68‍\\ud83d\\udc67‍\\ud83d\\udc66',\n 'family_man_girl_girl':'\\ud83d\\udc68‍\\ud83d\\udc67‍\\ud83d\\udc67',\n 'family_man_man_boy':'\\ud83d\\udc68‍\\ud83d\\udc68‍\\ud83d\\udc66',\n 'family_man_man_boy_boy':'\\ud83d\\udc68‍\\ud83d\\udc68‍\\ud83d\\udc66‍\\ud83d\\udc66',\n 'family_man_man_girl':'\\ud83d\\udc68‍\\ud83d\\udc68‍\\ud83d\\udc67',\n 'family_man_man_girl_boy':'\\ud83d\\udc68‍\\ud83d\\udc68‍\\ud83d\\udc67‍\\ud83d\\udc66',\n 'family_man_man_girl_girl':'\\ud83d\\udc68‍\\ud83d\\udc68‍\\ud83d\\udc67‍\\ud83d\\udc67',\n 'family_man_woman_boy_boy':'\\ud83d\\udc68‍\\ud83d\\udc69‍\\ud83d\\udc66‍\\ud83d\\udc66',\n 'family_man_woman_girl':'\\ud83d\\udc68‍\\ud83d\\udc69‍\\ud83d\\udc67',\n 'family_man_woman_girl_boy':'\\ud83d\\udc68‍\\ud83d\\udc69‍\\ud83d\\udc67‍\\ud83d\\udc66',\n 'family_man_woman_girl_girl':'\\ud83d\\udc68‍\\ud83d\\udc69‍\\ud83d\\udc67‍\\ud83d\\udc67',\n 'family_woman_boy':'\\ud83d\\udc69‍\\ud83d\\udc66',\n 'family_woman_boy_boy':'\\ud83d\\udc69‍\\ud83d\\udc66‍\\ud83d\\udc66',\n 'family_woman_girl':'\\ud83d\\udc69‍\\ud83d\\udc67',\n 'family_woman_girl_boy':'\\ud83d\\udc69‍\\ud83d\\udc67‍\\ud83d\\udc66',\n 'family_woman_girl_girl':'\\ud83d\\udc69‍\\ud83d\\udc67‍\\ud83d\\udc67',\n 'family_woman_woman_boy':'\\ud83d\\udc69‍\\ud83d\\udc69‍\\ud83d\\udc66',\n 'family_woman_woman_boy_boy':'\\ud83d\\udc69‍\\ud83d\\udc69‍\\ud83d\\udc66‍\\ud83d\\udc66',\n 'family_woman_woman_girl':'\\ud83d\\udc69‍\\ud83d\\udc69‍\\ud83d\\udc67',\n 'family_woman_woman_girl_boy':'\\ud83d\\udc69‍\\ud83d\\udc69‍\\ud83d\\udc67‍\\ud83d\\udc66',\n 'family_woman_woman_girl_girl':'\\ud83d\\udc69‍\\ud83d\\udc69‍\\ud83d\\udc67‍\\ud83d\\udc67',\n 'fast_forward':'\\u23e9',\n 'fax':'\\ud83d\\udce0',\n 'fearful':'\\ud83d\\ude28',\n 'feet':'\\ud83d\\udc3e',\n 'female_detective':'\\ud83d\\udd75\\ufe0f‍\\u2640\\ufe0f',\n 'ferris_wheel':'\\ud83c\\udfa1',\n 'ferry':'\\u26f4',\n 'field_hockey':'\\ud83c\\udfd1',\n 'file_cabinet':'\\ud83d\\uddc4',\n 'file_folder':'\\ud83d\\udcc1',\n 'film_projector':'\\ud83d\\udcfd',\n 'film_strip':'\\ud83c\\udf9e',\n 'fire':'\\ud83d\\udd25',\n 'fire_engine':'\\ud83d\\ude92',\n 'fireworks':'\\ud83c\\udf86',\n 'first_quarter_moon':'\\ud83c\\udf13',\n 'first_quarter_moon_with_face':'\\ud83c\\udf1b',\n 'fish':'\\ud83d\\udc1f',\n 'fish_cake':'\\ud83c\\udf65',\n 'fishing_pole_and_fish':'\\ud83c\\udfa3',\n 'fist_raised':'\\u270a',\n 'fist_left':'\\ud83e\\udd1b',\n 'fist_right':'\\ud83e\\udd1c',\n 'flags':'\\ud83c\\udf8f',\n 'flashlight':'\\ud83d\\udd26',\n 'fleur_de_lis':'\\u269c\\ufe0f',\n 'flight_arrival':'\\ud83d\\udeec',\n 'flight_departure':'\\ud83d\\udeeb',\n 'floppy_disk':'\\ud83d\\udcbe',\n 'flower_playing_cards':'\\ud83c\\udfb4',\n 'flushed':'\\ud83d\\ude33',\n 'fog':'\\ud83c\\udf2b',\n 'foggy':'\\ud83c\\udf01',\n 'football':'\\ud83c\\udfc8',\n 'footprints':'\\ud83d\\udc63',\n 'fork_and_knife':'\\ud83c\\udf74',\n 'fountain':'\\u26f2\\ufe0f',\n 'fountain_pen':'\\ud83d\\udd8b',\n 'four_leaf_clover':'\\ud83c\\udf40',\n 'fox_face':'\\ud83e\\udd8a',\n 'framed_picture':'\\ud83d\\uddbc',\n 'free':'\\ud83c\\udd93',\n 'fried_egg':'\\ud83c\\udf73',\n 'fried_shrimp':'\\ud83c\\udf64',\n 'fries':'\\ud83c\\udf5f',\n 'frog':'\\ud83d\\udc38',\n 'frowning':'\\ud83d\\ude26',\n 'frowning_face':'\\u2639\\ufe0f',\n 'frowning_man':'\\ud83d\\ude4d‍\\u2642\\ufe0f',\n 'frowning_woman':'\\ud83d\\ude4d',\n 'middle_finger':'\\ud83d\\udd95',\n 'fuelpump':'\\u26fd\\ufe0f',\n 'full_moon':'\\ud83c\\udf15',\n 'full_moon_with_face':'\\ud83c\\udf1d',\n 'funeral_urn':'\\u26b1\\ufe0f',\n 'game_die':'\\ud83c\\udfb2',\n 'gear':'\\u2699\\ufe0f',\n 'gem':'\\ud83d\\udc8e',\n 'gemini':'\\u264a\\ufe0f',\n 'ghost':'\\ud83d\\udc7b',\n 'gift':'\\ud83c\\udf81',\n 'gift_heart':'\\ud83d\\udc9d',\n 'girl':'\\ud83d\\udc67',\n 'globe_with_meridians':'\\ud83c\\udf10',\n 'goal_net':'\\ud83e\\udd45',\n 'goat':'\\ud83d\\udc10',\n 'golf':'\\u26f3\\ufe0f',\n 'golfing_man':'\\ud83c\\udfcc\\ufe0f',\n 'golfing_woman':'\\ud83c\\udfcc\\ufe0f‍\\u2640\\ufe0f',\n 'gorilla':'\\ud83e\\udd8d',\n 'grapes':'\\ud83c\\udf47',\n 'green_apple':'\\ud83c\\udf4f',\n 'green_book':'\\ud83d\\udcd7',\n 'green_heart':'\\ud83d\\udc9a',\n 'green_salad':'\\ud83e\\udd57',\n 'grey_exclamation':'\\u2755',\n 'grey_question':'\\u2754',\n 'grimacing':'\\ud83d\\ude2c',\n 'grin':'\\ud83d\\ude01',\n 'grinning':'\\ud83d\\ude00',\n 'guardsman':'\\ud83d\\udc82',\n 'guardswoman':'\\ud83d\\udc82‍\\u2640\\ufe0f',\n 'guitar':'\\ud83c\\udfb8',\n 'gun':'\\ud83d\\udd2b',\n 'haircut_woman':'\\ud83d\\udc87',\n 'haircut_man':'\\ud83d\\udc87‍\\u2642\\ufe0f',\n 'hamburger':'\\ud83c\\udf54',\n 'hammer':'\\ud83d\\udd28',\n 'hammer_and_pick':'\\u2692',\n 'hammer_and_wrench':'\\ud83d\\udee0',\n 'hamster':'\\ud83d\\udc39',\n 'hand':'\\u270b',\n 'handbag':'\\ud83d\\udc5c',\n 'handshake':'\\ud83e\\udd1d',\n 'hankey':'\\ud83d\\udca9',\n 'hatched_chick':'\\ud83d\\udc25',\n 'hatching_chick':'\\ud83d\\udc23',\n 'headphones':'\\ud83c\\udfa7',\n 'hear_no_evil':'\\ud83d\\ude49',\n 'heart':'\\u2764\\ufe0f',\n 'heart_decoration':'\\ud83d\\udc9f',\n 'heart_eyes':'\\ud83d\\ude0d',\n 'heart_eyes_cat':'\\ud83d\\ude3b',\n 'heartbeat':'\\ud83d\\udc93',\n 'heartpulse':'\\ud83d\\udc97',\n 'hearts':'\\u2665\\ufe0f',\n 'heavy_check_mark':'\\u2714\\ufe0f',\n 'heavy_division_sign':'\\u2797',\n 'heavy_dollar_sign':'\\ud83d\\udcb2',\n 'heavy_heart_exclamation':'\\u2763\\ufe0f',\n 'heavy_minus_sign':'\\u2796',\n 'heavy_multiplication_x':'\\u2716\\ufe0f',\n 'heavy_plus_sign':'\\u2795',\n 'helicopter':'\\ud83d\\ude81',\n 'herb':'\\ud83c\\udf3f',\n 'hibiscus':'\\ud83c\\udf3a',\n 'high_brightness':'\\ud83d\\udd06',\n 'high_heel':'\\ud83d\\udc60',\n 'hocho':'\\ud83d\\udd2a',\n 'hole':'\\ud83d\\udd73',\n 'honey_pot':'\\ud83c\\udf6f',\n 'horse':'\\ud83d\\udc34',\n 'horse_racing':'\\ud83c\\udfc7',\n 'hospital':'\\ud83c\\udfe5',\n 'hot_pepper':'\\ud83c\\udf36',\n 'hotdog':'\\ud83c\\udf2d',\n 'hotel':'\\ud83c\\udfe8',\n 'hotsprings':'\\u2668\\ufe0f',\n 'hourglass':'\\u231b\\ufe0f',\n 'hourglass_flowing_sand':'\\u23f3',\n 'house':'\\ud83c\\udfe0',\n 'house_with_garden':'\\ud83c\\udfe1',\n 'houses':'\\ud83c\\udfd8',\n 'hugs':'\\ud83e\\udd17',\n 'hushed':'\\ud83d\\ude2f',\n 'ice_cream':'\\ud83c\\udf68',\n 'ice_hockey':'\\ud83c\\udfd2',\n 'ice_skate':'\\u26f8',\n 'icecream':'\\ud83c\\udf66',\n 'id':'\\ud83c\\udd94',\n 'ideograph_advantage':'\\ud83c\\ude50',\n 'imp':'\\ud83d\\udc7f',\n 'inbox_tray':'\\ud83d\\udce5',\n 'incoming_envelope':'\\ud83d\\udce8',\n 'tipping_hand_woman':'\\ud83d\\udc81',\n 'information_source':'\\u2139\\ufe0f',\n 'innocent':'\\ud83d\\ude07',\n 'interrobang':'\\u2049\\ufe0f',\n 'iphone':'\\ud83d\\udcf1',\n 'izakaya_lantern':'\\ud83c\\udfee',\n 'jack_o_lantern':'\\ud83c\\udf83',\n 'japan':'\\ud83d\\uddfe',\n 'japanese_castle':'\\ud83c\\udfef',\n 'japanese_goblin':'\\ud83d\\udc7a',\n 'japanese_ogre':'\\ud83d\\udc79',\n 'jeans':'\\ud83d\\udc56',\n 'joy':'\\ud83d\\ude02',\n 'joy_cat':'\\ud83d\\ude39',\n 'joystick':'\\ud83d\\udd79',\n 'kaaba':'\\ud83d\\udd4b',\n 'key':'\\ud83d\\udd11',\n 'keyboard':'\\u2328\\ufe0f',\n 'keycap_ten':'\\ud83d\\udd1f',\n 'kick_scooter':'\\ud83d\\udef4',\n 'kimono':'\\ud83d\\udc58',\n 'kiss':'\\ud83d\\udc8b',\n 'kissing':'\\ud83d\\ude17',\n 'kissing_cat':'\\ud83d\\ude3d',\n 'kissing_closed_eyes':'\\ud83d\\ude1a',\n 'kissing_heart':'\\ud83d\\ude18',\n 'kissing_smiling_eyes':'\\ud83d\\ude19',\n 'kiwi_fruit':'\\ud83e\\udd5d',\n 'koala':'\\ud83d\\udc28',\n 'koko':'\\ud83c\\ude01',\n 'label':'\\ud83c\\udff7',\n 'large_blue_circle':'\\ud83d\\udd35',\n 'large_blue_diamond':'\\ud83d\\udd37',\n 'large_orange_diamond':'\\ud83d\\udd36',\n 'last_quarter_moon':'\\ud83c\\udf17',\n 'last_quarter_moon_with_face':'\\ud83c\\udf1c',\n 'latin_cross':'\\u271d\\ufe0f',\n 'laughing':'\\ud83d\\ude06',\n 'leaves':'\\ud83c\\udf43',\n 'ledger':'\\ud83d\\udcd2',\n 'left_luggage':'\\ud83d\\udec5',\n 'left_right_arrow':'\\u2194\\ufe0f',\n 'leftwards_arrow_with_hook':'\\u21a9\\ufe0f',\n 'lemon':'\\ud83c\\udf4b',\n 'leo':'\\u264c\\ufe0f',\n 'leopard':'\\ud83d\\udc06',\n 'level_slider':'\\ud83c\\udf9a',\n 'libra':'\\u264e\\ufe0f',\n 'light_rail':'\\ud83d\\ude88',\n 'link':'\\ud83d\\udd17',\n 'lion':'\\ud83e\\udd81',\n 'lips':'\\ud83d\\udc44',\n 'lipstick':'\\ud83d\\udc84',\n 'lizard':'\\ud83e\\udd8e',\n 'lock':'\\ud83d\\udd12',\n 'lock_with_ink_pen':'\\ud83d\\udd0f',\n 'lollipop':'\\ud83c\\udf6d',\n 'loop':'\\u27bf',\n 'loud_sound':'\\ud83d\\udd0a',\n 'loudspeaker':'\\ud83d\\udce2',\n 'love_hotel':'\\ud83c\\udfe9',\n 'love_letter':'\\ud83d\\udc8c',\n 'low_brightness':'\\ud83d\\udd05',\n 'lying_face':'\\ud83e\\udd25',\n 'm':'\\u24c2\\ufe0f',\n 'mag':'\\ud83d\\udd0d',\n 'mag_right':'\\ud83d\\udd0e',\n 'mahjong':'\\ud83c\\udc04\\ufe0f',\n 'mailbox':'\\ud83d\\udceb',\n 'mailbox_closed':'\\ud83d\\udcea',\n 'mailbox_with_mail':'\\ud83d\\udcec',\n 'mailbox_with_no_mail':'\\ud83d\\udced',\n 'man':'\\ud83d\\udc68',\n 'man_artist':'\\ud83d\\udc68‍\\ud83c\\udfa8',\n 'man_astronaut':'\\ud83d\\udc68‍\\ud83d\\ude80',\n 'man_cartwheeling':'\\ud83e\\udd38‍\\u2642\\ufe0f',\n 'man_cook':'\\ud83d\\udc68‍\\ud83c\\udf73',\n 'man_dancing':'\\ud83d\\udd7a',\n 'man_facepalming':'\\ud83e\\udd26‍\\u2642\\ufe0f',\n 'man_factory_worker':'\\ud83d\\udc68‍\\ud83c\\udfed',\n 'man_farmer':'\\ud83d\\udc68‍\\ud83c\\udf3e',\n 'man_firefighter':'\\ud83d\\udc68‍\\ud83d\\ude92',\n 'man_health_worker':'\\ud83d\\udc68‍\\u2695\\ufe0f',\n 'man_in_tuxedo':'\\ud83e\\udd35',\n 'man_judge':'\\ud83d\\udc68‍\\u2696\\ufe0f',\n 'man_juggling':'\\ud83e\\udd39‍\\u2642\\ufe0f',\n 'man_mechanic':'\\ud83d\\udc68‍\\ud83d\\udd27',\n 'man_office_worker':'\\ud83d\\udc68‍\\ud83d\\udcbc',\n 'man_pilot':'\\ud83d\\udc68‍\\u2708\\ufe0f',\n 'man_playing_handball':'\\ud83e\\udd3e‍\\u2642\\ufe0f',\n 'man_playing_water_polo':'\\ud83e\\udd3d‍\\u2642\\ufe0f',\n 'man_scientist':'\\ud83d\\udc68‍\\ud83d\\udd2c',\n 'man_shrugging':'\\ud83e\\udd37‍\\u2642\\ufe0f',\n 'man_singer':'\\ud83d\\udc68‍\\ud83c\\udfa4',\n 'man_student':'\\ud83d\\udc68‍\\ud83c\\udf93',\n 'man_teacher':'\\ud83d\\udc68‍\\ud83c\\udfeb',\n 'man_technologist':'\\ud83d\\udc68‍\\ud83d\\udcbb',\n 'man_with_gua_pi_mao':'\\ud83d\\udc72',\n 'man_with_turban':'\\ud83d\\udc73',\n 'tangerine':'\\ud83c\\udf4a',\n 'mans_shoe':'\\ud83d\\udc5e',\n 'mantelpiece_clock':'\\ud83d\\udd70',\n 'maple_leaf':'\\ud83c\\udf41',\n 'martial_arts_uniform':'\\ud83e\\udd4b',\n 'mask':'\\ud83d\\ude37',\n 'massage_woman':'\\ud83d\\udc86',\n 'massage_man':'\\ud83d\\udc86‍\\u2642\\ufe0f',\n 'meat_on_bone':'\\ud83c\\udf56',\n 'medal_military':'\\ud83c\\udf96',\n 'medal_sports':'\\ud83c\\udfc5',\n 'mega':'\\ud83d\\udce3',\n 'melon':'\\ud83c\\udf48',\n 'memo':'\\ud83d\\udcdd',\n 'men_wrestling':'\\ud83e\\udd3c‍\\u2642\\ufe0f',\n 'menorah':'\\ud83d\\udd4e',\n 'mens':'\\ud83d\\udeb9',\n 'metal':'\\ud83e\\udd18',\n 'metro':'\\ud83d\\ude87',\n 'microphone':'\\ud83c\\udfa4',\n 'microscope':'\\ud83d\\udd2c',\n 'milk_glass':'\\ud83e\\udd5b',\n 'milky_way':'\\ud83c\\udf0c',\n 'minibus':'\\ud83d\\ude90',\n 'minidisc':'\\ud83d\\udcbd',\n 'mobile_phone_off':'\\ud83d\\udcf4',\n 'money_mouth_face':'\\ud83e\\udd11',\n 'money_with_wings':'\\ud83d\\udcb8',\n 'moneybag':'\\ud83d\\udcb0',\n 'monkey':'\\ud83d\\udc12',\n 'monkey_face':'\\ud83d\\udc35',\n 'monorail':'\\ud83d\\ude9d',\n 'moon':'\\ud83c\\udf14',\n 'mortar_board':'\\ud83c\\udf93',\n 'mosque':'\\ud83d\\udd4c',\n 'motor_boat':'\\ud83d\\udee5',\n 'motor_scooter':'\\ud83d\\udef5',\n 'motorcycle':'\\ud83c\\udfcd',\n 'motorway':'\\ud83d\\udee3',\n 'mount_fuji':'\\ud83d\\uddfb',\n 'mountain':'\\u26f0',\n 'mountain_biking_man':'\\ud83d\\udeb5',\n 'mountain_biking_woman':'\\ud83d\\udeb5‍\\u2640\\ufe0f',\n 'mountain_cableway':'\\ud83d\\udea0',\n 'mountain_railway':'\\ud83d\\ude9e',\n 'mountain_snow':'\\ud83c\\udfd4',\n 'mouse':'\\ud83d\\udc2d',\n 'mouse2':'\\ud83d\\udc01',\n 'movie_camera':'\\ud83c\\udfa5',\n 'moyai':'\\ud83d\\uddff',\n 'mrs_claus':'\\ud83e\\udd36',\n 'muscle':'\\ud83d\\udcaa',\n 'mushroom':'\\ud83c\\udf44',\n 'musical_keyboard':'\\ud83c\\udfb9',\n 'musical_note':'\\ud83c\\udfb5',\n 'musical_score':'\\ud83c\\udfbc',\n 'mute':'\\ud83d\\udd07',\n 'nail_care':'\\ud83d\\udc85',\n 'name_badge':'\\ud83d\\udcdb',\n 'national_park':'\\ud83c\\udfde',\n 'nauseated_face':'\\ud83e\\udd22',\n 'necktie':'\\ud83d\\udc54',\n 'negative_squared_cross_mark':'\\u274e',\n 'nerd_face':'\\ud83e\\udd13',\n 'neutral_face':'\\ud83d\\ude10',\n 'new':'\\ud83c\\udd95',\n 'new_moon':'\\ud83c\\udf11',\n 'new_moon_with_face':'\\ud83c\\udf1a',\n 'newspaper':'\\ud83d\\udcf0',\n 'newspaper_roll':'\\ud83d\\uddde',\n 'next_track_button':'\\u23ed',\n 'ng':'\\ud83c\\udd96',\n 'no_good_man':'\\ud83d\\ude45‍\\u2642\\ufe0f',\n 'no_good_woman':'\\ud83d\\ude45',\n 'night_with_stars':'\\ud83c\\udf03',\n 'no_bell':'\\ud83d\\udd15',\n 'no_bicycles':'\\ud83d\\udeb3',\n 'no_entry':'\\u26d4\\ufe0f',\n 'no_entry_sign':'\\ud83d\\udeab',\n 'no_mobile_phones':'\\ud83d\\udcf5',\n 'no_mouth':'\\ud83d\\ude36',\n 'no_pedestrians':'\\ud83d\\udeb7',\n 'no_smoking':'\\ud83d\\udead',\n 'non-potable_water':'\\ud83d\\udeb1',\n 'nose':'\\ud83d\\udc43',\n 'notebook':'\\ud83d\\udcd3',\n 'notebook_with_decorative_cover':'\\ud83d\\udcd4',\n 'notes':'\\ud83c\\udfb6',\n 'nut_and_bolt':'\\ud83d\\udd29',\n 'o':'\\u2b55\\ufe0f',\n 'o2':'\\ud83c\\udd7e\\ufe0f',\n 'ocean':'\\ud83c\\udf0a',\n 'octopus':'\\ud83d\\udc19',\n 'oden':'\\ud83c\\udf62',\n 'office':'\\ud83c\\udfe2',\n 'oil_drum':'\\ud83d\\udee2',\n 'ok':'\\ud83c\\udd97',\n 'ok_hand':'\\ud83d\\udc4c',\n 'ok_man':'\\ud83d\\ude46‍\\u2642\\ufe0f',\n 'ok_woman':'\\ud83d\\ude46',\n 'old_key':'\\ud83d\\udddd',\n 'older_man':'\\ud83d\\udc74',\n 'older_woman':'\\ud83d\\udc75',\n 'om':'\\ud83d\\udd49',\n 'on':'\\ud83d\\udd1b',\n 'oncoming_automobile':'\\ud83d\\ude98',\n 'oncoming_bus':'\\ud83d\\ude8d',\n 'oncoming_police_car':'\\ud83d\\ude94',\n 'oncoming_taxi':'\\ud83d\\ude96',\n 'open_file_folder':'\\ud83d\\udcc2',\n 'open_hands':'\\ud83d\\udc50',\n 'open_mouth':'\\ud83d\\ude2e',\n 'open_umbrella':'\\u2602\\ufe0f',\n 'ophiuchus':'\\u26ce',\n 'orange_book':'\\ud83d\\udcd9',\n 'orthodox_cross':'\\u2626\\ufe0f',\n 'outbox_tray':'\\ud83d\\udce4',\n 'owl':'\\ud83e\\udd89',\n 'ox':'\\ud83d\\udc02',\n 'package':'\\ud83d\\udce6',\n 'page_facing_up':'\\ud83d\\udcc4',\n 'page_with_curl':'\\ud83d\\udcc3',\n 'pager':'\\ud83d\\udcdf',\n 'paintbrush':'\\ud83d\\udd8c',\n 'palm_tree':'\\ud83c\\udf34',\n 'pancakes':'\\ud83e\\udd5e',\n 'panda_face':'\\ud83d\\udc3c',\n 'paperclip':'\\ud83d\\udcce',\n 'paperclips':'\\ud83d\\udd87',\n 'parasol_on_ground':'\\u26f1',\n 'parking':'\\ud83c\\udd7f\\ufe0f',\n 'part_alternation_mark':'\\u303d\\ufe0f',\n 'partly_sunny':'\\u26c5\\ufe0f',\n 'passenger_ship':'\\ud83d\\udef3',\n 'passport_control':'\\ud83d\\udec2',\n 'pause_button':'\\u23f8',\n 'peace_symbol':'\\u262e\\ufe0f',\n 'peach':'\\ud83c\\udf51',\n 'peanuts':'\\ud83e\\udd5c',\n 'pear':'\\ud83c\\udf50',\n 'pen':'\\ud83d\\udd8a',\n 'pencil2':'\\u270f\\ufe0f',\n 'penguin':'\\ud83d\\udc27',\n 'pensive':'\\ud83d\\ude14',\n 'performing_arts':'\\ud83c\\udfad',\n 'persevere':'\\ud83d\\ude23',\n 'person_fencing':'\\ud83e\\udd3a',\n 'pouting_woman':'\\ud83d\\ude4e',\n 'phone':'\\u260e\\ufe0f',\n 'pick':'\\u26cf',\n 'pig':'\\ud83d\\udc37',\n 'pig2':'\\ud83d\\udc16',\n 'pig_nose':'\\ud83d\\udc3d',\n 'pill':'\\ud83d\\udc8a',\n 'pineapple':'\\ud83c\\udf4d',\n 'ping_pong':'\\ud83c\\udfd3',\n 'pisces':'\\u2653\\ufe0f',\n 'pizza':'\\ud83c\\udf55',\n 'place_of_worship':'\\ud83d\\uded0',\n 'plate_with_cutlery':'\\ud83c\\udf7d',\n 'play_or_pause_button':'\\u23ef',\n 'point_down':'\\ud83d\\udc47',\n 'point_left':'\\ud83d\\udc48',\n 'point_right':'\\ud83d\\udc49',\n 'point_up':'\\u261d\\ufe0f',\n 'point_up_2':'\\ud83d\\udc46',\n 'police_car':'\\ud83d\\ude93',\n 'policewoman':'\\ud83d\\udc6e‍\\u2640\\ufe0f',\n 'poodle':'\\ud83d\\udc29',\n 'popcorn':'\\ud83c\\udf7f',\n 'post_office':'\\ud83c\\udfe3',\n 'postal_horn':'\\ud83d\\udcef',\n 'postbox':'\\ud83d\\udcee',\n 'potable_water':'\\ud83d\\udeb0',\n 'potato':'\\ud83e\\udd54',\n 'pouch':'\\ud83d\\udc5d',\n 'poultry_leg':'\\ud83c\\udf57',\n 'pound':'\\ud83d\\udcb7',\n 'rage':'\\ud83d\\ude21',\n 'pouting_cat':'\\ud83d\\ude3e',\n 'pouting_man':'\\ud83d\\ude4e‍\\u2642\\ufe0f',\n 'pray':'\\ud83d\\ude4f',\n 'prayer_beads':'\\ud83d\\udcff',\n 'pregnant_woman':'\\ud83e\\udd30',\n 'previous_track_button':'\\u23ee',\n 'prince':'\\ud83e\\udd34',\n 'princess':'\\ud83d\\udc78',\n 'printer':'\\ud83d\\udda8',\n 'purple_heart':'\\ud83d\\udc9c',\n 'purse':'\\ud83d\\udc5b',\n 'pushpin':'\\ud83d\\udccc',\n 'put_litter_in_its_place':'\\ud83d\\udeae',\n 'question':'\\u2753',\n 'rabbit':'\\ud83d\\udc30',\n 'rabbit2':'\\ud83d\\udc07',\n 'racehorse':'\\ud83d\\udc0e',\n 'racing_car':'\\ud83c\\udfce',\n 'radio':'\\ud83d\\udcfb',\n 'radio_button':'\\ud83d\\udd18',\n 'radioactive':'\\u2622\\ufe0f',\n 'railway_car':'\\ud83d\\ude83',\n 'railway_track':'\\ud83d\\udee4',\n 'rainbow':'\\ud83c\\udf08',\n 'rainbow_flag':'\\ud83c\\udff3\\ufe0f‍\\ud83c\\udf08',\n 'raised_back_of_hand':'\\ud83e\\udd1a',\n 'raised_hand_with_fingers_splayed':'\\ud83d\\udd90',\n 'raised_hands':'\\ud83d\\ude4c',\n 'raising_hand_woman':'\\ud83d\\ude4b',\n 'raising_hand_man':'\\ud83d\\ude4b‍\\u2642\\ufe0f',\n 'ram':'\\ud83d\\udc0f',\n 'ramen':'\\ud83c\\udf5c',\n 'rat':'\\ud83d\\udc00',\n 'record_button':'\\u23fa',\n 'recycle':'\\u267b\\ufe0f',\n 'red_circle':'\\ud83d\\udd34',\n 'registered':'\\u00ae\\ufe0f',\n 'relaxed':'\\u263a\\ufe0f',\n 'relieved':'\\ud83d\\ude0c',\n 'reminder_ribbon':'\\ud83c\\udf97',\n 'repeat':'\\ud83d\\udd01',\n 'repeat_one':'\\ud83d\\udd02',\n 'rescue_worker_helmet':'\\u26d1',\n 'restroom':'\\ud83d\\udebb',\n 'revolving_hearts':'\\ud83d\\udc9e',\n 'rewind':'\\u23ea',\n 'rhinoceros':'\\ud83e\\udd8f',\n 'ribbon':'\\ud83c\\udf80',\n 'rice':'\\ud83c\\udf5a',\n 'rice_ball':'\\ud83c\\udf59',\n 'rice_cracker':'\\ud83c\\udf58',\n 'rice_scene':'\\ud83c\\udf91',\n 'right_anger_bubble':'\\ud83d\\uddef',\n 'ring':'\\ud83d\\udc8d',\n 'robot':'\\ud83e\\udd16',\n 'rocket':'\\ud83d\\ude80',\n 'rofl':'\\ud83e\\udd23',\n 'roll_eyes':'\\ud83d\\ude44',\n 'roller_coaster':'\\ud83c\\udfa2',\n 'rooster':'\\ud83d\\udc13',\n 'rose':'\\ud83c\\udf39',\n 'rosette':'\\ud83c\\udff5',\n 'rotating_light':'\\ud83d\\udea8',\n 'round_pushpin':'\\ud83d\\udccd',\n 'rowing_man':'\\ud83d\\udea3',\n 'rowing_woman':'\\ud83d\\udea3‍\\u2640\\ufe0f',\n 'rugby_football':'\\ud83c\\udfc9',\n 'running_man':'\\ud83c\\udfc3',\n 'running_shirt_with_sash':'\\ud83c\\udfbd',\n 'running_woman':'\\ud83c\\udfc3‍\\u2640\\ufe0f',\n 'sa':'\\ud83c\\ude02\\ufe0f',\n 'sagittarius':'\\u2650\\ufe0f',\n 'sake':'\\ud83c\\udf76',\n 'sandal':'\\ud83d\\udc61',\n 'santa':'\\ud83c\\udf85',\n 'satellite':'\\ud83d\\udce1',\n 'saxophone':'\\ud83c\\udfb7',\n 'school':'\\ud83c\\udfeb',\n 'school_satchel':'\\ud83c\\udf92',\n 'scissors':'\\u2702\\ufe0f',\n 'scorpion':'\\ud83e\\udd82',\n 'scorpius':'\\u264f\\ufe0f',\n 'scream':'\\ud83d\\ude31',\n 'scream_cat':'\\ud83d\\ude40',\n 'scroll':'\\ud83d\\udcdc',\n 'seat':'\\ud83d\\udcba',\n 'secret':'\\u3299\\ufe0f',\n 'see_no_evil':'\\ud83d\\ude48',\n 'seedling':'\\ud83c\\udf31',\n 'selfie':'\\ud83e\\udd33',\n 'shallow_pan_of_food':'\\ud83e\\udd58',\n 'shamrock':'\\u2618\\ufe0f',\n 'shark':'\\ud83e\\udd88',\n 'shaved_ice':'\\ud83c\\udf67',\n 'sheep':'\\ud83d\\udc11',\n 'shell':'\\ud83d\\udc1a',\n 'shield':'\\ud83d\\udee1',\n 'shinto_shrine':'\\u26e9',\n 'ship':'\\ud83d\\udea2',\n 'shirt':'\\ud83d\\udc55',\n 'shopping':'\\ud83d\\udecd',\n 'shopping_cart':'\\ud83d\\uded2',\n 'shower':'\\ud83d\\udebf',\n 'shrimp':'\\ud83e\\udd90',\n 'signal_strength':'\\ud83d\\udcf6',\n 'six_pointed_star':'\\ud83d\\udd2f',\n 'ski':'\\ud83c\\udfbf',\n 'skier':'\\u26f7',\n 'skull':'\\ud83d\\udc80',\n 'skull_and_crossbones':'\\u2620\\ufe0f',\n 'sleeping':'\\ud83d\\ude34',\n 'sleeping_bed':'\\ud83d\\udecc',\n 'sleepy':'\\ud83d\\ude2a',\n 'slightly_frowning_face':'\\ud83d\\ude41',\n 'slightly_smiling_face':'\\ud83d\\ude42',\n 'slot_machine':'\\ud83c\\udfb0',\n 'small_airplane':'\\ud83d\\udee9',\n 'small_blue_diamond':'\\ud83d\\udd39',\n 'small_orange_diamond':'\\ud83d\\udd38',\n 'small_red_triangle':'\\ud83d\\udd3a',\n 'small_red_triangle_down':'\\ud83d\\udd3b',\n 'smile':'\\ud83d\\ude04',\n 'smile_cat':'\\ud83d\\ude38',\n 'smiley':'\\ud83d\\ude03',\n 'smiley_cat':'\\ud83d\\ude3a',\n 'smiling_imp':'\\ud83d\\ude08',\n 'smirk':'\\ud83d\\ude0f',\n 'smirk_cat':'\\ud83d\\ude3c',\n 'smoking':'\\ud83d\\udeac',\n 'snail':'\\ud83d\\udc0c',\n 'snake':'\\ud83d\\udc0d',\n 'sneezing_face':'\\ud83e\\udd27',\n 'snowboarder':'\\ud83c\\udfc2',\n 'snowflake':'\\u2744\\ufe0f',\n 'snowman':'\\u26c4\\ufe0f',\n 'snowman_with_snow':'\\u2603\\ufe0f',\n 'sob':'\\ud83d\\ude2d',\n 'soccer':'\\u26bd\\ufe0f',\n 'soon':'\\ud83d\\udd1c',\n 'sos':'\\ud83c\\udd98',\n 'sound':'\\ud83d\\udd09',\n 'space_invader':'\\ud83d\\udc7e',\n 'spades':'\\u2660\\ufe0f',\n 'spaghetti':'\\ud83c\\udf5d',\n 'sparkle':'\\u2747\\ufe0f',\n 'sparkler':'\\ud83c\\udf87',\n 'sparkles':'\\u2728',\n 'sparkling_heart':'\\ud83d\\udc96',\n 'speak_no_evil':'\\ud83d\\ude4a',\n 'speaker':'\\ud83d\\udd08',\n 'speaking_head':'\\ud83d\\udde3',\n 'speech_balloon':'\\ud83d\\udcac',\n 'speedboat':'\\ud83d\\udea4',\n 'spider':'\\ud83d\\udd77',\n 'spider_web':'\\ud83d\\udd78',\n 'spiral_calendar':'\\ud83d\\uddd3',\n 'spiral_notepad':'\\ud83d\\uddd2',\n 'spoon':'\\ud83e\\udd44',\n 'squid':'\\ud83e\\udd91',\n 'stadium':'\\ud83c\\udfdf',\n 'star':'\\u2b50\\ufe0f',\n 'star2':'\\ud83c\\udf1f',\n 'star_and_crescent':'\\u262a\\ufe0f',\n 'star_of_david':'\\u2721\\ufe0f',\n 'stars':'\\ud83c\\udf20',\n 'station':'\\ud83d\\ude89',\n 'statue_of_liberty':'\\ud83d\\uddfd',\n 'steam_locomotive':'\\ud83d\\ude82',\n 'stew':'\\ud83c\\udf72',\n 'stop_button':'\\u23f9',\n 'stop_sign':'\\ud83d\\uded1',\n 'stopwatch':'\\u23f1',\n 'straight_ruler':'\\ud83d\\udccf',\n 'strawberry':'\\ud83c\\udf53',\n 'stuck_out_tongue':'\\ud83d\\ude1b',\n 'stuck_out_tongue_closed_eyes':'\\ud83d\\ude1d',\n 'stuck_out_tongue_winking_eye':'\\ud83d\\ude1c',\n 'studio_microphone':'\\ud83c\\udf99',\n 'stuffed_flatbread':'\\ud83e\\udd59',\n 'sun_behind_large_cloud':'\\ud83c\\udf25',\n 'sun_behind_rain_cloud':'\\ud83c\\udf26',\n 'sun_behind_small_cloud':'\\ud83c\\udf24',\n 'sun_with_face':'\\ud83c\\udf1e',\n 'sunflower':'\\ud83c\\udf3b',\n 'sunglasses':'\\ud83d\\ude0e',\n 'sunny':'\\u2600\\ufe0f',\n 'sunrise':'\\ud83c\\udf05',\n 'sunrise_over_mountains':'\\ud83c\\udf04',\n 'surfing_man':'\\ud83c\\udfc4',\n 'surfing_woman':'\\ud83c\\udfc4‍\\u2640\\ufe0f',\n 'sushi':'\\ud83c\\udf63',\n 'suspension_railway':'\\ud83d\\ude9f',\n 'sweat':'\\ud83d\\ude13',\n 'sweat_drops':'\\ud83d\\udca6',\n 'sweat_smile':'\\ud83d\\ude05',\n 'sweet_potato':'\\ud83c\\udf60',\n 'swimming_man':'\\ud83c\\udfca',\n 'swimming_woman':'\\ud83c\\udfca‍\\u2640\\ufe0f',\n 'symbols':'\\ud83d\\udd23',\n 'synagogue':'\\ud83d\\udd4d',\n 'syringe':'\\ud83d\\udc89',\n 'taco':'\\ud83c\\udf2e',\n 'tada':'\\ud83c\\udf89',\n 'tanabata_tree':'\\ud83c\\udf8b',\n 'taurus':'\\u2649\\ufe0f',\n 'taxi':'\\ud83d\\ude95',\n 'tea':'\\ud83c\\udf75',\n 'telephone_receiver':'\\ud83d\\udcde',\n 'telescope':'\\ud83d\\udd2d',\n 'tennis':'\\ud83c\\udfbe',\n 'tent':'\\u26fa\\ufe0f',\n 'thermometer':'\\ud83c\\udf21',\n 'thinking':'\\ud83e\\udd14',\n 'thought_balloon':'\\ud83d\\udcad',\n 'ticket':'\\ud83c\\udfab',\n 'tickets':'\\ud83c\\udf9f',\n 'tiger':'\\ud83d\\udc2f',\n 'tiger2':'\\ud83d\\udc05',\n 'timer_clock':'\\u23f2',\n 'tipping_hand_man':'\\ud83d\\udc81‍\\u2642\\ufe0f',\n 'tired_face':'\\ud83d\\ude2b',\n 'tm':'\\u2122\\ufe0f',\n 'toilet':'\\ud83d\\udebd',\n 'tokyo_tower':'\\ud83d\\uddfc',\n 'tomato':'\\ud83c\\udf45',\n 'tongue':'\\ud83d\\udc45',\n 'top':'\\ud83d\\udd1d',\n 'tophat':'\\ud83c\\udfa9',\n 'tornado':'\\ud83c\\udf2a',\n 'trackball':'\\ud83d\\uddb2',\n 'tractor':'\\ud83d\\ude9c',\n 'traffic_light':'\\ud83d\\udea5',\n 'train':'\\ud83d\\ude8b',\n 'train2':'\\ud83d\\ude86',\n 'tram':'\\ud83d\\ude8a',\n 'triangular_flag_on_post':'\\ud83d\\udea9',\n 'triangular_ruler':'\\ud83d\\udcd0',\n 'trident':'\\ud83d\\udd31',\n 'triumph':'\\ud83d\\ude24',\n 'trolleybus':'\\ud83d\\ude8e',\n 'trophy':'\\ud83c\\udfc6',\n 'tropical_drink':'\\ud83c\\udf79',\n 'tropical_fish':'\\ud83d\\udc20',\n 'truck':'\\ud83d\\ude9a',\n 'trumpet':'\\ud83c\\udfba',\n 'tulip':'\\ud83c\\udf37',\n 'tumbler_glass':'\\ud83e\\udd43',\n 'turkey':'\\ud83e\\udd83',\n 'turtle':'\\ud83d\\udc22',\n 'tv':'\\ud83d\\udcfa',\n 'twisted_rightwards_arrows':'\\ud83d\\udd00',\n 'two_hearts':'\\ud83d\\udc95',\n 'two_men_holding_hands':'\\ud83d\\udc6c',\n 'two_women_holding_hands':'\\ud83d\\udc6d',\n 'u5272':'\\ud83c\\ude39',\n 'u5408':'\\ud83c\\ude34',\n 'u55b6':'\\ud83c\\ude3a',\n 'u6307':'\\ud83c\\ude2f\\ufe0f',\n 'u6708':'\\ud83c\\ude37\\ufe0f',\n 'u6709':'\\ud83c\\ude36',\n 'u6e80':'\\ud83c\\ude35',\n 'u7121':'\\ud83c\\ude1a\\ufe0f',\n 'u7533':'\\ud83c\\ude38',\n 'u7981':'\\ud83c\\ude32',\n 'u7a7a':'\\ud83c\\ude33',\n 'umbrella':'\\u2614\\ufe0f',\n 'unamused':'\\ud83d\\ude12',\n 'underage':'\\ud83d\\udd1e',\n 'unicorn':'\\ud83e\\udd84',\n 'unlock':'\\ud83d\\udd13',\n 'up':'\\ud83c\\udd99',\n 'upside_down_face':'\\ud83d\\ude43',\n 'v':'\\u270c\\ufe0f',\n 'vertical_traffic_light':'\\ud83d\\udea6',\n 'vhs':'\\ud83d\\udcfc',\n 'vibration_mode':'\\ud83d\\udcf3',\n 'video_camera':'\\ud83d\\udcf9',\n 'video_game':'\\ud83c\\udfae',\n 'violin':'\\ud83c\\udfbb',\n 'virgo':'\\u264d\\ufe0f',\n 'volcano':'\\ud83c\\udf0b',\n 'volleyball':'\\ud83c\\udfd0',\n 'vs':'\\ud83c\\udd9a',\n 'vulcan_salute':'\\ud83d\\udd96',\n 'walking_man':'\\ud83d\\udeb6',\n 'walking_woman':'\\ud83d\\udeb6‍\\u2640\\ufe0f',\n 'waning_crescent_moon':'\\ud83c\\udf18',\n 'waning_gibbous_moon':'\\ud83c\\udf16',\n 'warning':'\\u26a0\\ufe0f',\n 'wastebasket':'\\ud83d\\uddd1',\n 'watch':'\\u231a\\ufe0f',\n 'water_buffalo':'\\ud83d\\udc03',\n 'watermelon':'\\ud83c\\udf49',\n 'wave':'\\ud83d\\udc4b',\n 'wavy_dash':'\\u3030\\ufe0f',\n 'waxing_crescent_moon':'\\ud83c\\udf12',\n 'wc':'\\ud83d\\udebe',\n 'weary':'\\ud83d\\ude29',\n 'wedding':'\\ud83d\\udc92',\n 'weight_lifting_man':'\\ud83c\\udfcb\\ufe0f',\n 'weight_lifting_woman':'\\ud83c\\udfcb\\ufe0f‍\\u2640\\ufe0f',\n 'whale':'\\ud83d\\udc33',\n 'whale2':'\\ud83d\\udc0b',\n 'wheel_of_dharma':'\\u2638\\ufe0f',\n 'wheelchair':'\\u267f\\ufe0f',\n 'white_check_mark':'\\u2705',\n 'white_circle':'\\u26aa\\ufe0f',\n 'white_flag':'\\ud83c\\udff3\\ufe0f',\n 'white_flower':'\\ud83d\\udcae',\n 'white_large_square':'\\u2b1c\\ufe0f',\n 'white_medium_small_square':'\\u25fd\\ufe0f',\n 'white_medium_square':'\\u25fb\\ufe0f',\n 'white_small_square':'\\u25ab\\ufe0f',\n 'white_square_button':'\\ud83d\\udd33',\n 'wilted_flower':'\\ud83e\\udd40',\n 'wind_chime':'\\ud83c\\udf90',\n 'wind_face':'\\ud83c\\udf2c',\n 'wine_glass':'\\ud83c\\udf77',\n 'wink':'\\ud83d\\ude09',\n 'wolf':'\\ud83d\\udc3a',\n 'woman':'\\ud83d\\udc69',\n 'woman_artist':'\\ud83d\\udc69‍\\ud83c\\udfa8',\n 'woman_astronaut':'\\ud83d\\udc69‍\\ud83d\\ude80',\n 'woman_cartwheeling':'\\ud83e\\udd38‍\\u2640\\ufe0f',\n 'woman_cook':'\\ud83d\\udc69‍\\ud83c\\udf73',\n 'woman_facepalming':'\\ud83e\\udd26‍\\u2640\\ufe0f',\n 'woman_factory_worker':'\\ud83d\\udc69‍\\ud83c\\udfed',\n 'woman_farmer':'\\ud83d\\udc69‍\\ud83c\\udf3e',\n 'woman_firefighter':'\\ud83d\\udc69‍\\ud83d\\ude92',\n 'woman_health_worker':'\\ud83d\\udc69‍\\u2695\\ufe0f',\n 'woman_judge':'\\ud83d\\udc69‍\\u2696\\ufe0f',\n 'woman_juggling':'\\ud83e\\udd39‍\\u2640\\ufe0f',\n 'woman_mechanic':'\\ud83d\\udc69‍\\ud83d\\udd27',\n 'woman_office_worker':'\\ud83d\\udc69‍\\ud83d\\udcbc',\n 'woman_pilot':'\\ud83d\\udc69‍\\u2708\\ufe0f',\n 'woman_playing_handball':'\\ud83e\\udd3e‍\\u2640\\ufe0f',\n 'woman_playing_water_polo':'\\ud83e\\udd3d‍\\u2640\\ufe0f',\n 'woman_scientist':'\\ud83d\\udc69‍\\ud83d\\udd2c',\n 'woman_shrugging':'\\ud83e\\udd37‍\\u2640\\ufe0f',\n 'woman_singer':'\\ud83d\\udc69‍\\ud83c\\udfa4',\n 'woman_student':'\\ud83d\\udc69‍\\ud83c\\udf93',\n 'woman_teacher':'\\ud83d\\udc69‍\\ud83c\\udfeb',\n 'woman_technologist':'\\ud83d\\udc69‍\\ud83d\\udcbb',\n 'woman_with_turban':'\\ud83d\\udc73‍\\u2640\\ufe0f',\n 'womans_clothes':'\\ud83d\\udc5a',\n 'womans_hat':'\\ud83d\\udc52',\n 'women_wrestling':'\\ud83e\\udd3c‍\\u2640\\ufe0f',\n 'womens':'\\ud83d\\udeba',\n 'world_map':'\\ud83d\\uddfa',\n 'worried':'\\ud83d\\ude1f',\n 'wrench':'\\ud83d\\udd27',\n 'writing_hand':'\\u270d\\ufe0f',\n 'x':'\\u274c',\n 'yellow_heart':'\\ud83d\\udc9b',\n 'yen':'\\ud83d\\udcb4',\n 'yin_yang':'\\u262f\\ufe0f',\n 'yum':'\\ud83d\\ude0b',\n 'zap':'\\u26a1\\ufe0f',\n 'zipper_mouth_face':'\\ud83e\\udd10',\n 'zzz':'\\ud83d\\udca4',\n\n /* special emojis :P */\n 'octocat': '\":octocat:\"',\n 'showdown': 'S'\n};\n\r\n/**\n * Created by Estevao on 31-05-2015.\n */\n\n/**\n * Showdown Converter class\n * @class\n * @param {object} [converterOptions]\n * @returns {Converter}\n */\nshowdown.Converter = function (converterOptions) {\n 'use strict';\n\n var\n /**\n * Options used by this converter\n * @private\n * @type {{}}\n */\n options = {},\n\n /**\n * Language extensions used by this converter\n * @private\n * @type {Array}\n */\n langExtensions = [],\n\n /**\n * Output modifiers extensions used by this converter\n * @private\n * @type {Array}\n */\n outputModifiers = [],\n\n /**\n * Event listeners\n * @private\n * @type {{}}\n */\n listeners = {},\n\n /**\n * The flavor set in this converter\n */\n setConvFlavor = setFlavor,\n\n /**\n * Metadata of the document\n * @type {{parsed: {}, raw: string, format: string}}\n */\n metadata = {\n parsed: {},\n raw: '',\n format: ''\n };\n\n _constructor();\n\n /**\n * Converter constructor\n * @private\n */\n function _constructor () {\n converterOptions = converterOptions || {};\n\n for (var gOpt in globalOptions) {\n if (globalOptions.hasOwnProperty(gOpt)) {\n options[gOpt] = globalOptions[gOpt];\n }\n }\n\n // Merge options\n if (typeof converterOptions === 'object') {\n for (var opt in converterOptions) {\n if (converterOptions.hasOwnProperty(opt)) {\n options[opt] = converterOptions[opt];\n }\n }\n } else {\n throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions +\n ' was passed instead.');\n }\n\n if (options.extensions) {\n showdown.helper.forEach(options.extensions, _parseExtension);\n }\n }\n\n /**\n * Parse extension\n * @param {*} ext\n * @param {string} [name='']\n * @private\n */\n function _parseExtension (ext, name) {\n\n name = name || null;\n // If it's a string, the extension was previously loaded\n if (showdown.helper.isString(ext)) {\n ext = showdown.helper.stdExtName(ext);\n name = ext;\n\n // LEGACY_SUPPORT CODE\n if (showdown.extensions[ext]) {\n console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' +\n 'Please inform the developer that the extension should be updated!');\n legacyExtensionLoading(showdown.extensions[ext], ext);\n return;\n // END LEGACY SUPPORT CODE\n\n } else if (!showdown.helper.isUndefined(extensions[ext])) {\n ext = extensions[ext];\n\n } else {\n throw Error('Extension \"' + ext + '\" could not be loaded. It was either not found or is not a valid extension.');\n }\n }\n\n if (typeof ext === 'function') {\n ext = ext();\n }\n\n if (!showdown.helper.isArray(ext)) {\n ext = [ext];\n }\n\n var validExt = validate(ext, name);\n if (!validExt.valid) {\n throw Error(validExt.error);\n }\n\n for (var i = 0; i < ext.length; ++i) {\n switch (ext[i].type) {\n\n case 'lang':\n langExtensions.push(ext[i]);\n break;\n\n case 'output':\n outputModifiers.push(ext[i]);\n break;\n }\n if (ext[i].hasOwnProperty('listeners')) {\n for (var ln in ext[i].listeners) {\n if (ext[i].listeners.hasOwnProperty(ln)) {\n listen(ln, ext[i].listeners[ln]);\n }\n }\n }\n }\n\n }\n\n /**\n * LEGACY_SUPPORT\n * @param {*} ext\n * @param {string} name\n */\n function legacyExtensionLoading (ext, name) {\n if (typeof ext === 'function') {\n ext = ext(new showdown.Converter());\n }\n if (!showdown.helper.isArray(ext)) {\n ext = [ext];\n }\n var valid = validate(ext, name);\n\n if (!valid.valid) {\n throw Error(valid.error);\n }\n\n for (var i = 0; i < ext.length; ++i) {\n switch (ext[i].type) {\n case 'lang':\n langExtensions.push(ext[i]);\n break;\n case 'output':\n outputModifiers.push(ext[i]);\n break;\n default:// should never reach here\n throw Error('Extension loader error: Type unrecognized!!!');\n }\n }\n }\n\n /**\n * Listen to an event\n * @param {string} name\n * @param {function} callback\n */\n function listen (name, callback) {\n if (!showdown.helper.isString(name)) {\n throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given');\n }\n\n if (typeof callback !== 'function') {\n throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given');\n }\n\n if (!listeners.hasOwnProperty(name)) {\n listeners[name] = [];\n }\n listeners[name].push(callback);\n }\n\n function rTrimInputText (text) {\n var rsp = text.match(/^\\s*/)[0].length,\n rgx = new RegExp('^\\\\s{0,' + rsp + '}', 'gm');\n return text.replace(rgx, '');\n }\n\n /**\n * Dispatch an event\n * @private\n * @param {string} evtName Event name\n * @param {string} text Text\n * @param {{}} options Converter Options\n * @param {{}} globals\n * @returns {string}\n */\n this._dispatch = function dispatch (evtName, text, options, globals) {\n if (listeners.hasOwnProperty(evtName)) {\n for (var ei = 0; ei < listeners[evtName].length; ++ei) {\n var nText = listeners[evtName][ei](evtName, text, this, options, globals);\n if (nText && typeof nText !== 'undefined') {\n text = nText;\n }\n }\n }\n return text;\n };\n\n /**\n * Listen to an event\n * @param {string} name\n * @param {function} callback\n * @returns {showdown.Converter}\n */\n this.listen = function (name, callback) {\n listen(name, callback);\n return this;\n };\n\n /**\n * Converts a markdown string into HTML\n * @param {string} text\n * @returns {*}\n */\n this.makeHtml = function (text) {\n //check if text is not falsy\n if (!text) {\n return text;\n }\n\n var globals = {\n gHtmlBlocks: [],\n gHtmlMdBlocks: [],\n gHtmlSpans: [],\n gUrls: {},\n gTitles: {},\n gDimensions: {},\n gListLevel: 0,\n hashLinkCounts: {},\n langExtensions: langExtensions,\n outputModifiers: outputModifiers,\n converter: this,\n ghCodeBlocks: [],\n metadata: {\n parsed: {},\n raw: '',\n format: ''\n }\n };\n\n // This lets us use ¨ trema as an escape char to avoid md5 hashes\n // The choice of character is arbitrary; anything that isn't\n // magic in Markdown will work.\n text = text.replace(/¨/g, '¨T');\n\n // Replace $ with ¨D\n // RegExp interprets $ as a special character\n // when it's in a replacement string\n text = text.replace(/\\$/g, '¨D');\n\n // Standardize line endings\n text = text.replace(/\\r\\n/g, '\\n'); // DOS to Unix\n text = text.replace(/\\r/g, '\\n'); // Mac to Unix\n\n // Stardardize line spaces\n text = text.replace(/\\u00A0/g, ' ');\n\n if (options.smartIndentationFix) {\n text = rTrimInputText(text);\n }\n\n // Make sure text begins and ends with a couple of newlines:\n text = '\\n\\n' + text + '\\n\\n';\n\n // detab\n text = showdown.subParser('detab')(text, options, globals);\n\n /**\n * Strip any lines consisting only of spaces and tabs.\n * This makes subsequent regexs easier to write, because we can\n * match consecutive blank lines with /\\n+/ instead of something\n * contorted like /[ \\t]*\\n+/\n */\n text = text.replace(/^[ \\t]+$/mg, '');\n\n //run languageExtensions\n showdown.helper.forEach(langExtensions, function (ext) {\n text = showdown.subParser('runExtension')(ext, text, options, globals);\n });\n\n // run the sub parsers\n text = showdown.subParser('metadata')(text, options, globals);\n text = showdown.subParser('hashPreCodeTags')(text, options, globals);\n text = showdown.subParser('githubCodeBlocks')(text, options, globals);\n text = showdown.subParser('hashHTMLBlocks')(text, options, globals);\n text = showdown.subParser('hashCodeTags')(text, options, globals);\n text = showdown.subParser('stripLinkDefinitions')(text, options, globals);\n text = showdown.subParser('blockGamut')(text, options, globals);\n text = showdown.subParser('unhashHTMLSpans')(text, options, globals);\n text = showdown.subParser('unescapeSpecialChars')(text, options, globals);\n\n // attacklab: Restore dollar signs\n text = text.replace(/¨D/g, '$$');\n\n // attacklab: Restore tremas\n text = text.replace(/¨T/g, '¨');\n\n // render a complete html document instead of a partial if the option is enabled\n text = showdown.subParser('completeHTMLDocument')(text, options, globals);\n\n // Run output modifiers\n showdown.helper.forEach(outputModifiers, function (ext) {\n text = showdown.subParser('runExtension')(ext, text, options, globals);\n });\n\n // update metadata\n metadata = globals.metadata;\n return text;\n };\n\n /**\n * Converts an HTML string into a markdown string\n * @param src\n * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used.\n * @returns {string}\n */\n this.makeMarkdown = this.makeMd = function (src, HTMLParser) {\n\n // replace \\r\\n with \\n\n src = src.replace(/\\r\\n/g, '\\n');\n src = src.replace(/\\r/g, '\\n'); // old macs\n\n // due to an edge case, we need to find this: > <\n // to prevent removing of non silent white spaces\n // ex: this is sparta\n src = src.replace(/>[ \\t]+¨NBSP;<');\n\n if (!HTMLParser) {\n if (window && window.document) {\n HTMLParser = window.document;\n } else {\n throw new Error('HTMLParser is undefined. If in a webworker or nodejs environment, you need to provide a WHATWG DOM and HTML such as JSDOM');\n }\n }\n\n var doc = HTMLParser.createElement('div');\n doc.innerHTML = src;\n\n var globals = {\n preList: substitutePreCodeTags(doc)\n };\n\n // remove all newlines and collapse spaces\n clean(doc);\n\n // some stuff, like accidental reference links must now be escaped\n // TODO\n // doc.innerHTML = doc.innerHTML.replace(/\\[[\\S\\t ]]/);\n\n var nodes = doc.childNodes,\n mdDoc = '';\n\n for (var i = 0; i < nodes.length; i++) {\n mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals);\n }\n\n function clean (node) {\n for (var n = 0; n < node.childNodes.length; ++n) {\n var child = node.childNodes[n];\n if (child.nodeType === 3) {\n if (!/\\S/.test(child.nodeValue)) {\n node.removeChild(child);\n --n;\n } else {\n child.nodeValue = child.nodeValue.split('\\n').join(' ');\n child.nodeValue = child.nodeValue.replace(/(\\s)+/g, '$1');\n }\n } else if (child.nodeType === 1) {\n clean(child);\n }\n }\n }\n\n // find all pre tags and replace contents with placeholder\n // we need this so that we can remove all indentation from html\n // to ease up parsing\n function substitutePreCodeTags (doc) {\n\n var pres = doc.querySelectorAll('pre'),\n presPH = [];\n\n for (var i = 0; i < pres.length; ++i) {\n\n if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') {\n var content = pres[i].firstChild.innerHTML.trim(),\n language = pres[i].firstChild.getAttribute('data-language') || '';\n\n // if data-language attribute is not defined, then we look for class language-*\n if (language === '') {\n var classes = pres[i].firstChild.className.split(' ');\n for (var c = 0; c < classes.length; ++c) {\n var matches = classes[c].match(/^language-(.+)$/);\n if (matches !== null) {\n language = matches[1];\n break;\n }\n }\n }\n\n // unescape html entities in content\n content = showdown.helper.unescapeHTMLEntities(content);\n\n presPH.push(content);\n pres[i].outerHTML = '';\n } else {\n presPH.push(pres[i].innerHTML);\n pres[i].innerHTML = '';\n pres[i].setAttribute('prenum', i.toString());\n }\n }\n return presPH;\n }\n\n return mdDoc;\n };\n\n /**\n * Set an option of this Converter instance\n * @param {string} key\n * @param {*} value\n */\n this.setOption = function (key, value) {\n options[key] = value;\n };\n\n /**\n * Get the option of this Converter instance\n * @param {string} key\n * @returns {*}\n */\n this.getOption = function (key) {\n return options[key];\n };\n\n /**\n * Get the options of this Converter instance\n * @returns {{}}\n */\n this.getOptions = function () {\n return options;\n };\n\n /**\n * Add extension to THIS converter\n * @param {{}} extension\n * @param {string} [name=null]\n */\n this.addExtension = function (extension, name) {\n name = name || null;\n _parseExtension(extension, name);\n };\n\n /**\n * Use a global registered extension with THIS converter\n * @param {string} extensionName Name of the previously registered extension\n */\n this.useExtension = function (extensionName) {\n _parseExtension(extensionName);\n };\n\n /**\n * Set the flavor THIS converter should use\n * @param {string} name\n */\n this.setFlavor = function (name) {\n if (!flavor.hasOwnProperty(name)) {\n throw Error(name + ' flavor was not found');\n }\n var preset = flavor[name];\n setConvFlavor = name;\n for (var option in preset) {\n if (preset.hasOwnProperty(option)) {\n options[option] = preset[option];\n }\n }\n };\n\n /**\n * Get the currently set flavor of this converter\n * @returns {string}\n */\n this.getFlavor = function () {\n return setConvFlavor;\n };\n\n /**\n * Remove an extension from THIS converter.\n * Note: This is a costly operation. It's better to initialize a new converter\n * and specify the extensions you wish to use\n * @param {Array} extension\n */\n this.removeExtension = function (extension) {\n if (!showdown.helper.isArray(extension)) {\n extension = [extension];\n }\n for (var a = 0; a < extension.length; ++a) {\n var ext = extension[a];\n for (var i = 0; i < langExtensions.length; ++i) {\n if (langExtensions[i] === ext) {\n langExtensions[i].splice(i, 1);\n }\n }\n for (var ii = 0; ii < outputModifiers.length; ++i) {\n if (outputModifiers[ii] === ext) {\n outputModifiers[ii].splice(i, 1);\n }\n }\n }\n };\n\n /**\n * Get all extension of THIS converter\n * @returns {{language: Array, output: Array}}\n */\n this.getAllExtensions = function () {\n return {\n language: langExtensions,\n output: outputModifiers\n };\n };\n\n /**\n * Get the metadata of the previously parsed document\n * @param raw\n * @returns {string|{}}\n */\n this.getMetadata = function (raw) {\n if (raw) {\n return metadata.raw;\n } else {\n return metadata.parsed;\n }\n };\n\n /**\n * Get the metadata format of the previously parsed document\n * @returns {string}\n */\n this.getMetadataFormat = function () {\n return metadata.format;\n };\n\n /**\n * Private: set a single key, value metadata pair\n * @param {string} key\n * @param {string} value\n */\n this._setMetadataPair = function (key, value) {\n metadata.parsed[key] = value;\n };\n\n /**\n * Private: set metadata format\n * @param {string} format\n */\n this._setMetadataFormat = function (format) {\n metadata.format = format;\n };\n\n /**\n * Private: set metadata raw text\n * @param {string} raw\n */\n this._setMetadataRaw = function (raw) {\n metadata.raw = raw;\n };\n};\n\r\n/**\n * Turn Markdown link shortcuts into XHTML tags.\n */\nshowdown.subParser('anchors', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('anchors.before', text, options, globals);\n\n var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) {\n if (showdown.helper.isUndefined(title)) {\n title = '';\n }\n linkId = linkId.toLowerCase();\n\n // Special case for explicit empty url\n if (wholeMatch.search(/\\(? ?(['\"].*['\"])?\\)$/m) > -1) {\n url = '';\n } else if (!url) {\n if (!linkId) {\n // lower-case and turn embedded newlines into spaces\n linkId = linkText.toLowerCase().replace(/ ?\\n/g, ' ');\n }\n url = '#' + linkId;\n\n if (!showdown.helper.isUndefined(globals.gUrls[linkId])) {\n url = globals.gUrls[linkId];\n if (!showdown.helper.isUndefined(globals.gTitles[linkId])) {\n title = globals.gTitles[linkId];\n }\n } else {\n return wholeMatch;\n }\n }\n\n //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance\n url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);\n\n var result = '';\n\n return result;\n };\n\n // First, handle reference-style links: [link text] [id]\n text = text.replace(/\\[((?:\\[[^\\]]*]|[^\\[\\]])*)] ?(?:\\n *)?\\[(.*?)]()()()()/g, writeAnchorTag);\n\n // Next, inline-style links: [link text](url \"optional title\")\n // cases with crazy urls like ./image/cat1).png\n text = text.replace(/\\[((?:\\[[^\\]]*]|[^\\[\\]])*)]()[ \\t]*\\([ \\t]?<([^>]*)>(?:[ \\t]*(([\"'])([^\"]*?)\\5))?[ \\t]?\\)/g,\n writeAnchorTag);\n\n // normal cases\n text = text.replace(/\\[((?:\\[[^\\]]*]|[^\\[\\]])*)]()[ \\t]*\\([ \\t]??(?:[ \\t]*(([\"'])([^\"]*?)\\5))?[ \\t]?\\)/g,\n writeAnchorTag);\n\n // handle reference-style shortcuts: [link text]\n // These must come last in case you've also got [link test][1]\n // or [link test](/foo)\n text = text.replace(/\\[([^\\[\\]]+)]()()()()()/g, writeAnchorTag);\n\n // Lastly handle GithubMentions if option is enabled\n if (options.ghMentions) {\n text = text.replace(/(^|\\s)(\\\\)?(@([a-z\\d]+(?:[a-z\\d.-]+?[a-z\\d]+)*))/gmi, function (wm, st, escape, mentions, username) {\n if (escape === '\\\\') {\n return st + mentions;\n }\n\n //check if options.ghMentionsLink is a string\n if (!showdown.helper.isString(options.ghMentionsLink)) {\n throw new Error('ghMentionsLink option must be a string');\n }\n var lnk = options.ghMentionsLink.replace(/\\{u}/g, username),\n target = '';\n if (options.openLinksInNewWindow) {\n target = ' rel=\"noopener noreferrer\" target=\"¨E95Eblank\"';\n }\n return st + '' + mentions + '';\n });\n }\n\n text = globals.converter._dispatch('anchors.after', text, options, globals);\n return text;\n});\n\r\n// url allowed chars [a-z\\d_.~:/?#[]@!$&'()*+,;=-]\n\nvar simpleURLRegex = /([*~_]+|\\b)(((https?|ftp|dict):\\/\\/|www\\.)[^'\">\\s]+?\\.[^'\">\\s]+?)()(\\1)?(?=\\s|$)(?![\"<>])/gi,\n simpleURLRegex2 = /([*~_]+|\\b)(((https?|ftp|dict):\\/\\/|www\\.)[^'\">\\s]+\\.[^'\">\\s]+?)([.!?,()\\[\\]])?(\\1)?(?=\\s|$)(?![\"<>])/gi,\n delimUrlRegex = /()<(((https?|ftp|dict):\\/\\/|www\\.)[^'\">\\s]+)()>()/gi,\n simpleMailRegex = /(^|\\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\\.[-a-z0-9]+)*\\.[a-z]+)(?=$|\\s)/gmi,\n delimMailRegex = /<()(?:mailto:)?([-.\\w]+@[-a-z0-9]+(\\.[-a-z0-9]+)*\\.[a-z]+)>/gi,\n\n replaceLink = function (options) {\n 'use strict';\n return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) {\n link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);\n var lnkTxt = link,\n append = '',\n target = '',\n lmc = leadingMagicChars || '',\n tmc = trailingMagicChars || '';\n if (/^www\\./i.test(link)) {\n link = link.replace(/^www\\./i, 'http://www.');\n }\n if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) {\n append = trailingPunctuation;\n }\n if (options.openLinksInNewWindow) {\n target = ' rel=\"noopener noreferrer\" target=\"¨E95Eblank\"';\n }\n return lmc + '' + lnkTxt + '' + append + tmc;\n };\n },\n\n replaceMail = function (options, globals) {\n 'use strict';\n return function (wholeMatch, b, mail) {\n var href = 'mailto:';\n b = b || '';\n mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals);\n if (options.encodeEmails) {\n href = showdown.helper.encodeEmailAddress(href + mail);\n mail = showdown.helper.encodeEmailAddress(mail);\n } else {\n href = href + mail;\n }\n return b + '' + mail + '';\n };\n };\n\nshowdown.subParser('autoLinks', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('autoLinks.before', text, options, globals);\n\n text = text.replace(delimUrlRegex, replaceLink(options));\n text = text.replace(delimMailRegex, replaceMail(options, globals));\n\n text = globals.converter._dispatch('autoLinks.after', text, options, globals);\n\n return text;\n});\n\nshowdown.subParser('simplifiedAutoLinks', function (text, options, globals) {\n 'use strict';\n\n if (!options.simplifiedAutoLink) {\n return text;\n }\n\n text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals);\n\n if (options.excludeTrailingPunctuationFromURLs) {\n text = text.replace(simpleURLRegex2, replaceLink(options));\n } else {\n text = text.replace(simpleURLRegex, replaceLink(options));\n }\n text = text.replace(simpleMailRegex, replaceMail(options, globals));\n\n text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals);\n\n return text;\n});\n\r\n/**\n * These are all the transformations that form block-level\n * tags like paragraphs, headers, and list items.\n */\nshowdown.subParser('blockGamut', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('blockGamut.before', text, options, globals);\n\n // we parse blockquotes first so that we can have headings and hrs\n // inside blockquotes\n text = showdown.subParser('blockQuotes')(text, options, globals);\n text = showdown.subParser('headers')(text, options, globals);\n\n // Do Horizontal Rules:\n text = showdown.subParser('horizontalRule')(text, options, globals);\n\n text = showdown.subParser('lists')(text, options, globals);\n text = showdown.subParser('codeBlocks')(text, options, globals);\n text = showdown.subParser('tables')(text, options, globals);\n\n // We already ran _HashHTMLBlocks() before, in Markdown(), but that\n // was to escape raw HTML in the original Markdown source. This time,\n // we're escaping the markup we've just created, so that we don't wrap\n //

tags around block-level tags.\n text = showdown.subParser('hashHTMLBlocks')(text, options, globals);\n text = showdown.subParser('paragraphs')(text, options, globals);\n\n text = globals.converter._dispatch('blockGamut.after', text, options, globals);\n\n return text;\n});\n\r\nshowdown.subParser('blockQuotes', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('blockQuotes.before', text, options, globals);\n\n // add a couple extra lines after the text and endtext mark\n text = text + '\\n\\n';\n\n var rgx = /(^ {0,3}>[ \\t]?.+\\n(.+\\n)*\\n*)+/gm;\n\n if (options.splitAdjacentBlockquotes) {\n rgx = /^ {0,3}>[\\s\\S]*?(?:\\n\\n)/gm;\n }\n\n text = text.replace(rgx, function (bq) {\n // attacklab: hack around Konqueror 3.5.4 bug:\n // \"----------bug\".replace(/^-/g,\"\") == \"bug\"\n bq = bq.replace(/^[ \\t]*>[ \\t]?/gm, ''); // trim one level of quoting\n\n // attacklab: clean up hack\n bq = bq.replace(/¨0/g, '');\n\n bq = bq.replace(/^[ \\t]+$/gm, ''); // trim whitespace-only lines\n bq = showdown.subParser('githubCodeBlocks')(bq, options, globals);\n bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse\n\n bq = bq.replace(/(^|\\n)/g, '$1 ');\n // These leading spaces screw with

 content, so we need to fix that:\n    bq = bq.replace(/(\\s*
[^\\r]+?<\\/pre>)/gm, function (wholeMatch, m1) {\n      var pre = m1;\n      // attacklab: hack around Konqueror 3.5.4 bug:\n      pre = pre.replace(/^  /mg, '¨0');\n      pre = pre.replace(/¨0/g, '');\n      return pre;\n    });\n\n    return showdown.subParser('hashBlock')('
\\n' + bq + '\\n
', options, globals);\n });\n\n text = globals.converter._dispatch('blockQuotes.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Process Markdown `
` blocks.\n */\nshowdown.subParser('codeBlocks', function (text, options, globals) {\n  'use strict';\n\n  text = globals.converter._dispatch('codeBlocks.before', text, options, globals);\n\n  // sentinel workarounds for lack of \\A and \\Z, safari\\khtml bug\n  text += '¨0';\n\n  var pattern = /(?:\\n\\n|^)((?:(?:[ ]{4}|\\t).*\\n+)+)(\\n*[ ]{0,3}[^ \\t\\n]|(?=¨0))/g;\n  text = text.replace(pattern, function (wholeMatch, m1, m2) {\n    var codeblock = m1,\n        nextChar = m2,\n        end = '\\n';\n\n    codeblock = showdown.subParser('outdent')(codeblock, options, globals);\n    codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);\n    codeblock = showdown.subParser('detab')(codeblock, options, globals);\n    codeblock = codeblock.replace(/^\\n+/g, ''); // trim leading newlines\n    codeblock = codeblock.replace(/\\n+$/g, ''); // trim trailing newlines\n\n    if (options.omitExtraWLInCodeBlocks) {\n      end = '';\n    }\n\n    codeblock = '
' + codeblock + end + '
';\n\n return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar;\n });\n\n // strip sentinel\n text = text.replace(/¨0/, '');\n\n text = globals.converter._dispatch('codeBlocks.after', text, options, globals);\n return text;\n});\n\r\n/**\n *\n * * Backtick quotes are used for spans.\n *\n * * You can use multiple backticks as the delimiters if you want to\n * include literal backticks in the code span. So, this input:\n *\n * Just type ``foo `bar` baz`` at the prompt.\n *\n * Will translate to:\n *\n *

Just type foo `bar` baz at the prompt.

\n *\n * There's no arbitrary limit to the number of backticks you\n * can use as delimters. If you need three consecutive backticks\n * in your code, use four for delimiters, etc.\n *\n * * You can use spaces to get literal backticks at the edges:\n *\n * ... type `` `bar` `` ...\n *\n * Turns to:\n *\n * ... type `bar` ...\n */\nshowdown.subParser('codeSpans', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('codeSpans.before', text, options, globals);\n\n if (typeof text === 'undefined') {\n text = '';\n }\n text = text.replace(/(^|[^\\\\])(`+)([^\\r]*?[^`])\\2(?!`)/gm,\n function (wholeMatch, m1, m2, m3) {\n var c = m3;\n c = c.replace(/^([ \\t]*)/g, '');\t// leading whitespace\n c = c.replace(/[ \\t]*$/g, '');\t// trailing whitespace\n c = showdown.subParser('encodeCode')(c, options, globals);\n c = m1 + '' + c + '';\n c = showdown.subParser('hashHTMLSpans')(c, options, globals);\n return c;\n }\n );\n\n text = globals.converter._dispatch('codeSpans.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Create a full HTML document from the processed markdown\n */\nshowdown.subParser('completeHTMLDocument', function (text, options, globals) {\n 'use strict';\n\n if (!options.completeHTMLDocument) {\n return text;\n }\n\n text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals);\n\n var doctype = 'html',\n doctypeParsed = '\\n',\n title = '',\n charset = '\\n',\n lang = '',\n metadata = '';\n\n if (typeof globals.metadata.parsed.doctype !== 'undefined') {\n doctypeParsed = '\\n';\n doctype = globals.metadata.parsed.doctype.toString().toLowerCase();\n if (doctype === 'html' || doctype === 'html5') {\n charset = '';\n }\n }\n\n for (var meta in globals.metadata.parsed) {\n if (globals.metadata.parsed.hasOwnProperty(meta)) {\n switch (meta.toLowerCase()) {\n case 'doctype':\n break;\n\n case 'title':\n title = '' + globals.metadata.parsed.title + '\\n';\n break;\n\n case 'charset':\n if (doctype === 'html' || doctype === 'html5') {\n charset = '\\n';\n } else {\n charset = '\\n';\n }\n break;\n\n case 'language':\n case 'lang':\n lang = ' lang=\"' + globals.metadata.parsed[meta] + '\"';\n metadata += '\\n';\n break;\n\n default:\n metadata += '\\n';\n }\n }\n }\n\n text = doctypeParsed + '\\n\\n' + title + charset + metadata + '\\n\\n' + text.trim() + '\\n\\n';\n\n text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Convert all tabs to spaces\n */\nshowdown.subParser('detab', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('detab.before', text, options, globals);\n\n // expand first n-1 tabs\n text = text.replace(/\\t(?=\\t)/g, ' '); // g_tab_width\n\n // replace the nth with two sentinels\n text = text.replace(/\\t/g, '¨A¨B');\n\n // use the sentinel to anchor our regex so it doesn't explode\n text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) {\n var leadingText = m1,\n numSpaces = 4 - leadingText.length % 4; // g_tab_width\n\n // there *must* be a better way to do this:\n for (var i = 0; i < numSpaces; i++) {\n leadingText += ' ';\n }\n\n return leadingText;\n });\n\n // clean up sentinels\n text = text.replace(/¨A/g, ' '); // g_tab_width\n text = text.replace(/¨B/g, '');\n\n text = globals.converter._dispatch('detab.after', text, options, globals);\n return text;\n});\n\r\nshowdown.subParser('ellipsis', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('ellipsis.before', text, options, globals);\n\n text = text.replace(/\\.\\.\\./g, '…');\n\n text = globals.converter._dispatch('ellipsis.after', text, options, globals);\n\n return text;\n});\n\r\n/**\n * Turn emoji codes into emojis\n *\n * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis\n */\nshowdown.subParser('emoji', function (text, options, globals) {\n 'use strict';\n\n if (!options.emoji) {\n return text;\n }\n\n text = globals.converter._dispatch('emoji.before', text, options, globals);\n\n var emojiRgx = /:([\\S]+?):/g;\n\n text = text.replace(emojiRgx, function (wm, emojiCode) {\n if (showdown.helper.emojis.hasOwnProperty(emojiCode)) {\n return showdown.helper.emojis[emojiCode];\n }\n return wm;\n });\n\n text = globals.converter._dispatch('emoji.after', text, options, globals);\n\n return text;\n});\n\r\n/**\n * Smart processing for ampersands and angle brackets that need to be encoded.\n */\nshowdown.subParser('encodeAmpsAndAngles', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals);\n\n // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:\n // http://bumppo.net/projects/amputator/\n text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\\w+);)/g, '&');\n\n // Encode naked <'s\n text = text.replace(/<(?![a-z\\/?$!])/gi, '<');\n\n // Encode <\n text = text.replace(/\n text = text.replace(/>/g, '>');\n\n text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Returns the string, with after processing the following backslash escape sequences.\n *\n * attacklab: The polite way to do this is with the new escapeCharacters() function:\n *\n * text = escapeCharacters(text,\"\\\\\",true);\n * text = escapeCharacters(text,\"`*_{}[]()>#+-.!\",true);\n *\n * ...but we're sidestepping its use of the (slow) RegExp constructor\n * as an optimization for Firefox. This function gets called a LOT.\n */\nshowdown.subParser('encodeBackslashEscapes', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals);\n\n text = text.replace(/\\\\(\\\\)/g, showdown.helper.escapeCharactersCallback);\n text = text.replace(/\\\\([`*_{}\\[\\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback);\n\n text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Encode/escape certain characters inside Markdown code runs.\n * The point is that in code, these characters are literals,\n * and lose their special Markdown meanings.\n */\nshowdown.subParser('encodeCode', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('encodeCode.before', text, options, globals);\n\n // Encode all ampersands; HTML entities are not\n // entities within a Markdown code span.\n text = text\n .replace(/&/g, '&')\n // Do the angle bracket song and dance:\n .replace(//g, '>')\n // Now, escape characters that are magic in Markdown:\n .replace(/([*_{}\\[\\]\\\\=~-])/g, showdown.helper.escapeCharactersCallback);\n\n text = globals.converter._dispatch('encodeCode.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Within tags -- meaning between < and > -- encode [\\ ` * _ ~ =] so they\n * don't conflict with their use in Markdown for code, italics and strong.\n */\nshowdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals);\n\n // Build a regex to find HTML tags.\n var tags = /<\\/?[a-z\\d_:-]+(?:[\\s]+[\\s\\S]+?)?>/gi,\n comments = /-]|-[^>])(?:[^-]|-[^-])*)--)>/gi;\n\n text = text.replace(tags, function (wholeMatch) {\n return wholeMatch\n .replace(/(.)<\\/?code>(?=.)/g, '$1`')\n .replace(/([\\\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);\n });\n\n text = text.replace(comments, function (wholeMatch) {\n return wholeMatch\n .replace(/([\\\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);\n });\n\n text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Handle github codeblocks prior to running HashHTML so that\n * HTML contained within the codeblock gets escaped properly\n * Example:\n * ```ruby\n * def hello_world(x)\n * puts \"Hello, #{x}\"\n * end\n * ```\n */\nshowdown.subParser('githubCodeBlocks', function (text, options, globals) {\n 'use strict';\n\n // early exit if option is not enabled\n if (!options.ghCodeBlocks) {\n return text;\n }\n\n text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals);\n\n text += '¨0';\n\n text = text.replace(/(?:^|\\n)(?: {0,3})(```+|~~~+)(?: *)([^\\s`~]*)\\n([\\s\\S]*?)\\n(?: {0,3})\\1/g, function (wholeMatch, delim, language, codeblock) {\n var end = (options.omitExtraWLInCodeBlocks) ? '' : '\\n';\n\n // First parse the github code block\n codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);\n codeblock = showdown.subParser('detab')(codeblock, options, globals);\n codeblock = codeblock.replace(/^\\n+/g, ''); // trim leading newlines\n codeblock = codeblock.replace(/\\n+$/g, ''); // trim trailing whitespace\n\n codeblock = '
' + codeblock + end + '
';\n\n codeblock = showdown.subParser('hashBlock')(codeblock, options, globals);\n\n // Since GHCodeblocks can be false positives, we need to\n // store the primitive text and the parsed text in a global var,\n // and then return a token\n return '\\n\\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\\n\\n';\n });\n\n // attacklab: strip sentinel\n text = text.replace(/¨0/, '');\n\n return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals);\n});\n\r\nshowdown.subParser('hashBlock', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('hashBlock.before', text, options, globals);\n text = text.replace(/(^\\n+|\\n+$)/g, '');\n text = '\\n\\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\\n\\n';\n text = globals.converter._dispatch('hashBlock.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Hash and escape elements that should not be parsed as markdown\n */\nshowdown.subParser('hashCodeTags', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('hashCodeTags.before', text, options, globals);\n\n var repFunc = function (wholeMatch, match, left, right) {\n var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;\n return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C';\n };\n\n // Hash naked \n text = showdown.helper.replaceRecursiveRegExp(text, repFunc, ']*>', '', 'gim');\n\n text = globals.converter._dispatch('hashCodeTags.after', text, options, globals);\n return text;\n});\n\r\nshowdown.subParser('hashElement', function (text, options, globals) {\n 'use strict';\n\n return function (wholeMatch, m1) {\n var blockText = m1;\n\n // Undo double lines\n blockText = blockText.replace(/\\n\\n/g, '\\n');\n blockText = blockText.replace(/^\\n/, '');\n\n // strip trailing blank lines\n blockText = blockText.replace(/\\n+$/g, '');\n\n // Replace the element text with a marker (\"¨KxK\" where x is its key)\n blockText = '\\n\\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\\n\\n';\n\n return blockText;\n };\n});\n\r\nshowdown.subParser('hashHTMLBlocks', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals);\n\n var blockTags = [\n 'pre',\n 'div',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'blockquote',\n 'table',\n 'dl',\n 'ol',\n 'ul',\n 'script',\n 'noscript',\n 'form',\n 'fieldset',\n 'iframe',\n 'math',\n 'style',\n 'section',\n 'header',\n 'footer',\n 'nav',\n 'article',\n 'aside',\n 'address',\n 'audio',\n 'canvas',\n 'figure',\n 'hgroup',\n 'output',\n 'video',\n 'p'\n ],\n repFunc = function (wholeMatch, match, left, right) {\n var txt = wholeMatch;\n // check if this html element is marked as markdown\n // if so, it's contents should be parsed as markdown\n if (left.search(/\\bmarkdown\\b/) !== -1) {\n txt = left + globals.converter.makeHtml(match) + right;\n }\n return '\\n\\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\\n\\n';\n };\n\n if (options.backslashEscapesHTMLTags) {\n // encode backslash escaped HTML tags\n text = text.replace(/\\\\<(\\/?[^>]+?)>/g, function (wm, inside) {\n return '<' + inside + '>';\n });\n }\n\n // hash HTML Blocks\n for (var i = 0; i < blockTags.length; ++i) {\n\n var opTagPos,\n rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\\\b[^>]*>)', 'im'),\n patLeft = '<' + blockTags[i] + '\\\\b[^>]*>',\n patRight = '';\n // 1. Look for the first position of the first opening HTML tag in the text\n while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) {\n\n // if the HTML tag is \\ escaped, we need to escape it and break\n\n\n //2. Split the text in that position\n var subTexts = showdown.helper.splitAtIndex(text, opTagPos),\n //3. Match recursively\n newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im');\n\n // prevent an infinite loop\n if (newSubText1 === subTexts[1]) {\n break;\n }\n text = subTexts[0].concat(newSubText1);\n }\n }\n // HR SPECIAL CASE\n text = text.replace(/(\\n {0,3}(<(hr)\\b([^<>])*?\\/?>)[ \\t]*(?=\\n{2,}))/g,\n showdown.subParser('hashElement')(text, options, globals));\n\n // Special case for standalone HTML comments\n text = showdown.helper.replaceRecursiveRegExp(text, function (txt) {\n return '\\n\\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\\n\\n';\n }, '^ {0,3}', 'gm');\n\n // PHP and ASP-style processor instructions ( and <%...%>)\n text = text.replace(/(?:\\n\\n)( {0,3}(?:<([?%])[^\\r]*?\\2>)[ \\t]*(?=\\n{2,}))/g,\n showdown.subParser('hashElement')(text, options, globals));\n\n text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Hash span elements that should not be parsed as markdown\n */\nshowdown.subParser('hashHTMLSpans', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals);\n\n function hashHTMLSpan (html) {\n return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C';\n }\n\n // Hash Self Closing tags\n text = text.replace(/<[^>]+?\\/>/gi, function (wm) {\n return hashHTMLSpan(wm);\n });\n\n // Hash tags without properties\n text = text.replace(/<([^>]+?)>[\\s\\S]*?<\\/\\1>/g, function (wm) {\n return hashHTMLSpan(wm);\n });\n\n // Hash tags with properties\n text = text.replace(/<([^>]+?)\\s[^>]+?>[\\s\\S]*?<\\/\\1>/g, function (wm) {\n return hashHTMLSpan(wm);\n });\n\n // Hash self closing tags without />\n text = text.replace(/<[^>]+?>/gi, function (wm) {\n return hashHTMLSpan(wm);\n });\n\n /*showdown.helper.matchRecursiveRegExp(text, ']*>', '', 'gi');*/\n\n text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals);\n return text;\n});\n\n/**\n * Unhash HTML spans\n */\nshowdown.subParser('unhashHTMLSpans', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals);\n\n for (var i = 0; i < globals.gHtmlSpans.length; ++i) {\n var repText = globals.gHtmlSpans[i],\n // limiter to prevent infinite loop (assume 10 as limit for recurse)\n limit = 0;\n\n while (/¨C(\\d+)C/.test(repText)) {\n var num = RegExp.$1;\n repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]);\n if (limit === 10) {\n console.error('maximum nesting of 10 spans reached!!!');\n break;\n }\n ++limit;\n }\n text = text.replace('¨C' + i + 'C', repText);\n }\n\n text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Hash and escape
 elements that should not be parsed as markdown\n */\nshowdown.subParser('hashPreCodeTags', function (text, options, globals) {\n  'use strict';\n  text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals);\n\n  var repFunc = function (wholeMatch, match, left, right) {\n    // encode html entities\n    var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;\n    return '\\n\\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\\n\\n';\n  };\n\n  // Hash 
\n  text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}]*>\\\\s*]*>', '^ {0,3}\\\\s*
', 'gim');\n\n text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals);\n return text;\n});\n\r\nshowdown.subParser('headers', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('headers.before', text, options, globals);\n\n var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),\n\n // Set text-style headers:\n //\tHeader 1\n //\t========\n //\n //\tHeader 2\n //\t--------\n //\n setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \\t]*\\n={2,}[ \\t]*\\n+/gm : /^(.+)[ \\t]*\\n=+[ \\t]*\\n+/gm,\n setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \\t]*\\n-{2,}[ \\t]*\\n+/gm : /^(.+)[ \\t]*\\n-+[ \\t]*\\n+/gm;\n\n text = text.replace(setextRegexH1, function (wholeMatch, m1) {\n\n var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),\n hID = (options.noHeaderId) ? '' : ' id=\"' + headerId(m1) + '\"',\n hLevel = headerLevelStart,\n hashBlock = '' + spanGamut + '';\n return showdown.subParser('hashBlock')(hashBlock, options, globals);\n });\n\n text = text.replace(setextRegexH2, function (matchFound, m1) {\n var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),\n hID = (options.noHeaderId) ? '' : ' id=\"' + headerId(m1) + '\"',\n hLevel = headerLevelStart + 1,\n hashBlock = '' + spanGamut + '';\n return showdown.subParser('hashBlock')(hashBlock, options, globals);\n });\n\n // atx-style headers:\n // # Header 1\n // ## Header 2\n // ## Header 2 with closing hashes ##\n // ...\n // ###### Header 6\n //\n var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \\t]+(.+?)[ \\t]*#*\\n+/gm : /^(#{1,6})[ \\t]*(.+?)[ \\t]*#*\\n+/gm;\n\n text = text.replace(atxStyle, function (wholeMatch, m1, m2) {\n var hText = m2;\n if (options.customizedHeaderId) {\n hText = m2.replace(/\\s?\\{([^{]+?)}\\s*$/, '');\n }\n\n var span = showdown.subParser('spanGamut')(hText, options, globals),\n hID = (options.noHeaderId) ? '' : ' id=\"' + headerId(m2) + '\"',\n hLevel = headerLevelStart - 1 + m1.length,\n header = '' + span + '';\n\n return showdown.subParser('hashBlock')(header, options, globals);\n });\n\n function headerId (m) {\n var title,\n prefix;\n\n // It is separate from other options to allow combining prefix and customized\n if (options.customizedHeaderId) {\n var match = m.match(/\\{([^{]+?)}\\s*$/);\n if (match && match[1]) {\n m = match[1];\n }\n }\n\n title = m;\n\n // Prefix id to prevent causing inadvertent pre-existing style matches.\n if (showdown.helper.isString(options.prefixHeaderId)) {\n prefix = options.prefixHeaderId;\n } else if (options.prefixHeaderId === true) {\n prefix = 'section-';\n } else {\n prefix = '';\n }\n\n if (!options.rawPrefixHeaderId) {\n title = prefix + title;\n }\n\n if (options.ghCompatibleHeaderId) {\n title = title\n .replace(/ /g, '-')\n // replace previously escaped chars (&, ¨ and $)\n .replace(/&/g, '')\n .replace(/¨T/g, '')\n .replace(/¨D/g, '')\n // replace rest of the chars (&~$ are repeated as they might have been escaped)\n // borrowed from github's redcarpet (some they should produce similar results)\n .replace(/[&+$,\\/:;=?@\"#{}|^¨~\\[\\]`\\\\*)(%.!'<>]/g, '')\n .toLowerCase();\n } else if (options.rawHeaderId) {\n title = title\n .replace(/ /g, '-')\n // replace previously escaped chars (&, ¨ and $)\n .replace(/&/g, '&')\n .replace(/¨T/g, '¨')\n .replace(/¨D/g, '$')\n // replace \" and '\n .replace(/[\"']/g, '-')\n .toLowerCase();\n } else {\n title = title\n .replace(/[^\\w]/g, '')\n .toLowerCase();\n }\n\n if (options.rawPrefixHeaderId) {\n title = prefix + title;\n }\n\n if (globals.hashLinkCounts[title]) {\n title = title + '-' + (globals.hashLinkCounts[title]++);\n } else {\n globals.hashLinkCounts[title] = 1;\n }\n return title;\n }\n\n text = globals.converter._dispatch('headers.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Turn Markdown link shortcuts into XHTML tags.\n */\nshowdown.subParser('horizontalRule', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('horizontalRule.before', text, options, globals);\n\n var key = showdown.subParser('hashBlock')('
', options, globals);\n text = text.replace(/^ {0,2}( ?-){3,}[ \\t]*$/gm, key);\n text = text.replace(/^ {0,2}( ?\\*){3,}[ \\t]*$/gm, key);\n text = text.replace(/^ {0,2}( ?_){3,}[ \\t]*$/gm, key);\n\n text = globals.converter._dispatch('horizontalRule.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Turn Markdown image shortcuts into tags.\n */\nshowdown.subParser('images', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('images.before', text, options, globals);\n\n var inlineRegExp = /!\\[([^\\]]*?)][ \\t]*()\\([ \\t]??(?: =([*\\d]+[A-Za-z%]{0,4})x([*\\d]+[A-Za-z%]{0,4}))?[ \\t]*(?:([\"'])([^\"]*?)\\6)?[ \\t]?\\)/g,\n crazyRegExp = /!\\[([^\\]]*?)][ \\t]*()\\([ \\t]?<([^>]*)>(?: =([*\\d]+[A-Za-z%]{0,4})x([*\\d]+[A-Za-z%]{0,4}))?[ \\t]*(?:(?:([\"'])([^\"]*?)\\6))?[ \\t]?\\)/g,\n base64RegExp = /!\\[([^\\]]*?)][ \\t]*()\\([ \\t]??(?: =([*\\d]+[A-Za-z%]{0,4})x([*\\d]+[A-Za-z%]{0,4}))?[ \\t]*(?:([\"'])([^\"]*?)\\6)?[ \\t]?\\)/g,\n referenceRegExp = /!\\[([^\\]]*?)] ?(?:\\n *)?\\[([\\s\\S]*?)]()()()()()/g,\n refShortcutRegExp = /!\\[([^\\[\\]]+)]()()()()()/g;\n\n function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) {\n url = url.replace(/\\s/g, '');\n return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title);\n }\n\n function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) {\n\n var gUrls = globals.gUrls,\n gTitles = globals.gTitles,\n gDims = globals.gDimensions;\n\n linkId = linkId.toLowerCase();\n\n if (!title) {\n title = '';\n }\n // Special case for explicit empty url\n if (wholeMatch.search(/\\(? ?(['\"].*['\"])?\\)$/m) > -1) {\n url = '';\n\n } else if (url === '' || url === null) {\n if (linkId === '' || linkId === null) {\n // lower-case and turn embedded newlines into spaces\n linkId = altText.toLowerCase().replace(/ ?\\n/g, ' ');\n }\n url = '#' + linkId;\n\n if (!showdown.helper.isUndefined(gUrls[linkId])) {\n url = gUrls[linkId];\n if (!showdown.helper.isUndefined(gTitles[linkId])) {\n title = gTitles[linkId];\n }\n if (!showdown.helper.isUndefined(gDims[linkId])) {\n width = gDims[linkId].width;\n height = gDims[linkId].height;\n }\n } else {\n return wholeMatch;\n }\n }\n\n altText = altText\n .replace(/\"/g, '"')\n //altText = showdown.helper.escapeCharacters(altText, '*_', false);\n .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);\n //url = showdown.helper.escapeCharacters(url, '*_', false);\n url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);\n var result = '\"'x \"optional title\")\n\n // base64 encoded images\n text = text.replace(base64RegExp, writeImageTagBase64);\n\n // cases with crazy urls like ./image/cat1).png\n text = text.replace(crazyRegExp, writeImageTag);\n\n // normal cases\n text = text.replace(inlineRegExp, writeImageTag);\n\n // handle reference-style shortcuts: ![img text]\n text = text.replace(refShortcutRegExp, writeImageTag);\n\n text = globals.converter._dispatch('images.after', text, options, globals);\n return text;\n});\n\r\nshowdown.subParser('italicsAndBold', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('italicsAndBold.before', text, options, globals);\n\n // it's faster to have 3 separate regexes for each case than have just one\n // because of backtracing, in some cases, it could lead to an exponential effect\n // called \"catastrophic backtrace\". Ominous!\n\n function parseInside (txt, left, right) {\n /*\n if (options.simplifiedAutoLink) {\n txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);\n }\n */\n return left + txt + right;\n }\n\n // Parse underscores\n if (options.literalMidWordUnderscores) {\n text = text.replace(/\\b___(\\S[\\s\\S]*?)___\\b/g, function (wm, txt) {\n return parseInside (txt, '', '');\n });\n text = text.replace(/\\b__(\\S[\\s\\S]*?)__\\b/g, function (wm, txt) {\n return parseInside (txt, '', '');\n });\n text = text.replace(/\\b_(\\S[\\s\\S]*?)_\\b/g, function (wm, txt) {\n return parseInside (txt, '', '');\n });\n } else {\n text = text.replace(/___(\\S[\\s\\S]*?)___/g, function (wm, m) {\n return (/\\S$/.test(m)) ? parseInside (m, '', '') : wm;\n });\n text = text.replace(/__(\\S[\\s\\S]*?)__/g, function (wm, m) {\n return (/\\S$/.test(m)) ? parseInside (m, '', '') : wm;\n });\n text = text.replace(/_([^\\s_][\\s\\S]*?)_/g, function (wm, m) {\n // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it)\n return (/\\S$/.test(m)) ? parseInside (m, '', '') : wm;\n });\n }\n\n // Now parse asterisks\n if (options.literalMidWordAsterisks) {\n text = text.replace(/([^*]|^)\\B\\*\\*\\*(\\S[\\s\\S]*?)\\*\\*\\*\\B(?!\\*)/g, function (wm, lead, txt) {\n return parseInside (txt, lead + '', '');\n });\n text = text.replace(/([^*]|^)\\B\\*\\*(\\S[\\s\\S]*?)\\*\\*\\B(?!\\*)/g, function (wm, lead, txt) {\n return parseInside (txt, lead + '', '');\n });\n text = text.replace(/([^*]|^)\\B\\*(\\S[\\s\\S]*?)\\*\\B(?!\\*)/g, function (wm, lead, txt) {\n return parseInside (txt, lead + '', '');\n });\n } else {\n text = text.replace(/\\*\\*\\*(\\S[\\s\\S]*?)\\*\\*\\*/g, function (wm, m) {\n return (/\\S$/.test(m)) ? parseInside (m, '', '') : wm;\n });\n text = text.replace(/\\*\\*(\\S[\\s\\S]*?)\\*\\*/g, function (wm, m) {\n return (/\\S$/.test(m)) ? parseInside (m, '', '') : wm;\n });\n text = text.replace(/\\*([^\\s*][\\s\\S]*?)\\*/g, function (wm, m) {\n // !/^\\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it)\n return (/\\S$/.test(m)) ? parseInside (m, '', '') : wm;\n });\n }\n\n\n text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Form HTML ordered (numbered) and unordered (bulleted) lists.\n */\nshowdown.subParser('lists', function (text, options, globals) {\n 'use strict';\n\n /**\n * Process the contents of a single ordered or unordered list, splitting it\n * into individual list items.\n * @param {string} listStr\n * @param {boolean} trimTrailing\n * @returns {string}\n */\n function processListItems (listStr, trimTrailing) {\n // The $g_list_level global keeps track of when we're inside a list.\n // Each time we enter a list, we increment it; when we leave a list,\n // we decrement. If it's zero, we're not in a list anymore.\n //\n // We do this because when we're not inside a list, we want to treat\n // something like this:\n //\n // I recommend upgrading to version\n // 8. Oops, now this line is treated\n // as a sub-list.\n //\n // As a single paragraph, despite the fact that the second line starts\n // with a digit-period-space sequence.\n //\n // Whereas when we're inside a list (or sub-list), that line will be\n // treated as the start of a sub-list. What a kludge, huh? This is\n // an aspect of Markdown's syntax that's hard to parse perfectly\n // without resorting to mind-reading. Perhaps the solution is to\n // change the syntax rules such that sub-lists must start with a\n // starting cardinal number; e.g. \"1.\" or \"a.\".\n globals.gListLevel++;\n\n // trim trailing blank lines:\n listStr = listStr.replace(/\\n{2,}$/, '\\n');\n\n // attacklab: add sentinel to emulate \\z\n listStr += '¨0';\n\n var rgx = /(\\n)?(^ {0,3})([*+-]|\\d+[.])[ \\t]+((\\[(x|X| )?])?[ \\t]*[^\\r]+?(\\n{1,2}))(?=\\n*(¨0| {0,3}([*+-]|\\d+[.])[ \\t]+))/gm,\n isParagraphed = (/\\n[ \\t]*\\n(?!¨0)/.test(listStr));\n\n // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation,\n // which is a syntax breaking change\n // activating this option reverts to old behavior\n if (options.disableForced4SpacesIndentedSublists) {\n rgx = /(\\n)?(^ {0,3})([*+-]|\\d+[.])[ \\t]+((\\[(x|X| )?])?[ \\t]*[^\\r]+?(\\n{1,2}))(?=\\n*(¨0|\\2([*+-]|\\d+[.])[ \\t]+))/gm;\n }\n\n listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {\n checked = (checked && checked.trim() !== '');\n\n var item = showdown.subParser('outdent')(m4, options, globals),\n bulletStyle = '';\n\n // Support for github tasklists\n if (taskbtn && options.tasklists) {\n bulletStyle = ' class=\"task-list-item\" style=\"list-style-type: none;\"';\n item = item.replace(/^[ \\t]*\\[(x|X| )?]/m, function () {\n var otp = '
  • a
  • \n // instead of:\n //
    • - - a
    \n // So, to prevent it, we will put a marker (¨A)in the beginning of the line\n // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser\n item = item.replace(/^([-*+]|\\d\\.)[ \\t]+[\\S\\n ]*/g, function (wm2) {\n return '¨A' + wm2;\n });\n\n // m1 - Leading line or\n // Has a double return (multi paragraph) or\n // Has sublist\n if (m1 || (item.search(/\\n{2,}/) > -1)) {\n item = showdown.subParser('githubCodeBlocks')(item, options, globals);\n item = showdown.subParser('blockGamut')(item, options, globals);\n } else {\n // Recursion for sub-lists:\n item = showdown.subParser('lists')(item, options, globals);\n item = item.replace(/\\n$/, ''); // chomp(item)\n item = showdown.subParser('hashHTMLBlocks')(item, options, globals);\n\n // Colapse double linebreaks\n item = item.replace(/\\n\\n+/g, '\\n\\n');\n if (isParagraphed) {\n item = showdown.subParser('paragraphs')(item, options, globals);\n } else {\n item = showdown.subParser('spanGamut')(item, options, globals);\n }\n }\n\n // now we need to remove the marker (¨A)\n item = item.replace('¨A', '');\n // we can finally wrap the line in list item tags\n item = '' + item + '\\n';\n\n return item;\n });\n\n // attacklab: strip sentinel\n listStr = listStr.replace(/¨0/g, '');\n\n globals.gListLevel--;\n\n if (trimTrailing) {\n listStr = listStr.replace(/\\s+$/, '');\n }\n\n return listStr;\n }\n\n function styleStartNumber (list, listType) {\n // check if ol and starts by a number different than 1\n if (listType === 'ol') {\n var res = list.match(/^ *(\\d+)\\./);\n if (res && res[1] !== '1') {\n return ' start=\"' + res[1] + '\"';\n }\n }\n return '';\n }\n\n /**\n * Check and parse consecutive lists (better fix for issue #142)\n * @param {string} list\n * @param {string} listType\n * @param {boolean} trimTrailing\n * @returns {string}\n */\n function parseConsecutiveLists (list, listType, trimTrailing) {\n // check if we caught 2 or more consecutive lists by mistake\n // we use the counterRgx, meaning if listType is UL we look for OL and vice versa\n var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\\d+\\.[ \\t]/gm : /^ {0,3}\\d+\\.[ \\t]/gm,\n ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \\t]/gm : /^ {0,3}[*+-][ \\t]/gm,\n counterRxg = (listType === 'ul') ? olRgx : ulRgx,\n result = '';\n\n if (list.search(counterRxg) !== -1) {\n (function parseCL (txt) {\n var pos = txt.search(counterRxg),\n style = styleStartNumber(list, listType);\n if (pos !== -1) {\n // slice\n result += '\\n\\n<' + listType + style + '>\\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '\\n';\n\n // invert counterType and listType\n listType = (listType === 'ul') ? 'ol' : 'ul';\n counterRxg = (listType === 'ul') ? olRgx : ulRgx;\n\n //recurse\n parseCL(txt.slice(pos));\n } else {\n result += '\\n\\n<' + listType + style + '>\\n' + processListItems(txt, !!trimTrailing) + '\\n';\n }\n })(list);\n } else {\n var style = styleStartNumber(list, listType);\n result = '\\n\\n<' + listType + style + '>\\n' + processListItems(list, !!trimTrailing) + '\\n';\n }\n\n return result;\n }\n\n /** Start of list parsing **/\n text = globals.converter._dispatch('lists.before', text, options, globals);\n // add sentinel to hack around khtml/safari bug:\n // http://bugs.webkit.org/show_bug.cgi?id=11231\n text += '¨0';\n\n if (globals.gListLevel) {\n text = text.replace(/^(( {0,3}([*+-]|\\d+[.])[ \\t]+)[^\\r]+?(¨0|\\n{2,}(?=\\S)(?![ \\t]*(?:[*+-]|\\d+[.])[ \\t]+)))/gm,\n function (wholeMatch, list, m2) {\n var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';\n return parseConsecutiveLists(list, listType, true);\n }\n );\n } else {\n text = text.replace(/(\\n\\n|^\\n?)(( {0,3}([*+-]|\\d+[.])[ \\t]+)[^\\r]+?(¨0|\\n{2,}(?=\\S)(?![ \\t]*(?:[*+-]|\\d+[.])[ \\t]+)))/gm,\n function (wholeMatch, m1, list, m3) {\n var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';\n return parseConsecutiveLists(list, listType, false);\n }\n );\n }\n\n // strip sentinel\n text = text.replace(/¨0/, '');\n text = globals.converter._dispatch('lists.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Parse metadata at the top of the document\n */\nshowdown.subParser('metadata', function (text, options, globals) {\n 'use strict';\n\n if (!options.metadata) {\n return text;\n }\n\n text = globals.converter._dispatch('metadata.before', text, options, globals);\n\n function parseMetadataContents (content) {\n // raw is raw so it's not changed in any way\n globals.metadata.raw = content;\n\n // escape chars forbidden in html attributes\n // double quotes\n content = content\n // ampersand first\n .replace(/&/g, '&')\n // double quotes\n .replace(/\"/g, '"');\n\n content = content.replace(/\\n {4}/g, ' ');\n content.replace(/^([\\S ]+): +([\\s\\S]+?)$/gm, function (wm, key, value) {\n globals.metadata.parsed[key] = value;\n return '';\n });\n }\n\n text = text.replace(/^\\s*«««+(\\S*?)\\n([\\s\\S]+?)\\n»»»+\\n/, function (wholematch, format, content) {\n parseMetadataContents(content);\n return '¨M';\n });\n\n text = text.replace(/^\\s*---+(\\S*?)\\n([\\s\\S]+?)\\n---+\\n/, function (wholematch, format, content) {\n if (format) {\n globals.metadata.format = format;\n }\n parseMetadataContents(content);\n return '¨M';\n });\n\n text = text.replace(/¨M/g, '');\n\n text = globals.converter._dispatch('metadata.after', text, options, globals);\n return text;\n});\n\r\n/**\n * Remove one level of line-leading tabs or spaces\n */\nshowdown.subParser('outdent', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('outdent.before', text, options, globals);\n\n // attacklab: hack around Konqueror 3.5.4 bug:\n // \"----------bug\".replace(/^-/g,\"\") == \"bug\"\n text = text.replace(/^(\\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width\n\n // attacklab: clean up hack\n text = text.replace(/¨0/g, '');\n\n text = globals.converter._dispatch('outdent.after', text, options, globals);\n return text;\n});\n\r\n/**\n *\n */\nshowdown.subParser('paragraphs', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('paragraphs.before', text, options, globals);\n // Strip leading and trailing lines:\n text = text.replace(/^\\n+/g, '');\n text = text.replace(/\\n+$/g, '');\n\n var grafs = text.split(/\\n{2,}/g),\n grafsOut = [],\n end = grafs.length; // Wrap

    tags\n\n for (var i = 0; i < end; i++) {\n var str = grafs[i];\n // if this is an HTML marker, copy it\n if (str.search(/¨(K|G)(\\d+)\\1/g) >= 0) {\n grafsOut.push(str);\n\n // test for presence of characters to prevent empty lines being parsed\n // as paragraphs (resulting in undesired extra empty paragraphs)\n } else if (str.search(/\\S/) >= 0) {\n str = showdown.subParser('spanGamut')(str, options, globals);\n str = str.replace(/^([ \\t]*)/g, '

    ');\n str += '

    ';\n grafsOut.push(str);\n }\n }\n\n /** Unhashify HTML blocks */\n end = grafsOut.length;\n for (i = 0; i < end; i++) {\n var blockText = '',\n grafsOutIt = grafsOut[i],\n codeFlag = false;\n // if this is a marker for an html block...\n // use RegExp.test instead of string.search because of QML bug\n while (/¨(K|G)(\\d+)\\1/.test(grafsOutIt)) {\n var delim = RegExp.$1,\n num = RegExp.$2;\n\n if (delim === 'K') {\n blockText = globals.gHtmlBlocks[num];\n } else {\n // we need to check if ghBlock is a false positive\n if (codeFlag) {\n // use encoded version of all text\n blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals);\n } else {\n blockText = globals.ghCodeBlocks[num].codeblock;\n }\n }\n blockText = blockText.replace(/\\$/g, '$$$$'); // Escape any dollar signs\n\n grafsOutIt = grafsOutIt.replace(/(\\n\\n)?¨(K|G)\\d+\\2(\\n\\n)?/, blockText);\n // Check if grafsOutIt is a pre->code\n if (/^]*>\\s*]*>/.test(grafsOutIt)) {\n codeFlag = true;\n }\n }\n grafsOut[i] = grafsOutIt;\n }\n text = grafsOut.join('\\n');\n // Strip leading and trailing lines:\n text = text.replace(/^\\n+/g, '');\n text = text.replace(/\\n+$/g, '');\n return globals.converter._dispatch('paragraphs.after', text, options, globals);\n});\n\r\n/**\n * Run extension\n */\nshowdown.subParser('runExtension', function (ext, text, options, globals) {\n 'use strict';\n\n if (ext.filter) {\n text = ext.filter(text, globals.converter, options);\n\n } else if (ext.regex) {\n // TODO remove this when old extension loading mechanism is deprecated\n var re = ext.regex;\n if (!(re instanceof RegExp)) {\n re = new RegExp(re, 'g');\n }\n text = text.replace(re, ext.replace);\n }\n\n return text;\n});\n\r\n/**\n * These are all the transformations that occur *within* block-level\n * tags like paragraphs, headers, and list items.\n */\nshowdown.subParser('spanGamut', function (text, options, globals) {\n 'use strict';\n\n text = globals.converter._dispatch('spanGamut.before', text, options, globals);\n text = showdown.subParser('codeSpans')(text, options, globals);\n text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals);\n text = showdown.subParser('encodeBackslashEscapes')(text, options, globals);\n\n // Process anchor and image tags. Images must come first,\n // because ![foo][f] looks like an anchor.\n text = showdown.subParser('images')(text, options, globals);\n text = showdown.subParser('anchors')(text, options, globals);\n\n // Make links out of things like ``\n // Must come after anchors, because you can use < and >\n // delimiters in inline links like [this]().\n text = showdown.subParser('autoLinks')(text, options, globals);\n text = showdown.subParser('simplifiedAutoLinks')(text, options, globals);\n text = showdown.subParser('emoji')(text, options, globals);\n text = showdown.subParser('underline')(text, options, globals);\n text = showdown.subParser('italicsAndBold')(text, options, globals);\n text = showdown.subParser('strikethrough')(text, options, globals);\n text = showdown.subParser('ellipsis')(text, options, globals);\n\n // we need to hash HTML tags inside spans\n text = showdown.subParser('hashHTMLSpans')(text, options, globals);\n\n // now we encode amps and angles\n text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals);\n\n // Do hard breaks\n if (options.simpleLineBreaks) {\n // GFM style hard breaks\n // only add line breaks if the text does not contain a block (special case for lists)\n if (!/\\n\\n¨K/.test(text)) {\n text = text.replace(/\\n+/g, '
    \\n');\n }\n } else {\n // Vanilla hard breaks\n text = text.replace(/ +\\n/g, '
    \\n');\n }\n\n text = globals.converter._dispatch('spanGamut.after', text, options, globals);\n return text;\n});\n\r\nshowdown.subParser('strikethrough', function (text, options, globals) {\n 'use strict';\n\n function parseInside (txt) {\n if (options.simplifiedAutoLink) {\n txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);\n }\n return '' + txt + '';\n }\n\n if (options.strikethrough) {\n text = globals.converter._dispatch('strikethrough.before', text, options, globals);\n text = text.replace(/(?:~){2}([\\s\\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); });\n text = globals.converter._dispatch('strikethrough.after', text, options, globals);\n }\n\n return text;\n});\n\r\n/**\n * Strips link definitions from text, stores the URLs and titles in\n * hash references.\n * Link defs are in the form: ^[id]: url \"optional title\"\n */\nshowdown.subParser('stripLinkDefinitions', function (text, options, globals) {\n 'use strict';\n\n var regex = /^ {0,3}\\[(.+)]:[ \\t]*\\n?[ \\t]*\\s]+)>?(?: =([*\\d]+[A-Za-z%]{0,4})x([*\\d]+[A-Za-z%]{0,4}))?[ \\t]*\\n?[ \\t]*(?:(\\n*)[\"|'(](.+?)[\"|')][ \\t]*)?(?:\\n+|(?=¨0))/gm,\n base64Regex = /^ {0,3}\\[(.+)]:[ \\t]*\\n?[ \\t]*?(?: =([*\\d]+[A-Za-z%]{0,4})x([*\\d]+[A-Za-z%]{0,4}))?[ \\t]*\\n?[ \\t]*(?:(\\n*)[\"|'(](.+?)[\"|')][ \\t]*)?(?:\\n\\n|(?=¨0)|(?=\\n\\[))/gm;\n\n // attacklab: sentinel workarounds for lack of \\A and \\Z, safari\\khtml bug\n text += '¨0';\n\n var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) {\n linkId = linkId.toLowerCase();\n if (url.match(/^data:.+?\\/.+?;base64,/)) {\n // remove newlines\n globals.gUrls[linkId] = url.replace(/\\s/g, '');\n } else {\n globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive\n }\n\n if (blankLines) {\n // Oops, found blank lines, so it's not a title.\n // Put back the parenthetical statement we stole.\n return blankLines + title;\n\n } else {\n if (title) {\n globals.gTitles[linkId] = title.replace(/\"|'/g, '"');\n }\n if (options.parseImgDimensions && width && height) {\n globals.gDimensions[linkId] = {\n width: width,\n height: height\n };\n }\n }\n // Completely remove the definition from the text\n return '';\n };\n\n // first we try to find base64 link references\n text = text.replace(base64Regex, replaceFunc);\n\n text = text.replace(regex, replaceFunc);\n\n // attacklab: strip sentinel\n text = text.replace(/¨0/, '');\n\n return text;\n});\n\r\nshowdown.subParser('tables', function (text, options, globals) {\n 'use strict';\n\n if (!options.tables) {\n return text;\n }\n\n var tableRgx = /^ {0,3}\\|?.+\\|.+\\n {0,3}\\|?[ \\t]*:?[ \\t]*(?:[-=]){2,}[ \\t]*:?[ \\t]*\\|[ \\t]*:?[ \\t]*(?:[-=]){2,}[\\s\\S]+?(?:\\n\\n|¨0)/gm,\n //singeColTblRgx = /^ {0,3}\\|.+\\|\\n {0,3}\\|[ \\t]*:?[ \\t]*(?:[-=]){2,}[ \\t]*:?[ \\t]*\\|[ \\t]*\\n(?: {0,3}\\|.+\\|\\n)+(?:\\n\\n|¨0)/gm;\n singeColTblRgx = /^ {0,3}\\|.+\\|[ \\t]*\\n {0,3}\\|[ \\t]*:?[ \\t]*(?:[-=]){2,}[ \\t]*:?[ \\t]*\\|[ \\t]*\\n( {0,3}\\|.+\\|[ \\t]*\\n)*(?:\\n|¨0)/gm;\n\n function parseStyles (sLine) {\n if (/^:[ \\t]*--*$/.test(sLine)) {\n return ' style=\"text-align:left;\"';\n } else if (/^--*[ \\t]*:[ \\t]*$/.test(sLine)) {\n return ' style=\"text-align:right;\"';\n } else if (/^:[ \\t]*--*[ \\t]*:$/.test(sLine)) {\n return ' style=\"text-align:center;\"';\n } else {\n return '';\n }\n }\n\n function parseHeaders (header, style) {\n var id = '';\n header = header.trim();\n // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility\n if (options.tablesHeaderId || options.tableHeaderId) {\n id = ' id=\"' + header.replace(/ /g, '_').toLowerCase() + '\"';\n }\n header = showdown.subParser('spanGamut')(header, options, globals);\n\n return '' + header + '\\n';\n }\n\n function parseCells (cell, style) {\n var subText = showdown.subParser('spanGamut')(cell, options, globals);\n return '' + subText + '\\n';\n }\n\n function buildTable (headers, cells) {\n var tb = '\\n\\n\\n',\n tblLgn = headers.length;\n\n for (var i = 0; i < tblLgn; ++i) {\n tb += headers[i];\n }\n tb += '\\n\\n\\n';\n\n for (i = 0; i < cells.length; ++i) {\n tb += '\\n';\n for (var ii = 0; ii < tblLgn; ++ii) {\n tb += cells[i][ii];\n }\n tb += '\\n';\n }\n tb += '\\n
    \\n';\n return tb;\n }\n\n function parseTable (rawTable) {\n var i, tableLines = rawTable.split('\\n');\n\n for (i = 0; i < tableLines.length; ++i) {\n // strip wrong first and last column if wrapped tables are used\n if (/^ {0,3}\\|/.test(tableLines[i])) {\n tableLines[i] = tableLines[i].replace(/^ {0,3}\\|/, '');\n }\n if (/\\|[ \\t]*$/.test(tableLines[i])) {\n tableLines[i] = tableLines[i].replace(/\\|[ \\t]*$/, '');\n }\n // parse code spans first, but we only support one line code spans\n tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals);\n }\n\n var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}),\n rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}),\n rawCells = [],\n headers = [],\n styles = [],\n cells = [];\n\n tableLines.shift();\n tableLines.shift();\n\n for (i = 0; i < tableLines.length; ++i) {\n if (tableLines[i].trim() === '') {\n continue;\n }\n rawCells.push(\n tableLines[i]\n .split('|')\n .map(function (s) {\n return s.trim();\n })\n );\n }\n\n if (rawHeaders.length < rawStyles.length) {\n return rawTable;\n }\n\n for (i = 0; i < rawStyles.length; ++i) {\n styles.push(parseStyles(rawStyles[i]));\n }\n\n for (i = 0; i < rawHeaders.length; ++i) {\n if (showdown.helper.isUndefined(styles[i])) {\n styles[i] = '';\n }\n headers.push(parseHeaders(rawHeaders[i], styles[i]));\n }\n\n for (i = 0; i < rawCells.length; ++i) {\n var row = [];\n for (var ii = 0; ii < headers.length; ++ii) {\n if (showdown.helper.isUndefined(rawCells[i][ii])) {\n\n }\n row.push(parseCells(rawCells[i][ii], styles[ii]));\n }\n cells.push(row);\n }\n\n return buildTable(headers, cells);\n }\n\n text = globals.converter._dispatch('tables.before', text, options, globals);\n\n // find escaped pipe characters\n text = text.replace(/\\\\(\\|)/g, showdown.helper.escapeCharactersCallback);\n\n // parse multi column tables\n text = text.replace(tableRgx, parseTable);\n\n // parse one column tables\n text = text.replace(singeColTblRgx, parseTable);\n\n text = globals.converter._dispatch('tables.after', text, options, globals);\n\n return text;\n});\n\r\nshowdown.subParser('underline', function (text, options, globals) {\n 'use strict';\n\n if (!options.underline) {\n return text;\n }\n\n text = globals.converter._dispatch('underline.before', text, options, globals);\n\n if (options.literalMidWordUnderscores) {\n text = text.replace(/\\b___(\\S[\\s\\S]*?)___\\b/g, function (wm, txt) {\n return '' + txt + '';\n });\n text = text.replace(/\\b__(\\S[\\s\\S]*?)__\\b/g, function (wm, txt) {\n return '' + txt + '';\n });\n } else {\n text = text.replace(/___(\\S[\\s\\S]*?)___/g, function (wm, m) {\n return (/\\S$/.test(m)) ? '' + m + '' : wm;\n });\n text = text.replace(/__(\\S[\\s\\S]*?)__/g, function (wm, m) {\n return (/\\S$/.test(m)) ? '' + m + '' : wm;\n });\n }\n\n // escape remaining underscores to prevent them being parsed by italic and bold\n text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback);\n\n text = globals.converter._dispatch('underline.after', text, options, globals);\n\n return text;\n});\n\r\n/**\n * Swap back in all the special characters we've hidden.\n */\nshowdown.subParser('unescapeSpecialChars', function (text, options, globals) {\n 'use strict';\n text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals);\n\n text = text.replace(/¨E(\\d+)E/g, function (wholeMatch, m1) {\n var charCodeToReplace = parseInt(m1);\n return String.fromCharCode(charCodeToReplace);\n });\n\n text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals);\n return text;\n});\n\r\nshowdown.subParser('makeMarkdown.blockquote', function (node, globals) {\n 'use strict';\n\n var txt = '';\n if (node.hasChildNodes()) {\n var children = node.childNodes,\n childrenLength = children.length;\n\n for (var i = 0; i < childrenLength; ++i) {\n var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals);\n\n if (innerTxt === '') {\n continue;\n }\n txt += innerTxt;\n }\n }\n // cleanup\n txt = txt.trim();\n txt = '> ' + txt.split('\\n').join('\\n> ');\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.codeBlock', function (node, globals) {\n 'use strict';\n\n var lang = node.getAttribute('language'),\n num = node.getAttribute('precodenum');\n return '```' + lang + '\\n' + globals.preList[num] + '\\n```';\n});\n\r\nshowdown.subParser('makeMarkdown.codeSpan', function (node) {\n 'use strict';\n\n return '`' + node.innerHTML + '`';\n});\n\r\nshowdown.subParser('makeMarkdown.emphasis', function (node, globals) {\n 'use strict';\n\n var txt = '';\n if (node.hasChildNodes()) {\n txt += '*';\n var children = node.childNodes,\n childrenLength = children.length;\n for (var i = 0; i < childrenLength; ++i) {\n txt += showdown.subParser('makeMarkdown.node')(children[i], globals);\n }\n txt += '*';\n }\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) {\n 'use strict';\n\n var headerMark = new Array(headerLevel + 1).join('#'),\n txt = '';\n\n if (node.hasChildNodes()) {\n txt = headerMark + ' ';\n var children = node.childNodes,\n childrenLength = children.length;\n\n for (var i = 0; i < childrenLength; ++i) {\n txt += showdown.subParser('makeMarkdown.node')(children[i], globals);\n }\n }\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.hr', function () {\n 'use strict';\n\n return '---';\n});\n\r\nshowdown.subParser('makeMarkdown.image', function (node) {\n 'use strict';\n\n var txt = '';\n if (node.hasAttribute('src')) {\n txt += '![' + node.getAttribute('alt') + '](';\n txt += '<' + node.getAttribute('src') + '>';\n if (node.hasAttribute('width') && node.hasAttribute('height')) {\n txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height');\n }\n\n if (node.hasAttribute('title')) {\n txt += ' \"' + node.getAttribute('title') + '\"';\n }\n txt += ')';\n }\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.links', function (node, globals) {\n 'use strict';\n\n var txt = '';\n if (node.hasChildNodes() && node.hasAttribute('href')) {\n var children = node.childNodes,\n childrenLength = children.length;\n txt = '[';\n for (var i = 0; i < childrenLength; ++i) {\n txt += showdown.subParser('makeMarkdown.node')(children[i], globals);\n }\n txt += '](';\n txt += '<' + node.getAttribute('href') + '>';\n if (node.hasAttribute('title')) {\n txt += ' \"' + node.getAttribute('title') + '\"';\n }\n txt += ')';\n }\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.list', function (node, globals, type) {\n 'use strict';\n\n var txt = '';\n if (!node.hasChildNodes()) {\n return '';\n }\n var listItems = node.childNodes,\n listItemsLenght = listItems.length,\n listNum = node.getAttribute('start') || 1;\n\n for (var i = 0; i < listItemsLenght; ++i) {\n if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') {\n continue;\n }\n\n // define the bullet to use in list\n var bullet = '';\n if (type === 'ol') {\n bullet = listNum.toString() + '. ';\n } else {\n bullet = '- ';\n }\n\n // parse list item\n txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals);\n ++listNum;\n }\n\n // add comment at the end to prevent consecutive lists to be parsed as one\n txt += '\\n\\n';\n return txt.trim();\n});\n\r\nshowdown.subParser('makeMarkdown.listItem', function (node, globals) {\n 'use strict';\n\n var listItemTxt = '';\n\n var children = node.childNodes,\n childrenLenght = children.length;\n\n for (var i = 0; i < childrenLenght; ++i) {\n listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals);\n }\n // if it's only one liner, we need to add a newline at the end\n if (!/\\n$/.test(listItemTxt)) {\n listItemTxt += '\\n';\n } else {\n // it's multiparagraph, so we need to indent\n listItemTxt = listItemTxt\n .split('\\n')\n .join('\\n ')\n .replace(/^ {4}$/gm, '')\n .replace(/\\n\\n+/g, '\\n\\n');\n }\n\n return listItemTxt;\n});\n\r\n\n\nshowdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) {\n 'use strict';\n\n spansOnly = spansOnly || false;\n\n var txt = '';\n\n // edge case of text without wrapper paragraph\n if (node.nodeType === 3) {\n return showdown.subParser('makeMarkdown.txt')(node, globals);\n }\n\n // HTML comment\n if (node.nodeType === 8) {\n return '\\n\\n';\n }\n\n // process only node elements\n if (node.nodeType !== 1) {\n return '';\n }\n\n var tagName = node.tagName.toLowerCase();\n\n switch (tagName) {\n\n //\n // BLOCKS\n //\n case 'h1':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\\n\\n'; }\n break;\n case 'h2':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\\n\\n'; }\n break;\n case 'h3':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\\n\\n'; }\n break;\n case 'h4':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\\n\\n'; }\n break;\n case 'h5':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\\n\\n'; }\n break;\n case 'h6':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\\n\\n'; }\n break;\n\n case 'p':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\\n\\n'; }\n break;\n\n case 'blockquote':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\\n\\n'; }\n break;\n\n case 'hr':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\\n\\n'; }\n break;\n\n case 'ol':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\\n\\n'; }\n break;\n\n case 'ul':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\\n\\n'; }\n break;\n\n case 'precode':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\\n\\n'; }\n break;\n\n case 'pre':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\\n\\n'; }\n break;\n\n case 'table':\n if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\\n\\n'; }\n break;\n\n //\n // SPANS\n //\n case 'code':\n txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals);\n break;\n\n case 'em':\n case 'i':\n txt = showdown.subParser('makeMarkdown.emphasis')(node, globals);\n break;\n\n case 'strong':\n case 'b':\n txt = showdown.subParser('makeMarkdown.strong')(node, globals);\n break;\n\n case 'del':\n txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals);\n break;\n\n case 'a':\n txt = showdown.subParser('makeMarkdown.links')(node, globals);\n break;\n\n case 'img':\n txt = showdown.subParser('makeMarkdown.image')(node, globals);\n break;\n\n default:\n txt = node.outerHTML + '\\n\\n';\n }\n\n // common normalization\n // TODO eventually\n\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.paragraph', function (node, globals) {\n 'use strict';\n\n var txt = '';\n if (node.hasChildNodes()) {\n var children = node.childNodes,\n childrenLength = children.length;\n for (var i = 0; i < childrenLength; ++i) {\n txt += showdown.subParser('makeMarkdown.node')(children[i], globals);\n }\n }\n\n // some text normalization\n txt = txt.trim();\n\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.pre', function (node, globals) {\n 'use strict';\n\n var num = node.getAttribute('prenum');\n return '
    ' + globals.preList[num] + '
    ';\n});\n\r\nshowdown.subParser('makeMarkdown.strikethrough', function (node, globals) {\n 'use strict';\n\n var txt = '';\n if (node.hasChildNodes()) {\n txt += '~~';\n var children = node.childNodes,\n childrenLength = children.length;\n for (var i = 0; i < childrenLength; ++i) {\n txt += showdown.subParser('makeMarkdown.node')(children[i], globals);\n }\n txt += '~~';\n }\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.strong', function (node, globals) {\n 'use strict';\n\n var txt = '';\n if (node.hasChildNodes()) {\n txt += '**';\n var children = node.childNodes,\n childrenLength = children.length;\n for (var i = 0; i < childrenLength; ++i) {\n txt += showdown.subParser('makeMarkdown.node')(children[i], globals);\n }\n txt += '**';\n }\n return txt;\n});\n\r\nshowdown.subParser('makeMarkdown.table', function (node, globals) {\n 'use strict';\n\n var txt = '',\n tableArray = [[], []],\n headings = node.querySelectorAll('thead>tr>th'),\n rows = node.querySelectorAll('tbody>tr'),\n i, ii;\n for (i = 0; i < headings.length; ++i) {\n var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals),\n allign = '---';\n\n if (headings[i].hasAttribute('style')) {\n var style = headings[i].getAttribute('style').toLowerCase().replace(/\\s/g, '');\n switch (style) {\n case 'text-align:left;':\n allign = ':---';\n break;\n case 'text-align:right;':\n allign = '---:';\n break;\n case 'text-align:center;':\n allign = ':---:';\n break;\n }\n }\n tableArray[0][i] = headContent.trim();\n tableArray[1][i] = allign;\n }\n\n for (i = 0; i < rows.length; ++i) {\n var r = tableArray.push([]) - 1,\n cols = rows[i].getElementsByTagName('td');\n\n for (ii = 0; ii < headings.length; ++ii) {\n var cellContent = ' ';\n if (typeof cols[ii] !== 'undefined') {\n cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals);\n }\n tableArray[r].push(cellContent);\n }\n }\n\n var cellSpacesCount = 3;\n for (i = 0; i < tableArray.length; ++i) {\n for (ii = 0; ii < tableArray[i].length; ++ii) {\n var strLen = tableArray[i][ii].length;\n if (strLen > cellSpacesCount) {\n cellSpacesCount = strLen;\n }\n }\n }\n\n for (i = 0; i < tableArray.length; ++i) {\n for (ii = 0; ii < tableArray[i].length; ++ii) {\n if (i === 1) {\n if (tableArray[i][ii].slice(-1) === ':') {\n tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':';\n } else {\n tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-');\n }\n } else {\n tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount);\n }\n }\n txt += '| ' + tableArray[i].join(' | ') + ' |\\n';\n }\n\n return txt.trim();\n});\n\r\nshowdown.subParser('makeMarkdown.tableCell', function (node, globals) {\n 'use strict';\n\n var txt = '';\n if (!node.hasChildNodes()) {\n return '';\n }\n var children = node.childNodes,\n childrenLength = children.length;\n\n for (var i = 0; i < childrenLength; ++i) {\n txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true);\n }\n return txt.trim();\n});\n\r\nshowdown.subParser('makeMarkdown.txt', function (node) {\n 'use strict';\n\n var txt = node.nodeValue;\n\n // multiple spaces are collapsed\n txt = txt.replace(/ +/g, ' ');\n\n // replace the custom ¨NBSP; with a space\n txt = txt.replace(/¨NBSP;/g, ' ');\n\n // \", <, > and & should replace escaped html entities\n txt = showdown.helper.unescapeHTMLEntities(txt);\n\n // escape markdown magic characters\n // emphasis, strong and strikethrough - can appear everywhere\n // we also escape pipe (|) because of tables\n // and escape ` because of code blocks and spans\n txt = txt.replace(/([*_~|`])/g, '\\\\$1');\n\n // escape > because of blockquotes\n txt = txt.replace(/^(\\s*)>/g, '\\\\$1>');\n\n // hash character, only troublesome at the beginning of a line because of headers\n txt = txt.replace(/^#/gm, '\\\\#');\n\n // horizontal rules\n txt = txt.replace(/^(\\s*)([-=]{3,})(\\s*)$/, '$1\\\\$2$3');\n\n // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer\n txt = txt.replace(/^( {0,3}\\d+)\\./gm, '$1\\\\.');\n\n // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped)\n txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\\\$2');\n\n // images and links, ] followed by ( is problematic, so we escape it\n txt = txt.replace(/]([\\s]*)\\(/g, '\\\\]$1\\\\(');\n\n // reference URIs must also be escaped\n txt = txt.replace(/^ {0,3}\\[([\\S \\t]*?)]:/gm, '\\\\[$1]:');\n\n return txt;\n});\n\r\nvar root = this;\n\n// AMD Loader\nif (typeof define === 'function' && define.amd) {\n define(function () {\n 'use strict';\n return showdown;\n });\n\n// CommonJS/nodeJS Loader\n} else if (typeof module !== 'undefined' && module.exports) {\n module.exports = showdown;\n\n// Regular Browser loader\n} else {\n root.showdown = showdown;\n}\n}).call(this);\r\n\n//# sourceMappingURL=showdown.js.map\r\n","import { getBasicAuthHeader } from './basic';\nimport { getBearerAuthHeader } from './bearer';\nimport { getOAuth1Header } from './oauth1';\nimport { getOAuth2Header } from './oauth2';\nimport { getHawkAuthHeader } from './hawk';\nimport { getNTLMAuthHeader } from './ntlm';\nimport { getASAPHeader } from './asap';\n\nfunction getDefaultAuthHeader() {\n return {\n name: 'Authorization',\n value: '{{authorization}}'\n };\n}\n\nexport default function generateAuthHeader(auth) {\n switch (auth.type) {\n case 'basic':\n return getBasicAuthHeader(auth.username, auth.password);\n case 'bearer':\n return getBearerAuthHeader(auth.token, auth.prefix);\n case 'oauth1':\n return getOAuth1Header(auth);\n case 'oauth2':\n return getOAuth2Header();\n case 'hawk':\n return getHawkAuthHeader(auth.id);\n case 'ntlm':\n return getNTLMAuthHeader();\n case 'asap':\n return getASAPHeader();\n default:\n return getDefaultAuthHeader();\n }\n};\n","export function getBasicAuthHeader(username = null, password = null) {\n const header = `${username || ''}:${password || ''}`;\n const authString = btoa(header); // eslint-disable-line no-undef\n\n return {\n name: 'Authorization',\n value: `Basic ${authString}`\n };\n};\n","export function getBearerAuthHeader(token, prefix) {\n return {\n name: 'Authorization',\n value: `${prefix || 'Bearer'} ${token}`\n };\n};\n","export function getOAuth1Header(opts) {\n const {\n callback,\n consumerKey,\n nonce,\n signatureMethod,\n timestamp,\n tokenKey\n } = opts;\n\n const value = `OAuth oauth_callback=\"${callback}\",\noauth_consumer_key=\"${consumerKey}\",\noauth_nonce=\"${nonce || '{{oauth_nonce}}'}\",\noauth_signature=\"{{oauth_signature}}\",\noauth_signature_method=\"${signatureMethod}\",\noauth_timestamp=\"${timestamp || 1103493600}\",\noauth_token=\"${tokenKey}\",\noauth_version=\"1.0\"`.split('\\n').join(' ');\n\n return {\n name: 'Authorization',\n value\n };\n};\n","// WIP.\n\nexport function getOAuth2Header() {\n return {\n name: 'Authorization',\n value: 'OAuth {{params}}, oauth_version=\"2.0\"'\n };\n};\n","export function getHawkAuthHeader(id) {\n return {\n name: 'Authorization',\n value: `Hawk id=\"${id}\", ts=\"1103493600\", nonce=\"{{hawk_nonce}}\", mac=\"{{hawk_mac}}\"`\n };\n};\n","export function getNTLMAuthHeader() {\n return {\n name: 'Authorization',\n value: 'NTLM {{ntlm_token}}'\n };\n};\n","export function getASAPHeader() {\n return {\n name: 'Authorization',\n value: 'Bearer {{jwt_token}}'\n };\n};\n","export default function parseUrlWithParams(url, req) {\n const params = req.parameters;\n\n if (!params || !params.length) {\n return url;\n }\n\n url = `${url}?`;\n\n url += params.filter(param => !param.disabled).map(param => {\n return `${encodeURIComponent(param.name)}=${encodeURIComponent(param.value)}`;\n }).join('&');\n\n return url;\n};\n","export default function (str) {\n return JSON.stringify(str).slice(1, -1);\n}\n","import buildUrl from '../helpers/buildUrl';\nimport escape from '../helpers/escape';\n\nexport default function curl(url, req) {\n let code = `curl \"${buildUrl(url, req)}\" \\\\\\n`;\n\n req.headers.forEach(header => {\n code += ` -H '${header.name}: ${header.value || ''}' \\\\\\n`;\n });\n\n if (req.authHeader) {\n code += ` -H '${req.authHeader.name}: ${escape(req.authHeader.value || '')}' \\\\\\n`;\n }\n\n code += ` -X ${req.method} \\\\\\n`;\n\n if (req.cookies && req.cookies.length) {\n req.cookies.forEach(cookie => {\n code += ` -b '${cookie.key}'='${cookie.value}' \\\\\\n`;\n });\n }\n\n if (req.body && req.body.params && req.body.params.length) {\n req.body.params.forEach(param => {\n if (param.value === null) {\n return false;\n }\n\n if (param.value.indexOf('\\'') >= 0 && param.value.indexOf('\"') >= 0) {\n code += ` -F \"${param.name}=${param.value.replace('\"', '\\\\\"')}\"`;\n } else if (param.value.indexOf('\\'') >= 0) {\n code += ` -F \"${param.name}=${param.value}\"`;\n } else if (param.value.indexOf('\"') >= 0) {\n code += ` -F '${param.name}=${param.value}'`;\n } else {\n code += ` -F '${param.name}=${param.value}'`;\n }\n code += ' \\\\\\n';\n });\n }\n\n if (req.body && req.body.text) {\n code += ` -d '${req.body.text.replace(/\\t/g, ' ')}' \\\\\\n`;\n }\n\n return code.slice(0, -2);\n};\n","import buildUrl from '../helpers/buildUrl';\n\nfunction parseBody(mime, body) {\n if (mime === 'application/json' && body.text) {\n return JSON.parse(body.text);\n }\n\n if (mime === 'application/x-www-form-urlencoded') {\n return body.params.map(p => `${encodeURIComponent(p.name)}=${encodeURIComponent(p.value)}`).join('&');\n }\n\n // xml to JS object conversion to be added\n\n return body.text;\n}\n\nexport default function javascript(url, req) {\n let code = '';\n let hasForm = false;\n\n if (req.body && req.body.mimeType === 'multipart/form-data') {\n hasForm = true;\n\n code += 'const form = new FormData();\\n';\n\n req.body.params.forEach(param => {\n code += `form.append(\"${param.name}\", \"${param.value}\");\\n`;\n });\n\n code += '\\n';\n }\n\n code += `fetch(\"${buildUrl(url, req)}\", `;\n\n const opts = {\n method: req.method\n };\n\n if (req.headers && req.headers.length) {\n opts.headers = {};\n\n req.headers.forEach(header => {\n opts.headers[header.name] = header.value;\n });\n }\n\n if (req.authHeader) {\n if (!opts.headers) {\n opts.headers = {};\n }\n\n opts.headers[req.authHeader.name] = req.authHeader.value;\n }\n\n if (req.cookies && req.cookies.length) {\n if (!opts.headers) {\n opts.headers = {};\n }\n\n opts.headers.cookie = req.cookies.map(cookie => `${encodeURIComponent(cookie.key)}=${encodeURIComponent(cookie.value)}`).join('; ');\n }\n\n if (!hasForm && req.body && req.body.mimeType !== 'multipart/form-data') {\n opts.body = parseBody(req.body.mimeType, req.body);\n }\n\n if (hasForm) {\n opts.body = '{{formVariable}}';\n }\n\n code += JSON.stringify(opts, null, 2);\n\n if (hasForm) {\n code = code.replace('\"{{formVariable}}\"', 'form');\n }\n\n code += ')\\n .then(response => console.log(response))\\n';\n code += ' .catch(err => console.error(err));';\n\n return code;\n};\n","function parseBody(body) {\n const mime = body.mimeType;\n\n if (mime === 'application/x-www-form-urlencoded') {\n return `payload = ${body.params.map(p => `${encodeURIComponent(p.name)}=${encodeURIComponent(p.value)}`).join('&')}`;\n }\n\n if (mime === 'multipart/form-data') {\n const payload = {};\n const files = {};\n body.params.forEach(p => {\n if (p.type === 'file') {\n files[p.name] = p.value;\n } else {\n payload[p.name] = p.value;\n }\n });\n\n return `payload = ${JSON.stringify(payload, null, 2)}\\n\\nfiles = ${JSON.stringify(files, null, 2)}`;\n }\n\n if (mime === 'application/json' && body.text) {\n return `payload = ${JSON.stringify(JSON.parse(body.text), null, 2)}`;\n }\n\n return body.text\n ? `payload = '${body.text}'`\n : null;\n}\n\nexport default function python(url, req) {\n let code = 'import requests\\n\\n';\n code += `url = '${url}'\\n`;\n\n if (req.parameters && req.parameters.length) {\n const params = {};\n req.parameters.forEach(p => {\n params[p.name] = p.value;\n });\n code += `querystring = ${JSON.stringify(params)}\\n`;\n }\n\n const headers = {};\n\n if (req.authHeader) {\n headers[req.authHeader.name] = req.authHeader.value;\n }\n\n if (req.headers && req.headers.length) {\n req.headers.forEach(h => {\n headers[h.name] = h.value;\n });\n }\n\n if (req.cookies && req.cookies.length) {\n headers.cookie = req.cookies.map(cookie => `${encodeURIComponent(cookie.key)}=${encodeURIComponent(cookie.value)}`).join('; ');\n }\n\n if (headers) {\n code += `headers = ${JSON.stringify(headers, null, 2)}\\n`;\n }\n\n const payload = parseBody(req.body);\n if (payload) {\n code += `${payload}\\n`;\n }\n\n code += `\\nresponse = requests.request('${req.method}', url, ${payload ? 'data = payload, ' : ''}headers=headers, files=files)\\n`;\n code += 'print(response.text)';\n\n return code;\n}\n","import escape from './escape';\n\nexport default function parseBody(body) {\n const mime = body.mimeType;\n\n if (mime === 'application/x-www-form-urlencoded') {\n return body.params.map(p => `${encodeURIComponent(p.name)}=${encodeURIComponent(p.value)}`).join('&');\n }\n\n if (mime === 'multipart/form-data') {\n const boundary = '-----011000010111000001101001'; // api :)\n const payload = body.params.map(p => {\n return `${boundary}\nContent-Disposition: form-data; name=\"${p.name}\"\n\n${p.value}`;\n }).join('\\n');\n return `\"${escape(payload)}\\n${boundary}--\"`;\n }\n\n return JSON.stringify(body.text);\n}\n","import buildUrl from '../helpers/buildUrl';\nimport parseBody from '../helpers/parseBody';\n\nfunction getMethod(method) {\n switch (method) {\n case 'GET':\n return 'Get';\n case 'POST':\n return 'Post';\n case 'PATCH':\n return 'Patch';\n case 'PUT':\n return 'Put';\n case 'DELETE':\n return 'Delete';\n default:\n return '{{METHOD}}';\n }\n}\n\nexport default function ruby(url, req) {\n url = buildUrl(url, req);\n const isHTTPS = url.startsWith('https://');\n\n let code = \"require 'uri'\\nrequire 'net/http'\\n\";\n\n if (isHTTPS) {\n code += \"require 'openssl'\\n\";\n }\n\n code += `\\nurl = URI(\"${url}\")\\n\\nhttp = Net::HTTP.new(url.host, url.port)\\n`;\n\n if (isHTTPS) {\n code += 'http.use_ssl = true\\nhttp.verify_mode = OpenSSL::SSL::VERIFY_NONE\\n';\n }\n\n code += `\\nrequest = Net::HTTP::${getMethod(req.method)}.new(url)\\n`;\n\n if (req.cookies && req.cookies.length) {\n const cookies = [];\n req.cookies.forEach(c => cookies.push(`${encodeURIComponent(c.key)}=${encodeURIComponent(c.value)}`));\n code += `request[\"cookie\"] = '${cookies.join('; ')}'\\n`;\n }\n\n if (req.headers && req.headers.length) {\n req.headers.forEach(header => {\n code += `request[\"${header.name}\"] = ${JSON.stringify(header.value)}\\n`;\n });\n }\n\n if (req.authHeader) {\n code += `request[\"${req.authHeader.name}\"] = ${JSON.stringify(req.authHeader.value)}\\n`;\n }\n\n if (req.body) {\n const body = parseBody(req.body);\n\n if (body) {\n code += `request.body = ${body}\\n`;\n }\n }\n\n code += '\\nresponse = http.request(request)\\nputs response.read_body';\n\n return code;\n}\n","import buildUrl from '../helpers/buildUrl';\nimport escape from '../helpers/escape';\nimport parseBody from '../helpers/parseBody';\n\nexport default function php(url, req) {\n let code = ` \"${buildUrl(url, req)}\"`,\n 'CURLOPT_RETURNTRANSFER => true',\n 'CURLOPT_ENCODING => \"\"',\n 'CURLOPT_MAXREDIRS => 10',\n 'CURLOPT_TIMEOUT => 30',\n 'CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1',\n `CURLOPT_CUSTOMREQUEST => \"${req.method}\"`\n ];\n\n const body = parseBody(req.body);\n if (body) {\n opts.push(`CURLOPT_POSTFIELDS => ${body}`);\n }\n\n if (req.cookies && req.cookies.length) {\n const cookies = [];\n req.cookies.forEach(c => cookies.push(`${encodeURIComponent(c.key)}=${encodeURIComponent(c.value)}`));\n opts.push(`CURLOPT_COOKIE => '${cookies.join('; ')}'`);\n }\n\n const headers = [];\n\n if (req.headers && req.headers.length) {\n req.headers.forEach(h => headers.push(`${h.name}: ${escape(h.value)}`));\n }\n\n if (req.authHeader) {\n headers.push(`${req.authHeader.name}: ${req.authHeader.value}`);\n }\n\n if (headers.length) {\n opts.push(`CURLOPTS_HTTPHEADER => array(\n ${headers.join(',\\n ')}\n )`);\n }\n\n code += `${opts.join(',\\n ')}\n));\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}`;\n\n return code;\n}\n","import buildUrl from '../helpers/buildUrl';\n\nfunction parseBody(body) {\n const mime = body.mimeType;\n\n if (mime === 'application/x-www-form-urlencoded') {\n return '\"' + body.params.map(p => `${encodeURIComponent(p.name)}=${encodeURIComponent(p.value)}`).join('&') + '\"';\n }\n\n if (mime === 'multipart/form-data') {\n const boundary = '-----011000010111000001101001'; // api :)\n const payload = body.params.map(p => {\n return `${boundary}\nContent-Disposition: form-data; name=\"${p.name}\"\n\n${p.value}`;\n }).join('\\n');\n return `\"${escape(payload)}\\n${boundary}--\"`;\n }\n\n return JSON.stringify(body.text);\n}\n\nexport default function golang(url, req) {\n const body = req.body && parseBody(req.body);\n\n let code = `package main\n\nimport (\n \"fmt\"${body ? '\\n\"strings\"' : ''}\n \"net/http\"\n \"io/ioutil\"\n)\n\nfunc main() {\n\n `;\n\n code += `url := \"${buildUrl(url, req)}\"\\n`;\n\n if (body) {\n code += ` payload := strings.NewReader(${body})\\n`;\n }\n\n code += ` req, _ := http.NewRequest(\"${req.method}\" url, ${body ? 'payload' : 'nil'})\\n\\n`;\n\n if (req.cookies && req.cookies.length) {\n const cookies = [];\n req.cookies.forEach(c => cookies.push(`${encodeURIComponent(c.key)}=${encodeURIComponent(c.value)}`));\n code += ` req.Header.Add(\"cookie\", ${JSON.stringify(cookies.join(';'))})\\n`;\n }\n\n req.headers.forEach(h => {\n code += ` req.Header.Add(\"${h.name}\", ${JSON.stringify(h.value)})\\n`;\n });\n\n if (req.authHeader) {\n code += ` req.Header.Add(\"${req.authHeader.name}\", ${JSON.stringify(req.authHeader.value)})\\n`;\n }\n\n code += ` res, _ := http.DefaultClient.Do(req)\n\n defer res.Body.Close()\n body, _ := ioutil.ReadAll(res.Body)\n\n fmt.Println(res)\n fmt.Println(string(body))\n\n}`;\n\n return code;\n}\n","import generateAuthHeader from './auth';\n\nimport curl from './targets/curl';\nimport javascript from './targets/javascript';\nimport python from './targets/python';\nimport ruby from './targets/ruby';\nimport php from './targets/php';\nimport golang from './targets/golang';\n\nclass CodeGenerator {\n constructor(request, url, cookiejars) {\n this.request = request;\n this.url = url;\n this.cookiejars = cookiejars;\n this.code = null;\n\n this.request.cookies = this.appendCookies();\n\n if (this.request.authentication && this.request.authentication.type) {\n this.request.authHeader = generateAuthHeader(this.request.authentication);\n }\n }\n\n generate(language) {\n switch (language) {\n case 'curl':\n this.code = curl;\n break;\n case 'javascript':\n this.code = javascript;\n break;\n case 'python':\n this.code = python;\n break;\n case 'node':\n return `const fetch = require('node-fetch');\\n\\n${javascript(this.url, this.request)}`;\n case 'ruby':\n this.code = ruby;\n break;\n case 'php':\n this.code = php;\n break;\n case 'golang':\n this.code = golang;\n break;\n default:\n return 'Not implemented yet...';\n }\n\n return this.code(this.url, this.request);\n }\n\n appendCookies() {\n const cookies = [];\n\n this.cookiejars.forEach(jar => {\n if (!jar.cookies || !jar.cookies.length) {\n return;\n }\n\n jar.cookies.forEach(cookie => {\n if (this.url && this.url.includes(cookie.domain) && (cookie.path === '/' || this.url.includes(cookie.path))) {\n cookies.push({\n key: cookie.key,\n value: cookie.value\n });\n }\n });\n });\n\n return cookies;\n }\n}\n\nexport default (request, url, language, cookiejars) => new CodeGenerator(request, url, cookiejars).generate(language);\n","export default function (variable) {\n if (!variable) return '';\n\n return variable.replace(\n /{{\\s*(_.)?([a-zA-Z0-9_]+)\\s*}}/g,\n '$2'\n );\n}\n","import generateAuthHeader from './generateCode/auth';\nimport formatEnv from './formatEnv';\n\nclass BodyParser {\n constructor(body) {\n this.body = body;\n this.mime = body.mimeType;\n }\n\n __parseJSON() {\n if (!this.body.text) {\n return;\n }\n\n this.body.text = this.body.text.replace(new RegExp('{{.*}}', 'g'), '\"!!Missing declaration in environment!!\"');\n let text;\n\n try {\n text = JSON.stringify(JSON.parse(this.body.text), null, 2);\n } catch (_) {\n console.warn('Failed to parse JSON body (expect incorrect tokenization):', this.body.text);\n text = this.body.text;\n }\n\n return {\n type: 'plain',\n note: 'json',\n text: `
    ${text}
    `\n };\n }\n\n __parseMultipart() {\n const rows = this.body.params.map(p => {\n return {\n name: p.name,\n value: p.value,\n description: p.description\n };\n });\n\n return {\n type: 'array',\n note: 'formdata',\n rows\n };\n }\n\n __parsePlain() {\n return {\n type: 'plain',\n note: 'raw',\n text: `
    ${this.body.text}
    `\n };\n }\n\n parse() {\n switch (this.mime) {\n case 'application/json':\n return this.__parseJSON();\n case 'multipart/form-data':\n case 'application/x-www-form-urlencoded':\n return this.__parseMultipart();\n default:\n return this.__parsePlain();\n }\n }\n}\n\nclass ContentGenerator {\n constructor(req) {\n this.req = req;\n }\n\n params() {\n const rows = [];\n\n this.req.parameters.forEach(param => {\n rows.push({\n name: param.name,\n value: param.value,\n description: param.description\n });\n });\n\n return {\n title: 'Parameters',\n rows\n };\n }\n\n headers() {\n const rows = [];\n\n this.req.headers.forEach(header => {\n rows.push({\n name: header.name,\n value: formatEnv(header.value || ''),\n description: header.description\n });\n });\n\n if (this.req.authentication && this.req.authentication.type) {\n const authHeader = generateAuthHeader(this.req.authentication);\n\n rows.push({\n name: authHeader.name,\n value: `
    ${formatEnv(authHeader.value)}
    `\n });\n }\n\n return {\n title: 'Headers',\n rows\n };\n }\n\n body() {\n const parser = new BodyParser(this.req.body);\n const data = parser.parse();\n\n switch (data.type) {\n case 'array':\n return {\n title: 'Body',\n note: data.note,\n rows: data.rows\n };\n case 'plain':\n return {\n title: 'Body',\n note: data.note,\n text: data.text\n };\n }\n }\n}\n\nexport default ContentGenerator;\n","\n\n
    \n
    \n {data.title}\n {#if data.note}\n {data.note}\n {/if}\n
    \n\n {#if data.text}\n
    {@html data.text}
    \n {/if}\n\n {#if data.rows && data.rows.length}\n {#each data.rows as row}\n
    \n
    {row.name}
    \n
    {@html row.value}
    \n
    \n {#if row.description}\n
    \n {@html row.description}\n
    \n {/if}\n {/each}\n {/if}\n
    \n\n\n","\n\n
    \n
    \n
     
    \n

    {request.method} {reqData.name}\n

    \n
    {@html reqData.url}
    \n\n {#if description}\n
    {@html description}
    \n {/if}\n\n
    \n\n {#if request.parameters && request.parameters.length}\n \n {/if}\n\n {#if (request.headers && request.headers.length) || (request.authentication && request.authentication.type)}\n
    \n {/if}\n\n {#if request.body && (request.body.text || request.body.params)}\n
    \n {/if}\n\n \n\n
    \n \n
    \n
    \n
    \n
    Example request:
    \n \n
    \n
    {@html exampleHTML}
    \n
    \n {#if reqData.exampleResponses && reqData.exampleResponses.length}\n {#each reqData.exampleResponses as example}\n {#if example.value}\n
    \n
    \n
    Example\n response{ example.code && example.code.length ? ` - ${example.code}` : '' }:\n
    \n
    \n
    {@html hljs.highlightAuto(example.value).value}
    \n
    \n {/if}\n {/each}\n {/if}\n
    \n\n\n\n","export default function (value, env) {\n if (!value) {\n return null;\n }\n\n Object.keys(env.data).forEach(key => {\n value = value.replace(new RegExp('{{(\\\\s*(_.)?' + key + '\\\\s*)}}', 'g'), env.data[key]);\n });\n\n return value;\n}\n","\n\n
    \n
    \n

    {groupData.name}

    \n\n {#if description}\n
    {@html description}
    \n {/if}\n\n
    \n
    \n
    \n
    \n","\n\n{#each content as row}\n {#if row._type === 'request'}\n \n {:else}\n \n \n {/if}\n{/each}\n","\n\n\n\n\n\n
    \n {@html getOptionLabel(item, filterText)}\n
    \n","\n\n\n\n\n\t\n\t\t{#each visible as row (row.index)}\n\t\t\t\n\t\t\t\tMissing template\n\t\t\t\n\t\t{/each}\n\t\n\n","\n\n\n\n{#if isVirtualList}\n
    \n\n \n\n
    handleHover(i)}\" on:click=\"{event => handleClick({item, i, event})}\"\n class=\"listItem\">\n \n
    \n\n
    \n
    \n{/if}\n\n{#if !isVirtualList}\n
    \n {#each items as item, i}\n {#if item.isGroupHeader && !item.isSelectable}\n
    {getGroupHeaderLabel(item)}
    \n { :else }\n handleHover(i)}\"\n on:click=\"{event => handleClick({item, i, event})}\"\n class=\"listItem\"\n >\n \n
    \n {/if}\n {:else}\n {#if !hideEmptyState}\n
    {noOptionsMessage}
    \n {/if}\n {/each}\n\n{/if}\n\n\n","\n\n\n\n
    \n {@html getSelectionLabel(item)}\n
    \n","\n\n{#each selectedValue as value, i}\n
    multiFullItemClearable ? handleClear(i, event) : {}}>\n
    \n {@html getSelectionLabel(value)}\n
    \n {#if !isDisabled && !multiFullItemClearable}\n
    handleClear(i, event)}\">\n \n \n \n
    \n {/if}\n
    \n{/each}\n\n\n\n\n","\n\n\n\n\n\n\n\n {#if Icon}\n \n {/if}\n\n {#if isMulti && selectedValue && selectedValue.length > 0}\n \n {/if}\n\n {#if isDisabled}\n \n {:else}\n \n {/if}\n\n {#if !isMulti && showSelectedItem}\n
    \n \n
    \n {/if}\n\n {#if showSelectedItem && isClearable && !isDisabled && !isWaiting}\n
    \n \n
    \n {/if}\n\n {#if showIndicator || (showChevron && !selectedValue || (!isSearchable && !isDisabled && !isWaiting && ((showSelectedItem && !isClearable) || !showSelectedItem)))}\n
    \n {#if indicatorSvg}\n {@html indicatorSvg}\n {:else}\n \n \n \n {/if}\n
    \n {/if}\n\n {#if isWaiting}\n
    \n \n \n \n
    \n {/if}\n\n","export default function debounce(func, wait, immediate) {\n let timeout;\n\n return function executedFunction() {\n let context = this;\n let args = arguments;\n\n let later = function() {\n timeout = null;\n if (!immediate) func.apply(context, args);\n };\n\n let callNow = immediate && !timeout;\n\n clearTimeout(timeout);\n\n timeout = setTimeout(later, wait);\n\n if (callNow) func.apply(context, args);\n };\n};\n","export default function(elem) {\n const bounding = elem.getBoundingClientRect();\n const out = {};\n\n out.top = bounding.top < 0;\n out.left = bounding.left < 0;\n out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);\n out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);\n out.any = out.top || out.left || out.bottom || out.right;\n\n return out;\n};\n","\n\n
    \n
    \n
    \n

    {workspace.name}

    \n {#if description}\n
    {@html description}
    \n {/if}\n
    \n
    \n
    \n \n
    \n
    \n
    \n \n
    \n\n\n","import applyEnv from './applyEnv';\n\nexport default function applyEnvForObject(object, env) {\n let obj = object;\n if (typeof obj === 'object') {\n obj = JSON.parse(JSON.stringify(object));\n replaceObjectValues(obj, env);\n }\n return obj;\n}\n\nfunction replaceObjectValues(obj, env) {\n Object.keys(obj).forEach(key => {\n if (obj[key] !== null) {\n switch (typeof obj[key]) {\n case 'object':\n replaceObjectValues(obj[key], env);\n break;\n case 'string':\n obj[key] = applyEnv(obj[key], env);\n break;\n }\n }\n });\n}\n","\n\n\n\n\n {config.workspace.name}\n\n\n
    \n
    \n \n \n \n\n
    \n {config.workspace.name}\n
    \n\n

    {config.workspace.name}

    \n
    \n
    \n
    \n \n \"Run\n \n
    \n
    \n \n \n
    \n \n \n \n
    \n
    \n\n
    \n \n \n
    \n","\n Uh-oh!\n\n\n
    \n

    Uh-oh!

    \n

    \n It looks like it's not possible to retrieve the contents of the API documentation\n at the moment. If you're the owner of this site, make sure that your\n Insomnia JSON file is accessible.\n

    \n

    \n The developer console of your browser might have more things to say about this error.\n

    \n
    \n\n\n","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n symbolTag = '[object Symbol]';\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\n/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array ? array.length : 0,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\n/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar Symbol = root.Symbol,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\nfunction baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n}\n\n/**\n * The base implementation of `_.pick` without support for individual\n * property identifiers.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} props The property identifiers to pick.\n * @returns {Object} Returns the new object.\n */\nfunction basePick(object, props) {\n object = Object(object);\n return basePickBy(object, props, function(value, key) {\n return key in object;\n });\n}\n\n/**\n * The base implementation of `_.pickBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} props The property identifiers to pick from.\n * @param {Function} predicate The function invoked per property.\n * @returns {Object} Returns the new object.\n */\nfunction basePickBy(object, props, predicate) {\n var index = -1,\n length = props.length,\n result = {};\n\n while (++index < length) {\n var key = props[index],\n value = object[key];\n\n if (predicate(value, key)) {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = array;\n return apply(func, this, otherArgs);\n };\n}\n\n/**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\nfunction isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n}\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8-9 which returns 'object' for typed array and other constructors.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Creates an object composed of the picked `object` properties.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [props] The property identifiers to pick.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pick(object, ['a', 'c']);\n * // => { 'a': 1, 'c': 3 }\n */\nvar pick = baseRest(function(object, props) {\n return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));\n});\n\nmodule.exports = pick;\n","import pick from 'lodash.pick';\n\nconst reExampleResponse = /```response(:(\\d+))?\\n([\\s\\S]*?)\\n```/gm;\n\nfunction makeExampleResponse(match) {\n const code = match[2] || null;\n const value = match[3].trim();\n\n return { code, value };\n}\n\nexport default function (requestData) {\n requestData = pick(\n requestData,\n '_id',\n 'method',\n 'name',\n 'description',\n 'parameters',\n 'url',\n 'authentication',\n 'body',\n 'headers',\n '_type'\n );\n\n if (!requestData.description) {\n return requestData;\n }\n\n const exampleResponses = [];\n\n let match;\n\n while ((match = reExampleResponse.exec(requestData.description))) {\n exampleResponses.push(makeExampleResponse(match));\n }\n\n requestData.exampleResponses = exampleResponses;\n requestData.description = requestData.description.replace(\n reExampleResponse,\n ''\n );\n\n return requestData;\n}\n","import buildRequest from './buildRequest';\nimport pick from 'lodash.pick';\n\nclass CuteConfig {\n constructor(json) {\n this.json = json;\n this.id = null;\n\n this.cute = {\n workspace: {\n name: null,\n description: null\n },\n cookiejars: [],\n environments: [],\n groups: [],\n requests: []\n };\n }\n\n metaSort(a, b) {\n return a.metaSortKey - b.metaSortKey;\n }\n\n mapCookiejar(cookiejar) {\n return pick(cookiejar, 'name', 'cookies');\n }\n\n filterCookiejars() {\n return this.json.resources\n .filter(r => r._type === 'cookie_jar')\n .map(this.mapCookiejar);\n }\n\n mapEnvironment(environment) {\n return pick(environment, 'color', 'data', 'name');\n }\n\n filterEnvironments() {\n return this.json.resources\n .filter(r => r._type === 'environment' && !r.isPrivate)\n .sort(this.metaSort)\n .map(this.mapEnvironment);\n }\n\n filterRequests(groupId = null) {\n const parentId = groupId || this.id;\n return this.json.resources\n .filter(r => r._type === 'request' && r.parentId === parentId && !r.isPrivate)\n .sort(this.metaSort)\n .map(buildRequest);\n }\n\n deepMapGroups(predicate) {\n const group = {\n name: predicate.name,\n description: predicate.description,\n _type: predicate._type\n };\n\n group.children = this.json.resources\n .filter(r => r._type === 'request_group' && r.parentId === predicate._id)\n .sort(this.metaSort)\n .map(this.deepMapGroups.bind(this));\n\n group.requests = this.filterRequests(predicate._id);\n\n return group;\n }\n\n filterRootGroups() {\n const filteredGroups = this.json.resources.filter(r => r._type === 'request_group' && r.parentId === this.id);\n if (!filteredGroups) {\n return [];\n }\n\n return filteredGroups\n .sort(this.metaSort)\n .map(this.deepMapGroups.bind(this));\n }\n\n generate() {\n const workspace = this.json.resources.find(r => r._type === 'workspace');\n this.id = workspace._id;\n this.cute.workspace.name = workspace.name;\n this.cute.workspace.description = workspace.description;\n\n this.cute.cookiejars = this.filterCookiejars();\n this.cute.environments = this.filterEnvironments();\n\n if (this.cute.environments.length > 1) {\n this.cute.environments = this.cute.environments.slice(1);\n }\n\n this.cute.groups = this.filterRootGroups();\n this.cute.requests = this.filterRequests();\n\n return this.cute;\n }\n}\n\nexport default CuteConfig;\n","import App from './App.svelte';\nimport ErrorPage from './ErrorPage.svelte';\nimport CuteConfig from './lib/cuteConfig';\n\nasync function app() {\n const root = document.getElementById('app');\n const rootPath = root.getAttribute('data-root') || '';\n\n const url = process.env.NODE_ENV === 'demo'\n ? '/insomnia-documenter/insomnia.json'\n : `${rootPath}/insomnia.json`;\n\n window.INSOMNIA_URL = url;\n\n try {\n // eslint-disable-next-line no-undef\n const json = await fetch(url, {\n method: 'GET',\n credentials: 'same-origin',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'\n }\n }).then(res => res.json());\n\n const insomniaConfig = new CuteConfig(json).generate();\n\n return new App({\n target: root,\n props: {\n config: insomniaConfig\n }\n });\n } catch (err) {\n console.error(err);\n\n return new ErrorPage({\n target: root\n });\n }\n}\n\nexport default app();\n"],"names":["noop","assign","tar","src","k","run","fn","blank_object","Object","create","run_all","fns","forEach","is_function","thing","safe_not_equal","a","b","get_slot_context","definition","ctx","$$scope","slice","update_slot","slot","slot_definition","dirty","get_slot_changes_fn","get_slot_context_fn","slot_changes","lets","undefined","merged","len","Math","max","length","i","get_slot_changes","slot_context","p","null_to_empty","value","append","target","node","appendChild","insert","anchor","insertBefore","detach","parentNode","removeChild","destroy_each","iterations","detaching","d","element","name","document","createElement","svg_element","createElementNS","text","data","createTextNode","space","empty","listen","event","handler","options","addEventListener","removeEventListener","attr","attribute","removeAttribute","getAttribute","setAttribute","set_attributes","attributes","descriptors","getOwnPropertyDescriptors","__proto__","key","style","cssText","set","set_custom_element_data","prop","set_data","wholeText","set_input_value","input","set_style","important","setProperty","select_option","select","option","__value","selected","crossorigin","current_component","is_crossorigin","window","parent","error","toggle_class","toggle","classList","HtmlTag","[object Object]","this","e","n","html","nodeName","t","h","innerHTML","Array","from","childNodes","set_current_component","component","get_current_component","Error","beforeUpdate","$$","before_update","push","onMount","on_mount","onDestroy","on_destroy","createEventDispatcher","type","detail","callbacks","createEvent","initCustomEvent","custom_event","call","dirty_components","binding_callbacks","render_callbacks","flush_callbacks","resolved_promise","Promise","resolve","update_scheduled","schedule_update","then","flush","tick","add_render_callback","flushing","seen_callbacks","Set","update","pop","callback","has","add","clear","fragment","after_update","outroing","outros","group_outros","r","c","check_outros","transition_in","block","local","delete","transition_out","o","outro_and_destroy_block","lookup","get_spread_update","levels","updates","to_null_out","accounted_for","get_spread_object","spread_props","create_component","mount_component","customElement","m","new_on_destroy","map","filter","destroy_component","init","instance","create_fragment","not_equal","props","parent_component","bound","on_disconnect","context","Map","skip_bound","ready","ret","rest","fill","make_dirty","hydrate","nodes","children","l","intro","SvelteComponent","$destroy","index","indexOf","splice","$$props","obj","$$set","keys","method","toLowerCase","_id","request","root","expanded","requests","groups","workspace","visible","deepFreeze","freeze","getOwnPropertyNames","isFrozen","deepFreezeEs6","_default","default","Response","mode","isMatchIgnored","escapeHTML","replace","inherit","original","objects","result","emitsWrappingTags","kind","HTMLRenderer","parseTree","buffer","classPrefix","walk","className","sublanguage","span","TokenTree","rootNode","stack","top","closeNode","JSON","stringify","builder","constructor","_walk","addText","openNode","child","every","el","join","_collapse","TokenTreeEmitter","super","emitter","source","re","BACKREF_RE","C_NUMBER_RE","BACKSLASH_ESCAPE","begin","relevance","APOS_STRING_MODE","end","illegal","contains","QUOTE_STRING_MODE","PHRASAL_WORDS_MODE","COMMENT","modeOptions","C_LINE_COMMENT_MODE","C_BLOCK_COMMENT_MODE","HASH_COMMENT_MODE","NUMBER_MODE","C_NUMBER_MODE","BINARY_NUMBER_MODE","CSS_NUMBER_MODE","NUMBER_RE","REGEXP_MODE","TITLE_MODE","UNDERSCORE_TITLE_MODE","METHOD_GUARD","MODES","MATCH_NOTHING_RE","IDENT_RE","UNDERSCORE_IDENT_RE","BINARY_NUMBER_RE","RE_STARTERS_RE","SHEBANG","opts","beginShebang","binary","args","x","concat","on:begin","resp","ignoreMatch","END_SAME_AS_BEGIN","_beginMatch","on:end","skipIfhasPrecedingDot","match","response","beginKeywords","split","__beforeBegin","keywords","compileIllegal","_parent","isArray","either","compileMatch","compileRelevance","COMMON_KEYWORDS","scoreForKeyword","keyword","providedScore","Number","includes","commonKeyword","compileLanguage","language","plugins","langRe","global","RegExp","case_insensitive","MultiRegex","matchIndexes","regexes","matchAt","position","toString","exec","countMatchGroups","terminators","matcherRe","regexps","separator","numCaptures","regex","offset","out","substring","String","lastIndex","s","findIndex","matchData","ResumableMultiRegex","rules","multiRegexes","count","regexIndex","matcher","addRule","compile","getMatcher","resumingScanAtSamePosition","m2","considerAll","compilerExtensions","classNameAliases","compileMode","cmode","isCompiled","ext","keywordPattern","$pattern","compileKeywords","rawKeywords","caseInsensitive","compiledKeywords","compileList","keywordList","pair","lexemes","keywordPatternRe","beginRe","endSameAsBegin","endsWithParent","endRe","terminatorEnd","illegalRe","variants","cachedVariants","variant","dependencyOnParent","starts","expandOrCloneMode","mm","term","rule","buildModeRegex","BuildVuePlugin","hljs","Component","detectedLanguage","unknownLanguage","computed","autoDetect","getLanguage","console","warn","code","highlightAuto","highlight","ignoreIllegals","autodetect","Boolean","class","domProps","highlighted","VuePlugin","Vue","mergeHTMLPlugin","after:highlightElement","originalStream","nodeStream","resultNode","processed","nodeStack","selectStream","open","tag","close","render","stream","reverse","substr","mergeStreams","_nodeStream","firstChild","nextSibling","nodeType","nodeValue","seenDeprecations","message","log","deprecated","version","escape$1","inherit$1","NO_MATCH","Symbol","languages","aliases","SAFE_MODE","fixMarkupRe","LANGUAGE_NOT_FOUND","PLAINTEXT_LANGUAGE","disableAutodetect","noHighlightRe","languageDetectRe","tabReplace","useBR","__emitter","shouldNotHighlight","languageName","test","codeOrlanguageName","optionsOrCode","continuation","fire","_highlight","codeToHighlight","keywordData","matchText","prototype","hasOwnProperty","processBuffer","subLanguage","modeBuffer","continuations","addSublanguage","processSubLanguage","buf","keywordRelevance","startsWith","cssClass","addKeyword","processKeywords","startNewMode","doIgnore","lexeme","resumeScanAtSamePosition","doBeginMatch","newMode","beforeCallbacks","cb","skip","excludeBegin","returnBegin","doEndMatch","matchPlusRemainder","endMode","endOfMode","matched","endsParent","origin","returnEnd","excludeEnd","lastMatch","processLexeme","textBeforeMatch","err","badRule","md","list","current","unshift","item","processContinuations","processedCount","closeAllNodes","finalize","toHTML","floor","illegalBy","msg","sofar","errorRaised","languageSubset","plaintext","justTextHighlightResult","results","autoDetection","sorted","sort","supersetOf","best","secondBest","second_best","brPlugin","before:highlightElement","TAB_REPLACE_RE","tabReplacePlugin","highlightElement","classes","find","_class","blockLanguage","textContent","currentLang","resultLang","updateClassName","relavance","initHighlighting","called","querySelectorAll","wantsHighlight","highlightAll","readyState","registerAliases","aliasList","alias","lang","plugin","fixMarkup","arg","highlightBlock","configure","userOptions","initHighlightingOnLoad","registerLanguage","languageDefinition","error$1","rawDefinition","bind","unregisterLanguage","listLanguages","requireLanguage","addPlugin","upgradePluginAPI","vuePlugin","debugMode","safeMode","versionString","HLJS","KEYWORDS","LITERALS","BUILT_INS","lookahead","IDENT_RE$1","FRAGMENT","XML_TAG","isTrulyOpeningTag","afterMatchIndex","nextChar","after","hasClosingTag","KEYWORDS$1","literal","built_in","frac","NUMBER","SUBST","HTML_TEMPLATE","CSS_TEMPLATE","TEMPLATE_STRING","SUBST_INTERNALS","SUBST_AND_COMMENTS","PARAMS_CONTAINS","PARAMS","exports","label","PROMPT","LITERAL_BRACKET","STRING","digitpart","pointfloat","COMMENT_TYPE","VAR","BRACED_VAR","HERE_DOC","QUOTE_STRING","ARITHMETIC","KNOWN_SHEBANG","FUNCTION","RUBY_METHOD_RE","RUBY_KEYWORDS","YARDOCTAG","IRB_OBJECT","COMMENT_MODES","RUBY_DEFAULT_CONTAINS","IRB_DEFAULT","GO_KEYWORDS","VARIABLE","PREPROCESSOR","SINGLE_QUOTED","DOUBLE_QUOTED","HEREDOC","javascript","python","bash","ruby","golang","php","factory","__webpack_modules__","134","__unused_webpack_module","__webpack_exports__","__webpack_require__","clipboard","tiny_emitter","tiny_emitter_default","listen_default","src_select","select_default","_typeof","iterator","_defineProperties","descriptor","enumerable","configurable","writable","defineProperty","clipboard_action","ClipboardAction","Constructor","TypeError","_classCallCheck","resolveOptions","initSelection","protoProps","staticProps","arguments","action","container","trigger","selectedText","selectFake","selectTarget","isRTL","documentElement","fakeElem","fontSize","border","padding","margin","yPosition","pageYOffset","scrollTop","_this","createFakeElement","fakeHandlerCallback","removeFake","fakeHandler","copyText","succeeded","execCommand","handleResult","emit","clearSelection","focus","activeElement","blur","getSelection","removeAllRanges","_action","get","hasAttribute","_target","clipboard_typeof","clipboard_defineProperties","_setPrototypeOf","setPrototypeOf","_createSuper","Derived","hasNativeReflectConstruct","Reflect","construct","sham","Proxy","Date","_isNativeReflectConstruct","Super","_getPrototypeOf","NewTarget","apply","_possibleConstructorReturn","self","ReferenceError","_assertThisInitialized","getPrototypeOf","getAttributeValue","suffix","_Emitter","subClass","superClass","_inherits","Clipboard","_super","clipboard_classCallCheck","listenClick","actions","support","queryCommandSupported","defaultAction","defaultTarget","defaultText","body","_this2","listener","onClick","delegateTarget","currentTarget","clipboardAction","selector","querySelector","destroy","828","module","Element","matches","proto","matchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","webkitMatchesSelector","438","__unused_webpack_exports","closest","_delegate","useCapture","listenerFn","elements","879","HTMLElement","nodeList","string","370","is","delegate","listenNode","listenNodeList","listenSelector","817","isReadOnly","setSelectionRange","selection","range","createRange","selectNodeContents","addRange","279","E","on","once","off","_","evtArr","evts","liveEvents","TinyEmitter","__webpack_module_cache__","moduleId","getter","__esModule","getDefaultOpts","simple","defaultOptions","omitExtraWLInCodeBlocks","defaultValue","describe","noHeaderId","prefixHeaderId","rawPrefixHeaderId","ghCompatibleHeaderId","rawHeaderId","headerLevelStart","parseImgDimensions","simplifiedAutoLink","excludeTrailingPunctuationFromURLs","literalMidWordUnderscores","literalMidWordAsterisks","strikethrough","tables","tablesHeaderId","ghCodeBlocks","tasklists","smoothLivePreview","smartIndentationFix","description","disableForced4SpacesIndentedSublists","simpleLineBreaks","requireSpaceBeforeHeadingText","ghMentions","ghMentionsLink","encodeEmails","openLinksInNewWindow","backslashEscapesHTMLTags","emoji","underline","completeHTMLDocument","metadata","splitAdjacentBlockquotes","parse","opt","showdown","parsers","extensions","globalOptions","setFlavor","flavor","github","ghost","vanilla","allOn","allOptionsOn","validate","extension","errMsg","valid","helper","baseMsg","isString","isUndefined","listeners","ln","escapeCharactersCallback","wholeMatch","m1","charCodeAt","setOption","getOption","getOptions","resetOptions","preset","getFlavor","getFlavorOptions","getDefaultOptions","subParser","func","stdExtName","validExtension","getAllExtensions","removeExtension","resetExtensions","validateExtension","isFunction","escapeCharacters","charsToEscape","afterBackslash","regexString","unescapeHTMLEntities","txt","rgxFindMatchPos","str","left","right","flags","start","f","g","pos","matchRecursiveRegExp","matchPos","replaceRecursiveRegExp","replacement","repStr","finalStr","lng","bits","regexIndexOf","fromIndex","search","splitAtIndex","encodeEmailAddress","mail","encode","ch","random","padEnd","targetLength","padString","repeat","alert","asteriskDashAndColon","emojis","+1","-1","100","1234","1st_place_medal","2nd_place_medal","3rd_place_medal","8ball","ab","abc","abcd","accept","aerial_tramway","airplane","alarm_clock","alembic","alien","ambulance","amphora","angel","anger","angry","anguished","ant","apple","aquarius","aries","arrow_backward","arrow_double_down","arrow_double_up","arrow_down","arrow_down_small","arrow_forward","arrow_heading_down","arrow_heading_up","arrow_left","arrow_lower_left","arrow_lower_right","arrow_right","arrow_right_hook","arrow_up","arrow_up_down","arrow_up_small","arrow_upper_left","arrow_upper_right","arrows_clockwise","arrows_counterclockwise","art","articulated_lorry","artificial_satellite","astonished","athletic_shoe","atm","atom_symbol","avocado","baby","baby_bottle","baby_chick","baby_symbol","back","bacon","badminton","baggage_claim","baguette_bread","balance_scale","balloon","ballot_box","ballot_box_with_check","bamboo","banana","bangbang","bank","bar_chart","barber","baseball","basketball","basketball_man","basketball_woman","bat","bath","bathtub","battery","beach_umbrella","bear","bed","bee","beer","beers","beetle","beginner","bell","bellhop_bell","bento","biking_man","bike","biking_woman","bikini","biohazard","bird","birthday","black_circle","black_flag","black_heart","black_joker","black_large_square","black_medium_small_square","black_medium_square","black_nib","black_small_square","black_square_button","blonde_man","blonde_woman","blossom","blowfish","blue_book","blue_car","blue_heart","blush","boar","boat","bomb","book","bookmark","bookmark_tabs","books","boom","boot","bouquet","bowing_man","bow_and_arrow","bowing_woman","bowling","boxing_glove","boy","bread","bride_with_veil","bridge_at_night","briefcase","broken_heart","bug","building_construction","bulb","bullettrain_front","bullettrain_side","burrito","bus","business_suit_levitating","busstop","bust_in_silhouette","busts_in_silhouette","butterfly","cactus","cake","calendar","call_me_hand","calling","camel","camera","camera_flash","camping","cancer","candle","candy","canoe","capital_abcd","capricorn","car","card_file_box","card_index","card_index_dividers","carousel_horse","carrot","cat","cat2","cd","chains","champagne","chart","chart_with_downwards_trend","chart_with_upwards_trend","checkered_flag","cheese","cherries","cherry_blossom","chestnut","chicken","children_crossing","chipmunk","chocolate_bar","christmas_tree","church","cinema","circus_tent","city_sunrise","city_sunset","cityscape","cl","clamp","clap","clapper","classical_building","clinking_glasses","clock1","clock10","clock1030","clock11","clock1130","clock12","clock1230","clock130","clock2","clock230","clock3","clock330","clock4","clock430","clock5","clock530","clock6","clock630","clock7","clock730","clock8","clock830","clock9","clock930","closed_book","closed_lock_with_key","closed_umbrella","cloud","cloud_with_lightning","cloud_with_lightning_and_rain","cloud_with_rain","cloud_with_snow","clown_face","clubs","cocktail","coffee","coffin","cold_sweat","comet","computer","computer_mouse","confetti_ball","confounded","confused","congratulations","construction","construction_worker_man","construction_worker_woman","control_knobs","convenience_store","cookie","cool","policeman","copyright","corn","couch_and_lamp","couple","couple_with_heart_woman_man","couple_with_heart_man_man","couple_with_heart_woman_woman","couplekiss_man_man","couplekiss_man_woman","couplekiss_woman_woman","cow","cow2","cowboy_hat_face","crab","crayon","credit_card","crescent_moon","cricket","crocodile","croissant","crossed_fingers","crossed_flags","crossed_swords","crown","cry","crying_cat_face","crystal_ball","cucumber","cupid","curly_loop","currency_exchange","curry","custard","customs","cyclone","dagger","dancer","dancing_women","dancing_men","dango","dark_sunglasses","dart","dash","date","deciduous_tree","deer","department_store","derelict_house","desert","desert_island","desktop_computer","male_detective","diamond_shape_with_a_dot_inside","diamonds","disappointed","disappointed_relieved","dizzy","dizzy_face","do_not_litter","dog","dog2","dollar","dolls","dolphin","door","doughnut","dove","dragon","dragon_face","dress","dromedary_camel","drooling_face","droplet","drum","duck","dvd","e-mail","eagle","ear","ear_of_rice","earth_africa","earth_americas","earth_asia","egg","eggplant","eight_pointed_black_star","eight_spoked_asterisk","electric_plug","elephant","email","envelope_with_arrow","euro","european_castle","european_post_office","evergreen_tree","exclamation","expressionless","eye","eye_speech_bubble","eyeglasses","eyes","face_with_head_bandage","face_with_thermometer","fist_oncoming","fallen_leaf","family_man_woman_boy","family_man_boy","family_man_boy_boy","family_man_girl","family_man_girl_boy","family_man_girl_girl","family_man_man_boy","family_man_man_boy_boy","family_man_man_girl","family_man_man_girl_boy","family_man_man_girl_girl","family_man_woman_boy_boy","family_man_woman_girl","family_man_woman_girl_boy","family_man_woman_girl_girl","family_woman_boy","family_woman_boy_boy","family_woman_girl","family_woman_girl_boy","family_woman_girl_girl","family_woman_woman_boy","family_woman_woman_boy_boy","family_woman_woman_girl","family_woman_woman_girl_boy","family_woman_woman_girl_girl","fast_forward","fax","fearful","feet","female_detective","ferris_wheel","ferry","field_hockey","file_cabinet","file_folder","film_projector","film_strip","fire_engine","fireworks","first_quarter_moon","first_quarter_moon_with_face","fish","fish_cake","fishing_pole_and_fish","fist_raised","fist_left","fist_right","flashlight","fleur_de_lis","flight_arrival","flight_departure","floppy_disk","flower_playing_cards","flushed","fog","foggy","football","footprints","fork_and_knife","fountain","fountain_pen","four_leaf_clover","fox_face","framed_picture","free","fried_egg","fried_shrimp","fries","frog","frowning","frowning_face","frowning_man","frowning_woman","middle_finger","fuelpump","full_moon","full_moon_with_face","funeral_urn","game_die","gear","gem","gemini","gift","gift_heart","girl","globe_with_meridians","goal_net","goat","golf","golfing_man","golfing_woman","gorilla","grapes","green_apple","green_book","green_heart","green_salad","grey_exclamation","grey_question","grimacing","grin","grinning","guardsman","guardswoman","guitar","gun","haircut_woman","haircut_man","hamburger","hammer","hammer_and_pick","hammer_and_wrench","hamster","hand","handbag","handshake","hankey","hatched_chick","hatching_chick","headphones","hear_no_evil","heart","heart_decoration","heart_eyes","heart_eyes_cat","heartbeat","heartpulse","hearts","heavy_check_mark","heavy_division_sign","heavy_dollar_sign","heavy_heart_exclamation","heavy_minus_sign","heavy_multiplication_x","heavy_plus_sign","helicopter","herb","hibiscus","high_brightness","high_heel","hocho","hole","honey_pot","horse","horse_racing","hospital","hot_pepper","hotdog","hotel","hotsprings","hourglass","hourglass_flowing_sand","house","house_with_garden","houses","hugs","hushed","ice_cream","ice_hockey","ice_skate","icecream","id","ideograph_advantage","imp","inbox_tray","incoming_envelope","tipping_hand_woman","information_source","innocent","interrobang","iphone","izakaya_lantern","jack_o_lantern","japan","japanese_castle","japanese_goblin","japanese_ogre","jeans","joy","joy_cat","joystick","kaaba","keyboard","keycap_ten","kick_scooter","kimono","kiss","kissing","kissing_cat","kissing_closed_eyes","kissing_heart","kissing_smiling_eyes","kiwi_fruit","koala","koko","large_blue_circle","large_blue_diamond","large_orange_diamond","last_quarter_moon","last_quarter_moon_with_face","latin_cross","laughing","leaves","ledger","left_luggage","left_right_arrow","leftwards_arrow_with_hook","lemon","leo","leopard","level_slider","libra","light_rail","link","lion","lips","lipstick","lizard","lock","lock_with_ink_pen","lollipop","loop","loud_sound","loudspeaker","love_hotel","love_letter","low_brightness","lying_face","mag","mag_right","mahjong","mailbox","mailbox_closed","mailbox_with_mail","mailbox_with_no_mail","man","man_artist","man_astronaut","man_cartwheeling","man_cook","man_dancing","man_facepalming","man_factory_worker","man_farmer","man_firefighter","man_health_worker","man_in_tuxedo","man_judge","man_juggling","man_mechanic","man_office_worker","man_pilot","man_playing_handball","man_playing_water_polo","man_scientist","man_shrugging","man_singer","man_student","man_teacher","man_technologist","man_with_gua_pi_mao","man_with_turban","tangerine","mans_shoe","mantelpiece_clock","maple_leaf","martial_arts_uniform","mask","massage_woman","massage_man","meat_on_bone","medal_military","medal_sports","mega","melon","memo","men_wrestling","menorah","mens","metal","metro","microphone","microscope","milk_glass","milky_way","minibus","minidisc","mobile_phone_off","money_mouth_face","money_with_wings","moneybag","monkey","monkey_face","monorail","moon","mortar_board","mosque","motor_boat","motor_scooter","motorcycle","motorway","mount_fuji","mountain","mountain_biking_man","mountain_biking_woman","mountain_cableway","mountain_railway","mountain_snow","mouse","mouse2","movie_camera","moyai","mrs_claus","muscle","mushroom","musical_keyboard","musical_note","musical_score","mute","nail_care","name_badge","national_park","nauseated_face","necktie","negative_squared_cross_mark","nerd_face","neutral_face","new","new_moon","new_moon_with_face","newspaper","newspaper_roll","next_track_button","ng","no_good_man","no_good_woman","night_with_stars","no_bell","no_bicycles","no_entry","no_entry_sign","no_mobile_phones","no_mouth","no_pedestrians","no_smoking","non-potable_water","nose","notebook","notebook_with_decorative_cover","notes","nut_and_bolt","o2","ocean","octopus","oden","office","oil_drum","ok","ok_hand","ok_man","ok_woman","old_key","older_man","older_woman","om","oncoming_automobile","oncoming_bus","oncoming_police_car","oncoming_taxi","open_file_folder","open_hands","open_mouth","open_umbrella","ophiuchus","orange_book","orthodox_cross","outbox_tray","owl","ox","package","page_facing_up","page_with_curl","pager","paintbrush","palm_tree","pancakes","panda_face","paperclip","paperclips","parasol_on_ground","parking","part_alternation_mark","partly_sunny","passenger_ship","passport_control","pause_button","peace_symbol","peach","peanuts","pear","pen","pencil2","penguin","pensive","performing_arts","persevere","person_fencing","pouting_woman","phone","pick","pig","pig2","pig_nose","pill","pineapple","ping_pong","pisces","pizza","place_of_worship","plate_with_cutlery","play_or_pause_button","point_down","point_left","point_right","point_up","point_up_2","police_car","policewoman","poodle","popcorn","post_office","postal_horn","postbox","potable_water","potato","pouch","poultry_leg","pound","rage","pouting_cat","pouting_man","pray","prayer_beads","pregnant_woman","previous_track_button","prince","princess","printer","purple_heart","purse","pushpin","put_litter_in_its_place","question","rabbit","rabbit2","racehorse","racing_car","radio","radio_button","radioactive","railway_car","railway_track","rainbow","rainbow_flag","raised_back_of_hand","raised_hand_with_fingers_splayed","raised_hands","raising_hand_woman","raising_hand_man","ram","ramen","rat","record_button","recycle","red_circle","registered","relaxed","relieved","reminder_ribbon","repeat_one","rescue_worker_helmet","restroom","revolving_hearts","rewind","rhinoceros","ribbon","rice","rice_ball","rice_cracker","rice_scene","right_anger_bubble","ring","robot","rocket","rofl","roll_eyes","roller_coaster","rooster","rose","rosette","rotating_light","round_pushpin","rowing_man","rowing_woman","rugby_football","running_man","running_shirt_with_sash","running_woman","sa","sagittarius","sake","sandal","santa","satellite","saxophone","school","school_satchel","scissors","scorpion","scorpius","scream","scream_cat","scroll","seat","secret","see_no_evil","seedling","selfie","shallow_pan_of_food","shamrock","shark","shaved_ice","sheep","shell","shield","shinto_shrine","ship","shirt","shopping","shopping_cart","shower","shrimp","signal_strength","six_pointed_star","ski","skier","skull","skull_and_crossbones","sleeping","sleeping_bed","sleepy","slightly_frowning_face","slightly_smiling_face","slot_machine","small_airplane","small_blue_diamond","small_orange_diamond","small_red_triangle","small_red_triangle_down","smile","smile_cat","smiley","smiley_cat","smiling_imp","smirk","smirk_cat","smoking","snail","snake","sneezing_face","snowboarder","snowflake","snowman","snowman_with_snow","sob","soccer","soon","sos","sound","space_invader","spades","spaghetti","sparkle","sparkler","sparkles","sparkling_heart","speak_no_evil","speaker","speaking_head","speech_balloon","speedboat","spider","spider_web","spiral_calendar","spiral_notepad","spoon","squid","stadium","star","star2","star_and_crescent","star_of_david","stars","station","statue_of_liberty","steam_locomotive","stew","stop_button","stop_sign","stopwatch","straight_ruler","strawberry","stuck_out_tongue","stuck_out_tongue_closed_eyes","stuck_out_tongue_winking_eye","studio_microphone","stuffed_flatbread","sun_behind_large_cloud","sun_behind_rain_cloud","sun_behind_small_cloud","sun_with_face","sunflower","sunglasses","sunny","sunrise","sunrise_over_mountains","surfing_man","surfing_woman","sushi","suspension_railway","sweat","sweat_drops","sweat_smile","sweet_potato","swimming_man","swimming_woman","symbols","synagogue","syringe","taco","tada","tanabata_tree","taurus","taxi","tea","telephone_receiver","telescope","tennis","tent","thermometer","thinking","thought_balloon","ticket","tickets","tiger","tiger2","timer_clock","tipping_hand_man","tired_face","tm","toilet","tokyo_tower","tomato","tongue","tophat","tornado","trackball","tractor","traffic_light","train","train2","tram","triangular_flag_on_post","triangular_ruler","trident","triumph","trolleybus","trophy","tropical_drink","tropical_fish","truck","trumpet","tulip","tumbler_glass","turkey","turtle","tv","twisted_rightwards_arrows","two_hearts","two_men_holding_hands","two_women_holding_hands","u5272","u5408","u55b6","u6307","u6708","u6709","u6e80","u7121","u7533","u7981","u7a7a","umbrella","unamused","underage","unicorn","unlock","up","upside_down_face","v","vertical_traffic_light","vhs","vibration_mode","video_camera","video_game","violin","virgo","volcano","volleyball","vs","vulcan_salute","walking_man","walking_woman","waning_crescent_moon","waning_gibbous_moon","warning","wastebasket","watch","water_buffalo","watermelon","wave","wavy_dash","waxing_crescent_moon","wc","weary","wedding","weight_lifting_man","weight_lifting_woman","whale","whale2","wheel_of_dharma","wheelchair","white_check_mark","white_circle","white_flag","white_flower","white_large_square","white_medium_small_square","white_medium_square","white_small_square","white_square_button","wilted_flower","wind_chime","wind_face","wine_glass","wink","wolf","woman","woman_artist","woman_astronaut","woman_cartwheeling","woman_cook","woman_facepalming","woman_factory_worker","woman_farmer","woman_firefighter","woman_health_worker","woman_judge","woman_juggling","woman_mechanic","woman_office_worker","woman_pilot","woman_playing_handball","woman_playing_water_polo","woman_scientist","woman_shrugging","woman_singer","woman_student","woman_teacher","woman_technologist","woman_with_turban","womans_clothes","womans_hat","women_wrestling","womens","world_map","worried","wrench","writing_hand","yellow_heart","yen","yin_yang","yum","zap","zipper_mouth_face","zzz","octocat","Converter","converterOptions","langExtensions","outputModifiers","setConvFlavor","parsed","raw","format","_parseExtension","legacyExtensionLoading","validExt","gOpt","_constructor","_dispatch","evtName","globals","ei","nText","makeHtml","gHtmlBlocks","gHtmlMdBlocks","gHtmlSpans","gUrls","gTitles","gDimensions","gListLevel","hashLinkCounts","converter","rsp","rgx","rTrimInputText","makeMarkdown","makeMd","HTMLParser","doc","preList","pres","presPH","childElementCount","tagName","content","trim","outerHTML","substitutePreCodeTags","clean","mdDoc","addExtension","useExtension","extensionName","output","getMetadata","getMetadataFormat","_setMetadataPair","_setMetadataFormat","_setMetadataRaw","writeAnchorTag","linkText","linkId","url","m5","m6","title","wm","st","escape","mentions","username","lnk","simpleURLRegex","simpleURLRegex2","delimUrlRegex","simpleMailRegex","delimMailRegex","replaceLink","leadingMagicChars","m3","trailingPunctuation","trailingMagicChars","lnkTxt","lmc","tmc","replaceMail","href","bq","pre","codeblock","doctype","doctypeParsed","charset","meta","leadingText","numSpaces","emojiCode","delim","blockText","blockTags","repFunc","inside","opTagPos","rgx1","patLeft","patRight","subTexts","newSubText1","hashHTMLSpan","repText","limit","num","$1","isNaN","parseInt","setextRegexH1","setextRegexH2","spanGamut","hID","headerId","hashBlock","matchFound","hLevel","atxStyle","prefix","customizedHeaderId","hText","header","writeImageTag","altText","width","height","gDims","parseInside","lead","processListItems","listStr","trimTrailing","isParagraphed","m4","taskbtn","checked","bulletStyle","otp","wm2","styleStartNumber","listType","res","parseConsecutiveLists","olRgx","ulRgx","counterRxg","parseCL","parseMetadataContents","wholematch","grafs","grafsOut","grafsOutIt","codeFlag","$2","replaceFunc","blankLines","parseCells","cell","parseTable","rawTable","tableLines","sLine","rawHeaders","rawStyles","rawCells","headers","styles","cells","shift","tableHeaderId","row","ii","tb","tblLgn","buildTable","charCodeToReplace","fromCharCode","hasChildNodes","childrenLength","innerTxt","headerLevel","headerMark","listItems","listItemsLenght","listNum","listItemTxt","childrenLenght","spansOnly","tableArray","headings","rows","headContent","allign","cols","getElementsByTagName","cellContent","cellSpacesCount","strLen","generateAuthHeader","auth","password","btoa","getBasicAuthHeader","token","consumerKey","nonce","signatureMethod","timestamp","tokenKey","getOAuth1Header","parseUrlWithParams","req","params","parameters","param","disabled","encodeURIComponent","curl","buildUrl","authHeader","cookies","hasForm","mimeType","mime","payload","files","parseBody","boundary","isHTTPS","getMethod","CodeGenerator","cookiejars","appendCookies","authentication","jar","domain","path","variable","BodyParser","note","__parseJSON","__parseMultipart","__parsePlain","ContentGenerator","formatEnv","exampleResponses","getClassForStatusCode","markdown","copyButton","codeElement","env","reqData","exampleCode","generate","generateCode","exampleHTML","ClipboardJS","setTimeout","group","groupData","applyEnv","_type","isActive","isFirst","isHover","getOptionLabel","filterText","itemClasses","isGroupHeader","isGroupItem","slot_ctx","getComputedStyle","iframe","tabIndex","unsubscribe","contentWindow","onload","old_blocks","get_key","dynamic","create_each_block","next","get_context","old_indexes","new_blocks","new_lookup","deltas","child_ctx","abs","will_move","did_move","first","new_block","old_block","new_key","viewport","contents","mounted","average_height","items","itemHeight","hoverItemIndex","height_map","viewport_height","bottom","content_height","offsetHeight","remaining","refresh","old_start","y","row_height","expected_height","actual_height","scrollTo","isItemFirst","isItemActive","isItemHover","isSelectable","selectedValue","optionIdentifier","itemIndex","dispatch","prev_items","Item","ItemComponent","isVirtualList","isCreator","getGroupHeaderLabel","hideEmptyState","noOptionsMessage","isMulti","activeItemIndex","isScrollingTimer","isScrolling","handleSelect","handleHover","handleClick","stopPropagation","closeList","updateHoverItem","increment","isNonSelectableItem","scrollToActiveItem","offsetBounding","focusedElemBounding","getBoundingClientRect","_hoverItemIndex","clearTimeout","preventDefault","hoverItem","getSelectionLabel","activeSelectedValue","isDisabled","multiFullItemClearable","handleClear","originalItemsClone","prev_selectedValue","prev_listOpen","prev_filterText","prev_isFocused","prev_filteredItems","Selection","SelectionComponent","MultiSelection","MultiSelectionComponent","isCreatable","isFocused","placeholder","itemFilter","groupBy","groupFilter","isGroupHeaderSelectable","loadOptions","hasError","containerStyles","createGroupHeaderItem","groupValue","createItem","isSearchable","inputStyles","isClearable","isWaiting","listPlacement","listOpen","loadOptionsInterval","filteredItems","inputAttributes","listAutoWidth","Icon","iconProps","showChevron","showIndicator","containerClasses","indicatorSvg","ClearIcon","DefaultClearIcon","resetFilter","getItemsHasInvoked","getItems","wait","immediate","timeout","later","callNow","debounce","catch","details","cancelled","_inputAttributes","checkSelectedValueForDuplicates","noDuplicates","ids","uniqueValues","val","findItem","matchTo","setList","$set","loadList","handleMultiItemClear","itemToRemove","getPosition","elem","bounding","innerHeight","clientHeight","innerWidth","clientWidth","any","isOutOfViewport","visibility","handleFocus","removeList","z-index","List","$on","_filteredItems","itemToCreate","existingItemWithFilterValue","existingSelectionWithFilterValue","some","updateSelectedValueDisplay","showSelectedItem","placeholderText","autocomplete","autocorrect","spellcheck","readonly","_items","keepItem","groupValues","sortedGroupedItems","eventTarget","applyEnvForObject","object","replaceObjectValues","environments","config","envId","jsonUrl","location","INSOMNIA_URL","runInInsomniaLink","menuVisible","exampleVisible","localStorage","getItem","color","setItem","selected_option","freeGlobal","freeSelf","Function","thisArg","arrayPush","array","values","objectProto","objectToString","propertyIsEnumerable","spreadableSymbol","isConcatSpreadable","nativeMax","isFlattenable","isObjectLike","isLength","isObject","isArrayLike","isArrayLikeObject","isArguments","toKey","isSymbol","predicate","basePickBy","basePick","iteratee","arrayMap","baseFlatten","depth","isStrict","otherArgs","reExampleResponse","makeExampleResponse","requestData","CuteConfig","json","cute","metaSortKey","cookiejar","resources","mapCookiejar","environment","isPrivate","metaSort","mapEnvironment","groupId","parentId","buildRequest","deepMapGroups","filterRequests","filteredGroups","filterCookiejars","filterEnvironments","filterRootGroups","async","getElementById","fetch","credentials","Accept","Content-Type","insomniaConfig","App","ErrorPage","app"],"mappings":"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A,SACA,MACA,MACA,aACA,MACA,OACA,SACA,MACA,OACA,MACA,MACA,QACA,WACA,QACA,OACA,WACA,QACA,MACA,UACA,QACA,SACA,eACA,MACA,MACA,QACA,QACA,OACA,OACA,OAmCAD,QAhCe,CACf,YACA,WACA,QACA,OACA,iBACA,QA2BApe,KArBY,CACZ,MACA,WACA,YACA,OACA,OACA,UACA,UACA,WACA,WACA,MACA,QACA,OACA,UAWIkf,EAAS,CACbvX,UAAW,OACX4B,MAAO,kBAGHiV,EAAQ,CACZ7W,UAAW,QACX4B,MAAO,KACPG,IAAK,KACL4C,SAAUiR,EACV5T,QAAS,KAGLwV,EAAkB,CACtB5V,MAAO,OACPC,UAAW,GAGP4V,EAAS,CACbzX,UAAW,SACXiC,SAAU,CAAEmI,EAAKzI,kBACjB8H,SAAU,CACR,CACE7H,MAAO,yCACPG,IAAK,MACLE,SAAU,CACRmI,EAAKzI,iBACL4V,GAEF1V,UAAW,IAEb,CACED,MAAO,yCACPG,IAAK,MACLE,SAAU,CACRmI,EAAKzI,iBACL4V,GAEF1V,UAAW,IAEb,CACED,MAAO,8BACPG,IAAK,MACLE,SAAU,CACRmI,EAAKzI,iBACL4V,EACAC,EACAX,IAGJ,CACEjV,MAAO,8BACPG,IAAK,MACLE,SAAU,CACRmI,EAAKzI,iBACL4V,EACAC,EACAX,IAGJ,CACEjV,MAAO,eACPG,IAAK,IACLF,UAAW,IAEb,CACED,MAAO,eACPG,IAAK,IACLF,UAAW,IAEb,CACED,MAAO,4BACPG,IAAK,KAEP,CACEH,MAAO,4BACPG,IAAK,KAEP,CACEH,MAAO,4BACPG,IAAK,IACLE,SAAU,CACRmI,EAAKzI,iBACL6V,EACAX,IAGJ,CACEjV,MAAO,4BACPG,IAAK,IACLE,SAAU,CACRmI,EAAKzI,iBACL6V,EACAX,IAGJzM,EAAKtI,iBACLsI,EAAKlI,oBAKHwV,EAAY,kBACZC,EAAa,QAAQD,WAAmBA,UAAkBA,QAC1Dd,EAAS,CACb5W,UAAW,SACX6B,UAAW,EACX4H,SAAU,CAWR,CACE7H,MAAO,QAAQ8V,OAAeC,gBAAyBD,cA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"} \ No newline at end of file diff --git a/app/src/main/docs/html/favicon.ico b/app/src/main/docs/html/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4bfb9afe97a450ad3de14151b547424c18cd38b4 GIT binary patch literal 33310 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 + + + + + + + + + + + + +
    + + diff --git a/app/src/main/docs/html/insomnia.json b/app/src/main/docs/html/insomnia.json new file mode 100644 index 00000000..cfec23ea --- /dev/null +++ b/app/src/main/docs/html/insomnia.json @@ -0,0 +1 @@ +{"_type":"export","__export_format":4,"__export_date":"2022-10-20T19:06:47.174Z","__export_source":"insomnia.desktop.app:v2022.6.0","resources":[{"_id":"req_1a7b1ee2f01f4ce2a1621855a3c3351a","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666292507799,"created":1666185103116,"url":"{{baseUrl}}/users/1/transactions","name":"Create User Transaction","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"amount\": 1500,\n\t\"type\": \"debt\",\n\t\"to\": 2\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1666185103116,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_a052e33ed66e4d98834b4bf6cd760389","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666114938461,"created":1666114938461,"name":"Users","description":"","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1666114938461,"_type":"request_group"},{"_id":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","parentId":null,"modified":1666114932310,"created":1666114932310,"name":"BackendChallenge","description":"","scope":"collection","_type":"workspace"},{"_id":"req_f37c3f6499564ea491356edb40740fdc","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666235521765,"created":1666188017345,"url":"{{baseUrl}}/users/1/transactions","name":"Get User Transactions","description":"","method":"GET","body":{},"parameters":[{"id":"pair_0a074b65359146829f9f4feb765b4ba5","name":"page","value":"2","description":""},{"id":"pair_8e4a6d20f778413c90342aabc8318576","name":"perPage","value":"3","description":""}],"headers":[],"authentication":{},"metaSortKey":-1666150021495,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_ce08a86a916b47bbb07b8be9a06b91bf","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666186702358,"created":1666114939874,"url":"{{baseUrl}}/users","name":"Get Users","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1666114939874,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_33367c55d2064f56952a51330682d298","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666123446983,"created":1666123443230,"url":"{{baseUrl}}/users/1","name":"Delete User","description":"","method":"DELETE","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1665817526841.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_9022a9bb05cc45c288bb68601e7b1b7c","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666115032037,"created":1666115028820,"url":"{{baseUrl}}/users/1","name":"Get Users By Id","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1665520113809,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_cf3fb2462edc49b0b3f087a7420a7eea","parentId":"fld_a052e33ed66e4d98834b4bf6cd760389","modified":1666292513172,"created":1666115039543,"url":"{{baseUrl}}/users","name":"Create User","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"name\": \"João Teixeira Ais\",\n\t\"email\": \"joaoteixeiraais@gmail.com\",\n\t\"birthDay\": \"2003-08-26\",\n\t\"password\": \"123321\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1665222700776.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_7c7d33b661bb4542be9eddc0713f95fe","parentId":"fld_1d2b2c2bc6204adb9659454b69e60852","modified":1666292501589,"created":1666236236507,"url":"{{baseUrl}}/transactions","name":"Post Transactions","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"amount\": 1500,\n\t\"type\": \"chargeback\",\n\t\"to\": 2,\n\t\"from\": 1,\n\t \"chargebackFrom\": 1\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1666185103116,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_1d2b2c2bc6204adb9659454b69e60852","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666236236484,"created":1666236236484,"name":"Trasactions","description":"","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1664568081339.5,"_type":"request_group"},{"_id":"req_3bec4a7a6bfe4d42a355f6ba992b641c","parentId":"fld_1d2b2c2bc6204adb9659454b69e60852","modified":1666292497072,"created":1666236236507,"url":"{{baseUrl}}/transactions","name":"Get Transactions","description":"","method":"GET","body":{},"parameters":[{"id":"pair_0a074b65359146829f9f4feb765b4ba5","name":"page","value":"2","description":""},{"id":"pair_8e4a6d20f778413c90342aabc8318576","name":"perPage","value":"3","description":""},{"id":"pair_2f5d823bb1c744179297554bc6356419","name":"userId","value":"1","description":""}],"headers":[],"authentication":{},"metaSortKey":-1666150021495,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_8ae68353e95c4081ad2a743afd848478","parentId":"fld_1d2b2c2bc6204adb9659454b69e60852","modified":1666292155112,"created":1666292152246,"url":"{{baseUrl}}/transactions/csv","name":"Get Transactions CSV","description":"","method":"GET","body":{},"parameters":[{"id":"pair_0a074b65359146829f9f4feb765b4ba5","name":"page","value":"2","description":""},{"id":"pair_8e4a6d20f778413c90342aabc8318576","name":"perPage","value":"3","description":""},{"id":"pair_2f5d823bb1c744179297554bc6356419","name":"userId","value":"1","description":""}],"headers":[],"authentication":{},"metaSortKey":-1666132480684.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_3ccb4c4d6d9247644c2c79a62f41d4e744699ee0","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666114952084,"created":1666114932313,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1666114932313,"_type":"environment"},{"_id":"jar_3ccb4c4d6d9247644c2c79a62f41d4e744699ee0","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666114932314,"created":1666114932314,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_74154c8af1f24d998cc4b26b0897a649","parentId":"wrk_72ad3ffb0a8242eaa4e5cfcf1beff91d","modified":1666114932311,"created":1666114932311,"fileName":"BackendChallenge","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_c7a84395678a441fb7da3e2c70536328","parentId":"env_3ccb4c4d6d9247644c2c79a62f41d4e744699ee0","modified":1666114984073,"created":1666114954031,"name":"localhost","data":{"baseUrl":"http://localhost:3000"},"dataPropertyOrder":{"&":["baseUrl"]},"color":"#04d755","isPrivate":false,"metaSortKey":1666114954031,"_type":"environment"}]} \ No newline at end of file diff --git a/app/src/main/docs/html/logo.png b/app/src/main/docs/html/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..434c951fd4e61e7935e6ff627da7bc2c4dec8113 GIT binary patch literal 1957 zcmY*aXIPWj5~eLe1VRaH1nCHYMbXfe2myg4QeuEB+(ko+B29W#dQn0V;Uc|A2Ppxh z+7Jbk7*Io%2r4D81c*Vp#QnT~?%p5gooCLR^PKa{yz|aotev$eNEXDy!y}4DUBCg> z0rR{p)VjEBY9b}u^)JNj$HlaEe`zY=fLEB@$Khc)@|0S@Qhrjp_zxI zIZnt{=OTrGR1*9MS0CDL3$yT{xBQz(;h)(b(@@xMPeYGWIx+r+w*8&p)mP3gQ<(nt zOD+B<#w0)H36%8MW}*|<=BLhUY!`Ca=-YR~ZymkB*{CxK`z%kCRjEIdD69HU5X&!^ zWO`kBP(IO?=2o92_&k-`+^+P1mTLoj<#|k9^~R8u)Usx7&4Qb7Rni_PYBkM8$a~+}IWqC>pbq7S!t`qibk5%FMkH`bo|7CdrI0pwOC&y(kZ$4qb0x z1kp6zcc@@@oEYe1gi*eEN%M%bk5BmKLZxVDgaP~Kll^}C-q3Y*;w6aCNacCB zT|U~_h<((gNaJiWXXlfML27mCMv*;fz;71C^XeO>Y4o(1K%Ye1-YvVc6NcDyKlRaz zIvMPxyJ+BK%P4iEpJS54hA)G1;Iq^nw zO@R|rh@RB#5kajl;2zi{9xulP9<0t95ex^nR6-I}_V{IiIyB@x#2Qc&O`qsdnj>Xy zY;aF=dVfDyO`$Cnk7g>OybxNETc)Mj{3Yo>>A`sb~)(_K|5J_RKxhlU*R z^}S_|$cHZZlK@lFm0>TJ62yzt>m3brN9z>lYGqS@${;`J4Gi)t13~k-e5LWgZPPP0 zRc87bnd*1#mQja)CPFOS23JGcy9TXmmOgBXD3(_gohl`&Hm|Y2Y#EbO+ej_cY!!%> zy9;~xvK9J-NaG4+@tB$=?9nR6)7q^{pH(TD|6AN19jfS>;ox6xP507`s-9>&a*j`K z04x826`EB{5_w%zT+CdoQhgEzr{G`^Z4ZYK6c7zRKIP5!MM+7NKEOlWhs&H;jE+7?M|FN%0>;EnV>*8u5rVi=|5L@yWdQj}CFD#TD2i54&jo;JBZ)7;MJ zan-_|Djv>yVFh2s0Gqr!0i;>HDl=ynen-9oAG-Y8Z64Vg4 zih-mMD&u^`R{$45@UX@v?~DxRth+dkK1J}ZcZFSvo#>3pIaQkNAcB-QRdUxI`djtQ zb#O@c+Mykkd>Z6xB2@)VR9WsLPtzSxs~cOJZgIL17dMh@{hsK=hi-p|^abEVkU6Q@ z_V=huISNssh^ytf=VyqRli~%~IvgM1eE}ONAJ>97QS--Pk`jLDatf!obzZeY20>Egqn$X z%zoQZ%-%0?EFNB6_-t=T3K`W>qr=!=H!l}F`%jId4}RmF1V&G{R5kbtvy!XS*x2Sq zsL!JDD_{F+TzkH}N>*Xncd4-4Uj+~ycqZTTC@!cxgHe0@zZWUu*@WHi^8!!7`jx$o zGCiNP@Y9mjF`n@=y2iEhE|?lvo4Z5&a4ds1`FuRJe_YK|$Nl6%Dk0JvWF$Z&6E;hXWWJ0A=9$kv#ECUl-0R+*l*@IEH2j~w1I%3>w58pJ7IU}6zX2XDz>WX_ literal 0 HcmV?d00001 From 4c760805472998d74ee1fc65a1cba8f3b083bf53 Mon Sep 17 00:00:00 2001 From: Guilherme Teixeira Ais Date: Thu, 20 Oct 2022 16:40:43 -0300 Subject: [PATCH 105/105] =?UTF-8?q?feat:=20serve=20arquivos=20est=C3=A1tic?= =?UTF-8?q?os?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/config/app.ts | 2 ++ app/src/main/config/setup-docs.ts | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 app/src/main/config/setup-docs.ts diff --git a/app/src/main/config/app.ts b/app/src/main/config/app.ts index 5e4951ba..baef5646 100644 --- a/app/src/main/config/app.ts +++ b/app/src/main/config/app.ts @@ -1,8 +1,10 @@ import express from 'express' import { setupMiddlewares } from './middlewares' import { setupRoutes } from './routes' +import { setupDocs } from './setup-docs' const app = express() +setupDocs(app) setupMiddlewares(app) setupRoutes(app) diff --git a/app/src/main/config/setup-docs.ts b/app/src/main/config/setup-docs.ts new file mode 100644 index 00000000..4ea5f7fd --- /dev/null +++ b/app/src/main/config/setup-docs.ts @@ -0,0 +1,6 @@ +import express, { Express } from 'express' +import { resolve } from 'path' + +export function setupDocs(app: Express): void { + app.use('/', express.static(resolve(__dirname, '../docs/html/'))) +}