diff --git a/.github/workflows/linting-action.yml b/.github/workflows/linting-action.yml index 7a51c39..94180c4 100644 --- a/.github/workflows/linting-action.yml +++ b/.github/workflows/linting-action.yml @@ -2,13 +2,13 @@ name: Application Linting # When the to run the greeting -on: [pull_request] +on: [pull_request, push] # Jobs to run for the action (You can have multiple actions in one file) jobs: run-linters: # Job display name - name: Linting Action + name: Running the eslint checks # Runs on a Linux based OS runs-on: ubuntu-latest @@ -49,7 +49,7 @@ jobs: # Installs all the project dependencies e.g. prettier, eslint etc via a custom project script - name: Install Node.js dependencies - run: npm run all-dependencies + run: npm run allDependencies # Run the linting action - name: Run linters diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml index 9cd7a09..723aa0a 100644 --- a/.github/workflows/test-action.yml +++ b/.github/workflows/test-action.yml @@ -1,14 +1,14 @@ # Job name -name: Intergration and Unit Tests +name: Integration and Unit Tests # When the to run the greeting -on: [pull_request] +on: [pull_request, push] # Jobs to run for the action (You can have multiple actions in one file) jobs: test: # Job display name - name: Running React-Testing-Library and Jest tests + name: Running the jest tests # Runs on a Linux based OS runs-on: ubuntu-latest @@ -20,7 +20,7 @@ jobs: # Steps involved for this particular task steps: - # Checks out the reporsitoy and enables the use of commands made avaliable in the project ie npm run + # Checks out the repository and enables the use of commands made available in the project ie npm run - name: Check out Git repository uses: actions/checkout@v2 @@ -54,7 +54,7 @@ jobs: # Installs all the project dependencies e.g. prettier, eslint etc via a custom project script - name: Install Node.js dependencies - run: npm run all-dependencies + run: npm run allDependencies # Run the react-testing-library tests - name: Run all tests diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a7549e7 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,20 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "VisualStudioExptTeam.vscodeintellicode", + "christian-kohler.npm-intellisense", + "letrieu.expand-region", + "formulahendry.auto-rename-tag", + "christian-kohler.path-intellisense", + "2gua.rainbow-brackets", + "PKief.material-icon-theme", + "orta.vscode-jest", + "kumar-harsh.graphql-for-vscode", + "jpoissonnier.vscode-styled-components", + "ionutvmi.path-autocomplete", + "emmanuelbeziat.vscode-great-icons", + "vincaslt.highlight-matching-tag", + "eamodio.gitlens" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b9bcebb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,67 @@ +{ + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "editor.detectIndentation": true, + "editor.fontLigatures": false, + "editor.snippetSuggestions": "top", + "editor.suggest.localityBonus": true, + "editor.acceptSuggestionOnCommitCharacter": false, + "editor.renderWhitespace": "boundary", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, + "editor.cursorSmoothCaretAnimation": true, + "editor.fontSize": 20, + "editor.minimap.enabled": false, + "editor.tabSize": 2, + + "files.trimTrailingWhitespace": true, + "files.trimFinalNewlines": true, + + "workbench.sideBar.location": "left", + + "javascript.updateImportsOnFileMove.enabled": "always", + + "files.autoSave": "off", + "files.exclude": { + "USE_GITIGNORE": true + }, + "files.defaultLanguage": "{activeEditorLanguage}", + + "javascript.validate.enable": true, // Highligts the unused imports when true + "editor.showUnused": true, // Highligts the unused imports when true + + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.code-search": true, + "**/build": true, + "**/.build": true + }, + + "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], + + "javascript.implicitProjectConfig.checkJs": true, + + "breadcrumbs.enabled": true, + "grunt.autoDetect": "off", + "npm.runSilent": true, + "explorer.confirmDragAndDrop": true, + + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.suggestSelection": "recentlyUsedByPrefix", + "editor.suggest.showKeywords": true + }, + + "[json]": { + "breadcrumbs.showBooleans": true + }, + + "files.associations": { + "*.react.js": "javascriptreact", + "*.jsx": "javascriptreact", + "*.js": "javascriptreact" + } +} diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..e6bfae7 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "checkJs": true, + "target": "es5" + }, + "exclude": ["node_modules", "**/node_modules/*"] +} diff --git a/models/Show/CreatedBy.js b/models/BelongsToCollection/index.js similarity index 61% rename from models/Show/CreatedBy.js rename to models/BelongsToCollection/index.js index 0ac460a..342c39e 100644 --- a/models/Show/CreatedBy.js +++ b/models/BelongsToCollection/index.js @@ -1,12 +1,11 @@ const { gql } = require('apollo-server'); const typeDef = gql` - type CreatedBy { + type BelowsToCollection { id: Int - credit_id: String name: String - gender: Int - profile_path: String + backgroundUrl: String + posterUrl: String } `; diff --git a/models/Cast/index.js b/models/Cast/index.js index ebb560b..8a2a5be 100644 --- a/models/Cast/index.js +++ b/models/Cast/index.js @@ -2,14 +2,11 @@ const { gql } = require('apollo-server'); const typeDef = gql` type Cast { - cast_id: Int - character: String - credit_id: String - gender: Int id: Int - name: String - order: Int - image: String + character: String + profileImageUrl: String + gender: String + episodeCount: Int } `; diff --git a/models/Company/index.js b/models/Company/index.js index 6435493..553d427 100644 --- a/models/Company/index.js +++ b/models/Company/index.js @@ -5,7 +5,6 @@ const typeDef = gql` id: Int logo: String name: String - origin_country: String } `; diff --git a/models/Crew/index.js b/models/Crew/index.js index 5611a0f..9fec7d5 100644 --- a/models/Crew/index.js +++ b/models/Crew/index.js @@ -2,13 +2,8 @@ const { gql } = require('apollo-server'); const typeDef = gql` type Crew { - credit_id: String - department: String - gender: Int - id: Int - job: String name: String - profile_path: String + roles: String } `; diff --git a/models/Language/index.js b/models/Language/index.js deleted file mode 100644 index 42dd186..0000000 --- a/models/Language/index.js +++ /dev/null @@ -1,10 +0,0 @@ -const { gql } = require('apollo-server'); - -const typeDef = gql` - type Language { - iso_3166_1: String - name: String - } -`; - -module.exports = typeDef; diff --git a/models/Movie/Movies.js b/models/Movie/Movies.js new file mode 100644 index 0000000..7d84cbb --- /dev/null +++ b/models/Movie/Movies.js @@ -0,0 +1,17 @@ +const { gql } = require('apollo-server'); + +const MoviesModel = gql` + type Movies { + id: Int + name: String + overview: String + backgroundUrl: String + posterUrl: String + genres: [Int] + releaseDate: String + originalLanguage: String + voteAverage: Float + } +`; + +module.exports = MoviesModel; diff --git a/models/Movie/index.js b/models/Movie/index.js new file mode 100644 index 0000000..a40b2c1 --- /dev/null +++ b/models/Movie/index.js @@ -0,0 +1,33 @@ +const { gql } = require('apollo-server'); + +const MovieModel = gql` + type Movie { + id: Int + name: String + overview: String + backgroundUrl: String + posterUrl: String + genres: [Genre] + homepage: String + originalLanguage: String + productionCompanies: [Company] + releaseDate: String + voteAverage: Float + status: String + reviews: [Review] + recommendations: [Movie] + keywords: [Keyword] + social: Social + featuredCast: [Cast] + featuredCrew: [Crew] + featuredVideo: Video + belongsToCollection: BelowsToCollection + tagline: String + runtime: String + + budget: String + revenue: String + } +`; + +module.exports = MovieModel; diff --git a/models/Movies/Movie.js b/models/Movies/Movie.js deleted file mode 100644 index 2e42528..0000000 --- a/models/Movies/Movie.js +++ /dev/null @@ -1,40 +0,0 @@ -const { gql } = require('apollo-server'); - -const MovieModel = gql` - type Movie { - adult: Boolean - backdrop_path: String - belongs_to_collection: String - budget: String - genres: [Genre] - homepage: String - id: Int - imdb_id: String - original_language: String - original_title: String - overview: String - popularity: Float - poster_path: String - production_companies: [Company] - production_countries: [Language] - release_date: String - revenue: String - runtime: Int - spoken_languages: [Language] - status: String - tagline: String - title: String - video: Boolean - vote_average: Float - vote_count: Int - reviews: [Review] - recomendations: [Movie] - keywords: [Keyword] - social: Social - cast: [Cast] - crew: [Crew] - videos: [Video] - } -`; - -module.exports = MovieModel; diff --git a/models/Movies/index.js b/models/Movies/index.js deleted file mode 100644 index d194a69..0000000 --- a/models/Movies/index.js +++ /dev/null @@ -1,22 +0,0 @@ -const { gql } = require('apollo-server'); - -const MovieModel = gql` - type Movies { - popularity: Float - vote_count: Int - video: Boolean - poster_path: String - id: Int - adult: Boolean - backdrop_path: String - original_language: String - original_title: String - genre_ids: [Int] - title: String - vote_average: Float - overview: String - release_date: String - } -`; - -module.exports = MovieModel; diff --git a/models/People/Credits.js b/models/People/Credits.js index ff17aec..082e08d 100644 --- a/models/People/Credits.js +++ b/models/People/Credits.js @@ -2,11 +2,16 @@ const { gql } = require('apollo-server'); const typeDef = gql` type Credits { - release_date: String - original_title: String - episode_count: String - first_air_date: String - media_type: String + year: String + credits: [Credit] + } + + type Credit { + releaseDate: String + title: String + episodeCount: String + mediaType: String + role: String } `; diff --git a/models/People/KnownFor.js b/models/People/KnownFor.js deleted file mode 100644 index 75a9830..0000000 --- a/models/People/KnownFor.js +++ /dev/null @@ -1,24 +0,0 @@ -const { gql } = require('apollo-server'); - -const typeDef = gql` - type KnownFor { - poster_path: String - adult: Boolean - overview: String - release_date: String - original_title: String - original_name: String - genre_ids: [Int] - id: Int - media_type: String - original_language: String - title: String - backdrop_path: String - popularity: Float - vote_count: Int - video: Boolean - vote_average: Float - } -`; - -module.exports = typeDef; diff --git a/models/People/Person.js b/models/People/Person.js index f87339d..5553990 100644 --- a/models/People/Person.js +++ b/models/People/Person.js @@ -2,21 +2,18 @@ const { gql } = require('apollo-server'); const typeDef = gql` type Person { - birthday: String - known_for_department: String - deathday: String id: Int + birthday: String + knowForDepartment: String name: String - also_known_as: [String] + alsoKnownAs: [String] gender: String - biography: String - popularity: Float - place_of_birth: String - profile_path: String - adult: Boolean - imdb_id: String - homepage: String + overview: String # Biography + placeOfBirth: String + posterUrl: String # profile_path credits: PeopleCredits + social: Social + homepage: String } type PeopleCredits { diff --git a/models/People/index.js b/models/People/index.js index ef18aa2..d4ccd95 100644 --- a/models/People/index.js +++ b/models/People/index.js @@ -2,12 +2,10 @@ const { gql } = require('apollo-server'); const typeDef = gql` type People { - profile_path: String - adult: Boolean id: Int - known_for: [KnownFor] name: String - popularity: Float + posterUrl: String + roles: String } `; diff --git a/models/Query/index.js b/models/Query/index.js index 55fc504..f7b19ad 100644 --- a/models/Query/index.js +++ b/models/Query/index.js @@ -34,8 +34,6 @@ const Query = gql` TopRatedMovies: [Movies] TopRatedShows: [Shows] - - FilterCredits(id: Int!, mediaType: String!): PeopleCredits } `; diff --git a/models/Show/CurrentSeason.js b/models/Show/CurrentSeason.js index d99c6f9..0adef69 100644 --- a/models/Show/CurrentSeason.js +++ b/models/Show/CurrentSeason.js @@ -2,10 +2,10 @@ const { gql } = require('apollo-server'); const typeDef = gql` type CurrentSeason { - image: String - season_number: Int + backgroundUrl: String + seasonNumber: Int year: String - episode_count: Int + episodeCount: Int overview: String } `; diff --git a/models/Show/LastEpisodeToAir.js b/models/Show/LastEpisodeToAir.js deleted file mode 100644 index b47f4b7..0000000 --- a/models/Show/LastEpisodeToAir.js +++ /dev/null @@ -1,19 +0,0 @@ -const { gql } = require('apollo-server'); - -const typeDef = gql` - type LastEpisodeToAir { - air_date: String - episode_number: Int - id: Int - name: String - overview: String - production_code: String - season_number: Int - show_id: Int - still_path: String - vote_average: Int - vote_count: Int - } -`; - -module.exports = typeDef; diff --git a/models/Show/Network.js b/models/Show/Network.js index f4493a5..b55bcb5 100644 --- a/models/Show/Network.js +++ b/models/Show/Network.js @@ -4,8 +4,8 @@ const typeDef = gql` type Network { name: String id: Int - logo_path: String - origin_country: String + logoUrl: String + originCountry: String } `; diff --git a/models/Show/Season.js b/models/Show/Season.js deleted file mode 100644 index da51c4e..0000000 --- a/models/Show/Season.js +++ /dev/null @@ -1,15 +0,0 @@ -const { gql } = require('apollo-server'); - -const typeDef = gql` - type Season { - air_date: String - episode_count: Int - id: Int - name: String - overview: String - poster_Path: String - season_number: Int - } -`; - -module.exports = typeDef; diff --git a/models/Show/Shows.js b/models/Show/Shows.js new file mode 100644 index 0000000..ef63dd0 --- /dev/null +++ b/models/Show/Shows.js @@ -0,0 +1,17 @@ +const { gql } = require('apollo-server'); + +const typeDef = gql` + type Shows { + id: String + name: String + overview: String + backgroundUrl: String + posterUrl: String + genres: [Int] + releaseDate: String + originalLanguage: String + voteAverage: Float + } +`; + +module.exports = typeDef; diff --git a/models/Show/index.js b/models/Show/index.js index 7aaab56..5699e51 100644 --- a/models/Show/index.js +++ b/models/Show/index.js @@ -2,56 +2,36 @@ const { gql } = require('apollo-server'); const typeDef = gql` type Show { - backdrop_path: String - created_by: [CreatedBy] - episode_run_time: String - genres: [Genre] - homepage: String id: Int - in_production: Boolean - languages: [String] - last_air_date: String - last_episode_to_air: LastEpisodeToAir name: String - next_episode_to_air: LastEpisodeToAir - networks: [Network] - number_of_episodes: Int - number_of_seasons: Int - origin_country: [String] - original_language: String - original_name: String overview: String - popularity: Int - poster_path: String - production_companies: [Company] - seasons: [Season] + backgroundUrl: String + posterUrl: String + genres: [Genre] + homepage: String + originalLanguage: String + productionCompanies: [Company] + releaseDate: String + voteAverage: Float status: String - type: String - vote_average: Int - vote_count: Int reviews: [Review] - recomendations: [Shows] + recommendations: [Movie] keywords: [Keyword] social: Social - cast: [Cast] - crew: [Crew] - videos: [Video] - current_season: CurrentSeason - } + featuredCast: [Cast] + featuredCrew: [Crew] + featuredVideo: Video + belongsToCollection: BelowsToCollection + tagline: String + runtime: String - type Shows { - poster_path: String - popularity: Float - id: Int - backdrop_path: String - vote_average: Float - overview: String - release_date: String - genre_ids: [Int] - original_language: String - vote_count: Int - name: String - original_name: String + Network: [Network] + numberOfSeasons: Int + numberOfEpisodes: Int + originCountry: [String] + company: [Company] + currentSeason: CurrentSeason + type: String } `; diff --git a/models/Social/index.js b/models/Social/index.js index ac7f30e..0a14c4d 100644 --- a/models/Social/index.js +++ b/models/Social/index.js @@ -2,11 +2,10 @@ const { gql } = require('apollo-server'); const typeDef = gql` type Social { - id: Int - imdb_id: String - facebook_id: String - instagram_id: String - twitter_id: String + facebook: String + instagram: String + twitter: String + homepage: String } `; diff --git a/models/Videos/index.js b/models/Videos/index.js index f31e61c..59b6e82 100644 --- a/models/Videos/index.js +++ b/models/Videos/index.js @@ -3,14 +3,10 @@ const { gql } = require('apollo-server'); const typeDef = gql` type Video { id: String - iso_639_1: String - iso_3166_1: String - key: String name: String - site: String - size: Int - type: String url: String + type: String + site: String } `; diff --git a/package-lock.json b/package-lock.json index e6cab1e..5513186 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@apollo/protobufjs": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.0.4.tgz", - "integrity": "sha512-EE3zx+/D/wur/JiLp6VCiw1iYdyy1lCJMf8CGPkLeDt5QJrN4N8tKFx33Ah4V30AUQzMk7Uz4IXKZ1LOj124gA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.0.5.tgz", + "integrity": "sha512-ZtyaBH1icCgqwIGb3zrtopV2D5Q8yxibkJzlaViM08eOhTQc7rACdYu0pfORFfhllvdMZ3aq69vifYHszY4gNA==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -25,9 +25,9 @@ }, "dependencies": { "@types/node": { - "version": "10.17.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.26.tgz", - "integrity": "sha512-myMwkO2Cr82kirHY8uknNRHEVtn0wV3DTQfkrjx17jmkstDRZ24gNUdl8AHXVyVclTYI/bNjgTPTAWvWLqXqkw==" + "version": "10.17.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.35.tgz", + "integrity": "sha512-gXx7jAWpMddu0f7a+L+txMplp3FnHl53OhQIF9puXKq3hDGY/GjH+MF04oWnV/adPSCrbtHumDCFwzq2VhltWA==" } } }, @@ -48,99 +48,38 @@ } }, "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "requires": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.10.4" } }, "@babel/core": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", - "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.2", - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helpers": "^7.10.1", - "@babel/parser": "^7.10.2", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.2", + "version": "7.11.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz", + "integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.6", + "@babel/helper-module-transforms": "^7.11.0", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.11.5", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.11.5", + "@babel/types": "^7.11.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", "json5": "^2.1.2", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "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" - } - }, - "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" - } - }, - "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -150,6 +89,15 @@ "ms": "^2.1.1" } }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -165,14 +113,13 @@ } }, "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "version": "7.11.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz", + "integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==", "dev": true, "requires": { - "@babel/types": "^7.10.2", + "@babel/types": "^7.11.5", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" }, "dependencies": { @@ -185,128 +132,128 @@ } }, "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", - "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", + "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.11.0" } }, "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.4" } }, "@babel/helper-module-transforms": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", - "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1", - "lodash": "^4.17.13" + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" } }, "@babel/helper-optimise-call-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", - "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.4" } }, "@babel/helper-plugin-utils": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", - "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true }, "@babel/helper-replace-supers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", - "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-simple-access": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", - "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", "dev": true, "requires": { - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.11.0" } }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "@babel/helpers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", - "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", "dev": true, "requires": { - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/highlight": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -349,9 +296,9 @@ } }, "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", + "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -373,12 +320,21 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", - "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-json-strings": { @@ -391,12 +347,12 @@ } }, "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.1.tgz", - "integrity": "sha512-XyHIFa9kdrgJS91CUH+ccPVTnJShr8nLGc5bG2IhGXv5p1Rd+8BleGE5yzIg2Nc1QZAdHDa0Qp4m6066OL96Iw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-nullish-coalescing-operator": { @@ -409,12 +365,12 @@ } }, "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", - "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -445,157 +401,33 @@ } }, "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "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" - } - }, - "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" - } - }, - "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - } + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", + "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.5", + "@babel/types": "^7.11.5", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.13" + "lodash": "^4.17.19" }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "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" - } - }, - "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" - } - }, - "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -605,6 +437,12 @@ "ms": "^2.1.1" } }, + "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 + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -614,22 +452,14 @@ } }, "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", - "dev": true - } } }, "@bcoe/v8-coverage": { @@ -648,6 +478,47 @@ "minimist": "^1.2.0" } }, + "@eslint/eslintrc": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", + "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -659,6 +530,63 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } } }, "@istanbuljs/schema": { @@ -668,15 +596,16 @@ "dev": true }, "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.3.0.tgz", + "integrity": "sha512-/5Pn6sJev0nPUcAdpJHMVIsA8sKizL2ZkcKPE5+dJrCccks7tcM7c9wbgHudBJbxXLoTbqsHkG1Dofoem4F09w==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.3.0", + "jest-util": "^26.3.0", "slash": "^3.0.0" }, "dependencies": { @@ -697,9 +626,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -708,33 +637,34 @@ } }, "@jest/core": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", - "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.4.2.tgz", + "integrity": "sha512-sDva7YkeNprxJfepOctzS8cAk9TOekldh+5FhVuXS40+94SHbiicRO1VV2tSoRtgIo+POs/Cdyf8p76vPTd6dg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/reporters": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/reporters": "^26.4.1", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.0.1", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-changed-files": "^26.3.0", + "jest-config": "^26.4.2", + "jest-haste-map": "^26.3.0", + "jest-message-util": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-resolve-dependencies": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "jest-watcher": "^26.0.1", + "jest-resolve": "^26.4.0", + "jest-resolve-dependencies": "^26.4.2", + "jest-runner": "^26.4.2", + "jest-runtime": "^26.4.2", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", + "jest-watcher": "^26.3.0", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -770,6 +700,15 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "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" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -780,9 +719,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -791,71 +730,73 @@ } }, "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" } }, "@jest/globals": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", - "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.4.2.tgz", + "integrity": "sha512-Ot5ouAlehhHLRhc+sDz2/9bmNv9p5ZWZ9LE1pXGGTCXBasmi5jnYjlgYcYt03FBwLmZXCZ7GrL29c33/XRQiow==", "dev": true, "requires": { - "@jest/environment": "^26.0.1", - "@jest/types": "^26.0.1", - "expect": "^26.0.1" + "@jest/environment": "^26.3.0", + "@jest/types": "^26.3.0", + "expect": "^26.4.2" } }, "@jest/reporters": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", - "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", + "version": "26.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.4.1.tgz", + "integrity": "sha512-aROTkCLU8++yiRGVxLsuDmZsQEKO6LprlrxtAuzvtpbIFl3eIjgIf3EUxDKgomkS25R9ZzwGEdB5weCcBZlrpQ==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.2", "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-instrument": "^4.0.3", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", - "node-notifier": "^7.0.0", + "jest-haste-map": "^26.3.0", + "jest-resolve": "^26.4.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", + "node-notifier": "^8.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.1.3" + "v8-to-istanbul": "^5.0.1" }, "dependencies": { "chalk": { @@ -881,9 +822,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -892,9 +833,9 @@ } }, "@jest/source-map": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", - "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.3.0.tgz", + "integrity": "sha512-hWX5IHmMDWe1kyrKl7IhFwqOuAreIwHhbe44+XH2ZRHjrKIh0LO5eLQ/vxHFeAfRwJapmxuqlGAEYLadDq6ZGQ==", "dev": true, "requires": { "callsites": "^3.0.0", @@ -911,28 +852,28 @@ } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", - "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.4.2.tgz", + "integrity": "sha512-83DRD8N3M0tOhz9h0bn6Kl6dSp+US6DazuVF8J9m21WAp5x7CqSMaNycMP0aemC/SH/pDQQddbsfHRTBXVUgog==", "dev": true, "requires": { - "@jest/test-result": "^26.0.1", + "@jest/test-result": "^26.3.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1" + "jest-haste-map": "^26.3.0", + "jest-runner": "^26.4.2", + "jest-runtime": "^26.4.2" }, "dependencies": { "graceful-fs": { @@ -944,21 +885,21 @@ } }, "@jest/transform": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", - "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.3.0.tgz", + "integrity": "sha512-Isj6NB68QorGoFWvcOjlUhpkT56PqNIsXKR7XfvoDlCANn/IANlh8DrKAA2l2JKC3yWSMH5wS0GwuQM20w3b2A==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", + "jest-haste-map": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-util": "^26.0.1", + "jest-util": "^26.3.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -989,9 +930,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -1000,13 +941,14 @@ } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1028,9 +970,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -1098,9 +1040,9 @@ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" }, "@sinonjs/commons": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", - "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -1132,9 +1074,9 @@ } }, "@types/babel__core": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", - "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==", + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1164,9 +1106,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", - "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.14.tgz", + "integrity": "sha512-8w9szzKs14ZtBVuP6Wn7nMLRJ0D6dfB0VEBEyRgxrZ/Ln49aNMykrghM2FaNn4FJRzNppCSa0Rv9pBRM5Xc3wg==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -1211,17 +1153,17 @@ } }, "@types/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-invOmosX0DqbpA+cE2yoHGUlF/blyf7nB0OGYBBiH27crcVm5NmFaZkLP4Ta1hGaesckCi5lVLlydNJCxkTOSg==", + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.7.tgz", + "integrity": "sha512-sOdDRU3oRS7LBNTIqwDkPJyq0lpHYcbMTt0TrjzsXbk/e37hcLTH6eZX7CdbDeN0yJJvzw9hFBZkbtCSbk/jAQ==", "requires": { "@types/express": "*" } }, "@types/express": { - "version": "4.17.6", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.6.tgz", - "integrity": "sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w==", + "version": "4.17.8", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.8.tgz", + "integrity": "sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ==", "requires": { "@types/body-parser": "*", "@types/express-serve-static-core": "*", @@ -1230,9 +1172,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.7.tgz", - "integrity": "sha512-EMgTj/DF9qpgLXyc+Btimg+XoH7A2liE8uKul8qSmMTHCeNYzydDKFdsJskDvw42UsesCnhO63dO0Grbj8J4Dw==", + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.12.tgz", + "integrity": "sha512-EaEdY+Dty1jEU7U6J4CUWwxL+hyEGMkO5jan5gplfegUgCUsIUWqXxqw47uGjimeT4Qgkz/XUfwoau08+fgvKA==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -1257,14 +1199,14 @@ } }, "@types/graphql-upload": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@types/graphql-upload/-/graphql-upload-8.0.3.tgz", - "integrity": "sha512-hmLg9pCU/GmxBscg8GCr1vmSoEmbItNNxdD5YH2TJkXm//8atjwuprB+xJBK714JG1dkxbbhp5RHX+Pz1KsCMA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@types/graphql-upload/-/graphql-upload-8.0.4.tgz", + "integrity": "sha512-0TRyJD2o8vbkmJF8InppFcPVcXKk+Rvlg/xvpHBIndSJYpmDWfmtx/ZAtl4f3jR2vfarpTqYgj8MZuJssSoU7Q==", "requires": { "@types/express": "*", "@types/fs-capacitor": "*", "@types/koa": "*", - "graphql": "^14.5.3" + "graphql": "^15.3.0" } }, "@types/http-assert": { @@ -1272,6 +1214,11 @@ "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==" }, + "@types/http-errors": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz", + "integrity": "sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==" + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -1288,15 +1235,90 @@ } }, "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "26.0.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.14.tgz", + "integrity": "sha512-Hz5q8Vu0D288x3iWXePSn53W7hAjP0H7EQ6QvDO9c7t46mR0lNOLlfuwQ+JkVxuhygHzlzPX+0jKdA3ZgSh+Vg==", + "dev": true, + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1309,14 +1331,15 @@ "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==" }, "@types/koa": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.3.tgz", - "integrity": "sha512-ABxVkrNWa4O/Jp24EYI/hRNqEVRlhB9g09p48neQp4m3xL1TJtdWk2NyNQSMCU45ejeELMQZBYyfstyVvO2H3Q==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.4.tgz", + "integrity": "sha512-Etqs0kdqbuAsNr5k6mlZQelpZKVwMu9WPRHVVTLnceZlhr0pYmblRNJbCgoCMzKWWePldydU0AYEOX4Q9fnGUQ==", "requires": { "@types/accepts": "*", "@types/content-disposition": "*", "@types/cookies": "*", "@types/http-assert": "*", + "@types/http-errors": "*", "@types/keygrip": "*", "@types/koa-compose": "*", "@types/node": "*" @@ -1336,14 +1359,14 @@ "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "@types/mime": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.2.tgz", - "integrity": "sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", + "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==" }, "@types/node": { - "version": "14.0.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.11.tgz", - "integrity": "sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg==" + "version": "14.10.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.10.3.tgz", + "integrity": "sha512-zdN0hor7TLkjAdKTnYW+Y22oIhUUpil5ZD1V1OFq0CR0CLKw+NdR6dkziTfkWRLo6sKzisayoj/GNpNbe4LY9Q==" }, "@types/node-fetch": { "version": "2.5.7", @@ -1361,15 +1384,15 @@ "dev": true }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.1.tgz", + "integrity": "sha512-2zs+O+UkDsJ1Vcp667pd3f8xearMdopz/z54i99wtRDI5KLmngk7vlrYZD0ZjKHaROR03EznlBbVY9PfAEyJIQ==", "dev": true }, "@types/qs": { - "version": "6.9.3", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.3.tgz", - "integrity": "sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA==" + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ==" }, "@types/range-parser": { "version": "1.2.3", @@ -1377,9 +1400,9 @@ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" }, "@types/serve-static": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.4.tgz", - "integrity": "sha512-jTDt0o/YbpNwZbQmE/+2e+lfjJEJJR0I3OFaKQKPWkASkCoW3i6fsUnqudSMcNAfbtmADGu8f4MV4q+GqULmug==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.5.tgz", + "integrity": "sha512-6M64P58N+OXjU432WoLLBQxbA0LRGBCRm7aAGQJ+SMC1IMl0dgRVi9EFfoDcS2a7Xogygk/eGN94CfwU9UF7UQ==", "requires": { "@types/express-serve-static-core": "*", "@types/mime": "*" @@ -1392,9 +1415,9 @@ "dev": true }, "@types/ws": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.2.5.tgz", - "integrity": "sha512-4UEih9BI1nBKii385G9id1oFrSkLcClbwtDfcYj8HJLQqZVAtb/42vXVrYvRWCcufNF/a+rZD3MxNwghA7UmCg==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.2.6.tgz", + "integrity": "sha512-Q07IrQUSNpr+cXU4E4LtkSIBPie5GLZyyMC1QtQYRLWz701+XcoVygGUZgvLqElq1nU4ICldMYPnexlBsg3dqQ==", "requires": { "@types/node": "*" } @@ -1423,9 +1446,9 @@ } }, "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, "abbrev": { @@ -1443,9 +1466,9 @@ } }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true }, "acorn-globals": { @@ -1459,21 +1482,21 @@ } }, "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", "dev": true }, "acorn-walk": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", - "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, "ajv": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", - "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "version": "6.12.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", + "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -1502,6 +1525,12 @@ } } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", @@ -1543,50 +1572,43 @@ } }, "apollo-cache-control": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.0.tgz", - "integrity": "sha512-dmRnQ9AXGw2SHahVGLzB/p4UW/taFBAJxifxubp8hqY5p9qdlSu4MPRq8zvV2ULMYf50rBtZyC4C+dZLqmHuHQ==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.1.tgz", + "integrity": "sha512-6iHa8TkcKt4rx5SKRzDNjUIpCQX+7/FlZwD7vRh9JDnM4VH8SWhpj8fUR3CiEY8Kuc4ChXnOY8bCcMju5KPnIQ==", "requires": { - "apollo-server-env": "^2.4.4", - "apollo-server-plugin-base": "^0.9.0" + "apollo-server-env": "^2.4.5", + "apollo-server-plugin-base": "^0.9.1" } }, "apollo-datasource": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.1.tgz", - "integrity": "sha512-h++/jQAY7GA+4TBM+7ezvctFmmGNLrAPf51KsagZj+NkT9qvxp585rdsuatynVbSl59toPK2EuVmc6ilmQHf+g==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.2.tgz", + "integrity": "sha512-ibnW+s4BMp4K2AgzLEtvzkjg7dJgCaw9M5b5N0YKNmeRZRnl/I/qBTQae648FsRKgMwTbRQIvBhQ0URUFAqFOw==", "requires": { - "apollo-server-caching": "^0.5.1", - "apollo-server-env": "^2.4.4" + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5" } }, "apollo-engine-reporting": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-2.0.1.tgz", - "integrity": "sha512-3OYYk7DqNuJ5xKYnyLy5O2n506jYSryim8WqzBTn9MRphRamwPFjHYQm+akPA60AubXrWnYa6A8euMAiQU0ttA==", - "requires": { - "apollo-engine-reporting-protobuf": "^0.5.1", - "apollo-graphql": "^0.4.0", - "apollo-server-caching": "^0.5.1", - "apollo-server-env": "^2.4.4", - "apollo-server-errors": "^2.4.1", - "apollo-server-plugin-base": "^0.9.0", - "apollo-server-types": "^0.5.0", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-2.3.0.tgz", + "integrity": "sha512-SbcPLFuUZcRqDEZ6mSs8uHM9Ftr8yyt2IEu0JA8c3LNBmYXSLM7MHqFe80SVcosYSTBgtMz8mLJO8orhYoSYZw==", + "requires": { + "apollo-engine-reporting-protobuf": "^0.5.2", + "apollo-graphql": "^0.5.0", + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5", + "apollo-server-errors": "^2.4.2", + "apollo-server-plugin-base": "^0.9.1", + "apollo-server-types": "^0.5.1", "async-retry": "^1.2.1", "uuid": "^8.0.0" - }, - "dependencies": { - "uuid": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz", - "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==" - } } }, "apollo-engine-reporting-protobuf": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.5.1.tgz", - "integrity": "sha512-TSfr9iAaInV8dhXkesdcmqsthRkVcJkzznmiM+1Ob/GScK7r6hBYCjVDt2613EHAg9SUzTOltIKlGD+N+GJRUw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.5.2.tgz", + "integrity": "sha512-4wm9FR3B7UvJxcK/69rOiS5CAJPEYKufeRWb257ZLfX7NGFTMqvbc1hu4q8Ch7swB26rTpkzfsftLED9DqH9qg==", "requires": { "@apollo/protobufjs": "^1.0.3" } @@ -1603,9 +1625,9 @@ } }, "apollo-graphql": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.4.5.tgz", - "integrity": "sha512-0qa7UOoq7E71kBYE7idi6mNQhHLVdMEDInWk6TNw3KsSWZE2/I68gARP84Mj+paFTO5NYuw1Dht66PVX76Cc2w==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.5.0.tgz", + "integrity": "sha512-YSdF/BKPbsnQpxWpmCE53pBJX44aaoif31Y22I/qKpB6ZSGzYijV5YBoCL5Q15H2oA/v/02Oazh9lbp4ek3eig==", "requires": { "apollo-env": "^0.6.5", "lodash.sortby": "^4.7.0" @@ -1623,45 +1645,45 @@ } }, "apollo-server": { - "version": "2.14.4", - "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.14.4.tgz", - "integrity": "sha512-5RRs/UnzZMK+QGqCE8Wyfy5vNBFPmweFlkMRs966pM+6orN/g2GxxypKRsGa2rit2Wz0wki8vw+MjI80t2lPvg==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.17.0.tgz", + "integrity": "sha512-vVMu+VqjmsB6yk5iNTb/AXM6EJGd2uwzrcTAbwqvGI7GqCYDRZlGBwrQCjOU/jT/EPWdNRWks/qhJYiQMeVXSg==", "requires": { - "apollo-server-core": "^2.14.4", - "apollo-server-express": "^2.14.4", + "apollo-server-core": "^2.17.0", + "apollo-server-express": "^2.17.0", "express": "^4.0.0", "graphql-subscriptions": "^1.0.0", "graphql-tools": "^4.0.0" } }, "apollo-server-caching": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.1.tgz", - "integrity": "sha512-L7LHZ3k9Ao5OSf2WStvQhxdsNVplRQi7kCAPfqf9Z3GBEnQ2uaL0EgO0hSmtVHfXTbk5CTRziMT1Pe87bXrFIw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.2.tgz", + "integrity": "sha512-HUcP3TlgRsuGgeTOn8QMbkdx0hLPXyEJehZIPrcof0ATz7j7aTPA4at7gaiFHCo8gk07DaWYGB3PFgjboXRcWQ==", "requires": { "lru-cache": "^5.0.0" } }, "apollo-server-core": { - "version": "2.14.4", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.14.4.tgz", - "integrity": "sha512-aAfsvbJ2YrqAXDBgcBQocOmQJ5DkeOnEYQ6ADdkkDNU68V5yBRkAHLTOzPfbUlGHVrnOH8PT1FIVWwu5mBgkVA==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.17.0.tgz", + "integrity": "sha512-rjAkBbKSrGLDfg/g5bohnPlQahmkAxgEBuMDVsoF3aa+RaEPXPUMYrLbOxntl0LWeLbPiMa/IyFF43dvlGqV7w==", "requires": { "@apollographql/apollo-tools": "^0.4.3", "@apollographql/graphql-playground-html": "1.6.26", "@types/graphql-upload": "^8.0.0", "@types/ws": "^7.0.0", - "apollo-cache-control": "^0.11.0", - "apollo-datasource": "^0.7.1", - "apollo-engine-reporting": "^2.0.1", - "apollo-server-caching": "^0.5.1", - "apollo-server-env": "^2.4.4", - "apollo-server-errors": "^2.4.1", - "apollo-server-plugin-base": "^0.9.0", - "apollo-server-types": "^0.5.0", - "apollo-tracing": "^0.11.0", + "apollo-cache-control": "^0.11.1", + "apollo-datasource": "^0.7.2", + "apollo-engine-reporting": "^2.3.0", + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5", + "apollo-server-errors": "^2.4.2", + "apollo-server-plugin-base": "^0.9.1", + "apollo-server-types": "^0.5.1", + "apollo-tracing": "^0.11.2", "fast-json-stable-stringify": "^2.0.0", - "graphql-extensions": "^0.12.3", + "graphql-extensions": "^0.12.4", "graphql-tag": "^2.9.2", "graphql-tools": "^4.0.0", "graphql-upload": "^8.0.2", @@ -1672,32 +1694,32 @@ } }, "apollo-server-env": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.4.4.tgz", - "integrity": "sha512-c2oddDS3lwAl6QNCIKCLEzt/dF9M3/tjjYRVdxOVN20TidybI7rAbnT4QOzf4tORnGXtiznEAvr/Kc9ahhKADg==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.4.5.tgz", + "integrity": "sha512-nfNhmGPzbq3xCEWT8eRpoHXIPNcNy3QcEoBlzVMjeglrBGryLG2LXwBSPnVmTRRrzUYugX0ULBtgE3rBFNoUgA==", "requires": { "node-fetch": "^2.1.2", "util.promisify": "^1.0.0" } }, "apollo-server-errors": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.4.1.tgz", - "integrity": "sha512-7oEd6pUxqyWYUbQ9TA8tM0NU/3aGtXSEibo6+txUkuHe7QaxfZ2wHRp+pfT1LC1K3RXYjKj61/C2xEO19s3Kdg==" + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.4.2.tgz", + "integrity": "sha512-FeGxW3Batn6sUtX3OVVUm7o56EgjxDlmgpTLNyWcLb0j6P8mw9oLNyAm3B+deHA4KNdNHO5BmHS2g1SJYjqPCQ==" }, "apollo-server-express": { - "version": "2.14.4", - "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.14.4.tgz", - "integrity": "sha512-g0ml0NGmghvJhTiXMR0HqDD8eTz77zdgzDG2XoqNoRehtVIsZq8fmKTagVt9cUKCKKiBPUF+4tqAGD9lnprUdw==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.17.0.tgz", + "integrity": "sha512-PonpWOuM1DH3Cz0bu56Tusr3GXOnectC6AD/gy2GXK0v84E7tKTuxEY3SgsgxhvfvvhfwJbXTyIogL/wezqnCw==", "requires": { "@apollographql/graphql-playground-html": "1.6.26", "@types/accepts": "^1.3.5", "@types/body-parser": "1.19.0", "@types/cors": "^2.8.4", - "@types/express": "4.17.4", + "@types/express": "4.17.7", "accepts": "^1.3.5", - "apollo-server-core": "^2.14.4", - "apollo-server-types": "^0.5.0", + "apollo-server-core": "^2.17.0", + "apollo-server-types": "^0.5.1", "body-parser": "^1.18.3", "cors": "^2.8.4", "express": "^4.17.1", @@ -1709,9 +1731,9 @@ }, "dependencies": { "@types/express": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.4.tgz", - "integrity": "sha512-DO1L53rGqIDUEvOjJKmbMEQ5Z+BM2cIEPy/eV3En+s166Gz+FeuzRerxcab757u/U4v4XF4RYrZPmqKa+aY/2w==", + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz", + "integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==", "requires": { "@types/body-parser": "*", "@types/express-serve-static-core": "*", @@ -1722,30 +1744,30 @@ } }, "apollo-server-plugin-base": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.9.0.tgz", - "integrity": "sha512-LWcPrsy2+xqwlNseh/QaGa/MPNopS8c4qGgh0g0cAn0lZBRrJ9Yab7dq+iQ6vdUBwIhUWYN6s9dwUWCZw2SL8g==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.9.1.tgz", + "integrity": "sha512-kvrX4Z3FdpjrZdHkyl5iY2A1Wvp4b6KQp00DeZqss7GyyKNUBKr80/7RQgBLEw7EWM7WB19j459xM/TjvW0FKQ==", "requires": { - "apollo-server-types": "^0.5.0" + "apollo-server-types": "^0.5.1" } }, "apollo-server-types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.5.0.tgz", - "integrity": "sha512-zhtsqqqfdeoJQAfc41Sy6WnnBVxKNgZ34BKXf/Q+kXmw7rbZ/B5SG3SJMvj1iFsbzZxILmWdUsE9aD20lEr0bg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.5.1.tgz", + "integrity": "sha512-my2cPw+DAb2qVnIuBcsRKGyS28uIc2vjFxa1NpRoJZe9gK0BWUBk7wzXnIzWy3HZ5Er11e/40MPTUesNfMYNVA==", "requires": { - "apollo-engine-reporting-protobuf": "^0.5.1", - "apollo-server-caching": "^0.5.1", - "apollo-server-env": "^2.4.4" + "apollo-engine-reporting-protobuf": "^0.5.2", + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5" } }, "apollo-tracing": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.11.0.tgz", - "integrity": "sha512-I9IFb/8lkBW8ZwOAi4LEojfT7dMfUSkpnV8LHQI8Rcj0HtzL9HObQ3woBmzyGHdGHLFuD/6/VHyFD67SesSrJg==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.11.2.tgz", + "integrity": "sha512-QjmRd2ozGD+PfmF6U9w/w6jrclYSBNczN6Bzppr8qA5somEGl5pqdprIZYL28H0IapZiutA3x6p6ZVF/cVX8wA==", "requires": { - "apollo-server-env": "^2.4.4", - "apollo-server-plugin-base": "^0.9.0" + "apollo-server-env": "^2.4.5", + "apollo-server-plugin-base": "^0.9.1" } }, "apollo-utilities": { @@ -1876,9 +1898,9 @@ "dev": true }, "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", + "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "dev": true }, "axios": { @@ -1890,16 +1912,16 @@ } }, "babel-jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", - "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.3.0.tgz", + "integrity": "sha512-sxPnQGEyHAOPF8NcUsD0g7hDCnvLL2XyblRBcgrzTWBB/mAIpWow3n1bEL+VghnnZfreLhFSBsFluRoK2tRK4g==", "dev": true, "requires": { - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.0.0", + "babel-preset-jest": "^26.3.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -1928,9 +1950,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -1952,25 +1974,27 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", - "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", + "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", "dev": true, "requires": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", "@types/babel__traverse": "^7.0.6" } }, "babel-preset-current-node-syntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", - "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", "dev": true, "requires": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1981,13 +2005,13 @@ } }, "babel-preset-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", - "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.3.0.tgz", + "integrity": "sha512-5WPdf7nyYi2/eRxCbVrE1kKCWxgWY4RsPEbdJWFm7QsesFGqjdkyLeu1zRkwM1cxK6EPIlNd6d2AxLk7J+t4pw==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.0.0", - "babel-preset-current-node-syntax": "^0.1.2" + "babel-plugin-jest-hoist": "^26.2.0", + "babel-preset-current-node-syntax": "^0.1.3" } }, "backo2": { @@ -2102,6 +2126,11 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" } } }, @@ -2273,12 +2302,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "chokidar": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", @@ -2327,21 +2350,6 @@ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==" }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -2536,27 +2544,14 @@ } }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "crypto-random-string": { @@ -2752,9 +2747,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz", + "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==", "dev": true }, "doctrine": { @@ -2816,6 +2811,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "emittery": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "dev": true + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -2834,6 +2835,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2888,9 +2898,9 @@ "dev": true }, "escodegen": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.2.tgz", - "integrity": "sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, "requires": { "esprima": "^4.0.1", @@ -2898,24 +2908,67 @@ "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" + }, + "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } } }, "eslint": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.2.0.tgz", - "integrity": "sha512-B3BtEyaDKC5MlfDa2Ha8/D6DsS4fju95zs0hjS3HdGazw+LNayai38A25qMppK37wWGWNYSPOR6oYzlz5MHsRQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.9.0.tgz", + "integrity": "sha512-V6QyhX21+uXp4T+3nrNfI3hQNBDa/P8ga7LoQOenwrlEFXrEnUEE+ok1dMtaS3b6rmLXhT1TkTIsG75HMLbknA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.1.3", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", + "enquirer": "^2.3.5", "eslint-scope": "^5.1.0", - "eslint-utils": "^2.0.0", - "eslint-visitor-keys": "^1.2.0", - "espree": "^7.1.0", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^1.3.0", + "espree": "^7.3.0", "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", @@ -2925,12 +2978,11 @@ "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.14", + "lodash": "^4.17.19", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -2960,17 +3012,6 @@ "supports-color": "^7.1.0" } }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -2980,84 +3021,24 @@ "ms": "^2.1.1" } }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, "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 }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.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 }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "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==", - "dev": true, - "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==", - "dev": true - }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -3068,28 +3049,19 @@ } }, "strip-json-comments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", - "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } } } }, @@ -3114,9 +3086,9 @@ } }, "eslint-import-resolver-node": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", - "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", "dev": true, "requires": { "debug": "^2.6.9", @@ -3131,72 +3103,12 @@ "requires": { "debug": "^2.6.9", "pkg-dir": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } } }, "eslint-plugin-import": { - "version": "2.21.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz", - "integrity": "sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA==", + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz", + "integrity": "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==", "dev": true, "requires": { "array-includes": "^3.1.1", @@ -3223,130 +3135,52 @@ "esutils": "^2.0.2", "isarray": "^1.0.0" } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } } } }, "eslint-plugin-prettier": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz", - "integrity": "sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" } }, "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz", - "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", - "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", "dev": true, "requires": { - "acorn": "^7.2.0", + "acorn": "^7.4.0", "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.2.0" - }, - "dependencies": { - "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", - "dev": true - } + "eslint-visitor-keys": "^1.3.0" } }, "esprima": { @@ -3365,20 +3199,28 @@ }, "dependencies": { "estraverse": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", - "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "estraverse": { @@ -3422,6 +3264,51 @@ "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "exit": { @@ -3466,16 +3353,16 @@ } }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz", + "integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", "jest-regex-util": "^26.0.0" } }, @@ -3520,6 +3407,11 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" } } }, @@ -3550,17 +3442,6 @@ } } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -3633,9 +3514,9 @@ "dev": true }, "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-diff": { @@ -3664,15 +3545,6 @@ "bser": "2.1.1" } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", @@ -3705,13 +3577,12 @@ } }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^2.0.0" } }, "flat-cache": { @@ -3723,17 +3594,6 @@ "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "flatted": { @@ -3907,10 +3767,13 @@ } }, "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 + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } }, "got": { "version": "9.6.0", @@ -3936,21 +3799,18 @@ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "graphql": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.6.0.tgz", - "integrity": "sha512-VKzfvHEKybTKjQVpTFrA5yUq2S9ihcZvfJAtsDBBCuV6wauPu1xl/f9ehgVf0FcEJJs4vz6ysb/ZMkGigQZseg==", - "requires": { - "iterall": "^1.2.2" - } + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.3.0.tgz", + "integrity": "sha512-GTCJtzJmkFLWRfFJuoo9RWWa/FfamUHgiFosxi/X1Ani4AVWbeyBenZTNX6dM+7WSbbFfTo/25eh0LLkwHMw2w==" }, "graphql-extensions": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.3.tgz", - "integrity": "sha512-W7iT0kzlwTiZU7fXfw9IgWnsqVj7EFLd0/wVcZZRAbR8L3f4+YsGls0oxKdsrvYBnbG347BXKQmIyo6GTEk4XA==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.4.tgz", + "integrity": "sha512-GnR4LiWk3s2bGOqIh6V1JgnSXw2RCH4NOgbCFEWvB6JqWHXTlXnLZ8bRSkCiD4pltv7RHUPWqN/sGh8R6Ae/ag==", "requires": { "@apollographql/apollo-tools": "^0.4.3", - "apollo-server-env": "^2.4.4", - "apollo-server-types": "^0.5.0" + "apollo-server-env": "^2.4.5", + "apollo-server-types": "^0.5.1" } }, "graphql-subscriptions": { @@ -3962,9 +3822,9 @@ } }, "graphql-tag": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.3.tgz", - "integrity": "sha512-4FOv3ZKfA4WdOKJeHdz6B3F/vxBLSgmBcGeAFPf4n1F64ltJUvOOerNj0rsJxONQGdhUMynQIvd6LzB+1J5oKA==" + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.11.0.tgz", + "integrity": "sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA==" }, "graphql-tools": { "version": "4.0.8", @@ -3976,6 +3836,13 @@ "deprecated-decorator": "^0.1.6", "iterall": "^1.1.3", "uuid": "^3.1.0" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } } }, "graphql-upload": { @@ -4003,12 +3870,12 @@ "dev": true }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, @@ -4114,13 +3981,13 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz", + "integrity": "sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==", "requires": { "depd": "~1.1.2", "inherits": "2.0.4", - "setprototypeof": "1.1.1", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" } @@ -4169,14 +4036,6 @@ "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } } }, "import-lazy": { @@ -4192,6 +4051,66 @@ "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } } }, "imurmurhash": { @@ -4219,44 +4138,6 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, - "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -4366,9 +4247,9 @@ } }, "is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", "dev": true, "optional": true }, @@ -4568,9 +4449,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -4622,14 +4503,14 @@ "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" }, "jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", - "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.4.2.tgz", + "integrity": "sha512-LLCjPrUh98Ik8CzW8LLVnSCfLaiY+wbK53U7VxnFSX7Q+kWC4noVeDvGWIFw0Amfq1lq2VfGm7YHWSLBV62MJw==", "dev": true, "requires": { - "@jest/core": "^26.0.1", + "@jest/core": "^26.4.2", "import-local": "^3.0.2", - "jest-cli": "^26.0.1" + "jest-cli": "^26.4.2" }, "dependencies": { "chalk": { @@ -4655,30 +4536,30 @@ "dev": true }, "jest-cli": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", - "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.4.2.tgz", + "integrity": "sha512-zb+lGd/SfrPvoRSC/0LWdaWCnscXc1mGYW//NP4/tmBvRPT3VntZ2jtKUONsRi59zc5JqmsSajA9ewJKFYp8Cw==", "dev": true, "requires": { - "@jest/core": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/core": "^26.4.2", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", + "jest-config": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "prompts": "^2.0.1", "yargs": "^15.3.1" } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -4687,31 +4568,20 @@ } }, "jest-changed-files": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", - "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.3.0.tgz", + "integrity": "sha512-1C4R4nijgPltX6fugKxM4oQ18zimS7LqQ+zTTY8lMCMFPrxqBFb7KJH0Z2fRQJvw2Slbaipsqq7s1mgX5Iot+g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "execa": "^4.0.0", "throat": "^5.0.0" }, "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -4726,9 +4596,9 @@ } }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -4748,54 +4618,33 @@ "requires": { "path-key": "^3.0.0" } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "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==", - "dev": true, - "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==", - "dev": true } } }, "jest-config": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", - "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.4.2.tgz", + "integrity": "sha512-QBf7YGLuToiM8PmTnJEdRxyYy3mHWLh24LJZKVdXZ2PNdizSe1B/E8bVm+HYcjbEzGuVXDv/di+EzdO/6Gq80A==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.0.1", - "@jest/types": "^26.0.1", - "babel-jest": "^26.0.1", + "@jest/test-sequencer": "^26.4.2", + "@jest/types": "^26.3.0", + "babel-jest": "^26.3.0", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.0.1", - "jest-environment-node": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.0.1", + "jest-environment-jsdom": "^26.3.0", + "jest-environment-node": "^26.3.0", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.4.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", + "jest-resolve": "^26.4.0", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "micromatch": "^4.0.2", - "pretty-format": "^26.0.1" + "pretty-format": "^26.4.2" }, "dependencies": { "chalk": { @@ -4821,9 +4670,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -4832,15 +4681,15 @@ } }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz", + "integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.3.0", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" }, "dependencies": { "chalk": { @@ -4860,9 +4709,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -4880,16 +4729,16 @@ } }, "jest-each": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", - "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.4.2.tgz", + "integrity": "sha512-p15rt8r8cUcRY0Mvo1fpkOGYm7iI8S6ySxgIdfh3oOIv+gHwrHTy5VWCGOecWUhDsit4Nz8avJWdT07WLpbwDA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1" + "jest-get-type": "^26.3.0", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.2" }, "dependencies": { "chalk": { @@ -4909,9 +4758,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -4920,57 +4769,60 @@ } }, "jest-environment-jsdom": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", - "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.3.0.tgz", + "integrity": "sha512-zra8He2btIMJkAzvLaiZ9QwEPGEetbxqmjEBQwhH3CA+Hhhu0jSiEJxnJMbX28TGUvPLxBt/zyaTLrOPF4yMJA==", "dev": true, "requires": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0", "jsdom": "^16.2.2" } }, "jest-environment-node": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", - "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.3.0.tgz", + "integrity": "sha512-c9BvYoo+FGcMj5FunbBgtBnbR5qk3uky8PKyRVpSfe2/8+LrNQMiXX53z6q2kY+j15SkjQCOSL/6LHnCPLVHNw==", "dev": true, "requires": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-haste-map": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", - "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.3.0.tgz", + "integrity": "sha512-DHWBpTJgJhLLGwE5Z1ZaqLTYqeODQIZpby0zMBsCU9iRFHYyhklYqP4EiG73j5dkbaAdSZhgB938mL51Q5LeZA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "@types/graceful-fs": "^4.1.2", + "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "jest-serializer": "^26.0.0", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.3.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "walker": "^1.0.7" }, "dependencies": { "graceful-fs": { @@ -4982,27 +4834,28 @@ } }, "jest-jasmine2": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", - "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.4.2.tgz", + "integrity": "sha512-z7H4EpCldHN1J8fNgsja58QftxBSL+JcwZmaXIvV9WKIM+x49F4GLHu/+BQh2kzRKHAgaN/E82od+8rTOBPyPA==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/environment": "^26.3.0", + "@jest/source-map": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.0.1", + "expect": "^26.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^26.0.1", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1", + "jest-each": "^26.4.2", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-runtime": "^26.4.2", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.2", "throat": "^5.0.0" }, "dependencies": { @@ -5023,9 +4876,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5034,25 +4887,25 @@ } }, "jest-leak-detector": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", - "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.4.2.tgz", + "integrity": "sha512-akzGcxwxtE+9ZJZRW+M2o+nTNnmQZxrHJxX/HjgDaU5+PLmY1qnQPnMjgADPGCRPhB+Yawe1iij0REe+k/aHoA==", "dev": true, "requires": { - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" } }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.4.2.tgz", + "integrity": "sha512-KcbNqWfWUG24R7tu9WcAOKKdiXiXCbMvQYT6iodZ9k1f7065k0keUOW6XpJMMvah+hTfqkhJhRXmA3r3zMAg0Q==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.4.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" }, "dependencies": { "chalk": { @@ -5072,9 +4925,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5083,13 +4936,13 @@ } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.3.0.tgz", + "integrity": "sha512-xIavRYqr4/otGOiLxLZGj3ieMmjcNE73Ui+LdSW/Y790j5acqCsAdDiLIbzHCZMpN07JOENRWX5DcU+OQ+TjTA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "@types/stack-utils": "^1.0.1", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -5121,9 +4974,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5132,18 +4985,19 @@ } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.3.0.tgz", + "integrity": "sha512-PeaRrg8Dc6mnS35gOo/CbZovoDPKAeB1FICZiuagAgGvbWdNNyjQjkOaGUa/3N3JtpQ/Mh9P4A2D4Fv51NnP8Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.3.0", + "@types/node": "*" } }, "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true }, "jest-regex-util": { @@ -5153,16 +5007,16 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.4.0.tgz", + "integrity": "sha512-bn/JoZTEXRSlEx3+SfgZcJAVuTMOksYq9xe9O6s4Ekg84aKBObEaVXKOEilULRqviSLAYJldnoWV9c07kwtiCg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.3.0", "read-pkg-up": "^7.0.1", "resolve": "^1.17.0", "slash": "^3.0.0" @@ -5174,26 +5028,118 @@ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "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 + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "has-flag": { + "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5202,39 +5148,40 @@ } }, "jest-resolve-dependencies": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", - "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.4.2.tgz", + "integrity": "sha512-ADHaOwqEcVc71uTfySzSowA/RdxUpCxhxa2FNLiin9vWLB1uLPad3we+JSSROq5+SrL9iYPdZZF8bdKM7XABTQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.0.1" + "jest-snapshot": "^26.4.2" } }, "jest-runner": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", - "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.4.2.tgz", + "integrity": "sha512-FgjDHeVknDjw1gRAYaoUoShe1K3XUuFMkIaXbdhEys+1O4bEJS8Avmn4lBwoMfL8O5oFTdWYKcf3tEJyyYyk8g==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/environment": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", + "emittery": "^0.7.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", + "jest-config": "^26.4.2", "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.0.1", - "jest-jasmine2": "^26.0.1", - "jest-leak-detector": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-haste-map": "^26.3.0", + "jest-leak-detector": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-resolve": "^26.4.0", + "jest-runtime": "^26.4.2", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, @@ -5262,9 +5209,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5273,34 +5220,34 @@ } }, "jest-runtime": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", - "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/globals": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.4.2.tgz", + "integrity": "sha512-4Pe7Uk5a80FnbHwSOk7ojNCJvz3Ks2CNQWT5Z7MJo4tX0jb3V/LThKvD9tKPNVNyeMH98J/nzGlcwc00R2dSHQ==", + "dev": true, + "requires": { + "@jest/console": "^26.3.0", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/globals": "^26.4.2", + "@jest/source-map": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", + "jest-config": "^26.4.2", + "jest-haste-map": "^26.3.0", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", + "jest-resolve": "^26.4.0", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^15.3.1" @@ -5328,10 +5275,16 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5340,11 +5293,12 @@ } }, "jest-serializer": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", - "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.3.0.tgz", + "integrity": "sha512-IDRBQBLPlKa4flg77fqg0n/pH87tcRKwe8zxOVTWISxGpPHYkRZ1dXKyh04JOja7gppc60+soKVZ791mruVdow==", "dev": true, "requires": { + "@types/node": "*", "graceful-fs": "^4.2.4" }, "dependencies": { @@ -5357,25 +5311,25 @@ } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.4.2.tgz", + "integrity": "sha512-N6Uub8FccKlf5SBFnL2Ri/xofbaA68Cc3MGjP/NuwgnsvWh+9hLIR/DhrxbSiKXMY9vUW5dI6EW1eHaDHqe9sg==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.4.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.4.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-resolve": "^26.4.0", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.4.2", "semver": "^7.3.2" }, "dependencies": { @@ -5408,9 +5362,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5419,16 +5373,17 @@ } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", + "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "dependencies": { "chalk": { @@ -5454,9 +5409,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5465,17 +5420,17 @@ } }, "jest-validate": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", - "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.4.2.tgz", + "integrity": "sha512-blft+xDX7XXghfhY0mrsBCYhX365n8K5wNDC4XAcNKqqjEzsRUSXP44m6PL0QJEW2crxQFLLztVnJ4j7oPlQrQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "camelcase": "^6.0.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", + "jest-get-type": "^26.3.0", "leven": "^3.1.0", - "pretty-format": "^26.0.1" + "pretty-format": "^26.4.2" }, "dependencies": { "camelcase": { @@ -5501,9 +5456,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5512,16 +5467,17 @@ } }, "jest-watcher": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", - "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.3.0.tgz", + "integrity": "sha512-XnLdKmyCGJ3VoF6G/p5ohbJ04q/vv5aH9ENI+i6BL0uu9WWB6Z7Z2lhQQk0d2AVZcRGp1yW+/TsoToMhBFPRdQ==", "dev": true, "requires": { - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.0.1", + "jest-util": "^26.3.0", "string-length": "^4.0.1" }, "dependencies": { @@ -5542,9 +5498,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5553,11 +5509,12 @@ } }, "jest-worker": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", - "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", + "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==", "dev": true, "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, @@ -5569,9 +5526,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -5586,9 +5543,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -5602,9 +5559,9 @@ "dev": true }, "jsdom": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", - "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", "dev": true, "requires": { "abab": "^2.0.3", @@ -5627,7 +5584,7 @@ "tough-cookie": "^3.0.1", "w3c-hr-time": "^1.0.2", "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.0.0", + "webidl-conversions": "^6.1.0", "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.0.0", @@ -5636,9 +5593,9 @@ }, "dependencies": { "ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", "dev": true } } @@ -5654,10 +5611,10 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema": { @@ -5685,12 +5642,12 @@ "dev": true }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "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.5" + "minimist": "^1.2.0" } }, "jsprim": { @@ -5740,13 +5697,13 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "lines-and-columns": { @@ -5765,38 +5722,22 @@ "parse-json": "^2.2.0", "pify": "^2.0.0", "strip-bom": "^3.0.0" - }, - "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } } }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { - "p-locate": "^4.1.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.sortby": { "version": "4.7.0", @@ -5804,9 +5745,9 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" }, "loglevel": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", - "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.0.tgz", + "integrity": "sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==" }, "long": { "version": "4.0.0", @@ -5902,16 +5843,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "requires": { - "mime-db": "1.43.0" + "mime-db": "1.44.0" } }, "mimic-fn": { @@ -5969,21 +5910,15 @@ } }, "moment": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", - "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.28.0.tgz", + "integrity": "sha512-Z5KOjYmnHyd/ukynmFd/WwyXHd7L4J9vTI/nn5Ap9AVUgaAE15VvQ9MOGmJJygEUklupqIrFnor/tjTwRU+tQw==" }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -6021,9 +5956,9 @@ "dev": true }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-int64": { "version": "0.4.0", @@ -6038,17 +5973,17 @@ "dev": true }, "node-notifier": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", - "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", + "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", "dev": true, "optional": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^2.1.1", - "semver": "^7.2.1", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", "shellwords": "^0.1.1", - "uuid": "^7.0.3", + "uuid": "^8.3.0", "which": "^2.0.2" }, "dependencies": { @@ -6058,13 +5993,6 @@ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true, "optional": true - }, - "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", - "dev": true, - "optional": true } } }, @@ -6137,6 +6065,14 @@ "dev": true, "requires": { "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + } } }, "nwsapi": { @@ -6280,34 +6216,28 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -6326,27 +6256,27 @@ "dev": true }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { - "p-try": "^2.0.0" + "p-try": "^1.0.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "^2.2.0" + "p-limit": "^1.1.0" } }, "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "package-json": { @@ -6377,15 +6307,12 @@ } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" + "error-ex": "^1.2.0" } }, "parse5": { @@ -6406,9 +6333,9 @@ "dev": true }, "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-is-absolute": { @@ -6418,9 +6345,9 @@ "dev": true }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { @@ -6470,12 +6397,12 @@ } }, "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "requires": { - "find-up": "^4.0.0" + "find-up": "^2.1.0" } }, "posix-character-classes": { @@ -6485,9 +6412,9 @@ "dev": true }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prepend-http": { @@ -6496,9 +6423,9 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", + "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==", "dev": true }, "prettier-linter-helpers": { @@ -6511,12 +6438,12 @@ } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", + "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -6626,6 +6553,11 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" } } }, @@ -6647,34 +6579,24 @@ "dev": true }, "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "readdirp": { @@ -6789,25 +6711,31 @@ "psl": "^1.1.28", "punycode": "^2.1.1" } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true } } }, "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, "requires": { - "lodash": "^4.17.15" + "lodash": "^4.17.19" } }, "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", "dev": true, "requires": { - "request-promise-core": "1.1.3", + "request-promise-core": "1.1.4", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" }, @@ -6852,12 +6780,20 @@ "dev": true, "requires": { "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } } }, "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "resolve-url": { @@ -6874,16 +6810,6 @@ "lowercase-keys": "^1.0.0" } }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -6896,9 +6822,9 @@ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" }, "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -6910,25 +6836,10 @@ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "rxjs": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", - "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-regex": { "version": "1.1.0", @@ -7134,10 +7045,27 @@ "statuses": "~1.5.0" }, "dependencies": { + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" } } }, @@ -7182,9 +7110,9 @@ } }, "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "sha.js": { "version": "2.4.11", @@ -7196,18 +7124,18 @@ } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "shellwords": { @@ -7420,9 +7348,9 @@ "dev": true }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -7436,9 +7364,9 @@ "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -7446,9 +7374,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", + "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", "dev": true }, "split-string": { @@ -7646,9 +7574,9 @@ } }, "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-eof": { @@ -7669,9 +7597,9 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "subscriptions-transport-ws": { - "version": "0.9.16", - "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.16.tgz", - "integrity": "sha512-pQdoU7nC+EpStXnCfh/+ho0zE0Z+ma+i7xvj7bkXKb1dvYHSZxgRPaU6spRP+Bjzow67c/rRDoix5RT0uU9omw==", + "version": "0.9.18", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz", + "integrity": "sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA==", "requires": { "backo2": "^1.0.2", "eventemitter3": "^3.1.0", @@ -7715,9 +7643,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -7799,21 +7727,6 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -7922,23 +7835,6 @@ "json5": "^1.0.1", "minimist": "^1.2.0", "strip-bom": "^3.0.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" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } } }, "tslib": { @@ -7962,12 +7858,12 @@ "dev": true }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -8092,9 +7988,9 @@ } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -8137,9 +8033,9 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==" }, "v8-compile-cache": { "version": "2.1.1", @@ -8148,9 +8044,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", - "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-5.0.1.tgz", + "integrity": "sha512-mbDNjuDajqYe3TXFk5qxcQy8L1msXNE37WTlLoqqpBfRsimbNcrlhQlDPntmECEcUvdC+AQ8CyMMf6EUx1r74Q==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -8241,22 +8137,14 @@ "dev": true }, "whatwg-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", - "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-PcVnO6NiewhkmzV0qn7A+UZ9Xx4maNTI+O+TShmfE4pqjoCMwUMjkvoNhNHPTvgR7QH9Xt3R13iHuWy2sToFxQ==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", "tr46": "^2.0.2", - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } + "webidl-conversions": "^6.1.0" } }, "which": { @@ -8367,9 +8255,9 @@ "dev": true }, "xss": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.7.tgz", - "integrity": "sha512-A9v7tblGvxu8TWXQC9rlpW96a+LN1lyw6wyhpTmmGW+FwRMactchBR3ROKSi33UPCUcUHSu8s9YP6F+K3Mw//w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.8.tgz", + "integrity": "sha512-3MgPdaXV8rfQ/pNn16Eio6VXYPTkqwa0vc7GkiymmY/DqR1SE/7VPAAVZz1GJsJFrllMYO3RHfEaiUGjab6TNw==", "requires": { "commander": "^2.20.3", "cssfilter": "0.0.10" @@ -8387,9 +8275,9 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -8402,7 +8290,58 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } } }, "yargs-parser": { diff --git a/package.json b/package.json index 8a36dad..a0197a0 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "start": "node index.js", "server": "nodemon index.js", "lint": "eslint --fix . --ext .js", - "all-dependencies": "npm run coreDependencies && npm run devDependencies", + "allDependencies": "npm run coreDependencies && npm run devDependencies", "coreDependencies": "npm install", "devDependencies": " npm install --only=dev" }, @@ -30,21 +30,22 @@ "author": "Alex Machin", "license": "MIT", "dependencies": { - "apollo-server": "^2.14.4", + "apollo-server": "^2.17.0", "axios": "^0.19.2", "dotenv": "^8.2.0", - "lodash": "^4.17.19", - "moment": "^2.24.0", + "lodash": "^4.17.20", + "moment": "^2.28.0", "nodemon": "^2.0.3" }, "devDependencies": { - "eslint": "^7.2.0", + "@types/jest": "^26.0.14", + "eslint": "^7.9.0", "eslint-config-airbnb-base": "^14.2.0", "eslint-config-prettier": "^6.11.0", - "eslint-plugin-import": "^2.21.2", - "eslint-plugin-prettier": "^3.1.3", - "jest": "^26.0.1", - "prettier": "^2.0.5" + "eslint-plugin-import": "^2.22.0", + "eslint-plugin-prettier": "^3.1.4", + "jest": "^26.4.2", + "prettier": "^2.1.2" }, "repository": { "type": "git", diff --git a/resolvers/Cast/MovieResolver.js b/resolvers/Cast/MovieResolver.js index 974e316..4441240 100644 --- a/resolvers/Cast/MovieResolver.js +++ b/resolvers/Cast/MovieResolver.js @@ -1,26 +1,19 @@ const axios = require('axios'); -const { has, filter, forEach } = require('lodash'); const generateCastURLEndpoint = require('../../utils/generateEndpoints/Cast'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const setValue = require('../../utils/objects/setValue'); -const replaceKey = require('../../utils/objects/replaceKey'); +const setCast = require('../../utils/resolverUtils/Cast/setCast'); // eslint-disable-next-line no-unused-vars const MovieCastResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateCastURLEndpoint(parent.id, 'movie')); - const featuredCast = filter(response.data.cast, (member) => member.order < 7); + const { data } = response; + const { cast } = data; - forEach(featuredCast, (member) => { - if (has(member, 'profile_path')) { - replaceKey(member, 'profile_path', 'image'); - setValue(member, 'image', generateAbsolutePath(member.image)); - } - }); + const Cast = setCast(cast); - return featuredCast; + return Cast; } catch (err) { console.log('The /credits (Cast) endpoint failed'); return err.response; diff --git a/resolvers/Cast/ShowResolver.js b/resolvers/Cast/ShowResolver.js index 2c455ca..e72a20e 100644 --- a/resolvers/Cast/ShowResolver.js +++ b/resolvers/Cast/ShowResolver.js @@ -1,30 +1,21 @@ const axios = require('axios'); -const { has, filter, forEach } = require('lodash'); const generateCastURLEndpoint = require('../../utils/generateEndpoints/Cast'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const setValue = require('../../utils/objects/setValue'); -const replaceKey = require('../../utils/objects/replaceKey'); +const setCast = require('../../utils/resolverUtils/Cast/setCast'); // eslint-disable-next-line no-unused-vars const TVCastResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateCastURLEndpoint(parent.id, 'tv')); - const featuredCast = filter(response.data.cast, (member) => member.order < 7); + const { data } = response; + const { cast } = data; - // Formatting the featured cast - forEach(featuredCast, (member) => { - if (has(member, 'profile_path')) { - replaceKey(member, 'profile_path', 'image'); - setValue(member, 'image', generateAbsolutePath(member.image)); - } - }); + const Cast = await setCast(cast, 'tv'); - return featuredCast; + return Cast; } catch (err) { console.log('The /credits (Cast) endpoint failed'); - console.log(err); return err.response; } }; diff --git a/resolvers/Credits/Credits.js b/resolvers/Credits/Credits.js index 5e4eab8..845c015 100644 --- a/resolvers/Credits/Credits.js +++ b/resolvers/Credits/Credits.js @@ -1,17 +1,15 @@ const axios = require('axios'); const generatePersonCreditsEndpoint = require('../../utils/generateEndpoints/Credits'); -const formatGroups = require('../../utils/resolverUtils/Credits'); -const mediaType = require('../../utils/resolverUtils/Credits/filterGroupByMediaType/types'); +const setCredits = require('../../utils/resolverUtils/Credits/setCredits'); // eslint-disable-next-line no-unused-vars const CreditsResolver = async (parent, args, info, context) => { try { const response = await axios.get(generatePersonCreditsEndpoint(parent.id)); - const { ActingGroup, ProductionGroup, WritingGroup, DirectingGroup, CrewGroup } = formatGroups( - response.data, - mediaType.ALL + const { ActingGroup, ProductionGroup, WritingGroup, DirectingGroup, CrewGroup } = setCredits( + response.data ); return { @@ -22,6 +20,7 @@ const CreditsResolver = async (parent, args, info, context) => { CrewGroup }; } catch (err) { + console.log(err); return err.response; } }; diff --git a/resolvers/Credits/FilterCredits.js b/resolvers/Credits/FilterCredits.js deleted file mode 100644 index 209c61f..0000000 --- a/resolvers/Credits/FilterCredits.js +++ /dev/null @@ -1,28 +0,0 @@ -const axios = require('axios'); - -const generatePersonCreditsEndpoint = require('../../utils/generateEndpoints/Credits'); -const formatGroups = require('../../utils/resolverUtils/Credits'); - -// eslint-disable-next-line no-unused-vars -const FilterCredits = async (parent, args, info, context) => { - try { - const response = await axios.get(generatePersonCreditsEndpoint(args.id)); - - const { ActingGroup, ProductionGroup, WritingGroup, DirectingGroup, CrewGroup } = formatGroups( - response.data, - args.mediaType - ); - - return { - ActingGroup, - ProductionGroup, - WritingGroup, - DirectingGroup, - CrewGroup - }; - } catch (err) { - return err.response; - } -}; - -module.exports = FilterCredits; diff --git a/resolvers/Credits/index.js b/resolvers/Credits/index.js index 603d4ef..0d85ea4 100644 --- a/resolvers/Credits/index.js +++ b/resolvers/Credits/index.js @@ -1,7 +1,5 @@ const CreditsResolver = require('./Credits'); -const FilteredCreditsResolver = require('./FilterCredits'); module.exports = { - CreditsResolver, - FilteredCreditsResolver + CreditsResolver }; diff --git a/resolvers/Crew/MovieResolver.js b/resolvers/Crew/MovieResolver.js index 436cb08..2f1141a 100644 --- a/resolvers/Crew/MovieResolver.js +++ b/resolvers/Crew/MovieResolver.js @@ -1,31 +1,19 @@ const axios = require('axios'); -const { has, filter, forEach } = require('lodash'); const generateCrewEndpoint = require('../../utils/generateEndpoints/Crew'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const setValue = require('../../utils/objects/setValue'); +const setCrew = require('../../utils/resolverUtils/Crew/setCrew'); // eslint-disable-next-line no-unused-vars const MovieCrewResolver = async (parent, args, context, info) => { try { - // Make a crew request using the Movie object id field const response = await axios.get(generateCrewEndpoint(parent.id, 'movie')); - // Getting the crew by specific job titles - const featuredCrew = filter( - response.data.crew, - (member) => - member.job === 'Director' || member.job === 'Screenplay' || member.job === 'Writer' - ); + const { data } = response; + const { crew } = data; - // URL formatting for images - forEach(featuredCrew, (member) => { - if (has(member, 'profile_path') === true) { - setValue(member, 'profile_path', generateAbsolutePath(member.profile_path)); - } - }); + const Crew = setCrew(crew); - return featuredCrew; + return Crew; } catch (err) { console.log('The /credits (Crew) endpoint failed'); return err; diff --git a/resolvers/Crew/ShowResolver.js b/resolvers/Crew/ShowResolver.js index b8eaa65..778b6b1 100644 --- a/resolvers/Crew/ShowResolver.js +++ b/resolvers/Crew/ShowResolver.js @@ -1,31 +1,19 @@ const axios = require('axios'); -const { has, filter, forEach } = require('lodash'); const generateCrewEndpoint = require('../../utils/generateEndpoints/Crew'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const setValue = require('../../utils/objects/setValue'); +const setCrew = require('../../utils/resolverUtils/Crew/setCrew'); // eslint-disable-next-line no-unused-vars const TVCrewResolver = async (parent, args, context, info) => { try { - // Make a crew request using the Movie object id field const response = await axios.get(generateCrewEndpoint(parent.id, 'tv')); - // Getting the crew by specific job titles - const featuredCrew = filter( - response.data.crew, - (member) => - member.job === 'Director' || member.job === 'Screenplay' || member.job === 'Writer' - ); + const { data } = response; + const { crew } = data; - // URL formatting for images - forEach(featuredCrew, (member) => { - if (has(member, 'profile_path') === true) { - setValue(member, 'profile_path', generateAbsolutePath(member.profile_path)); - } - }); + const Crew = setCrew(crew); - return featuredCrew; + return Crew; } catch (err) { console.log('The /credits (Crew) endpoint failed'); return err; diff --git a/resolvers/Discover/MoviesResolver.js b/resolvers/Discover/MoviesResolver.js index 69bde7c..a522983 100644 --- a/resolvers/Discover/MoviesResolver.js +++ b/resolvers/Discover/MoviesResolver.js @@ -1,12 +1,9 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generateDiscoverEndpoint = require('../../utils/generateEndpoints/Discover'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); const generateQueryParameters = require('../../utils/generateQueryParameters/Discover'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); + +const setMovies = require('../../utils/resolverUtils/Movies/setMovies'); // eslint-disable-next-line no-unused-vars const DiscoverMoviesResolver = async (parent, args, context, info) => { @@ -15,25 +12,12 @@ const DiscoverMoviesResolver = async (parent, args, context, info) => { generateQueryParameters(generateDiscoverEndpoint('movie'), args) ); - forEach(response.data.results, (movie) => { - if (has(movie, 'poster_path') === true) { - setValue(movie, 'poster_path', generateAbsolutePath(movie.poster_path)); - } - - if (has(movie, 'backdrop_path') === true) { - setValue(movie, 'backdrop_path', generateAbsolutePath(movie.backdrop_path)); - } - - if (has(movie, 'release_date') === true) { - setValue(movie, 'release_date', formatDate(movie.release_date, 'MMMM Do, YYYY')); - } + const { data } = response; + const { results } = data; - if (has(movie, 'vote_average') === true) { - setValue(movie, 'vote_average', toPercentage(movie.vote_average)); - } - }); + const Movies = setMovies(results); - return response.data.results; + return Movies; } catch (err) { console.log('The /Discover/Movie endpoint failed'); return err.response; diff --git a/resolvers/Discover/ShowResolver.js b/resolvers/Discover/ShowResolver.js index 7242773..068be83 100644 --- a/resolvers/Discover/ShowResolver.js +++ b/resolvers/Discover/ShowResolver.js @@ -1,39 +1,20 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generateDiscoverEndpoint = require('../../utils/generateEndpoints/Discover'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); const generateQueryParameters = require('../../utils/generateQueryParameters/Discover'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); -const replaceKey = require('../../utils/objects/replaceKey'); +const setShows = require('../../utils/resolverUtils/Shows/setShows'); // eslint-disable-next-line no-unused-vars const DiscoverTVResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateQueryParameters(generateDiscoverEndpoint('tv'), args)); - forEach(response.data.results, (show) => { - if (has(show, 'poster_path') === true) { - setValue(show, 'poster_path', generateAbsolutePath(show.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(show, 'backdrop_path') === true) { - setValue(show, 'backdrop_path', generateAbsolutePath(show.backdrop_path)); - } + const Shows = setShows(results); - if (has(show, 'first_air_date') === true) { - replaceKey(show, 'first_air_date', 'release_date'); - setValue(show, 'release_date', formatDate(show.release_date, 'MMMM Do, YYYY')); - } - - if (has(show, 'vote_average') === true) { - setValue(show, 'vote_average', toPercentage(show.vote_average)); - } - }); - - return response.data.results; + return Shows; } catch (err) { console.log(err); console.log('The /Discover/TV endpoint failed'); diff --git a/resolvers/Keywords/ShowResolver.js b/resolvers/Keywords/ShowResolver.js index fa722fb..0ee9901 100644 --- a/resolvers/Keywords/ShowResolver.js +++ b/resolvers/Keywords/ShowResolver.js @@ -7,8 +7,7 @@ const TVKeywordResolver = async (parent, args, info, context) => { try { // Make a keywords request using the TV object id field const response = await axios.get(generateKeywordEndpoint(parent.id, 'tv')); - - return response.data.keywords; + return response.data.results; } catch (err) { console.log('The /keywords endpoint failed'); return err; diff --git a/resolvers/NowPlaying/MoviesResolver.js b/resolvers/NowPlaying/MoviesResolver.js index 244705c..396f15b 100644 --- a/resolvers/NowPlaying/MoviesResolver.js +++ b/resolvers/NowPlaying/MoviesResolver.js @@ -1,40 +1,23 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); -const genereateNowPlayingEndpoint = require('../../utils/generateEndpoints/NowPlaying'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); +const generateNowPlayingEndpoint = require('../../utils/generateEndpoints/NowPlaying'); +const setMovies = require('../../utils/resolverUtils/Movies/setMovies'); // eslint-disable-next-line no-unused-vars -const NowPlayingTVResolver = async (parent, args, context, info) => { +const NowPlayingMovieResolver = async (parent, args, context, info) => { try { - const response = await axios.get(genereateNowPlayingEndpoint('movie')); + const response = await axios.get(generateNowPlayingEndpoint('movie')); - forEach(response.data.results, (movie) => { - if (has(movie, 'poster_path') === true) { - setValue(movie, 'poster_path', generateAbsolutePath(movie.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(movie, 'backdrop_path') === true) { - setValue(movie, 'backdrop_path', generateAbsolutePath(movie.backdrop_path)); - } + const Movies = setMovies(results); - if (has(movie, 'release_date') === true) { - setValue(movie, 'release_date', formatDate(movie.release_date, 'MMMM Do, YYYY')); - } - - if (has(movie, 'vote_average') === true) { - setValue(movie, 'vote_average', toPercentage(movie.vote_average)); - } - }); - - return response.data.results; + return Movies; } catch (err) { console.log('The tv/on_the_air endpoint failed'); return err.response; } }; -module.exports = NowPlayingTVResolver; +module.exports = NowPlayingMovieResolver; diff --git a/resolvers/NowPlaying/ShowResolver.js b/resolvers/NowPlaying/ShowResolver.js index 3b90e57..82a4935 100644 --- a/resolvers/NowPlaying/ShowResolver.js +++ b/resolvers/NowPlaying/ShowResolver.js @@ -1,39 +1,19 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); -const genereateNowPlayingEndpoint = require('../../utils/generateEndpoints/NowPlaying'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); -const replaceKey = require('../../utils/objects/replaceKey'); +const generateNowPlayingEndpoint = require('../../utils/generateEndpoints/NowPlaying'); +const setShows = require('../../utils/resolverUtils/Shows/setShows'); // eslint-disable-next-line no-unused-vars const NowPlayingTVResolver = async (parent, args, context, info) => { try { - const response = await axios.get(genereateNowPlayingEndpoint('tv')); + const response = await axios.get(generateNowPlayingEndpoint('tv')); - forEach(response.data.results, (show) => { - if (has(show, 'poster_path') === true) { - setValue(show, 'poster_path', generateAbsolutePath(show.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(show, 'backdrop_path') === true) { - setValue(show, 'backdrop_path', generateAbsolutePath(show.backdrop_path)); - } + const Shows = setShows(results); - if (has(show, 'first_air_date') === true) { - replaceKey(show, 'first_air_date', 'release_date'); - - setValue(show, 'release_date', formatDate(show.release_date, 'MMMM Do, YYYY')); - } - - if (has(show, 'vote_average') === true) { - setValue(show, 'vote_average', toPercentage(show.vote_average)); - } - }); - - return response.data.results; + return Shows; } catch (err) { console.log('The tv/on_the_air endpoint failed'); return err.response; diff --git a/resolvers/Popular/MovieResolver.js b/resolvers/Popular/MovieResolver.js index f1eaa02..556f6e9 100644 --- a/resolvers/Popular/MovieResolver.js +++ b/resolvers/Popular/MovieResolver.js @@ -1,36 +1,19 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generatePopularEndpoint = require('../../utils/generateEndpoints/Popular'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); +const setMovies = require('../../utils/resolverUtils/Movies/setMovies'); // eslint-disable-next-line no-unused-vars const MoviePopularResolver = async (parent, args, context, info) => { try { const response = await axios.get(generatePopularEndpoint('movie')); - forEach(response.data.results, (movie) => { - if (has(movie, 'poster_path') === true) { - setValue(movie, 'poster_path', generateAbsolutePath(movie.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(movie, 'backdrop_path') === true) { - setValue(movie, 'backdrop_path', generateAbsolutePath(movie.backdrop_path)); - } + const Movies = setMovies(results); - if (has(movie, 'release_date') === true) { - setValue(movie, 'release_date', formatDate(movie.release_date, 'MMMM Do, YYYY')); - } - - if (has(movie, 'vote_average') === true) { - setValue(movie, 'vote_average', toPercentage(movie.vote_average)); - } - }); - - return response.data.results; + return Movies; } catch (err) { console.log('The /movie/popular endpoint failed'); return err.response; diff --git a/resolvers/Popular/PeopleResolver.js b/resolvers/Popular/PeopleResolver.js index 1c1b609..5441495 100644 --- a/resolvers/Popular/PeopleResolver.js +++ b/resolvers/Popular/PeopleResolver.js @@ -1,42 +1,21 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generatePopularEndpoint = require('../../utils/generateEndpoints/Popular'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const replaceObjectKey = require('../../utils/objects/replaceKey'); -const setValue = require('../../utils/objects/setValue'); -const toPercentage = require('../../utils/maths/toPercentage'); +const setPeople = require('../../utils/resolverUtils/People/setPeople'); // eslint-disable-next-line no-unused-vars const PopularPeopleResolver = async (parent, args, context, info) => { try { const response = await axios.get(generatePopularEndpoint('person')); - forEach(response.data.results, (person) => { - if (has(person, 'profile_path') === true) { - person.profile_path = generateAbsolutePath(person.profile_path); - } + const { data } = response; + const { results } = data; - if (has(person, 'known_for') === true) { - forEach(person.known_for, (role) => { - if (has(role, 'backdrop_path') === true) { - setValue(role, 'backdrop_path', generateAbsolutePath(role.backdrop_path)); - } + const People = setPeople(results); - if (has(role, 'poster_path') === true) { - setValue(role, 'poster_path', generateAbsolutePath(role.poster_path)); - } + return People; - if (has(role, 'vote_average') === true) { - setValue(role, 'vote_avergage', toPercentage(role.vote_average)); - } - - replaceObjectKey(role, 'original_name', 'title'); - }); - } - }); - - return response.data.results; + // return response.data.results; } catch (err) { console.log(err); console.log('The /tv/popular endpoint failed'); diff --git a/resolvers/Popular/ShowResolver.js b/resolvers/Popular/ShowResolver.js index 007fb47..4f0be5e 100644 --- a/resolvers/Popular/ShowResolver.js +++ b/resolvers/Popular/ShowResolver.js @@ -1,39 +1,19 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generatePopularEndpoint = require('../../utils/generateEndpoints/Popular'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); -const replaceKey = require('../../utils/objects/replaceKey'); +const setShows = require('../../utils/resolverUtils/Shows/setShows'); // eslint-disable-next-line no-unused-vars const TVPopularResolver = async (parent, args, context, info) => { try { const response = await axios.get(generatePopularEndpoint('tv')); - forEach(response.data.results, (show) => { - if (has(show, 'poster_path') === true) { - setValue(show, 'poster_path', generateAbsolutePath(show.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(show, 'backdrop_path') === true) { - setValue(show, 'backdrop_path', generateAbsolutePath(show.backdrop_path)); - } + const Shows = setShows(results); - if (has(show, 'first_air_date') === true) { - replaceKey(show, 'first_air_date', 'release_date'); - - setValue(show, 'release_date', formatDate(show.release_date, 'MMMM Do, YYYY')); - } - - if (has(show, 'vote_average') === true) { - setValue(show, 'vote_average', toPercentage(show.vote_average)); - } - }); - - return response.data.results; + return Shows; } catch (err) { console.log('The /tv/popular endpoint failed'); return err.response; diff --git a/resolvers/Recomendations/MovieResolver.js b/resolvers/Recomendations/MovieResolver.js deleted file mode 100644 index 65405fa..0000000 --- a/resolvers/Recomendations/MovieResolver.js +++ /dev/null @@ -1,31 +0,0 @@ -const axios = require('axios'); -const { has, forEach } = require('lodash'); - -const generateRecomendationEndpoint = require('../../utils/generateEndpoints/Recomendations'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); - -// eslint-disable-next-line no-unused-vars -const MovieRecomendationsResolver = async (parent, args, content, info) => { - try { - const response = await axios.get(generateRecomendationEndpoint(parent.id, 'movie')); - - forEach(response.data.results, (movie) => { - if (has(movie, 'poster_path') === true) { - setValue(movie, 'poster_path', generateAbsolutePath(movie.poster_path)); - } - - if (has(movie, 'vote_average') === true) { - setValue(movie, 'vote_average', toPercentage(movie.vote_average)); - } - }); - - return response.data.results; - } catch (err) { - console.log('The /movie/reccomendations/ endpoint failed'); - return err; - } -}; - -module.exports = MovieRecomendationsResolver; diff --git a/resolvers/Recomendations/ShowResolver.js b/resolvers/Recomendations/ShowResolver.js deleted file mode 100644 index 9964123..0000000 --- a/resolvers/Recomendations/ShowResolver.js +++ /dev/null @@ -1,31 +0,0 @@ -const axios = require('axios'); -const { has, forEach } = require('lodash'); - -const generateRecomendationEndpoint = require('../../utils/generateEndpoints/Recomendations'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); - -// eslint-disable-next-line no-unused-vars -const TVRecomendationsResolver = async (parent, args, content, info) => { - try { - const response = await axios.get(generateRecomendationEndpoint(parent.id, 'tv')); - - forEach(response.data.results, (show) => { - if (has(show, 'poster_path') === true) { - setValue(show, 'poster_path', generateAbsolutePath(show.poster_path)); - } - - if (has(show, 'vote_average') === true) { - setValue(show, 'vote_average', toPercentage(show.vote_average)); - } - }); - - return response.data.results; - } catch (err) { - console.log('The /tv/reccomendations/ endpoint failed'); - return err; - } -}; - -module.exports = TVRecomendationsResolver; diff --git a/resolvers/Recomendations/index.js b/resolvers/Recomendations/index.js deleted file mode 100644 index dd8a2aa..0000000 --- a/resolvers/Recomendations/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const MovieRecomendationsResolver = require('./MovieResolver'); -const ShowRecomendationsResolver = require('./ShowResolver'); - -module.exports = { - MovieRecomendationsResolver, - ShowRecomendationsResolver -}; diff --git a/resolvers/Recommendations/MovieResolver.js b/resolvers/Recommendations/MovieResolver.js new file mode 100644 index 0000000..e4b365a --- /dev/null +++ b/resolvers/Recommendations/MovieResolver.js @@ -0,0 +1,24 @@ +const axios = require('axios'); + +const generateRecommendationsEndpoint = require('../../utils/generateEndpoints/Recommendations'); +const setMovies = require('../../utils/resolverUtils/Movies/setMovies'); + +// eslint-disable-next-line no-unused-vars +const MovieRecommendationsResolver = async (parent, args, content, info) => { + try { + const response = await axios.get(generateRecommendationsEndpoint(parent.id, 'movie')); + + const { data } = response; + + const { results } = data; + + const Movies = setMovies(results); + + return Movies; + } catch (err) { + console.log('The /movie/recommendations/ endpoint failed'); + return err; + } +}; + +module.exports = MovieRecommendationsResolver; diff --git a/resolvers/Recommendations/ShowResolver.js b/resolvers/Recommendations/ShowResolver.js new file mode 100644 index 0000000..4a2d3b6 --- /dev/null +++ b/resolvers/Recommendations/ShowResolver.js @@ -0,0 +1,23 @@ +const axios = require('axios'); + +const generateRecommendationsEndpoint = require('../../utils/generateEndpoints/Recommendations'); +const setShows = require('../../utils/resolverUtils/Shows/setShows'); + +// eslint-disable-next-line no-unused-vars +const TVRecommendationsResolver = async (parent, args, content, info) => { + try { + const response = await axios.get(generateRecommendationsEndpoint(parent.id, 'tv')); + + const { data } = response; + const { results } = data; + + const Shows = setShows(results); + + return Shows; + } catch (err) { + console.log('The /tv/recommendations/ endpoint failed'); + return err; + } +}; + +module.exports = TVRecommendationsResolver; diff --git a/resolvers/Recommendations/index.js b/resolvers/Recommendations/index.js new file mode 100644 index 0000000..1a01c4f --- /dev/null +++ b/resolvers/Recommendations/index.js @@ -0,0 +1,7 @@ +const MovieRecommendationsResolver = require('./MovieResolver'); +const ShowRecommendationsResolver = require('./ShowResolver'); + +module.exports = { + MovieRecommendationsResolver, + ShowRecommendationsResolver +}; diff --git a/resolvers/SingleItemLookup/MovieResolver.js b/resolvers/SingleItemLookup/MovieResolver.js index 1bedad4..191199e 100644 --- a/resolvers/SingleItemLookup/MovieResolver.js +++ b/resolvers/SingleItemLookup/MovieResolver.js @@ -1,12 +1,11 @@ const axios = require('axios'); -const { find, has, forEach } = require('lodash'); +const { find, has } = require('lodash'); const generateSingleItemLookupEndpoint = require('../../utils/generateEndpoints/SingleItemLookup'); const generateSearchEndpoint = require('../../utils/generateEndpoints/Search'); const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); -const replaceKey = require('../../utils/objects/replaceKey'); +const generateYear = require('../../utils/dates/generateYear'); // eslint-disable-next-line no-unused-vars const SearchForAMovieResolver = async (parent, args, context, info) => { @@ -22,41 +21,128 @@ const SearchForAMovieResolver = async (parent, args, context, info) => { const { data } = SingleMovieResponse; - if (has(data, 'backdrop_path') === true) { - setValue(data, 'backdrop_path', generateAbsolutePath(data.backdrop_path)); - } + const releaseDate = generateYear(data.release_date); + const voteAverage = toPercentage(data.vote_average); + + const Movie = { + id: data.id ? data.id : 0, + name: data.title || '', + overview: data.overview || '', + backgroundUrl: generateAbsolutePath(data.backdrop_path) || '', + posterUrl: generateAbsolutePath(data.poster_path) || '', + genres: data.genres.length !== 0 ? data.genres : [], + homepage: data.homepage || '', + originalLanguage: data.original_language, + productionCompanies: [], + releaseDate: releaseDate !== '-' ? releaseDate : '', + voteAverage: String(voteAverage) ? voteAverage : '', + status: data.status || '', + tagline: data.tagline || '', + belongsToCollection: { + id: 0, + name: '', + backgroundUrl: '', + posterUrl: '' + }, + runtime: data.runtime || '', + + // Movie Specific fields + budget: data.budget ? `$${data.budget.toLocaleString()}` : '-', + revenue: data.revenue ? `$${data.revenue.toLocaleString()}` : '-' + }; - if (has(data, 'poster_path') === true) { - setValue(data, 'poster_path', generateAbsolutePath(data.poster_path)); + // Name + if (Movie.name === '') { + Movie.name = data.original_title; } - if (has(data, 'budget') === true) { - setValue(data, 'budget', data.budget.toLocaleString()); + // Original language + if ( + Movie.originalLanguage !== '' && + has(data, 'spoken_languages') === true && + data.spoken_languages.length !== 0 + ) { + // Finds the first language which matches the original_Language assigned to the movie + const language = data.spoken_languages.find( + /** + * @param {Object} el + */ + (el) => el.iso_639_1 === data.original_language + ); + + Movie.originalLanguage = language.name; } - if (has(data, 'revenue') === true) { - setValue(data, 'revenue', data.revenue.toLocaleString()); + // Production companies + // When the production company is available and there isn't 0 companies + if (has(data, 'production_companies') === true) { + const productionCompanies = []; + + data.production_companies.forEach((singleCompany) => { + const company = { + id: String(singleCompany.id) ? singleCompany.id : 0, + logo: generateAbsolutePath(singleCompany.logo_path) || '', + name: singleCompany.name || '' + }; + + // Push the new production company object to the productionCompanies array + productionCompanies.push(company); + }); + + Movie.productionCompanies = productionCompanies; } - if (has(data, 'vote_average') === true) { - setValue(data, 'vote_average', toPercentage(data.vote_average)); + // Show Collections + // When the belongs_to_collection is available and the collection is not null update the default values + if (has(data, 'belongs_to_collection') === true && data.belongs_to_collection !== null) { + // eslint-disable-next-line camelcase + const { belongs_to_collection } = data; + + /* + + Setting the collection values: + + - Numbers are converted to string to check to see if they are truthy or false value + + - When a number has been converted make sure to return it as a number + + */ + + // Sets the collection id + Movie.belongsToCollection.id = String(belongs_to_collection.id) + ? belongs_to_collection.id + : ''; + + // Sets the collection name + Movie.belongsToCollection.name = belongs_to_collection.name || ''; + + // Sets the backgroundUrl (Used as the background for the collection card) + Movie.belongsToCollection.backgroundUrl = + generateAbsolutePath(belongs_to_collection.backdrop_path) || ''; + + // Sets the posterUrl (Not used in the collection card, but it could be eventually) + Movie.belongsToCollection.posterUrl = + generateAbsolutePath(belongs_to_collection.poster_path) || ''; } - // Data formatting for the production_companies field - forEach(data.production_companies, (company) => { - if (has(company, 'logo_path')) { - replaceKey(company, 'logo_path', 'logo'); - setValue(company, 'logo', generateAbsolutePath(company.logo)); - } - }); + // Runtime + // When the runtime is available overwrite with a movie/show length e.g. 1hr 2min + if (Movie.runtime !== '') { + const hours = Math.floor(data.runtime / 60); + const minutes = data.runtime % 60; + Movie.runtime = `${hours}h ${minutes}m`; + } - return data; + return Movie; } catch (err) { console.log(`The /Movie endpoint failed`); + console.log(err); + return err.response; } } catch (err) { console.log('The /Search endpoint failed'); + console.log(err.message); return err.response; } }; diff --git a/resolvers/SingleItemLookup/PersonResolver.js b/resolvers/SingleItemLookup/PersonResolver.js index b565de5..05ef1d8 100644 --- a/resolvers/SingleItemLookup/PersonResolver.js +++ b/resolvers/SingleItemLookup/PersonResolver.js @@ -1,11 +1,10 @@ const axios = require('axios'); -const { find, has } = require('lodash'); +const { find } = require('lodash'); const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); const generateSearchEndpoint = require('../../utils/generateEndpoints/Search'); const generateSingleItemLookupEndpoint = require('../../utils/generateEndpoints/SingleItemLookup'); const generateBirthdayDate = require('../../utils/dates/generateBirthday'); -const setValue = require('../../utils/objects/setValue'); // eslint-disable-next-line no-unused-vars const SearchForAPersonResolver = async (parent, args, context, info) => { @@ -21,23 +20,20 @@ const SearchForAPersonResolver = async (parent, args, context, info) => { const { data } = SinglePersonResponse; - if (has(data, 'gender') === true) { - setValue(data, 'gender', data.gender === 0 ? 'Male' : 'Female'); - } - - if (has(data, 'birthday') === true) { - setValue(data, 'birthday', generateBirthdayDate(data.birthday)); - } - - if (has(data, 'populaity') === true) { - setValue(data, 'popularity', data.popularity.toFixed(2)); - } - - if (has(data, 'profile_path') === true) { - setValue(data, 'profile_path', generateAbsolutePath(data.profile_path)); - } - - return data; + const Person = { + id: String(data.id) ? data.id : 0, + birthday: generateBirthdayDate(data.birthday) || '', + knownForDepartment: data.known_for_department || '', + name: data.name || '', + alsoKnownAs: data.also_known_as, + gender: data.gender === 2 ? 'Male' : 'Female', + overview: data.overview || '', + placeOfBirth: data.place_of_birth, + posterUrl: generateAbsolutePath(data.profile_path) || '', + homepage: data.homepage || '' + }; + + return Person; } catch (err) { console.log(`The /Person endpoint failed`); return err.response; diff --git a/resolvers/SingleItemLookup/ShowResolver.js b/resolvers/SingleItemLookup/ShowResolver.js index 85130c8..aebff65 100644 --- a/resolvers/SingleItemLookup/ShowResolver.js +++ b/resolvers/SingleItemLookup/ShowResolver.js @@ -1,12 +1,11 @@ const axios = require('axios'); -const { find, has, forEach } = require('lodash'); +const { find, has } = require('lodash'); const generateSingleItemLookupEndpoint = require('../../utils/generateEndpoints/SingleItemLookup'); const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); const generateSearchEndpoint = require('../../utils/generateEndpoints/Search'); const generateYear = require('../../utils/dates/generateYear'); const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); // eslint-disable-next-line no-unused-vars const SearchForAShowResolver = async (parent, args, context, info) => { @@ -14,7 +13,6 @@ const SearchForAShowResolver = async (parent, args, context, info) => { const response = await axios.get(generateSearchEndpoint(args.search, 'tv')); const SingleItemLookup = find(response.data.results, (show) => show.id === args.id); - try { const SingleItemLookupResponse = await axios.get( generateSingleItemLookupEndpoint(SingleItemLookup.id, 'tv') @@ -22,50 +20,176 @@ const SearchForAShowResolver = async (parent, args, context, info) => { const { data } = SingleItemLookupResponse; - if (has(data, 'created_by') === true) { - forEach(data.created_by, (creator) => { - if (has(creator, 'profile_path') === true) { - setValue(creator, 'profile_path', generateAbsolutePath(creator.profile_path)); - } - }); + const releaseDate = generateYear(data.first_air_date); + const voteAverage = toPercentage(data.vote_average); + + const Show = { + id: String(data.id) ? data.id : 0, + name: data.name || '', + overview: data.overview || '', + backgroundUrl: generateAbsolutePath(data.backdrop_path) || '', + posterUrl: generateAbsolutePath(data.poster_path) || '', + genres: data.genres.length !== 0 ? data.genres : [], + homepage: data.homepage || '', + originalLanguage: data.original_language, + productionCompanies: [], + releaseDate: releaseDate !== '-' ? releaseDate : '', + voteAverage: String(voteAverage) ? voteAverage : '', + status: data.status || '', + tagline: data.tagline || '', + belongsToCollection: { + id: 0, + name: '', + backgroundUrl: '', + posterUrl: '' + }, + runtime: data.episode_run_time || '', + + // Show Specific fields + type: data.type || '', + numberOfEpisodes: String(data.number_of_episodes) || 0, + numberOfSeasons: String(data.number_of_seasons) || 0, + CurrentSeason: { + backgroundUrl: '', + seasonNumber: 0, + year: '', + episodeCount: 0, + overview: '' + } + }; + + // Name + // When the name isn't available try to use the + if (Show.name === '') { + Show.name = data.original_name; } - if (has(data, 'last_episode_to_air') === true && has(data, 'seasons') === true) { - const CurrentSeasonIndex = data.seasons.findIndex( - (season) => season.season_number === data.last_episode_to_air.season_number - ); + // Original language + // If the below conditions are met overwrite the default originalLanguage to something meaningful e.g. "en" -> "English" + if ( + has(data, 'original_language') === true && + has(data, 'languages') === true && + data.languages.length !== 0 + ) { + // Finds the first language which matches the original_Language assigned to the Show + const language = data.languages.find((el) => el === data.original_language); - // Set the current_season field to the CurrentSeason - setValue(data, 'current_season', { - image: generateAbsolutePath(data.last_episode_to_air.still_path), - season_number: data.last_episode_to_air.season_number, - year: generateYear(data.last_episode_to_air.air_date), - episode_count: data.seasons[CurrentSeasonIndex].episode_count, - overview: data.seasons[CurrentSeasonIndex].overview - }); + Show.originalLanguage = language; } - if (has(data, 'backdrop_path') === true) { - setValue(data, 'backdrop_path', generateAbsolutePath(data.backdrop_path)); + // Production companies + // When the production company is available and there isn't 0 companies + if (has(data, 'production_companies') === true && data.production_companies.length !== 0) { + const productionCompanies = []; + + data.production_companies.forEach((singleCompany) => { + const company = { + id: String(singleCompany.id) ? singleCompany.id : 0, + logo: generateAbsolutePath(singleCompany.logo_path) || '', + name: singleCompany.name || '' + }; + + // Push the new production company object to the productionCompanies array + productionCompanies.push(company); + }); + + Show.productionCompanies = productionCompanies; } - if (has(data, 'poster_path') === true) { - setValue(data, 'poster_path', generateAbsolutePath(data.poster_path)); + // Show Collections + // When the belongs_to_collection is available update the default values + if (has(data, 'belongs_to_collection') === true) { + // eslint-disable-next-line camelcase + const { belongs_to_collection } = data; + + /* + + Setting the collection values: + + - Numbers are converted to string to check to see if they are truthy or false value + + - When a number has been converted make sure to return it as a number + + */ + + // Sets the collection id + Show.belongsToCollection.id = String(belongs_to_collection.id) + ? belongs_to_collection.id + : ''; + + // Sets the collection name + Show.belongsToCollection.name = belongs_to_collection.name || ''; + + // Sets the backgroundUrl (Used as the background for the collection card) + Show.belongsToCollection.backgroundUrl = + generateAbsolutePath(belongs_to_collection.backdrop_path) || ''; + + // Sets the posterUrl (Not used in the collection card, but it could be eventually) + Show.belongsToCollection.posterUrl = + generateAbsolutePath(belongs_to_collection.poster_path) || ''; } - if (has(data, 'vote_average') === true) { - setValue(data, 'vote_average', toPercentage(data.vote_average)); + // Runtime + // When the runtime is available overwrite with a movie/show length e.g. 1hr 2min + if (Show.runtime !== '') { + // Select the longest runtime + const runtime = Math.max(...data.episode_run_time); + + const hours = Math.floor(runtime / 60); + const minutes = runtime % 60; + Show.runtime = `${hours}h ${minutes}m`; } - if (has(data, 'networks') === true) { - forEach(data.networks, (network) => { - if (has(network, 'logo_path') === true) { - setValue(network, 'logo_path', generateAbsolutePath(network.logo_path)); + /* + + Show specific fields + + */ + + if (has(data, 'last_episode_to_air') === true && has(data, 'seasons') === true) { + // eslint-disable-next-line camelcase + const { last_episode_to_air, seasons } = data; + + Show.CurrentSeason.backgroundUrl = + generateAbsolutePath(last_episode_to_air.still_path) || ''; + + Show.CurrentSeason.seasonNumber = String(last_episode_to_air.season_number) + ? last_episode_to_air.season_number + : 0; + + Show.CurrentSeason.year = generateYear(last_episode_to_air.air_date) || ''; + + /* + + CurrentSeason functionality + + To get the episodeCount and overview we need the CurrentSeasonIndex, this requires additional checks to be put in place. + + Checks put in place: + + - To ensure the index is found we check to see if the index is available ie not -1 which findIndex returns. + + - Once we have the index we then need to check if the properties actual exist in the object, if they are available set them otherwise the default values will be used (Show object) + + */ + const CurrentSeasonIndex = seasons.findIndex( + (season) => season.season_number === data.last_episode_to_air.season_number + ); + + if (CurrentSeasonIndex !== -1) { + // Episode count + if (has(seasons[CurrentSeasonIndex], 'episode_count') === true) { + Show.CurrentSeason.episodeCount = seasons[CurrentSeasonIndex].episode_count; } - }); + + // Overview + if (has(seasons[CurrentSeasonIndex], 'overview') === true) { + Show.CurrentSeason.overview = seasons[CurrentSeasonIndex].overview; + } + } } - return data; + return Show; } catch (err) { console.log(`The /tv endpoint failed`); console.log(err); diff --git a/resolvers/Social/MovieResolver.js b/resolvers/Social/MovieResolver.js index 58b682d..a8fbfc6 100644 --- a/resolvers/Social/MovieResolver.js +++ b/resolvers/Social/MovieResolver.js @@ -1,13 +1,18 @@ const axios = require('axios'); const generateSocialLinksEndpoint = require('../../utils/generateEndpoints/Social'); +const setSocialLinks = require('../../utils/resolverUtils/Social/setSocialLinks'); // eslint-disable-next-line no-unused-vars const MovieSocialResolver = async (parent, args, info, context) => { try { const response = await axios.get(generateSocialLinksEndpoint(parent.id, 'movie')); - return response.data; + const { data } = response; + + const SocialLinks = setSocialLinks({ ...data, homepage: parent.homepage }); + + return SocialLinks; } catch (err) { console.log('The movie /external_ids (social) endpoint failed'); return err.response; diff --git a/resolvers/Social/PersonResolver.js b/resolvers/Social/PersonResolver.js new file mode 100644 index 0000000..f87ce96 --- /dev/null +++ b/resolvers/Social/PersonResolver.js @@ -0,0 +1,22 @@ +const axios = require('axios'); + +const generateSocialLinksEndpoint = require('../../utils/generateEndpoints/Social'); +const setSocialLinks = require('../../utils/resolverUtils/Social/setSocialLinks'); + +// eslint-disable-next-line no-unused-vars +const PersonSocialResolver = async (parent, args, info, context) => { + try { + const response = await axios.get(generateSocialLinksEndpoint(parent.id, 'person', 'person')); + + const { data } = response; + + const SocialLinks = setSocialLinks({ ...data, homepage: parent.homepage }, 'person'); + + return SocialLinks; + } catch (err) { + console.log('The Person /external_ids (social) endpoint failed'); + return err.response; + } +}; + +module.exports = PersonSocialResolver; diff --git a/resolvers/Social/ShowResolver.js b/resolvers/Social/ShowResolver.js index 1a1516e..35fa762 100644 --- a/resolvers/Social/ShowResolver.js +++ b/resolvers/Social/ShowResolver.js @@ -1,13 +1,18 @@ const axios = require('axios'); const generateSocialLinksEndpoint = require('../../utils/generateEndpoints/Social'); +const setSocialLinks = require('../../utils/resolverUtils/Social/setSocialLinks'); // eslint-disable-next-line no-unused-vars const TVSocialResolver = async (parent, args, info, context) => { try { const response = await axios.get(generateSocialLinksEndpoint(parent.id, 'tv')); - return response.data; + const { data } = response; + + const SocialLinks = setSocialLinks({ ...data, homepage: parent.homepage }); + + return SocialLinks; } catch (err) { console.log('The TV /external_ids (social) endpoint failed'); return err.response; diff --git a/resolvers/Social/index.js b/resolvers/Social/index.js index b3af818..9a78e66 100644 --- a/resolvers/Social/index.js +++ b/resolvers/Social/index.js @@ -1,7 +1,9 @@ const MovieSocialResolver = require('./MovieResolver'); const ShowSocialResolver = require('./ShowResolver'); +const PersonSocialResolver = require('./PersonResolver'); module.exports = { MovieSocialResolver, - ShowSocialResolver + ShowSocialResolver, + PersonSocialResolver }; diff --git a/resolvers/TopRated/MoviesResolver.js b/resolvers/TopRated/MoviesResolver.js index b257402..77bf295 100644 --- a/resolvers/TopRated/MoviesResolver.js +++ b/resolvers/TopRated/MoviesResolver.js @@ -1,36 +1,19 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generateTopRatedEndpoint = require('../../utils/generateEndpoints/TopRated'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); +const setMovies = require('../../utils/resolverUtils/Movies/setMovies'); // eslint-disable-next-line no-unused-vars const MoviePopularResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateTopRatedEndpoint('movie')); - forEach(response.data.results, (movie) => { - if (has(movie, 'poster_path') === true) { - setValue(movie, 'poster_path', generateAbsolutePath(movie.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(movie, 'backdrop_path') === true) { - setValue(movie, 'backdrop_path', generateAbsolutePath(movie.backdrop_path)); - } + const Movies = setMovies(results); - if (has(movie, 'release_date') === true) { - setValue(movie, 'release_date', formatDate(movie.release_date, 'MMMM Do, YYYY')); - } - - if (has(movie, 'vote_average') === true) { - setValue(movie, 'vote_average', toPercentage(movie.vote_average)); - } - }); - - return response.data.results; + return Movies; } catch (err) { console.log('The /movie/top_rated endpoint failed'); console.log(err); diff --git a/resolvers/TopRated/ShowResolver.js b/resolvers/TopRated/ShowResolver.js index 2854b47..460eead 100644 --- a/resolvers/TopRated/ShowResolver.js +++ b/resolvers/TopRated/ShowResolver.js @@ -1,38 +1,19 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generateTopRatedEndpoint = require('../../utils/generateEndpoints/TopRated'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); -const replaceKey = require('../../utils/objects/replaceKey'); +const setShows = require('../../utils/resolverUtils/Shows/setShows'); // eslint-disable-next-line no-unused-vars const PopularShowResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateTopRatedEndpoint('tv')); - forEach(response.data.results, (show) => { - if (has(show, 'poster_path') === true) { - setValue(show, 'poster_path', generateAbsolutePath(show.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(show, 'backdrop_path') === true) { - setValue(show, 'backdrop_path', generateAbsolutePath(show.backdrop_path)); - } + const Shows = setShows(results); - if (has(show, 'first_air_date') === true) { - replaceKey(show, 'first_air_date', 'release_date'); - setValue(show, 'release_date', formatDate(show.release_date, 'MMMM Do, YYYY')); - } - - if (has(show, 'vote_average') === true) { - setValue(show, 'vote_average', toPercentage(show.vote_average)); - } - }); - - return response.data.results; + return Shows; } catch (err) { console.log('The /movie/top_rated endpoint failed'); return err.response; diff --git a/resolvers/Upcoming/MoviesResolver.js b/resolvers/Upcoming/MoviesResolver.js index 9310ef3..de0e155 100644 --- a/resolvers/Upcoming/MoviesResolver.js +++ b/resolvers/Upcoming/MoviesResolver.js @@ -1,36 +1,19 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generateUpcomingEndpoint = require('../../utils/generateEndpoints/Upcoming'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); +const setMovies = require('../../utils/resolverUtils/Movies/setMovies'); // eslint-disable-next-line no-unused-vars const NowPlayingTVResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateUpcomingEndpoint('movie')); - forEach(response.data.results, (movie) => { - if (has(movie, 'poster_path') === true) { - setValue(movie, 'poster_path', generateAbsolutePath(movie.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(movie, 'backdrop_path') === true) { - setValue(movie, 'backdrop_path', generateAbsolutePath(movie.backdrop_path)); - } + const Movies = setMovies(results); - if (has(movie, 'release_date') === true) { - setValue(movie, 'release_date', formatDate(movie.release_date, 'MMMM Do, YYYY')); - } - - if (has(movie, 'vote_average') === true) { - setValue(movie, 'vote_average', toPercentage(movie.vote_average)); - } - }); - - return response.data.results; + return Movies; } catch (err) { console.log('The tv/on_the_air endpoint failed'); return err.response; diff --git a/resolvers/Upcoming/ShowResolver.js b/resolvers/Upcoming/ShowResolver.js index c061c3c..2e8eae8 100644 --- a/resolvers/Upcoming/ShowResolver.js +++ b/resolvers/Upcoming/ShowResolver.js @@ -1,38 +1,19 @@ const axios = require('axios'); -const { has, forEach } = require('lodash'); const generateUpcomingEndpoint = require('../../utils/generateEndpoints/Upcoming'); -const generateAbsolutePath = require('../../utils/images/generateAbsolutePath'); -const formatDate = require('../../utils/dates/custom'); -const toPercentage = require('../../utils/maths/toPercentage'); -const setValue = require('../../utils/objects/setValue'); -const replaceKey = require('../../utils/objects/replaceKey'); +const setShows = require('../../utils/resolverUtils/Shows/setShows'); // eslint-disable-next-line no-unused-vars const NowPlayingTVResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateUpcomingEndpoint('tv')); - forEach(response.data.results, (show) => { - if (has(show, 'poster_path') === true) { - setValue(show, 'poster_path', generateAbsolutePath(show.poster_path)); - } + const { data } = response; + const { results } = data; - if (has(show, 'backdrop_path') === true) { - setValue(show, 'backdrop_path', generateAbsolutePath(show.backdrop_path)); - } + const Shows = setShows(results); - if (has(show, 'first_air_date') === true) { - replaceKey(show, 'first_air_date', 'release_date'); - setValue(show, 'release_date', formatDate(show.release_date, 'MMMM Do, YYYY')); - } - - if (has(show, 'vote_average') === true) { - setValue(show, 'vote_average', toPercentage(show.vote_average)); - } - }); - - return response.data.results; + return Shows; } catch (err) { console.log('The tv/on_the_air endpoint failed'); return err.response; diff --git a/resolvers/Videos/MovieResolver.js b/resolvers/Videos/MovieResolver.js index af181e0..c0d4fe7 100644 --- a/resolvers/Videos/MovieResolver.js +++ b/resolvers/Videos/MovieResolver.js @@ -1,21 +1,19 @@ const axios = require('axios'); -const { filter, forEach } = require('lodash'); const generateVideoEndpoint = require('../../utils/generateEndpoints/Videos'); -const setValue = require('../../utils/objects/setValue'); +const setFeaturedVideo = require('../../utils/resolverUtils/Videos/setFeaturedVideo'); // eslint-disable-next-line no-unused-vars const MovieVideoResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateVideoEndpoint(parent.id, 'movie')); - const YoutubeVideos = filter(response.data.results, (video) => video.site === 'YouTube'); + const { data } = response; + const { results } = data; - forEach(YoutubeVideos, (video) => { - setValue(video, 'url', `https://www.youtube.com/watch?v=${video.key}`); - }); + const Video = setFeaturedVideo(results); - return YoutubeVideos; + return Video; } catch (err) { console.log('The movie/videos endpoint failed'); return err.response; diff --git a/resolvers/Videos/ShowResolver.js b/resolvers/Videos/ShowResolver.js index 7ef8876..b5f1acc 100644 --- a/resolvers/Videos/ShowResolver.js +++ b/resolvers/Videos/ShowResolver.js @@ -1,21 +1,19 @@ const axios = require('axios'); -const { filter, forEach } = require('lodash'); const generateVideoEndpoint = require('../../utils/generateEndpoints/Videos'); -const setValue = require('../../utils/objects/setValue'); +const setFeaturedVideo = require('../../utils/resolverUtils/Videos/setFeaturedVideo'); // eslint-disable-next-line no-unused-vars const ShowVideoResolver = async (parent, args, context, info) => { try { const response = await axios.get(generateVideoEndpoint(parent.id, 'tv')); - const YoutubeVideos = filter(response.data.results, (video) => video.site === 'YouTube'); + const { data } = response; + const { results } = data; - forEach(YoutubeVideos, (video) => { - setValue(video, 'url', `https://www.youtube.com/watch?v=${video.key}`); - }); + const Video = setFeaturedVideo(results); - return YoutubeVideos; + return Video; } catch (err) { console.log('The tv/videos endpoint failed'); return err.response; diff --git a/resolvers/index.js b/resolvers/index.js index cb7a1e3..160d129 100644 --- a/resolvers/index.js +++ b/resolvers/index.js @@ -7,14 +7,14 @@ const { MovieCastResolver, ShowCastResolver } = require('./Cast'); // Crew resolvers const { MovieCrewResolver, ShowCrewResolver } = require('./Crew'); -// Reccomendation resolvers -const { MovieRecomendationsResolver, ShowRecomendationsResolver } = require('./Recomendations'); +// Recommendation resolvers +const { MovieRecommendationsResolver, ShowRecommendationsResolver } = require('./Recommendations'); // Keyword resolver const { MovieKeywordResolver, ShowKeywordResolver } = require('./Keywords'); // Social resolver -const { MovieSocialResolver, ShowSocialResolver } = require('./Social'); +const { MovieSocialResolver, ShowSocialResolver, PersonSocialResolver } = require('./Social'); // Search for a movie/show resolvers const { @@ -42,34 +42,35 @@ const { TopRatedMoviesResolver, TopRatedShowsResolver } = require('./TopRated'); const { MovieVideoResolver, ShowVideoResolver } = require('./Videos'); // Credits resolver -const { CreditsResolver, FilteredCreditsResolver } = require('./Credits'); +const { CreditsResolver } = require('./Credits'); const resolvers = { // Additional data for the single movie object Movie: { reviews: MovieReviewResolver, - cast: MovieCastResolver, - crew: MovieCrewResolver, - recomendations: MovieRecomendationsResolver, + featuredCast: MovieCastResolver, + featuredCrew: MovieCrewResolver, + recommendations: MovieRecommendationsResolver, keywords: MovieKeywordResolver, social: MovieSocialResolver, - videos: MovieVideoResolver + featuredVideo: MovieVideoResolver }, // Additional data for the single show object Show: { reviews: ShowReviewResolver, - cast: ShowCastResolver, - crew: ShowCrewResolver, - recomendations: ShowRecomendationsResolver, + featuredCast: ShowCastResolver, + featuredCrew: ShowCrewResolver, + recommendations: ShowRecommendationsResolver, keywords: ShowKeywordResolver, social: ShowSocialResolver, - videos: ShowVideoResolver + featuredVideo: ShowVideoResolver }, // Additional data for the single person object Person: { - credits: CreditsResolver + credits: CreditsResolver, + social: PersonSocialResolver }, // Root query @@ -98,10 +99,7 @@ const resolvers = { // Top rated resolvers TopRatedMovies: TopRatedMoviesResolver, - TopRatedShows: TopRatedShowsResolver, - - // Credits resolver (Single endpoint to provide filtering capabilites) - FilterCredits: FilteredCreditsResolver + TopRatedShows: TopRatedShowsResolver } }; diff --git a/schema.js b/schema.js index a5808b7..dfed5f7 100644 --- a/schema.js +++ b/schema.js @@ -6,30 +6,27 @@ const Company = require('./models/Company'); const Crew = require('./models/Crew'); const Genre = require('./models/Genres'); const Keyword = require('./models/Keyword'); -const Language = require('./models/Language'); const Social = require('./models/Social'); const Review = require('./models/Review'); +const BelowsToCollection = require('./models/BelongsToCollection'); // Person Models const People = require('./models/People'); -const KnownFor = require('./models/People/KnownFor'); const Person = require('./models/People/Person'); const Credits = require('./models/People/Credits'); // Show Models -const CreatedBy = require('./models/Show/CreatedBy'); -const LastEpisodeToAir = require('./models/Show/LastEpisodeToAir'); const Network = require('./models/Show/Network'); -const Season = require('./models/Show/Season'); const CurrentSeason = require('./models/Show/CurrentSeason'); // Main models e.g. SingleMovie, TV, People etc const Query = require('./models/Query'); const Show = require('./models/Show'); +const Shows = require('./models/Show/Shows'); const Video = require('./models/Videos'); -const Movies = require('./models/Movies'); -const Movie = require('./models/Movies/Movie'); +const Movies = require('./models/Movie/Movies'); +const Movie = require('./models/Movie'); // Resolvers const { RootQuery } = require('./resolvers'); @@ -42,23 +39,20 @@ const stuff = makeExecutableSchema({ Crew, Genre, Keyword, - Language, Social, Review, - CreatedBy, - LastEpisodeToAir, Network, - Season, Show, + Shows, Movie, Video, Person, - KnownFor, Movie, Movies, People, CurrentSeason, - Credits + Credits, + BelowsToCollection ], resolvers: RootQuery }); diff --git a/utils/dates/custom/index.js b/utils/dates/custom/index.js index 3c5c878..b89db08 100644 --- a/utils/dates/custom/index.js +++ b/utils/dates/custom/index.js @@ -1,16 +1,16 @@ const moment = require('moment'); const { isEmpty } = require('lodash'); -const formatDate = (date, pattern) => { - let formattedDate = moment(date).format(pattern); +/** + * @param {string} date + * @param {string} pattern + * @returns {string} + */ +const formatDate = (date, pattern = 'MMMM Do, YYYY') => { + const formattedDate = moment(date).format(pattern); - if (isEmpty(pattern) === true) { - return 'Please provide a pattern'; - } - - if (isEmpty(date) === true) { - formattedDate = '--/--/----'; - return formattedDate; + if (isEmpty(pattern) === true || isEmpty(date) === true) { + return '-'; } return formattedDate; diff --git a/utils/dates/custom/index.test.js b/utils/dates/custom/index.test.js index 997292b..aa1fb96 100644 --- a/utils/dates/custom/index.test.js +++ b/utils/dates/custom/index.test.js @@ -3,16 +3,31 @@ const formatDate = require('./'); describe("Custom date unit test's", () => { // Valid date test('It should return April 23rd, 2020', () => { - expect(formatDate('2020-04-23', 'MMMM Do, YYYY')).toBe('April 23rd, 2020'); + // Arrange and act + const response = formatDate('2020-04-23', 'MMMM Do, YYYY'); + const output = 'April 23rd, 2020'; + + // Assertion + expect(response).toBe(output); }); // Default date (No date provided) - test('It should the default date (--/--/----)', () => { - expect(formatDate('', 'MMMM Do, YYYY')).toBe('--/--/----'); + test('No date provided', () => { + // Arrange and act + const response = formatDate('', 'MMMM Do, YYYY'); + const output = '-'; + + // Assertion + expect(response).toBe(output); }); // Invalid pattern test('It should return a pattern error message', () => { - expect(formatDate('2020-04-23', '')).toBe('Please provide a pattern'); + // Arrange and act + const response = formatDate('2020-04-23', ''); + const output = '-'; + + // Assertion + expect(response).toBe(output); }); }); diff --git a/utils/dates/generateBirthday/index.js b/utils/dates/generateBirthday/index.js index da9d7e3..21a7e56 100644 --- a/utils/dates/generateBirthday/index.js +++ b/utils/dates/generateBirthday/index.js @@ -1,18 +1,21 @@ const { isEmpty } = require('lodash'); const moment = require('moment'); +/** + * @param {string} date + * @returns {string} + */ const generateBirthdayDate = (date) => { - let birthdayDate = moment(date).format('DD/MM/YYYY'); + const birthdayDate = moment(date).format('DD/MM/YYYY'); if (isEmpty(date) === true) { - birthdayDate = '--/--/----'; - return birthdayDate; + return ''; } - const splitBirthayDate = birthdayDate.split('/'); + const splitBirthdayDate = birthdayDate.split('/'); const age = moment().diff( - `${splitBirthayDate[2]}-${splitBirthayDate[1]}-${splitBirthayDate[0]}`, + `${splitBirthdayDate[2]}-${splitBirthdayDate[1]}-${splitBirthdayDate[0]}`, 'years' ); diff --git a/utils/dates/generateBirthday/index.test.js b/utils/dates/generateBirthday/index.test.js index ad71e07..fa3b0e3 100644 --- a/utils/dates/generateBirthday/index.test.js +++ b/utils/dates/generateBirthday/index.test.js @@ -1,12 +1,12 @@ -const generateBirthday = require('./'); +const generateBirthday = require('./index'); describe("generateBirthday unit test's", () => { test('It should return 20/11/1997 (22 years old)', () => { - // Data - const input = generateBirthday('1997-11-20'); - const expectedOutput = '20/11/1997 (22 years old)'; + // Arrange and act + const response = generateBirthday('1997-11-20'); + const output = '20/11/1997 (22 years old)'; - // Test - expect(input).toBe(expectedOutput); + // Assertion + expect(response).toBe(output); }); }); diff --git a/utils/dates/generateYear/index.js b/utils/dates/generateYear/index.js index 573cd2b..dfe7727 100644 --- a/utils/dates/generateYear/index.js +++ b/utils/dates/generateYear/index.js @@ -1,6 +1,10 @@ const { isEmpty } = require('lodash'); const moment = require('moment'); +/** + * @param {string} date + * @returns {string} + */ const generateYear = (date) => { let newYear = moment(date).format('YYYY'); diff --git a/utils/dates/generateYear/index.test.js b/utils/dates/generateYear/index.test.js index 7cb019b..0aededc 100644 --- a/utils/dates/generateYear/index.test.js +++ b/utils/dates/generateYear/index.test.js @@ -1,21 +1,21 @@ -const generateYear = require('./'); +const generateYear = require('./index'); describe("generateYear unit test's", () => { - test('It should return 2020', () => { - // Data - const input = generateYear('2020-04-25'); - const exepectedOutput = '2020'; + test('The result should be 2020', () => { + // Arrange and act + const response = generateYear('2020-04-25'); + const output = '2020'; - // Test - expect(input).toBe(exepectedOutput); + // Assertion + expect(response).toBe(output); }); - test('It should return -', () => { - // Data - const input = generateYear(''); - const exepectedOutput = '-'; + test('The result should be a dash e.g. -', () => { + // Arrange and act + const response = generateYear(''); + const output = '-'; - // Test - expect(input).toBe(exepectedOutput); + // Assertion + expect(response).toBe(output); }); }); diff --git a/utils/generateEndpoints/Cast/index.js b/utils/generateEndpoints/Cast/index.js index 08e6db5..385d2c9 100644 --- a/utils/generateEndpoints/Cast/index.js +++ b/utils/generateEndpoints/Cast/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {number} id + * @param {string} resolverType + * @returns {string} + */ const generateCastURLEndpoint = (id, resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/${id}/credits?api_key=${API_KEY}`; diff --git a/utils/generateEndpoints/Cast/index.test.js b/utils/generateEndpoints/Cast/index.test.js index 2e2b7ed..2c13f97 100644 --- a/utils/generateEndpoints/Cast/index.test.js +++ b/utils/generateEndpoints/Cast/index.test.js @@ -1,26 +1,22 @@ -const generateCastEndpoint = require('./'); +const generateCastEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('GenerateCastEndpoint', () => { it('Should return the full cast endpoint (TV)', () => { - // Generated URL - const input = generateCastEndpoint(12, 'tv'); + // Arrange and act + const response = generateCastEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12/credits?api_key=${API_KEY}`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12/credits?api_key=${API_KEY}`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full cast endpoint (Movie)', () => { - // Generated URL - const input = generateCastEndpoint(14, 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/14/credits?api_key=${API_KEY}`; + // Arrange and act + const response = generateCastEndpoint(14, 'movie'); + const output = `${API_URI}/${API_VERSION}/movie/14/credits?api_key=${API_KEY}`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Credit/index.js b/utils/generateEndpoints/Credit/index.js new file mode 100644 index 0000000..f2c5dfa --- /dev/null +++ b/utils/generateEndpoints/Credit/index.js @@ -0,0 +1,11 @@ +const { API_URI, API_VERSION, API_KEY } = require('../../../config'); + +/** + * @param {string} id + * @returns {string} + */ +const generateCreditEndpoint = (id) => `${API_URI}/${API_VERSION}/credit/${id}/?api_key=${API_KEY}`; + +module.exports = generateCreditEndpoint; + +// `https://api.themoviedb.org/3/credit/${item.creditId}?api_key={API_kEY_GOES_HERE}`; diff --git a/utils/generateEndpoints/Credit/index.test.js b/utils/generateEndpoints/Credit/index.test.js new file mode 100644 index 0000000..da86760 --- /dev/null +++ b/utils/generateEndpoints/Credit/index.test.js @@ -0,0 +1,22 @@ +const generateCreditEndpoint = require('./index'); +const { API_URI, API_VERSION, API_KEY } = require('../../../config'); + +describe('generateCreditEndpoint', () => { + it('Should return the full credits endpoint (TV)', () => { + // Arrange and act + const response = generateCreditEndpoint('12'); + const output = `${API_URI}/${API_VERSION}/credit/12/?api_key=${API_KEY}`; + + // Assertion + expect(response).toMatch(output); + }); + + it('Should return the full credits endpoint (Movie)', () => { + // Arrange and act + const response = generateCreditEndpoint('14'); + const output = `${API_URI}/${API_VERSION}/credit/14/?api_key=${API_KEY}`; + + // Assertion + expect(response).toMatch(output); + }); +}); diff --git a/utils/generateEndpoints/Credits/index.js b/utils/generateEndpoints/Credits/index.js index e26c23d..7444627 100644 --- a/utils/generateEndpoints/Credits/index.js +++ b/utils/generateEndpoints/Credits/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {number} id + * @returns {string} + */ + const generatePersonCreditsEndpoint = (id) => `${API_URI}/${API_VERSION}/person/${id}/combined_credits?api_key=${API_KEY}`; diff --git a/utils/generateEndpoints/Credits/index.test.js b/utils/generateEndpoints/Credits/index.test.js index 2f7ad46..b27bf16 100644 --- a/utils/generateEndpoints/Credits/index.test.js +++ b/utils/generateEndpoints/Credits/index.test.js @@ -1,26 +1,22 @@ -const generateCreditsEndpoint = require('./'); +const generateCreditsEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateCreditsEndpoint', () => { it('Should return the full credits endpoint (TV)', () => { - // Generated URL - const input = generateCreditsEndpoint(12, 'tv'); + // Arrange and act + const response = generateCreditsEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/person/12/combined_credits?api_key=${API_KEY}`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/person/12/combined_credits?api_key=${API_KEY}`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full credits endpoint (Movie)', () => { - // Generated URL - const input = generateCreditsEndpoint(14, 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/person/14/combined_credits?api_key=${API_KEY}`; + // Arrange and act + const response = generateCreditsEndpoint(14, 'movie'); + const output = `${API_URI}/${API_VERSION}/person/14/combined_credits?api_key=${API_KEY}`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Crew/index.js b/utils/generateEndpoints/Crew/index.js index 9987ea5..e49567f 100644 --- a/utils/generateEndpoints/Crew/index.js +++ b/utils/generateEndpoints/Crew/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {number} id + * @param {string} resolverType + * @returns {string} + */ const generateCrewEndpoint = (id, resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/${id}/credits?api_key=${API_KEY}`; diff --git a/utils/generateEndpoints/Crew/index.test.js b/utils/generateEndpoints/Crew/index.test.js index 8529d8f..5ce4f7f 100644 --- a/utils/generateEndpoints/Crew/index.test.js +++ b/utils/generateEndpoints/Crew/index.test.js @@ -1,26 +1,22 @@ -const generateCrewEndpoint = require('./'); +const generateCrewEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateCrewEndpoint', () => { it('Should return the full crew endpoint (TV)', () => { - // Generated URL - const input = generateCrewEndpoint(12, 'tv'); + // Arrange and act + const response = generateCrewEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12/credits?api_key=${API_KEY}`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12/credits?api_key=${API_KEY}`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full crew endpoint (Movie)', () => { - // Generated URL - const input = generateCrewEndpoint(14, 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/14/credits?api_key=${API_KEY}`; + // Arrange and act + const response = generateCrewEndpoint(14, 'movie'); + const output = `${API_URI}/${API_VERSION}/movie/14/credits?api_key=${API_KEY}`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Discover/index.js b/utils/generateEndpoints/Discover/index.js index bc63b97..8fe4afe 100644 --- a/utils/generateEndpoints/Discover/index.js +++ b/utils/generateEndpoints/Discover/index.js @@ -1,5 +1,9 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {string} resolverType + * @returns {string} + */ const generateDiscoverEndpoint = (resolverType) => `${API_URI}/${API_VERSION}/discover/${resolverType}?api_key=${API_KEY}&page=1`; diff --git a/utils/generateEndpoints/Discover/index.test.js b/utils/generateEndpoints/Discover/index.test.js index a4f72fc..04f69e0 100644 --- a/utils/generateEndpoints/Discover/index.test.js +++ b/utils/generateEndpoints/Discover/index.test.js @@ -3,24 +3,20 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateDiscoverEndpoint', () => { it('Should return the full discover endpoint (TV)', () => { - // Generated URL - const input = generateDiscoverEndpoint('tv'); + // Arrange and act + const response = generateDiscoverEndpoint('tv'); + const output = `${API_URI}/${API_VERSION}/discover/tv?api_key=${API_KEY}&page=1`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/discover/tv?api_key=${API_KEY}&page=1`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full discover endpoint (Movie)', () => { - // Generated URL - const input = generateDiscoverEndpoint('movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/discover/movie?api_key=${API_KEY}&page=1`; + // Arrange and act + const response = generateDiscoverEndpoint('movie'); + const output = `${API_URI}/${API_VERSION}/discover/movie?api_key=${API_KEY}&page=1`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Keywords/index.js b/utils/generateEndpoints/Keywords/index.js index a588e93..322d148 100644 --- a/utils/generateEndpoints/Keywords/index.js +++ b/utils/generateEndpoints/Keywords/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {number} id + * @param {string} resolverType + * @returns {string} + */ const generateKeywordEndpoint = (id, resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/${id}/keywords?api_key=${API_KEY}`; diff --git a/utils/generateEndpoints/Keywords/index.test.js b/utils/generateEndpoints/Keywords/index.test.js index f6f13d5..606ab86 100644 --- a/utils/generateEndpoints/Keywords/index.test.js +++ b/utils/generateEndpoints/Keywords/index.test.js @@ -3,24 +3,20 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateKeywordsEndpoint', () => { it('Should return the full discover endpoint (TV)', () => { - // Generated URL - const input = generateKeywordsEndpoint(12, 'tv'); + // Arrange and act + const response = generateKeywordsEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12/keywords?api_key=${API_KEY}`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12/keywords?api_key=${API_KEY}`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full discover endpoint (Movie)', () => { - // Generated URL - const input = generateKeywordsEndpoint(12, 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/12/keywords?api_key=${API_KEY}`; + // Arrange and act + const response = generateKeywordsEndpoint(12, 'movie'); + const output = `${API_URI}/${API_VERSION}/movie/12/keywords?api_key=${API_KEY}`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/NowPlaying/index.js b/utils/generateEndpoints/NowPlaying/index.js index d0b853b..2170319 100644 --- a/utils/generateEndpoints/NowPlaying/index.js +++ b/utils/generateEndpoints/NowPlaying/index.js @@ -1,6 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); -const genereateNowPlayingEndpoint = (resolverType) => { +/** + * @param {string} resolverType + * @returns {string} + */ +const generateNowPlayingEndpoint = (resolverType) => { switch (resolverType) { case 'tv': { return `${API_URI}/${API_VERSION}/${resolverType}/airing_today?api_key=${API_KEY}&page=1`; @@ -11,4 +15,4 @@ const genereateNowPlayingEndpoint = (resolverType) => { } }; -module.exports = genereateNowPlayingEndpoint; +module.exports = generateNowPlayingEndpoint; diff --git a/utils/generateEndpoints/NowPlaying/index.test.js b/utils/generateEndpoints/NowPlaying/index.test.js index 2067fe8..bb8152e 100644 --- a/utils/generateEndpoints/NowPlaying/index.test.js +++ b/utils/generateEndpoints/NowPlaying/index.test.js @@ -1,26 +1,22 @@ -const generateNowPlayingEndpoint = require('./'); +const generateNowPlayingEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateNowPlayingEndpoint', () => { it('Should return the full now playing endpoint (TV)', () => { - // Generated URL - const input = generateNowPlayingEndpoint('tv'); + // Arrange and act + const response = generateNowPlayingEndpoint('tv'); + const output = `${API_URI}/${API_VERSION}/tv/airing_today?api_key=${API_KEY}&page=1`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/airing_today?api_key=${API_KEY}&page=1`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full now playing endpoint (Movie)', () => { - // Generated URL - const input = generateNowPlayingEndpoint('movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/now_playing?api_key=${API_KEY}&page=1`; + // Arrange and act + const response = generateNowPlayingEndpoint('movie'); + const output = `${API_URI}/${API_VERSION}/movie/now_playing?api_key=${API_KEY}&page=1`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Popular/index.js b/utils/generateEndpoints/Popular/index.js index dd365ba..de12f0d 100644 --- a/utils/generateEndpoints/Popular/index.js +++ b/utils/generateEndpoints/Popular/index.js @@ -1,5 +1,9 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {string} resolverType + * @returns {string} + */ const generatePopularEndpoint = (resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/popular?api_key=${API_KEY}`; diff --git a/utils/generateEndpoints/Popular/index.test.js b/utils/generateEndpoints/Popular/index.test.js index 8964d8a..aef040c 100644 --- a/utils/generateEndpoints/Popular/index.test.js +++ b/utils/generateEndpoints/Popular/index.test.js @@ -1,26 +1,22 @@ -const generatePopularEndpoint = require('./'); +const generatePopularEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generatePopularEndpoint', () => { it('Should return the full popular endpoint (TV)', () => { - // Generated URL - const input = generatePopularEndpoint('tv'); + // Arrange and act + const response = generatePopularEndpoint('tv'); + const output = `${API_URI}/${API_VERSION}/tv/popular?api_key=${API_KEY}`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/popular?api_key=${API_KEY}`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full popular endpoint (Movie)', () => { - // Generated URL - const input = generatePopularEndpoint('movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/popular?api_key=${API_KEY}`; + // Arrange and act + const response = generatePopularEndpoint('movie'); + const output = `${API_URI}/${API_VERSION}/movie/popular?api_key=${API_KEY}`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Recomendations/index.js b/utils/generateEndpoints/Recomendations/index.js deleted file mode 100644 index e0eae4d..0000000 --- a/utils/generateEndpoints/Recomendations/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const { API_URI, API_VERSION, API_KEY } = require('../../../config'); - -const generateRecomendationEndpoint = (id, resolverType) => - `${API_URI}/${API_VERSION}/${resolverType}/${id}/recommendations?api_key=${API_KEY}&language=en-US&page=1`; - -module.exports = generateRecomendationEndpoint; diff --git a/utils/generateEndpoints/Recomendations/index.test.js b/utils/generateEndpoints/Recomendations/index.test.js deleted file mode 100644 index d212d53..0000000 --- a/utils/generateEndpoints/Recomendations/index.test.js +++ /dev/null @@ -1,26 +0,0 @@ -const generateRecomendationsEndpoint = require('./'); -const { API_URI, API_VERSION, API_KEY } = require('../../../config'); - -describe('generateRecomendationsEndpoint', () => { - it('Should return the full recomendations endpoint (TV)', () => { - // Generated URL - const input = generateRecomendationsEndpoint(12, 'tv'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12/recommendations?api_key=${API_KEY}&language=en-US&page=1`; - - // Test - expect(input).toMatch(expectedOutput); - }); - - it('Should return the full recomendations endpoint (Movie)', () => { - // Generated URL - const input = generateRecomendationsEndpoint(12, 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/12/recommendations?api_key=${API_KEY}&language=en-US&page=1`; - - // Test - expect(input).toMatch(expectedOutput); - }); -}); diff --git a/utils/generateEndpoints/Recommendations/index.js b/utils/generateEndpoints/Recommendations/index.js new file mode 100644 index 0000000..43159d3 --- /dev/null +++ b/utils/generateEndpoints/Recommendations/index.js @@ -0,0 +1,11 @@ +const { API_URI, API_VERSION, API_KEY } = require('../../../config'); + +/** + * @param {number} id + * @param {string} resolverType + * @returns {string} + */ +const generateRecommendationEndpoint = (id, resolverType) => + `${API_URI}/${API_VERSION}/${resolverType}/${id}/recommendations?api_key=${API_KEY}&language=en-US&page=1`; + +module.exports = generateRecommendationEndpoint; diff --git a/utils/generateEndpoints/Recommendations/index.test.js b/utils/generateEndpoints/Recommendations/index.test.js new file mode 100644 index 0000000..c27deba --- /dev/null +++ b/utils/generateEndpoints/Recommendations/index.test.js @@ -0,0 +1,22 @@ +const generateRecommendationsEndpoint = require('./index'); +const { API_URI, API_VERSION, API_KEY } = require('../../../config'); + +describe('generateRecommendationsEndpoint', () => { + it('Should return the full recommendations endpoint (TV)', () => { + // Arrange and act + const response = generateRecommendationsEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12/recommendations?api_key=${API_KEY}&language=en-US&page=1`; + + // Assertion + expect(response).toMatch(output); + }); + + it('Should return the full recommendations endpoint (Movie)', () => { + // Arrange and act + const response = generateRecommendationsEndpoint(12, 'movie'); + const output = `${API_URI}/${API_VERSION}/movie/12/recommendations?api_key=${API_KEY}&language=en-US&page=1`; + + // Assertion + expect(response).toMatch(output); + }); +}); diff --git a/utils/generateEndpoints/Reviews/index.js b/utils/generateEndpoints/Reviews/index.js index 06d1f13..ed2106f 100644 --- a/utils/generateEndpoints/Reviews/index.js +++ b/utils/generateEndpoints/Reviews/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {number} id + * @param {string} resolverType + * @returns {string} + */ const generateReviewEndpoint = (id, resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/${id}/reviews?api_key=${API_KEY}&language=en-US&page=1`; diff --git a/utils/generateEndpoints/Reviews/index.test.js b/utils/generateEndpoints/Reviews/index.test.js index dd5c890..cad7015 100644 --- a/utils/generateEndpoints/Reviews/index.test.js +++ b/utils/generateEndpoints/Reviews/index.test.js @@ -1,26 +1,22 @@ -const generateReviewEndpoint = require('./'); +const generateReviewEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateReviewEndpoint', () => { it('Should return the full reviews endpoint (TV)', () => { - // Generated URL - const input = generateReviewEndpoint(12, 'tv'); + // Arrange and act + const response = generateReviewEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12/reviews?api_key=${API_KEY}&language=en-US&page=1`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12/reviews?api_key=${API_KEY}&language=en-US&page=1`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full reviews endpoint (Movie)', () => { - // Generated URL - const input = generateReviewEndpoint(12, 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/12/reviews?api_key=${API_KEY}&language=en-US&page=1`; + // Arrange and act + const response = generateReviewEndpoint(12, 'movie'); + const output = `${API_URI}/${API_VERSION}/movie/12/reviews?api_key=${API_KEY}&language=en-US&page=1`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Search/index.js b/utils/generateEndpoints/Search/index.js index 791b3b5..231e2b9 100644 --- a/utils/generateEndpoints/Search/index.js +++ b/utils/generateEndpoints/Search/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {string} searchTerm + * @param {string} resolverType + * @returns {string} + */ const generateSearchEndpoint = (searchTerm, resolverType) => `${API_URI}/${API_VERSION}/search/${resolverType}?api_key=${API_KEY}&language=en-US&query=${searchTerm}&page=1`; diff --git a/utils/generateEndpoints/Search/index.test.js b/utils/generateEndpoints/Search/index.test.js index b3f790a..3e34cd9 100644 --- a/utils/generateEndpoints/Search/index.test.js +++ b/utils/generateEndpoints/Search/index.test.js @@ -1,26 +1,22 @@ -const generateSearchEndpoint = require('./'); +const generateSearchEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateReviewEndpoint', () => { it('Should return the full search endpoint (TV)', () => { - // Generated URL - const input = generateSearchEndpoint('Westworld', 'tv'); + // Arrange and act + const response = generateSearchEndpoint('Westworld', 'tv'); + const output = `${API_URI}/${API_VERSION}/search/tv?api_key=${API_KEY}&language=en-US&query=Westworld&page=1`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/search/tv?api_key=${API_KEY}&language=en-US&query=Westworld&page=1`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full search endpoint (Movie)', () => { - // Generated URL - const input = generateSearchEndpoint('Avengers', 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/search/movie?api_key=${API_KEY}&language=en-US&query=Avengers&page=1`; + // Arrange and act + const response = generateSearchEndpoint('Avengers', 'movie'); + const output = `${API_URI}/${API_VERSION}/search/movie?api_key=${API_KEY}&language=en-US&query=Avengers&page=1`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/SingleItemLookup/index.js b/utils/generateEndpoints/SingleItemLookup/index.js index 688fed3..435c20a 100644 --- a/utils/generateEndpoints/SingleItemLookup/index.js +++ b/utils/generateEndpoints/SingleItemLookup/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {number} id + * @param {string} resolverType + * @returns {string} + */ const generateSingleItemLookupEndpoint = (id, resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/${id}?api_key=${API_KEY}&language=en-US`; diff --git a/utils/generateEndpoints/SingleItemLookup/index.test.js b/utils/generateEndpoints/SingleItemLookup/index.test.js index 0e0f826..b11181c 100644 --- a/utils/generateEndpoints/SingleItemLookup/index.test.js +++ b/utils/generateEndpoints/SingleItemLookup/index.test.js @@ -1,26 +1,22 @@ -const generateSingleItemLookEndpoint = require('./'); +const generateSingleItemLookEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateSingleItemLookEndpoint', () => { it('Should return the full single tv lookup endpoint (TV)', () => { - // Generated URL - const input = generateSingleItemLookEndpoint(12, 'tv'); + // Arrange and act + const response = generateSingleItemLookEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12?api_key=${API_KEY}&language=en-US`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12?api_key=${API_KEY}&language=en-US`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full single movie lookup endpoint (Movie)', () => { - // Generated URL - const input = generateSingleItemLookEndpoint(12, 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/12?api_key=${API_KEY}&language=en-US`; + // Arrange and act + const response = generateSingleItemLookEndpoint(12, 'movie'); + const output = `${API_URI}/${API_VERSION}/movie/12?api_key=${API_KEY}&language=en-US`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Social/index.js b/utils/generateEndpoints/Social/index.js index 981fb85..3ec8a74 100644 --- a/utils/generateEndpoints/Social/index.js +++ b/utils/generateEndpoints/Social/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {number} id + * @param {string} resolverType + * @returns {string} + */ const generateSocialLinksEndpoint = (id, resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/${id}/external_ids?api_key=${API_KEY}`; diff --git a/utils/generateEndpoints/Social/index.test.js b/utils/generateEndpoints/Social/index.test.js index 272f2fb..d1fbd9b 100644 --- a/utils/generateEndpoints/Social/index.test.js +++ b/utils/generateEndpoints/Social/index.test.js @@ -1,26 +1,22 @@ -const generateSocialEndpoint = require('./'); +const generateSocialEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generateSingleItemLookEndpoint', () => { it('Should return the full external_id lookup endpoint (TV)', () => { - // Generated URL - const input = generateSocialEndpoint(12, 'tv'); + // Arrange and act + const response = generateSocialEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12/external_ids?api_key=${API_KEY}`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12/external_ids?api_key=${API_KEY}`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full external_id lookup endpoint (TV)', () => { - // Generated URL - const input = generateSocialEndpoint(12, 'movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/12/external_ids?api_key=${API_KEY}`; + // Arrange and act + const response = generateSocialEndpoint(12, 'movie'); + const output = `${API_URI}/${API_VERSION}/movie/12/external_ids?api_key=${API_KEY}`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/TopRated/index.js b/utils/generateEndpoints/TopRated/index.js index d1cbf33..fbbfcef 100644 --- a/utils/generateEndpoints/TopRated/index.js +++ b/utils/generateEndpoints/TopRated/index.js @@ -1,5 +1,9 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {string} resolverType + * @returns {string} + */ const generateTopRatedEndpoint = (resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/top_rated?api_key=${API_KEY}&page=1`; diff --git a/utils/generateEndpoints/TopRated/index.test.js b/utils/generateEndpoints/TopRated/index.test.js index 6f8ee0d..64ee1c1 100644 --- a/utils/generateEndpoints/TopRated/index.test.js +++ b/utils/generateEndpoints/TopRated/index.test.js @@ -1,26 +1,22 @@ -const generatedTopRatedEndpoint = require('./'); +const generatedTopRatedEndpoint = require('./index'); const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generatedTopRatedEndpoint', () => { it('Should return the full popular endpoint (TV)', () => { - // Generated URL - const input = generatedTopRatedEndpoint('tv'); + // Arrange and act + const response = generatedTopRatedEndpoint('tv'); + const output = `${API_URI}/${API_VERSION}/tv/top_rated?api_key=${API_KEY}&page=1`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/top_rated?api_key=${API_KEY}&page=1`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full popular endpoint (TV)', () => { - // Generated URL - const input = generatedTopRatedEndpoint('movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/top_rated?api_key=${API_KEY}&page=1`; + // Arrange and act + const response = generatedTopRatedEndpoint('movie'); + const output = `${API_URI}/${API_VERSION}/movie/top_rated?api_key=${API_KEY}&page=1`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Upcoming/index.js b/utils/generateEndpoints/Upcoming/index.js index ddbef58..00dfba0 100644 --- a/utils/generateEndpoints/Upcoming/index.js +++ b/utils/generateEndpoints/Upcoming/index.js @@ -1,5 +1,9 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {string} resolverType + * @returns {string} + */ const generateUpcomingEndpoint = (resolverType) => { switch (resolverType) { case 'tv': diff --git a/utils/generateEndpoints/Upcoming/index.test.js b/utils/generateEndpoints/Upcoming/index.test.js index 1645213..6c16a1d 100644 --- a/utils/generateEndpoints/Upcoming/index.test.js +++ b/utils/generateEndpoints/Upcoming/index.test.js @@ -3,24 +3,20 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generatedTopRatedEndpoint', () => { it('Should return the full upcoming endpoint (TV)', () => { - // Generated URL - const input = generateUpcomingEndpoint('tv'); + // Arrange and act + const response = generateUpcomingEndpoint('tv'); + const output = `${API_URI}/${API_VERSION}/tv/on_the_air?api_key=${API_KEY}&page=1`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/on_the_air?api_key=${API_KEY}&page=1`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full upcoming endpoint (TV)', () => { - // Generated URL - const input = generateUpcomingEndpoint('movie'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/movie/upcoming?api_key=${API_KEY}&page=1`; + // Arrange and act + const response = generateUpcomingEndpoint('movie'); + const output = `${API_URI}/${API_VERSION}/movie/upcoming?api_key=${API_KEY}&page=1`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateEndpoints/Videos/index.js b/utils/generateEndpoints/Videos/index.js index dd00966..d7ee405 100644 --- a/utils/generateEndpoints/Videos/index.js +++ b/utils/generateEndpoints/Videos/index.js @@ -1,5 +1,10 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); +/** + * @param {number} id + * @param {string} resolverType + * @returns {string} + */ const generateVideoEndpoint = (id, resolverType) => `${API_URI}/${API_VERSION}/${resolverType}/${id}/videos?api_key=${API_KEY}&language=en-US`; diff --git a/utils/generateEndpoints/Videos/index.test.js b/utils/generateEndpoints/Videos/index.test.js index 3dc210a..08edaa8 100644 --- a/utils/generateEndpoints/Videos/index.test.js +++ b/utils/generateEndpoints/Videos/index.test.js @@ -3,24 +3,20 @@ const { API_URI, API_VERSION, API_KEY } = require('../../../config'); describe('generatedTopRatedEndpoint', () => { it('Should return the full video endpoint (TV)', () => { - // Generated URL - const input = generateVideoEndpoint(12, 'tv'); + // Arrange and act + const response = generateVideoEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12/videos?api_key=${API_KEY}&language=en-US`; - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12/videos?api_key=${API_KEY}&language=en-US`; - - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); it('Should return the full video endpoint (TV)', () => { - // Generated URL - const input = generateVideoEndpoint(12, 'tv'); - - // Actual URL - const expectedOutput = `${API_URI}/${API_VERSION}/tv/12/videos?api_key=${API_KEY}&language=en-US`; + // Arrange and act + const response = generateVideoEndpoint(12, 'tv'); + const output = `${API_URI}/${API_VERSION}/tv/12/videos?api_key=${API_KEY}&language=en-US`; - // Test - expect(input).toMatch(expectedOutput); + // Assertion + expect(response).toMatch(output); }); }); diff --git a/utils/generateQueryParameters/Discover/index.js b/utils/generateQueryParameters/Discover/index.js index e07a2f5..ac042e3 100644 --- a/utils/generateQueryParameters/Discover/index.js +++ b/utils/generateQueryParameters/Discover/index.js @@ -1,13 +1,25 @@ const { isEmpty } = require('lodash'); +/** + * @typedef {Object} Arguments + * @property {string} sortBy + * @property {string} genres + * @property {string} certifications + * @property {string} userscore + * @property {string} runtime + */ + +/** + * @description This utility creates the discover endpoint url + * @param {string} discoverURL + * @param {Arguments} args + * @returns {string} + */ const generateQueryParameter = (discoverURL, args) => { // Query parameters supported within TheOpenMovieDB Discover endpoint - const { sortBy } = args; - const { genres } = args; - const { certifications } = args; - const { userscore } = args; - const { runtime } = args; + const { sortBy, genres, certifications, userscore, runtime } = args; + // Base Url let url = discoverURL; // Sort by query diff --git a/utils/generateQueryParameters/Discover/index.test.js b/utils/generateQueryParameters/Discover/index.test.js index c579a0d..f955d57 100644 --- a/utils/generateQueryParameters/Discover/index.test.js +++ b/utils/generateQueryParameters/Discover/index.test.js @@ -1,97 +1,100 @@ const generateQueryParameters = require('./'); - const generateDiscoverEndpoint = require('../../generateEndpoints/Discover'); -const baseURL = generateDiscoverEndpoint('tv'); - -const generateQuery = (args) => { - return new URLSearchParams( - generateQueryParameters(baseURL, { - ...args - }) - ); -}; - -describe('sortBy query parameter tests', () => { - // Genres the query required - const sortByURL = generateQuery({ sortBy: 'popularity.asc' }); - - // Check to see if the sort_by query exists - it('Should return true', () => { - expect(sortByURL.get('sort_by')).toBeTruthy(); - }); -}); - -describe('genres query parameter tests', () => { - // Genres the query required - const genresURL = generateQuery({ genres: '14,16,18' }); - - // Checks to see if one of the with_genres query exist - it('Should return true', () => { - expect(genresURL.has('with_genres')).toBeTruthy(); - }); - - // Check the length of the with_genres array - it('Should have a length of 2', () => { - expect(genresURL.get('with_genres').length).toBe(2); - }); - - // Check the first element of the with_genres query - it('Should return 14', () => { - expect(genresURL.getAll('with_genres')[0]).toBe('14'); +describe('generateQueryParameters -> Discover', () => { + const baseURL = generateDiscoverEndpoint('tv'); + + const generateQuery = (args) => { + return new URLSearchParams( + generateQueryParameters(baseURL, { + ...args + }) + ); + }; + + describe('sortBy query parameter tests', () => { + it('Should return true', () => { + // Arrange and act + const sortByURL = generateQuery({ sortBy: 'popularity.asc' }); + + // Assertion + expect(sortByURL.get('sort_by')).toBeTruthy(); + }); }); - // Check the second element of the with_genres query - it('Should return 16', () => { - expect(genresURL.getAll('with_genres')[1]).toBe('16'); + describe('genres query parameter tests', () => { + // Arrange and act + const genresURL = generateQuery({ + genres: '14,16,18' + }); + + // Assertion + it('Should return true', () => { + expect(genresURL.has('with_genres')).toBeTruthy(); + }); + + // Assertion + it('Should have a length of 2', () => { + expect(genresURL.get('with_genres').length).toBe(2); + }); + + // Assertion + it('Should return 14', () => { + expect(genresURL.getAll('with_genres')[0]).toBe('14'); + }); + + // Assertion + it('Should return 16', () => { + expect(genresURL.getAll('with_genres')[1]).toBe('16'); + }); + + // Check the third element of the with_genres query + it('Should return 18', () => { + expect(genresURL.getAll('with_genres')[2]).toBe('18'); + }); }); - // Check the third element of the with_genres query - it('Should return 18', () => { - expect(genresURL.getAll('with_genres')[2]).toBe('18'); - }); -}); + describe('certification query parameter tests', () => { + const certificationsURL = generateQuery({ certifications: 'U,18' }); -describe('certification query parameter tests', () => { - const certificationsURL = generateQuery({ certifications: 'U,18' }); + it('Should return true', () => { + expect(certificationsURL.has('certification')).toBeTruthy(); + }); - it('Should return true', () => { - expect(certificationsURL.has('certification')).toBeTruthy(); - }); + it('Should return a length of 1', () => { + expect(certificationsURL.getAll('certification').length).toBe(1); + }); - it('Should return a length of 1', () => { - expect(certificationsURL.getAll('certification').length).toBe(1); - }); + it('It should return U', () => { + expect(certificationsURL.get('certification').split('|')[0]).toBe('U'); + }); - it('It should return U', () => { - expect(certificationsURL.get('certification').split('|')[0]).toBe('U'); + it('It should return 18', () => { + expect(certificationsURL.get('certification').split('|')[1]).toBe('18'); + }); }); - it('It should return 18', () => { - expect(certificationsURL.get('certification').split('|')[1]).toBe('18'); - }); -}); + describe('vote count query parameter tests', () => { + const voteCountURL = generateQuery({ userscore: '180' }); -describe('vote count query parameter tests', () => { - const voteCountURL = generateQuery({ userscore: '180' }); + it('Should return true', () => { + expect(voteCountURL.has('vote_count.gte')).toBeTruthy(); + }); - it('Should return true', () => { - expect(voteCountURL.has('vote_count.gte')).toBeTruthy(); + it('Should return 180', () => { + expect(voteCountURL.get('vote_count.gte')).toBe('180'); + }); }); - it('Should return 180', () => { - expect(voteCountURL.get('vote_count.gte')).toBe('180'); - }); -}); + describe('runtime query parameter tests', () => { + const runtimeURL = generateQuery({ runtime: '150' }); -describe('runtime query parameter tests', () => { - const runtimeURL = generateQuery({ runtime: '150' }); - - it('Should return true', () => { - expect(runtimeURL.has('with_runtime.gte')).toBeTruthy(); - }); + it('Should return true', () => { + expect(runtimeURL.has('with_runtime.gte')).toBeTruthy(); + }); - it('Should return 150', () => { - expect(runtimeURL.get('with_runtime.gte')).toBe('150'); + it('Should return 150', () => { + expect(runtimeURL.get('with_runtime.gte')).toBe('150'); + }); }); }); diff --git a/utils/images/generateAbsolutePath/index.js b/utils/images/generateAbsolutePath/index.js index 419ceed..9e8fb13 100644 --- a/utils/images/generateAbsolutePath/index.js +++ b/utils/images/generateAbsolutePath/index.js @@ -3,7 +3,7 @@ const { isEmpty } = require('lodash'); const generateAbsolutePath = (imageName) => { // Empty image check if (isEmpty(imageName) === true) { - return 'Please provide a relative path'; + return ''; } // Return the absolute path diff --git a/utils/images/generateAbsolutePath/index.test.js b/utils/images/generateAbsolutePath/index.test.js index c19bee0..32fbaf2 100644 --- a/utils/images/generateAbsolutePath/index.test.js +++ b/utils/images/generateAbsolutePath/index.test.js @@ -1,15 +1,23 @@ const generateAbsolutePath = require('./'); -describe("generateAbsolutePath unit test's", () => { +describe('images -> generateAbsolutePath', () => { // Valid image path test('It should return an absolute image path', () => { - expect(generateAbsolutePath('/gVVaukIifGJD78llZKgyT5FQbAe.jpg')).toBe( - 'https://image.tmdb.org/t/p/original/gVVaukIifGJD78llZKgyT5FQbAe.jpg' - ); + // Arrange and act + const response = generateAbsolutePath('/gVVaukIifGJD78llZKgyT5FQbAe.jpg'); + const output = 'https://image.tmdb.org/t/p/original/gVVaukIifGJD78llZKgyT5FQbAe.jpg'; + + // Assertion + expect(response).toBe(output); }); // No image resource provided test('It should return "Please provide a relative path" ', () => { - expect(generateAbsolutePath()).toBe('Please provide a relative path'); + // Arrange and act + const response = generateAbsolutePath(); + const output = ''; + + // Assertion + expect(response).toBe(output); }); }); diff --git a/utils/maths/toPercentage/index.js b/utils/maths/toPercentage/index.js index 0e877f3..7dbfde4 100644 --- a/utils/maths/toPercentage/index.js +++ b/utils/maths/toPercentage/index.js @@ -1,2 +1,15 @@ -const toPercentage = (value) => value * 10; +/** + * @description Transforms a value into a percentage + * @param {number} value + * @returns {number} + */ +const toPercentage = (value) => { + // Check to see if the value is null or undefined + if (value === null || value === undefined) { + return 0; + } + + // When the value isn't null or undefined convert the number to a percentage + return value * 10; +}; module.exports = toPercentage; diff --git a/utils/maths/toPercentage/index.test.js b/utils/maths/toPercentage/index.test.js index 9f5686b..3619936 100644 --- a/utils/maths/toPercentage/index.test.js +++ b/utils/maths/toPercentage/index.test.js @@ -1,30 +1,30 @@ const toPercentage = require('./'); -describe("generateYear unit test's", () => { +describe('maths -> toPercentage', () => { test('It should return 40', () => { - // Data - const input = toPercentage(6.4); - const expectedOutput = 64; + // Arrange and act + const response = toPercentage(6.4); + const output = 64; - // Test - expect(input).toBe(expectedOutput); + // Assertion + expect(response).toBe(output); }); test('It should return 50', () => { - // Data - const input = toPercentage(5); - const expectedOutput = 50; + // Arrange and act + const response = toPercentage(5); + const output = 50; - // Test - expect(input).toBe(expectedOutput); + // Assertion + expect(response).toBe(output); }); test('It should return 10', () => { - // Data - const input = toPercentage(1); - const expectedOutput = 10; + // Arrange and act + const response = toPercentage(1); + const output = 10; - // Test - expect(input).toBe(expectedOutput); + // Assertion + expect(response).toBe(output); }); }); diff --git a/utils/objects/replaceKey/index.js b/utils/objects/replaceKey/index.js deleted file mode 100644 index 947fa88..0000000 --- a/utils/objects/replaceKey/index.js +++ /dev/null @@ -1,19 +0,0 @@ -const { has } = require('lodash'); - -const replaceKey = (object, oldKey, newKey) => { - // Empty object key check - if (has(object, oldKey) === true) { - // New key - object[newKey] = object[oldKey]; - - // Delete the old key - delete object[oldKey]; - - // Return the data - return object; - } - - return object; -}; - -module.exports = replaceKey; diff --git a/utils/objects/replaceKey/index.test.js b/utils/objects/replaceKey/index.test.js deleted file mode 100644 index 2dc1da1..0000000 --- a/utils/objects/replaceKey/index.test.js +++ /dev/null @@ -1,20 +0,0 @@ -const replaceKey = require('./'); - -describe("replaceKey unit test's", () => { - // Test data - const mockedData = { - name: 'ALex James Machin', - date_of_birth: '25/04/2020' - }; - - // Checking the property doesn't exists - it('Should return true', () => { - expect(mockedData).not.toHaveProperty('dob'); - }); - - // Checking the property exists - it('Should return true', () => { - const input = replaceKey(mockedData, 'date_of_birth', 'dob'); - expect(input).toHaveProperty('dob'); - }); -}); diff --git a/utils/objects/setValue/index.js b/utils/objects/setValue/index.js deleted file mode 100644 index 07e9a8e..0000000 --- a/utils/objects/setValue/index.js +++ /dev/null @@ -1,11 +0,0 @@ -const { has } = require('lodash'); - -const setValue = (object, key, value) => { - if (has(object, key) === false) { - return value; - } - - return (object[key] = value); -}; - -module.exports = setValue; diff --git a/utils/objects/setValue/index.test.js b/utils/objects/setValue/index.test.js deleted file mode 100644 index 38367c1..0000000 --- a/utils/objects/setValue/index.test.js +++ /dev/null @@ -1,13 +0,0 @@ -const setValue = require('./index'); - -describe("replaceKey unit test's", () => { - const input = { - name: 'Alex James Machin', - dob: '25/04/2020' - }; - - it('It should return true', () => { - input.dob = setValue(input, 'dob', '20/11/1997'); - expect(input.dob).toBe('20/11/1997'); - }); -}); diff --git a/utils/resolverUtils/Cast/setCast/creditsData.js b/utils/resolverUtils/Cast/setCast/creditsData.js new file mode 100644 index 0000000..a25ffc9 --- /dev/null +++ b/utils/resolverUtils/Cast/setCast/creditsData.js @@ -0,0 +1,73 @@ +const data = { + media: { + seasons: [ + { + air_date: '2016-01-25', + episode_count: 13, + id: 68415, + name: 'Season 1', + overview: + 'Bored with being the Lord of Hell, the devil relocates to Los Angeles, where he opens a nightclub and forms a connection with a homicide detective.', + poster_path: '/9qvNXKYqZEsYn3g3yn5tXQe0ceB.jpg', + season_number: 1, + show_id: 63174 + }, + { + air_date: '2016-09-19', + episode_count: 18, + id: 78529, + name: 'Season 2', + overview: + 'Lucifer returns for another season, but his devil-may-care attitude may soon need an adjustment: His mother is coming to town.', + poster_path: '/zfUp0LO9ZpleAZxwMrjQj0n4b3X.jpg', + season_number: 2, + show_id: 63174 + }, + { + air_date: '2017-10-02', + episode_count: 26, + id: 91441, + name: 'Season 3', + overview: + 'As Lucifer struggles with an identity crisis, a gruff new police lieutenant shakes up the status quo with Chloe and the rest of the LAPD.', + poster_path: '/3wAYNK29W5PHusoFwPMBO5ei8R1.jpg', + season_number: 3, + show_id: 63174 + }, + { + air_date: '2015-08-10', + episode_count: 2, + id: 70781, + name: 'Specials', + overview: '', + poster_path: '/bQ5FupU7DFTbx9pSgPsEZQwyZKj.jpg', + season_number: 0, + show_id: 63174 + }, + { + air_date: '2019-05-08', + episode_count: 10, + id: 117593, + name: 'Season 4', + overview: + "As Chloe struggles to come to terms with Lucifer's disturbing revelation, a rogue priest sets out to stop a long-rumored prophecy.", + poster_path: '/q1li5do60mMrIONZcjwUNNZZpT4.jpg', + season_number: 4, + show_id: 63174 + }, + { + air_date: '2020-08-21', + episode_count: 8, + id: 152759, + name: 'Season 5', + overview: + 'Lucifer makes a tumultuous return to the land of the living in hopes of making things right with Chloe. A devil’s work is never done.', + poster_path: '/96D5o8ywmEbGvBfttj1JLXtJRhg.jpg', + season_number: 5, + show_id: 63174 + } + ] + } +}; + +module.exports = data; diff --git a/utils/resolverUtils/Cast/setCast/index.js b/utils/resolverUtils/Cast/setCast/index.js new file mode 100644 index 0000000..2402e00 --- /dev/null +++ b/utils/resolverUtils/Cast/setCast/index.js @@ -0,0 +1,124 @@ +const axios = require('axios'); + +const generateAbsolutePath = require('../../../images/generateAbsolutePath'); +const generateCreditURLEndpoint = require('../../../generateEndpoints/Credit'); + +/** + * @typedef {Object} IncomingCastMembers + * @property {number} [order] The original cast members order + * @property {number} [id] The original cast members id + * @property {string} [name] Stores the name of the cast member + * @property {string} [character] The original cast members character + * @property {string} [profile_path] The original cast members profile path (profile image) + * @property {number} [gender] The original cast members gender (Stored in a number format for some reason) + * @property {number} [episode_count] The original cast members episode count (Only needed for tv episodes) + * @property {string} [credit_id] Stores the credit id for the cast member + */ + +/** + * @typedef {Object} CastMember + * @property {number} id The new cast members id + * @property {string} character The new members character + * @property {string} profileImageUrl Stores an absolute path to the cast members profile image + * @property {string | number} gender Stores a string format representation of the cast members gender e.g. 0 -> Male + * @property {number} episodeCount Stores the total number of appearances in a particular show (Only applicable for shows) + * @property {string} creditId Stores the cast members credit. This is used to perform the tv credits episodeCount functionality + */ + +/** + * @typedef {Object} Season + * @property {number} episode_count + * @property {string} name + */ + +/** + * @description This function is currently used in the cast resolver, it creates a featured cast for a particular movie or tv series. + * @param {IncomingCastMembers[]} castMembers + * @async + * @returns {Promise} Returns an array of featured cast members + * @throws {string} + */ +const setCast = async (castMembers, resolverType = 'movie') => { + // Check the length of the array + if (castMembers.length === 0) return []; + + // Order the cast by the order property + let featuredCast = castMembers; + + if (castMembers.length > 0) { + featuredCast = castMembers.sort((a, b) => (a.order > b.order ? 1 : -1)); + } + + // Get the first 9 cast members + featuredCast = featuredCast.slice(0, 9); + + /** + * @description Stores the new featured cast members + * @type {CastMember[]} + */ + const updatedFeaturedCast = []; + + // Create the new cast objects + featuredCast.forEach((cast) => { + /** + * @description Store the cast members details + * @type {CastMember} + */ + const CastMember = { + id: cast.id ? cast.id : 0, + character: cast.character || '', + profileImageUrl: cast.profile_path || '', + gender: cast.gender || '', + episodeCount: 0, + creditId: cast.credit_id ? cast.credit_id : '' + }; + + // Profile image url + if (CastMember.profileImageUrl !== '') { + CastMember.profileImageUrl = generateAbsolutePath(cast.profile_path); + } + + // Gender + if (CastMember.gender !== '') { + CastMember.gender = CastMember.gender === 2 ? 'Male' : 'Female'; + } + + // Push the new castMember to the updatedFeaturedCast array + updatedFeaturedCast.push(CastMember); + }); + + // When the resolverType is tv + if (resolverType === 'tv') { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of + for await (const cast of updatedFeaturedCast) { + if (cast.creditId === '') return; + + try { + // Get the cast members credit information via the creditId + const response = await axios.get(generateCreditURLEndpoint(cast.creditId)); + + // Check to see if the status is not 200, if it's not throw an error + if (response.status !== 200) throw Error('Something went wrong'); + + // Calculate the episodeCount for each cast member + response.data.media.seasons.forEach( + /** + * @param {Season} season + */ + (season) => { + // Don't include special episodes, only include the core seasons + if (season.name !== 'Specials') { + cast.episodeCount += season.episode_count; + } + } + ); + } catch (err) { + return updatedFeaturedCast; + } + } + } + + return updatedFeaturedCast; +}; + +module.exports = setCast; diff --git a/utils/resolverUtils/Cast/setCast/index.test.js b/utils/resolverUtils/Cast/setCast/index.test.js new file mode 100644 index 0000000..803e2cb --- /dev/null +++ b/utils/resolverUtils/Cast/setCast/index.test.js @@ -0,0 +1,153 @@ +const axios = require('axios'); + +const setCast = require('./index'); +const creditData = require('./creditsData'); + +jest.mock('axios'); + +describe('setCast', () => { + // After each test reset the mocks - times the function has been called e.g. axios.get() + afterEach(() => { + jest.clearAllMocks(); + }); + + // Id + describe('id property', () => { + it('When the id is empty it should be 0', async () => { + // Arrange and act + const response = await setCast([{ id: undefined, order: 8 }]); + + // Assertion + expect(response[0].id).toBe(0); + }); + + it('When the id is not empty it should be 1', async () => { + // Arrange and act + const response = await setCast([{ id: 1, order: 8 }]); + + // Assertion + expect(response[0].id).toBe(1); + }); + }); + + // character + describe('character property', () => { + it('When the character is empty it should be 0', async () => { + // Arrange and act + const response = await setCast([{ character: undefined, order: 8 }]); + + // Assertion + expect(response[0].character).toBe(''); + }); + + it('When the character is not empty it should be Alex', async () => { + // Arrange and act + const response = await setCast([{ character: 'Alex', order: 8 }]); + + // Assertion + expect(response[0].character).toBe('Alex'); + }); + }); + + // profile image url + describe('profileImageUrl property', () => { + it('When the profileImageUrl is empty it should be 0', async () => { + // Arrange and act + const response = await setCast([{ profile_path: null, order: 8 }]); + + // Assertion + expect(response[0].profileImageUrl).toBe(''); + }); + + it('When the profileImageUrl is not empty it should be an absolute url', async () => { + // Arrange and act + const response = await setCast([{ profile_path: '/123', order: 8 }]); + + // Assertion + expect(response[0].profileImageUrl).toBe('https://image.tmdb.org/t/p/original/123'); + }); + }); + + // gender + describe('gender property', () => { + it('When the gender is empty it should be an empty string', async () => { + // Arrange and act + const response = await setCast([{ gender: null, order: 8 }]); + + // Assertion + expect(response[0].gender).toBe(''); + }); + + it('When the gender is 0 it should Male', async () => { + // Arrange and act + const response = await setCast([{ gender: 2, order: 8 }]); + + // Assertion + expect(response[0].gender).toBe('Male'); + }); + + it('When the gender is 2 it should Male', async () => { + // Arrange and act + const response = await setCast([{ gender: 2, order: 8 }]); + + // Assertion + expect(response[0].gender).toBe('Male'); + }); + }); + + // Episode count + describe('episodeCount', () => { + it('The episodeCount should be 75', async () => { + // Prepare - Create the mocked "get" request values + axios.get.mockImplementationOnce(() => + Promise.resolve({ + data: creditData, + status: 200 + }) + ); + + // Act - Run the function and await the response + const response = await setCast( + [ + { + character: 'Lucifer Morningstar', + credit_id: '559cb1f1c3a3681be4000bec', + id: 192944, + name: 'Tom Ellis', + gender: 2, + profile_path: '/sJkxqJfSgcwussMeywxyrnYxVX.jpg', + order: 0 + } + ], + 'tv' + ); + + // Assertion - Check the episodeCount value + expect(response[0].episodeCount).toBe(75); + }); + }); + + it('The episodeCount should be 0', async () => { + // Prepare - Create the mocked axios "get" error + axios.get.mockImplementationOnce(() => Promise.reject(new Error('Something went wrong'))); + + // Act - Run the function and await the response + const response = await setCast( + [ + { + character: 'Lucifer Morningstar', + credit_id: '559cb1f1c3a3681be4000bec', + id: 192944, + name: 'Tom Ellis', + gender: 2, + profile_path: '/sJkxqJfSgcwussMeywxyrnYxVX.jpg', + order: 0 + } + ], + 'tv' + ); + + // Assertion - Check the episodeCount value + expect(response[0].episodeCount).toBe(0); + }); +}); diff --git a/utils/resolverUtils/Credits/filterGroupByMediaType/index.js b/utils/resolverUtils/Credits/filterGroupByMediaType/index.js deleted file mode 100644 index 8e1ea7f..0000000 --- a/utils/resolverUtils/Credits/filterGroupByMediaType/index.js +++ /dev/null @@ -1,20 +0,0 @@ -const mediaTypes = require('./types'); - -const filterGroupByMediaType = (type = mediaTypes.ALL, group) => { - switch (type) { - case mediaTypes.ALL: { - return group; - } - case mediaTypes.MOVIE: { - return group.filter((data) => data.media_type === 'movie'); - } - case mediaTypes.TV: { - return group.filter((data) => data.media_type === 'tv'); - } - default: { - return group; - } - } -}; - -module.exports = filterGroupByMediaType; diff --git a/utils/resolverUtils/Credits/filterGroupByMediaType/index.test.js b/utils/resolverUtils/Credits/filterGroupByMediaType/index.test.js deleted file mode 100644 index 5911428..0000000 --- a/utils/resolverUtils/Credits/filterGroupByMediaType/index.test.js +++ /dev/null @@ -1,59 +0,0 @@ -const filterGroupByMediaType = require('./index'); - -describe('filterGroupByMediaType', () => { - const input = [ - { media_type: 'movie', name: 'Star Wars' }, - { media_type: 'tv', name: 'Westworld' }, - { media_type: 'movie', name: 'Fast and furious' } - ]; - - describe('TV', () => { - const response = filterGroupByMediaType('TV', input); - const shows = input.filter((el) => el.media_type === 'tv'); - - it('Should return only the shows with media_type = tv', () => { - expect(response).toStrictEqual(shows); - }); - - it('Should return a length of 1', () => { - expect(response.length).toBe(1); - }); - }); - - describe('MOVIE', () => { - const response = filterGroupByMediaType('MOVIE', input); - const movies = input.filter((el) => el.media_type === 'movie'); - - it('Should return only the shows with media_type = movie', () => { - expect(response).toStrictEqual(movies); - }); - - it('Should return a length of 2', () => { - expect(response.length).toBe(2); - }); - }); - - describe('ALL', () => { - const response = filterGroupByMediaType('ALL', input); - - it('Should return all the shows and tvs', () => { - expect(response).toStrictEqual(response); - }); - - it('Should return a length of 3', () => { - expect(response.length).toBe(3); - }); - }); - - describe('No mediaType provided', () => { - const response = filterGroupByMediaType('', input); - - it('Should return all the shows and tvs', () => { - expect(response).toStrictEqual(response); - }); - - it('Should return a length of 3', () => { - expect(response.length).toBe(3); - }); - }); -}); diff --git a/utils/resolverUtils/Credits/filterGroupByMediaType/types.js b/utils/resolverUtils/Credits/filterGroupByMediaType/types.js deleted file mode 100644 index 0cc0866..0000000 --- a/utils/resolverUtils/Credits/filterGroupByMediaType/types.js +++ /dev/null @@ -1,11 +0,0 @@ -const ALL = 'ALL'; -const MOVIE = 'MOVIE'; -const TV = 'TV'; - -const types = { - ALL, - MOVIE, - TV -}; - -module.exports = types; diff --git a/utils/resolverUtils/Credits/formatGroup/index.js b/utils/resolverUtils/Credits/formatGroup/index.js deleted file mode 100644 index f399746..0000000 --- a/utils/resolverUtils/Credits/formatGroup/index.js +++ /dev/null @@ -1,28 +0,0 @@ -const reorderGroupByReleaseDate = require('../reorderGroupByReleaseDate'); -const orderGroupByYear = require('../reorderGroupByYear'); -const filterGroupByMediaType = require('../filterGroupByMediaType'); -const replaceKeys = require('../replaceKeys'); -const setValues = require('../setValues'); - -const formatGroup = (singleGroup, mediaType) => { - let group = singleGroup; - - // Replace any specified keys - group = replaceKeys(group); - - // Replace any specified values - group = setValues(group); - - // Conditional filtering (based on the mediaType which is ALL, MOVIE or TV. Default is ALL) - group = filterGroupByMediaType(mediaType, group); - - // Sort the group by release_date - group = orderGroupByYear(group); - - // Taking all the release_dates which have - and making them the first elements - group = reorderGroupByReleaseDate(group); - - return group; -}; - -module.exports = formatGroup; diff --git a/utils/resolverUtils/Credits/formatGroup/index.test.js b/utils/resolverUtils/Credits/formatGroup/index.test.js deleted file mode 100644 index df1eb61..0000000 --- a/utils/resolverUtils/Credits/formatGroup/index.test.js +++ /dev/null @@ -1,39 +0,0 @@ -const formatGroup = require('./index'); - -describe('formatGroup', () => { - const input = [ - { - first_air_date: '2016-10-02', - name: 'Westworld', - media_type: 'tv' - }, - { - release_date: '2020-04-24', - original_title: 'Black widow', - media_type: 'movie' - } - ]; - - const output = [ - { - release_date: '2020', - original_title: 'Black widow', - media_type: 'movie' - }, - { - release_date: '2016', - original_title: 'Westworld', - media_type: 'tv' - } - ]; - - it('The arrays should match', () => { - const response = formatGroup(input, 'ALL'); - expect(response).toStrictEqual(output); - }); - - it('The arrays should have an array of 2', () => { - const response = formatGroup(input, 'ALL'); - expect(response.length).toBe(2); - }); -}); diff --git a/utils/resolverUtils/Credits/index.js b/utils/resolverUtils/Credits/index.js deleted file mode 100644 index e880829..0000000 --- a/utils/resolverUtils/Credits/index.js +++ /dev/null @@ -1,38 +0,0 @@ -const formatGroup = require('./formatGroup'); - -const formatGroups = (data, mediaType) => { - // Acting group - let ActingGroup = data.cast; - - ActingGroup = formatGroup(ActingGroup, mediaType); - - // Production group - let ProductionGroup = data.crew.filter((crew) => crew.department === 'Production'); - - ProductionGroup = formatGroup(ProductionGroup, mediaType); - - // Writing group - let WritingGroup = data.crew.filter((crew) => crew.department === 'Writing'); - - WritingGroup = formatGroup(WritingGroup, mediaType); - - // Directing group - let DirectingGroup = data.crew.filter((crew) => crew.department === 'Directing'); - - DirectingGroup = formatGroup(DirectingGroup, mediaType); - - // Crew group - let CrewGroup = data.crew.filter((crew) => crew.department === 'Crew'); - - CrewGroup = formatGroup(CrewGroup, mediaType); - - return { - ActingGroup, - ProductionGroup, - WritingGroup, - DirectingGroup, - CrewGroup - }; -}; - -module.exports = formatGroups; diff --git a/utils/resolverUtils/Credits/reorderGroupByReleaseDate/index.js b/utils/resolverUtils/Credits/reorderGroupByReleaseDate/index.js deleted file mode 100644 index d571248..0000000 --- a/utils/resolverUtils/Credits/reorderGroupByReleaseDate/index.js +++ /dev/null @@ -1,11 +0,0 @@ -const reorderGroupByReleaseDate = (group) => { - group.map((data, index) => { - if (data.release_date === '-') { - group.splice(index, 1); - group.unshift(data); - } - }); - return group; -}; - -module.exports = reorderGroupByReleaseDate; diff --git a/utils/resolverUtils/Credits/reorderGroupByYear/index.js b/utils/resolverUtils/Credits/reorderGroupByYear/index.js deleted file mode 100644 index e6eb620..0000000 --- a/utils/resolverUtils/Credits/reorderGroupByYear/index.js +++ /dev/null @@ -1,17 +0,0 @@ -const orderGroupByYear = (group) => { - const groupSorted = group.sort((a, b) => { - if (a.release_date > b.release_date) { - return -1; - } - - if (a.release_date < b.release_date) { - return 1; - } - - return 0; - }); - - return groupSorted; -}; - -module.exports = orderGroupByYear; diff --git a/utils/resolverUtils/Credits/reorderGroupByYear/index.test.js b/utils/resolverUtils/Credits/reorderGroupByYear/index.test.js deleted file mode 100644 index cb8f89c..0000000 --- a/utils/resolverUtils/Credits/reorderGroupByYear/index.test.js +++ /dev/null @@ -1,38 +0,0 @@ -const reorderGroupByYear = require('./index'); - -describe('reorderGroupByYear', () => { - const input = [ - { - release_date: '-', - name: 'Westworld' - }, - { - release_date: '06/05/2020', - name: 'Devs' - }, - { - release_date: '05/05/2010', - name: 'The Walking Dead' - } - ]; - - const output = [ - { - release_date: '06/05/2020', - name: 'Devs' - }, - { - release_date: '05/05/2010', - name: 'The Walking Dead' - }, - { - release_date: '-', - name: 'Westworld' - } - ]; - - it('The order should be The Walking Dead, Devs and Westworld', () => { - const response = reorderGroupByYear(input); - expect(response).toStrictEqual(output); - }); -}); diff --git a/utils/resolverUtils/Credits/replaceKeys/index.js b/utils/resolverUtils/Credits/replaceKeys/index.js deleted file mode 100644 index c16de6d..0000000 --- a/utils/resolverUtils/Credits/replaceKeys/index.js +++ /dev/null @@ -1,16 +0,0 @@ -const replaceKey = require('../../../objects/replaceKey'); - -// Any keys which need replacing place them here (Check https://developers.themoviedb.org/3/people/get-person-combined-credits for the schema) -const replaceKeys = (group) => { - group.map((data) => { - // Replace first_air_dates (TV credits) with the release_date - replaceKey(data, 'first_air_date', 'release_date'); - - // Replace the name with the original_title key (Movies already have this, but for TV it will need to be converted) - replaceKey(data, 'name', 'original_title'); - }); - - return group; -}; - -module.exports = replaceKeys; diff --git a/utils/resolverUtils/Credits/replaceKeys/index.test.js b/utils/resolverUtils/Credits/replaceKeys/index.test.js deleted file mode 100644 index 5d5332b..0000000 --- a/utils/resolverUtils/Credits/replaceKeys/index.test.js +++ /dev/null @@ -1,15 +0,0 @@ -const replaceKeys = require('./index'); - -describe('replaceKeys', () => { - // Will return the title if it can find the field - it('name field -> original_title field ', () => { - const input = replaceKeys([{ name: 'Westworld' }]); - expect(input[0].original_title).toBe('Westworld'); - }); - - // Will return the title if it can find the field - it('first_air_date field -> release_date field ', () => { - const input = replaceKeys([{ first_air_date: '2019' }]); - expect(input[0].release_date).toBe('2019'); - }); -}); diff --git a/utils/resolverUtils/Credits/setCredits/formatGroup/index.js b/utils/resolverUtils/Credits/setCredits/formatGroup/index.js new file mode 100644 index 0000000..2528628 --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/formatGroup/index.js @@ -0,0 +1,44 @@ +const reorderGroupByReleaseDate = require('../reorderGroupByReleaseDate'); +const orderGroupByYear = require('../reorderGroupByYear'); +const setValues = require('../setValues'); +const organizeGroup = require('../organizeGroup'); + +/** + * @typedef {Object} Credit + * @property {string} releaseDate + * @property {number | null} episodeCount + * @property {string} title + * @property {string} mediaType + */ + +/** + * @typedef {Object} FormattedGroup + * @property {string} year + * @property {Credit[]} credits + */ + +/** + * @param {Object[]} singleGroup + * @returns {FormattedGroup[]} + */ +const formatGroup = (singleGroup) => { + // Stores the initial credits + let group = singleGroup; + + if (group.length === 0) return []; + + // Replace any specified values + group = setValues(group); + + // Sort the group by release_date + group = orderGroupByYear(group); + + // Taking all the release_dates which have - and making them the first elements + group = reorderGroupByReleaseDate(group); + + group = organizeGroup(group); + + return group; +}; + +module.exports = formatGroup; diff --git a/utils/resolverUtils/Credits/setCredits/formatGroup/index.test.js b/utils/resolverUtils/Credits/setCredits/formatGroup/index.test.js new file mode 100644 index 0000000..30898d5 --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/formatGroup/index.test.js @@ -0,0 +1,7 @@ +const formatGroup = require('./index'); + +describe('formatGroup', () => { + it('test', () => { + expect(true).toBe(true); + }); +}); diff --git a/utils/resolverUtils/Credits/setCredits/index.js b/utils/resolverUtils/Credits/setCredits/index.js new file mode 100644 index 0000000..2874427 --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/index.js @@ -0,0 +1,67 @@ +const formatGroup = require('./formatGroup'); + +/** + * @typedef {Object} CrewInput + * @property {array} cast + * @property {array} crew + * @property {number} id + */ + +/** + * @typedef {Object} FormattedGroup + * @property {string} releaseDate + * @property {string} title + * @property {string} episodeCount + * @property {string} mediaType + */ + +/** + * @typedef {Object} Result + * @property {FormattedGroup[]} ActingGroup + * @property {FormattedGroup[]} ProductionGroup + * @property {FormattedGroup[]} WritingGroup + * @property {FormattedGroup[]} DirectingGroup + * @property {FormattedGroup[]} CrewGroup + */ + +/** + * @description This utility is used to create the persons credits table + * @param {CrewInput} data + * @returns {Result} + */ +const formatGroups = (data) => { + // Acting group + let ActingGroup = data.cast; + + ActingGroup = formatGroup(ActingGroup); + + // Production group + let ProductionGroup = data.crew.filter((crew) => crew.department === 'Production'); + + ProductionGroup = formatGroup(ProductionGroup); + + // Writing group + let WritingGroup = data.crew.filter((crew) => crew.department === 'Writing'); + + WritingGroup = formatGroup(WritingGroup); + + // Directing group + let DirectingGroup = data.crew.filter((crew) => crew.department === 'Directing'); + + DirectingGroup = formatGroup(DirectingGroup); + + // Crew group + let CrewGroup = data.crew.filter((crew) => crew.department === 'Crew'); + + CrewGroup = formatGroup(CrewGroup); + + return { + ActingGroup, + ProductionGroup, + WritingGroup, + DirectingGroup, + CrewGroup + }; +}; + +module.exports = formatGroups; diff --git a/utils/resolverUtils/Credits/setCredits/organizeGroup/index.js b/utils/resolverUtils/Credits/setCredits/organizeGroup/index.js new file mode 100644 index 0000000..d610581 --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/organizeGroup/index.js @@ -0,0 +1,52 @@ +/** + * @typedef {Object} Group + * @property {string} releaseDate + * @property {string} title + * @property {string} episodeCount + * @property {string} mediaType + * @property {string} role + */ + +/** + * @typedef {Object} FormattedGroup + * @property {string} year + * @property {Group[]} credits + */ + +/** + * @param {Group[]} array + * @description Formats the group so the front-end can format the UI correctly + * @returns {FormattedGroup[]} + */ +const organizeGroup = (array) => { + /** + * @type {FormattedGroup[]} + */ + const group = []; + + array.forEach((credit) => { + const existingGroup = group.find((el) => el.year === credit.releaseDate); + + // When the element exists already push the credit to the group.credits array + if (existingGroup !== undefined) { + existingGroup.credits.push(credit); + return existingGroup; + } + + /** + * @type {FormattedGroup} + * @description Stores the newly created year and adds the first credit for the year + */ + const model = { + year: credit.releaseDate, + credits: [credit] + }; + + // Push the new object to the group array, will create an object like this: {year: 1997, credits: [{title: 'Awesome movie'}]} + group.push(model); + }); + + return group; +}; + +module.exports = organizeGroup; diff --git a/utils/resolverUtils/Credits/setCredits/organizeGroup/index.test.js b/utils/resolverUtils/Credits/setCredits/organizeGroup/index.test.js new file mode 100644 index 0000000..8815eb3 --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/organizeGroup/index.test.js @@ -0,0 +1,42 @@ +const organizeGroup = require('./index'); + +describe('organizeGroup', () => { + const credits = organizeGroup([ + { + releaseDate: '2021', + title: 'Black Widow', + episodeCount: '0', + mediaType: 'movie', + role: 'Natasha Romanoff / Black Widow' + }, + { + releaseDate: '2021', + title: 'Sing 2', + episodeCount: '0', + mediaType: 'tv', + role: 'Ash (voice)' + } + ])[0]; + + describe('year property', () => { + it('The year should be 2021', () => { + // Arrange and act + const response = credits.year; + const output = '2021'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('credits property', () => { + it('The length should be 2', () => { + // Arrange and act + const response = credits.credits.length; + const output = 2; + + // Assertion + expect(response).toBe(output); + }); + }); +}); diff --git a/utils/resolverUtils/Credits/setCredits/reorderGroupByReleaseDate/index.js b/utils/resolverUtils/Credits/setCredits/reorderGroupByReleaseDate/index.js new file mode 100644 index 0000000..2a08847 --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/reorderGroupByReleaseDate/index.js @@ -0,0 +1,34 @@ +/** + * @typedef {Object} Group + * @property {string} releaseDate + * @property {string} title + * @property {number} episodeCount + * @property {string} mediaType + */ + +/** + * @description Any credits with a releaseDate of "-" move them to the top to mimics the functionality on TheOpenMovieDB. + * @param {Group[]} group + * @returns {Group[]} + */ + +const reorderGroupByReleaseDate = (group) => { + group.map((data, index) => { + // Only target credits with a releaseDate of "-" + if (data.releaseDate === '-') { + // Get the item index and remove this item only + group.splice(index, 1); + + // Readd the credit to the beginning of the array + group.unshift(data); + + // Return the item + return data; + } + }); + + // Return the array of credits + return group; +}; + +module.exports = reorderGroupByReleaseDate; diff --git a/utils/resolverUtils/Credits/reorderGroupByReleaseDate/index.test.js b/utils/resolverUtils/Credits/setCredits/reorderGroupByReleaseDate/index.test.js similarity index 72% rename from utils/resolverUtils/Credits/reorderGroupByReleaseDate/index.test.js rename to utils/resolverUtils/Credits/setCredits/reorderGroupByReleaseDate/index.test.js index 73787f4..61e2fe3 100644 --- a/utils/resolverUtils/Credits/reorderGroupByReleaseDate/index.test.js +++ b/utils/resolverUtils/Credits/setCredits/reorderGroupByReleaseDate/index.test.js @@ -3,36 +3,39 @@ const reorderGroupByReleaseDate = require('./index'); describe('reorderGroupByReleaseDate', () => { const data = [ { - release_date: '05/05/2020', + releaseDate: '05/05/2020', name: 'Devs' }, { - release_date: '-', + releaseDate: '-', name: 'Westworld' }, { - release_date: '05/05/2010', + releaseDate: '05/05/2010', name: 'The Walking Dead' } ]; const expectedResult = [ { - release_date: '-', + releaseDate: '-', name: 'Westworld' }, { - release_date: '05/05/2020', + releaseDate: '05/05/2020', name: 'Devs' }, { - release_date: '05/05/2010', + releaseDate: '05/05/2010', name: 'The Walking Dead' } ]; it('Westworld should be the first element in the array', () => { + // Arrange and act const response = reorderGroupByReleaseDate(data); + + // Assertion expect(response).toStrictEqual(expectedResult); }); }); diff --git a/utils/resolverUtils/Credits/setCredits/reorderGroupByYear/index.js b/utils/resolverUtils/Credits/setCredits/reorderGroupByYear/index.js new file mode 100644 index 0000000..b90e2ed --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/reorderGroupByYear/index.js @@ -0,0 +1,30 @@ +/** + * @typedef {Object} Group + * @property {string} releaseDate + * @property {string} title + * @property {number} episodeCount + * @property {string} mediaType + */ + +/** + * @description Reorders the credit group by releaseDate field + * @param {Group[]} group + * @returns {Group[]} + */ +const orderGroupByYear = (group) => { + const groupSorted = group.sort((a, b) => { + if (a.releaseDate > b.releaseDate) { + return -1; + } + + if (a.releaseDate < b.releaseDate) { + return 1; + } + + return 0; + }); + + return groupSorted; +}; + +module.exports = orderGroupByYear; diff --git a/utils/resolverUtils/Credits/setCredits/reorderGroupByYear/index.test.js b/utils/resolverUtils/Credits/setCredits/reorderGroupByYear/index.test.js new file mode 100644 index 0000000..1eb5e0b --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/reorderGroupByYear/index.test.js @@ -0,0 +1,37 @@ +const reorderGroupByYear = require('./index'); + +describe('reorderGroupByYear', () => { + it('The order should be The Walking Dead, Devs and Westworld', () => { + // Arrange and act + const response = reorderGroupByYear([ + { + releaseDate: '-', + name: 'Westworld' + }, + { + releaseDate: '2020', + name: 'Devs' + }, + { + releaseDate: '2010', + name: 'The Walking Dead' + } + ]); + const output = [ + { + releaseDate: '2020', + name: 'Devs' + }, + { + releaseDate: '2010', + name: 'The Walking Dead' + }, + { + releaseDate: '-', + name: 'Westworld' + } + ]; + // Assertion + expect(response).toStrictEqual(output); + }); +}); diff --git a/utils/resolverUtils/Credits/setCredits/setValues/index.js b/utils/resolverUtils/Credits/setCredits/setValues/index.js new file mode 100644 index 0000000..8109718 --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/setValues/index.js @@ -0,0 +1,70 @@ +const generateYear = require('../../../../dates/generateYear'); + +/** + * @typedef {Object} InputGroup + * @property {number} [id] + * @property {string} [first_air_date] + * @property {string} [name] + * @property {string} [original_name] + * @property {string} [title] + * @property {string} [original_title] + * @property {number} episode_count + * @property {string} [release_date] + * @property {string} media_type + * @property {string} character + * @property {string} job + */ + +/** + * @typedef {Object} Group + * @property {string} releaseDate + * @property {string} title + * @property {number} episodeCount + * @property {string} mediaType + * @property {string} role + */ + +/** + * @description Creates the keys and values for the new credits + * @param {InputGroup[]} group + * @returns {Group[]} Returns a new modified group. This will be used in the Credits query. + */ + +const setValues = (group) => { + /** + * @description Stores the new credits + * @type {Group[]} + */ + const credits = []; + + group.forEach((data) => { + /** + * @description The new credits object. It must match the properties in the People/Credits model + * @type {Group} + */ + const updatedGroup = { + releaseDate: '', + title: '', + episodeCount: 0, + mediaType: data.media_type, + role: data.character || data.job + }; + + // The movie and tv series use different object properties, so to get the correct values the media_type checks + if (data.media_type === 'tv') { + updatedGroup.releaseDate = generateYear(data.first_air_date) || ''; + updatedGroup.title = data.name || data.original_name; + updatedGroup.episodeCount = data.episode_count || 0; + } else { + updatedGroup.releaseDate = generateYear(data.release_date) || ''; + updatedGroup.title = data.title || data.original_title || ''; + } + + // Once the new object has been created push it to the newGroup + credits.push(updatedGroup); + }); + + return credits; +}; + +module.exports = setValues; diff --git a/utils/resolverUtils/Credits/setCredits/setValues/index.test.js b/utils/resolverUtils/Credits/setCredits/setValues/index.test.js new file mode 100644 index 0000000..2c98272 --- /dev/null +++ b/utils/resolverUtils/Credits/setCredits/setValues/index.test.js @@ -0,0 +1,193 @@ +const setValues = require('./index'); + +describe('setValues', () => { + const creditsWithoutMissingFields = setValues([ + { + id: 1398, + first_air_date: '1999-01-10', + episode_count: 10, + name: 'The Sopranos', + media_type: 'tv' + }, + { + id: 1398, + release_date: '1999-01-10', + episode_count: 0, + name: 'The Sopranos', + media_type: 'movie' + } + ]); + + const creditsWithMissingFields = setValues([ + { + id: 1398, + first_air_date: '1999-01-10', + episode_count: 1, + original_name: 'The Sopranos', + media_type: 'tv' + }, + { + id: 1398, + first_air_date: '1999-01-10', + episode_count: 0, + original_title: 'The Sopranos', + media_type: 'movie' + } + ]); + + describe('media_type === tv', () => { + const tvCredits = creditsWithoutMissingFields.find((el) => el.mediaType === 'tv'); + + describe('releaseDate property', () => { + it('releaseDate should exist', () => { + // Arrange and act + const response = tvCredits.hasOwnProperty('releaseDate'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('releaseDate should match', () => { + // Arrange and act + const response = tvCredits.releaseDate; + const output = '1999'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('title property', () => { + describe('name field exists', () => { + it('title should exist', () => { + // Arrange and act + const response = tvCredits.hasOwnProperty('title'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('title should match', () => { + // Arrange and act + const response = tvCredits.title; + const output = 'The Sopranos'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('name field doesnt exist', () => { + const nameFieldDoesNotExist = creditsWithMissingFields.find((el) => el.mediaType === 'tv'); + + it('title should exist', () => { + // Arrange and act + const response = nameFieldDoesNotExist.hasOwnProperty('title'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('title should match', () => { + // Arrange and act + const response = nameFieldDoesNotExist.title; + const output = 'The Sopranos'; + + // Assertion + expect(response).toBe(output); + }); + }); + }); + + describe('episodeCount property', () => { + it('episodeCount should exist', () => { + // Arrange and act + const response = tvCredits.hasOwnProperty('episodeCount'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('episodeCount should match', () => { + // Arrange and act + const response = tvCredits.episodeCount; + const output = 10; + + // Assertion + expect(response).toBe(output); + }); + }); + }); + + describe('media_type === movie', () => { + const movieCredits = creditsWithoutMissingFields.find((el) => el.mediaType === 'tv'); + + describe('releaseDate property', () => { + it('releaseDate should exist', () => { + // Arrange and act + const response = movieCredits.hasOwnProperty('releaseDate'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + it('releaseDate should match', () => { + // Arrange and act + const response = movieCredits.releaseDate; + const output = '1999'; + // Assertion + expect(response).toBe(output); + }); + }); + + describe('title property', () => { + describe('title property exists', () => { + it('title should exist', () => { + // Arrange and act + const response = movieCredits.hasOwnProperty('title'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('title should match', () => { + // Arrange and act + const response = movieCredits.title; + const output = 'The Sopranos'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('title property does not exist', () => { + const nameFieldDoesNotExist = creditsWithMissingFields.find( + (el) => el.mediaType === 'movie' + ); + + it('title should exist', () => { + // Arrange and act + const response = nameFieldDoesNotExist.hasOwnProperty('title'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('title should match', () => { + // Arrange and act + const response = nameFieldDoesNotExist.title; + const output = 'The Sopranos'; + + // Assertion + expect(response).toBe(output); + }); + }); + }); + }); +}); diff --git a/utils/resolverUtils/Credits/setValues/index.js b/utils/resolverUtils/Credits/setValues/index.js deleted file mode 100644 index 40b377b..0000000 --- a/utils/resolverUtils/Credits/setValues/index.js +++ /dev/null @@ -1,11 +0,0 @@ -const generateYear = require('../../../dates/generateYear'); -const setValue = require('../../../objects/setValue'); - -const setValues = (group) => { - group.map((data) => { - setValue(data, 'release_date', generateYear(data.release_date)); - }); - return group; -}; - -module.exports = setValues; diff --git a/utils/resolverUtils/Credits/setValues/index.test.js b/utils/resolverUtils/Credits/setValues/index.test.js deleted file mode 100644 index 957c586..0000000 --- a/utils/resolverUtils/Credits/setValues/index.test.js +++ /dev/null @@ -1,37 +0,0 @@ -const setValues = require('./index'); - -describe('setValues', () => { - const input = [ - { name: 'New girl', release_date: '2014-09-24' }, - { name: 'Westworld', release_date: '2016-09-24' }, - { name: 'The Walking Dead', release_date: '2010-09-24' } - ]; - - const output = [ - { name: 'New girl', release_date: '2014' }, - { name: 'Westworld', release_date: '2016' }, - { name: 'The Walking Dead', release_date: '2010' } - ]; - - const response = setValues(input); - - describe('release_date value generating', () => { - it('New girl should return 2014', () => { - const NewGirlInput = response.find((el) => el.name === 'New girl'); - const NewGirlOutput = output.find((el) => el.name === 'New girl'); - expect(NewGirlInput.release_date).toBe(NewGirlOutput.release_date); - }); - - it('Westworld should return 2016', () => { - const WestworldInput = response.find((el) => el.name === 'New girl'); - const WestworldOutput = output.find((el) => el.name === 'New girl'); - expect(WestworldInput.release_date).toBe(WestworldOutput.release_date); - }); - - it('The Walking Dead should return 10', () => { - const TheWalkingDeadInput = response.find((el) => el.name === 'The Walking Dead'); - const TheWalkingDeadOutput = output.find((el) => el.name === 'The Walking Dead'); - expect(TheWalkingDeadInput.release_date).toBe(TheWalkingDeadOutput.release_date); - }); - }); -}); diff --git a/utils/resolverUtils/Crew/setCrew/index.js b/utils/resolverUtils/Crew/setCrew/index.js new file mode 100644 index 0000000..4166194 --- /dev/null +++ b/utils/resolverUtils/Crew/setCrew/index.js @@ -0,0 +1,92 @@ +/** + * The incoming object model + * @typedef {Object} IncomingCrew + * @property {string} credit_id Stores the original credit id + * @property {string} department Stores the department of the crew member + * @property {number} gender The original crew members gender (Stored in a number format for some reason) + * @property {number} id The original crew members id + * @property {string} job The original crew members job e.g. Director + * @property {string} name The original crew members name + * @property {string} profile_path The original crew members profile path (profile image) + */ + +/** + * @typedef {Object} Crew + * @property {string} name - The name for the crew member e.g. Patty Jenkins + * @property {string} roles - Stores the combined roles for the crew member + */ + +/** + * @description This utility is currently only used for the credits resolver, it created a featured crew for a tv series or movie. + * @param {IncomingCrew[]} data + * @return {Crew[]} Returns an array of cast members which are used to display the featured cast + */ +const setCrew = (data) => { + /** + * @type {IncomingCrew[]} + * @description Stores the filtered crew members + */ + let crew = data.filter( + (member) => + member.job === 'Director' || + member.job === 'Screenplay' || + member.job === 'Writer' || + member.job === 'Story' + ); + + // Check to see if there are any crew members + if (crew.length === 0) return []; + + // Show only the first 6 crew members + crew = crew.slice(0, 6); + + /** + * @type {Crew[]} + * @description Will store the new crew members once they have been created + */ + const newCrewMembers = []; + + crew.forEach((member) => { + // Check to see if the crew member already exists in the array + if (newCrewMembers.find((element) => element.name === member.name) === undefined) { + /** + * @type {IncomingCrew[]} + * @description Stores all occurrences of the current crew member + */ + const CurrentCrewMembersRoles = data.filter((i) => i.id === member.id); + + /** + * @type {Crew} + * @description Stores the new crew members details e.g. name, roles (Joined array) + */ + const Member = { + name: member.name || '', + roles: '' + }; + + /** + * @description Used to store all the crew members roles, this array is then joined to create a string + * @type {string[]} + */ + const roles = []; + + // Check to see if the crew members has any roles + if (CurrentCrewMembersRoles.length !== 0) { + // Push each role to the new roles array + CurrentCrewMembersRoles.forEach((duplicateCrewMember) => + roles.push(duplicateCrewMember.job) + ); + + // Join the array items to form a string e.g. "Story, Producer, Editor" + Member.roles = roles.join(', '); + } + + // Push the new crew member to the NewCrewMembers array + newCrewMembers.push(Member); + } + }); + + return newCrewMembers; +}; + +module.exports = setCrew; diff --git a/utils/resolverUtils/Crew/setCrew/index.test.js b/utils/resolverUtils/Crew/setCrew/index.test.js new file mode 100644 index 0000000..5c9298c --- /dev/null +++ b/utils/resolverUtils/Crew/setCrew/index.test.js @@ -0,0 +1,102 @@ +const setCrew = require('./index'); + +describe('setCrew', () => { + const crew = setCrew([ + { + credit_id: '5a83baf9c3a368637c003f34', + department: 'Writing', + gender: 1, + id: 6884, + job: 'Screenplay', + name: 'Patty Jenkins', + profile_path: '/za4JYxjctECHLJJel3lEFPsbeht.jpg' + }, + { + credit_id: '5a847700c3a36863e700ec11', + department: 'Directing', + gender: 1, + id: 6884, + job: 'Director', + name: 'Patty Jenkins', + profile_path: '/za4JYxjctECHLJJel3lEFPsbeht.jpg' + }, + { + credit_id: '5b21246e9251416e0b00ad62', + department: 'Production', + gender: 1, + id: 6884, + job: 'Producer', + name: 'Patty Jenkins', + profile_path: '/za4JYxjctECHLJJel3lEFPsbeht.jpg' + }, + { + credit_id: '5b2e7080c3a3685335005ecc', + department: 'Writing', + gender: 1, + id: 6884, + job: 'Story', + name: 'Patty Jenkins', + profile_path: '/za4JYxjctECHLJJel3lEFPsbeht.jpg' + } + ]); + + describe('No crews', () => { + it('When there are no crews the length should be 0', () => { + // Arrange and act + const response = setCrew([]).length; + const output = 0; + + // Assertion + expect(response).toBe(0); + }); + + it('When there are crews the length should be 1', () => { + // Arrange and act + const response = crew.length; + const output = 1; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('name property', () => { + it('The name property should exist', () => { + // Arrange and act + const response = crew[0].hasOwnProperty('name'); + const output = true; + + // Assertion + expect(response).toBe(true); + }); + + it('The name property should match', () => { + // Arrange and act + const response = crew[0].name; + const output = 'Patty Jenkins'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('roles property', () => { + it('The roles property should exist', () => { + // Arrange and act + const response = crew[0].hasOwnProperty('roles'); + const output = true; + + // Assertion + expect(response).toBe(true); + }); + + it('The roles property should match', () => { + // Arrange and act + const response = crew[0].roles; + const output = 'Screenplay, Director, Producer, Story'; + + // Assertion + expect(response).toBe(output); + }); + }); +}); diff --git a/utils/resolverUtils/Movies/setMovies/index.js b/utils/resolverUtils/Movies/setMovies/index.js new file mode 100644 index 0000000..4280653 --- /dev/null +++ b/utils/resolverUtils/Movies/setMovies/index.js @@ -0,0 +1,81 @@ +const formatDate = require('../../../dates/custom'); +const toPercentage = require('../../../maths/toPercentage'); +const generateAbsolutePath = require('../../../images/generateAbsolutePath'); + +/** + * @typedef {Object} IncomingMovieObject + * @property {number} popularity Stores the popularity of the movie e.g. 45.55324 + * @property {number[]} genre_ids Stores the genre id's associated to the movie e.g. [3333] + * @property {string} backdrop_path Stores the background path for the movie (Only a partial path) + * @property {string} poster_path Stores the poster path for the movie (Only a partial path) + * @property {string} original_language - Stores the original language for the movie e.g. En + * @property {number} vote_average - Stores the vote average for the movie e.g. 45.553323 + * @property {number} vote_count Stores the vote count for the movie e.g. 34,000 + * @property {boolean} video Stores the video property (Not sure what this does actually :D ) + * @property {boolean} adult Stores the adult property (Not sure what this does actually :D ) + * @property {string} original_title Stores the original title for the movie e.g. Mad Max: Fury Road + * @property {string} title Stores the title for the movie e.g. Mad Max: Fury Road + * @property {string} release_date Stores the release date for the movie e.g. 09-20-2015 + * @property {number} id Stores the id for the movie e.g. 33243243232 + * @property {string} overview Stores the overview for the movie e.g. Awesome Movie Description + */ + +/** + * + * A Movie + * @typedef {Object} Movie + * @property {number} id Stores the new id for the movie + * @property {string} name Stores the name for the movie (It's either the title or the original_title) + * @property {string} overview Stores the overview for the movie e.g. Awesome movie description + * @property {string} backgroundUrl Stores an absolute path to the background image for the movie + * @property {string} posterUrl Stores the absolute path to the poster image for the movie + * @property {number[]} genres Stores the genre ids associated to the movie + * @property {string} releaseDate Stores the release year of the movie (Transformed via a date util) + * @property {string} originalLanguage Stores the original language for the movie e.g. en + * @property {number} voteAverage Stores the average vote to zero decimal places e.g. 40, used to display a rating on the FE + * + */ + +/** + * @description This utility is used to create a new movie array, this is used in the Upcoming, TopRated, Recommendations, Popular, NowPlaying and Discover resolvers. + * @param {IncomingMovieObject[]} movies + * @returns {Movie[]} Returns an array of movies + */ +const setMovies = (movies) => { + /** + * @type {Movie[]} + * @description This is the new Movie object, the properties must match the properties defined in the schema + */ + const Movies = []; + + // Check to see if any movies exist + if (movies.length === 0) return []; + + // Loop through each movie and created a new custom Movie object + movies.forEach((movie) => { + const Movie = { + id: movie.id ? movie.id : 0, // Id is cast to a string to perform truthy/falsy checks + name: movie.title || '', + overview: movie.overview || '', + backgroundUrl: generateAbsolutePath(movie.backdrop_path) || '', + posterUrl: generateAbsolutePath(movie.poster_path) || '', + genres: movie.genre_ids.length !== 0 ? movie.genre_ids : [], // The array length is checked, an array is not a falsy value + releaseDate: formatDate(movie.release_date, 'MMMM Do, YYYY') || '', + originalLanguage: movie.original_language || '', + voteAverage: toPercentage(movie.vote_average) || 0 + }; + + // When the name is blank + if (Movie.name === '') { + Movie.name = movie.original_title; + } + + // Pushes the current object to the Movies array + Movies.push(Movie); + }); + + // Return the new array to the GraphQL resolver + return Movies; +}; + +module.exports = setMovies; diff --git a/utils/resolverUtils/Movies/setMovies/index.test.js b/utils/resolverUtils/Movies/setMovies/index.test.js new file mode 100644 index 0000000..58da607 --- /dev/null +++ b/utils/resolverUtils/Movies/setMovies/index.test.js @@ -0,0 +1,139 @@ +const setMovies = require('./index'); + +describe('setMovies', () => { + // Arrange and act + const movies = setMovies([ + { + popularity: 1926.55, + vote_count: 37, + video: false, + poster_path: '/9Rj8l6gElLpRL7Kj17iZhrT5Zuw.jpg', + id: 734309, + adult: false, + backdrop_path: '/7fvdg211A2L0mHddvzyArRuRalp.jpg', + original_language: 'en', + original_title: 'Santana', + genre_ids: [28], + title: 'Santana', + vote_average: 5.8, + overview: + 'Two brothers — one a narcotics agent and the other a general — finally discover the identity of the drug lord who murdered their parents decades ago. They may kill each other before capturing the bad guys.', + release_date: '2020-08-28' + } + ]); + const actualMovie = movies[0]; + + describe('id property', () => { + // Assertion + it('The id should exist', () => { + expect(actualMovie.hasOwnProperty('id')).toBe(true); + }); + + // Assertion + it('The id should match', () => { + expect(actualMovie.id).toBe(734309); + }); + }); + + describe('name property', () => { + // Assertion + it('The name should exist', () => { + expect(actualMovie.hasOwnProperty('name')).toBe(true); + }); + + // Assertion + it('The name should match', () => { + expect(actualMovie.name).toBe('Santana'); + }); + }); + + describe('overview property', () => { + // Assertion + it('The overview should exist', () => { + expect(actualMovie.hasOwnProperty('overview')).toBe(true); + }); + + // Assertion + it('The overview should match', () => { + expect(actualMovie.overview).toBe( + 'Two brothers — one a narcotics agent and the other a general — finally discover the identity of the drug lord who murdered their parents decades ago. They may kill each other before capturing the bad guys.' + ); + }); + }); + + describe('backgroundUrl property', () => { + // Assertion + it('The backgroundUrl should exist', () => { + expect(actualMovie.hasOwnProperty('backgroundUrl')).toBe(true); + }); + + // Assertion + it('The backgroundUrl should match', () => { + expect(actualMovie.backgroundUrl).toBe( + 'https://image.tmdb.org/t/p/original/7fvdg211A2L0mHddvzyArRuRalp.jpg' + ); + }); + }); + + describe('posterUrl property', () => { + // Assertion + it('The posterUrl should exist', () => { + expect(actualMovie.hasOwnProperty('posterUrl')).toBe(true); + }); + + // Assertion + it('The posterUrl should match', () => { + expect(actualMovie.posterUrl).toBe( + 'https://image.tmdb.org/t/p/original/9Rj8l6gElLpRL7Kj17iZhrT5Zuw.jpg' + ); + }); + }); + + describe('genres property', () => { + // Assertion + it('The genres should exist', () => { + expect(actualMovie.hasOwnProperty('genres')).toBe(true); + }); + + // Assertion + it('The genres should match', () => { + expect(actualMovie.genres).toStrictEqual([28]); + }); + }); + + describe('releaseDate property', () => { + // Assertion + it('The releaseDate should exist', () => { + expect(actualMovie.hasOwnProperty('releaseDate')).toBe(true); + }); + + // Assertion + it('The releaseDate should be August 28th, 2020', () => { + expect(actualMovie.releaseDate).toBe('August 28th, 2020'); + }); + }); + + describe('originalLanguage', () => { + // Assertion + it('The originalLanguage should exist', () => { + expect(actualMovie.hasOwnProperty('originalLanguage')).toBe(true); + }); + + // Assertion + it('The originalLanguage should be en', () => { + expect(actualMovie.originalLanguage).toBe('en'); + }); + }); + + describe('voteAverage', () => { + // Assertion + it('The voteAverage should exist', () => { + expect(actualMovie.hasOwnProperty('voteAverage')).toBe(true); + }); + + // Assertion + it('The voteAverage should be 58', () => { + expect(actualMovie.voteAverage).toBe(58); + }); + }); +}); diff --git a/utils/resolverUtils/People/setPeople/index.js b/utils/resolverUtils/People/setPeople/index.js new file mode 100644 index 0000000..c287401 --- /dev/null +++ b/utils/resolverUtils/People/setPeople/index.js @@ -0,0 +1,97 @@ +const generateAbsolutePath = require('../../../images/generateAbsolutePath'); + +/** + * @typedef {Object} InputPeople + * @property {string} profile_path Stores the profile path for the person (Only a partial path) + * @property {boolean} adult Stores the adult property (Not sure what this does actually :D ) + * @property {number} id Stores the id for the movie e.g. 33243243232 + * @property {KnownFor[]} known_for Stores an array of tv and shows which the user is known for + * @property {string} name Stores the persons name + * @property {number} popularity Stores the popularity of the movie e.g. 45.55324 + */ + +/** + * @typedef {Object} People + * @property {number} id Stores the id for the movie e.g. 33243243232 + * @property {string} name Stores the persons name + * @property {string} posterUrl Stores the absolute path to the poster image for the movie + * @property {string} roles Stores a list of all the role + */ + +/** + * @typedef {Object} KnownFor + * @property {string} [name] Stores the original name for the show e.g. Lucifer + * @property {string} [original_name] Stores the original name for the movie e.g. Lucifer + * @property {string} [title] Stores the title for the movie e.g. Mad Max: Fury Road + * @property {string} [original_title] Stores the title for the movie e.g. Mad Max: Fury Road + * @property {string} [media_type] Stores the media type + */ + +/** + * @description This utility is used in the Popular people resolver, it is used to format the person responses. + * @param {InputPeople[]} people + * @returns {People[]} Returns an array of people, this is used in the popular people query + */ +const setPeople = (people) => { + /** + * @type People[] + */ + const People = []; + + people.forEach((person) => { + /** + * @type People + * @description This is the new Person object, the properties must match the properties defined in the schema + */ + const Person = { + id: person.id ? person.id : 0, + name: person.name || '', + posterUrl: generateAbsolutePath(person.profile_path) || '', + roles: '' + }; + + /** + * @description Used to store all the persons roles, this array is then joined to create a string + * @type {string[]} + */ + const roles = []; + + // Loop through each persons role and add the name of the movie or show to the roles array + person.known_for.forEach((role) => { + // Checks to see if the media_type is tv (Uses different attributes for the name e.g. original_name or name) + if (role.media_type === 'tv') { + let name = role.name || ''; + + // When the title isn't available try to use the original_name + if (name === '') { + name = role.original_name || ''; + } + + // Add the tv to the roles array + roles.push(name); + } + + // Checks to see if the media_type is movie (Uses different attributes for the name e.g. original_title or title) + if (role.media_type === 'movie') { + let name = role.title || ''; + + // When the title isn't available try to use the original_title + if (name === '') { + name = role.original_title || ''; + } + + // Add the movie to the roles array + roles.push(name); + } + + // Create a string from the array of roles + Person.roles = roles.join(', '); + }); + + People.push(Person); + }); + + return People; +}; + +module.exports = setPeople; diff --git a/utils/resolverUtils/People/setPeople/index.test.js b/utils/resolverUtils/People/setPeople/index.test.js new file mode 100644 index 0000000..39ad913 --- /dev/null +++ b/utils/resolverUtils/People/setPeople/index.test.js @@ -0,0 +1,110 @@ +const setPeople = require('./index'); + +describe('setPeople', () => { + const person = setPeople([ + { + profile_path: '/z3sLuRKP7hQVrvSTsqdLjGSldwG.jpg', + adult: false, + id: 28782, + known_for: [ + { + original_title: 'Spectre', + media_type: 'movie', + title: 'Spectre' + }, + { + original_title: 'The Matrix Reloaded', + media_type: 'movie', + title: 'The Matrix Reloaded' + }, + { + original_title: 'The Matrix Revolutions', + media_type: 'movie', + title: 'The Matrix Revolutions' + } + ], + name: 'Monica Bellucci', + popularity: 48.609344 + } + ])[0]; + + describe('id property', () => { + it('The id should exist', () => { + // Arrange and act + const response = person.hasOwnProperty('id'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The id should match', () => { + // Arrange and act + const response = person.id; + const output = 28782; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('name property', () => { + it('The name should exist', () => { + // Arrange and act + const response = person.hasOwnProperty('name'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The name should match', () => { + // Arrange and act + const response = person.name; + const output = 'Monica Bellucci'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('posterUrl property', () => { + it('The posterUrl should exist', () => { + // Arrange and act + const response = person.hasOwnProperty('posterUrl'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The posterUrl should match', () => { + // Arrange and act + const response = person.posterUrl; + const output = 'https://image.tmdb.org/t/p/original/z3sLuRKP7hQVrvSTsqdLjGSldwG.jpg'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('roles property', () => { + it('The roles should exist', () => { + // Arrange and act + const response = person.hasOwnProperty('roles'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The roles should match', () => { + // Arrange and act + const response = person.roles; + const output = 'Spectre, The Matrix Reloaded, The Matrix Revolutions'; + + // Assertion + expect(response).toBe(output); + }); + }); +}); diff --git a/utils/resolverUtils/Shows/setShows/index.js b/utils/resolverUtils/Shows/setShows/index.js new file mode 100644 index 0000000..b523af5 --- /dev/null +++ b/utils/resolverUtils/Shows/setShows/index.js @@ -0,0 +1,78 @@ +const generateAbsolutePath = require('../../../images/generateAbsolutePath'); +const formatDate = require('../../../dates/custom'); +const toPercentage = require('../../../maths/toPercentage'); + +/** + * @typedef {Object} IncomingShow + * @property {number} popularity Stores the popularity of the movie e.g. 45.55324 + * @property {number[]} genre_ids Stores the genre id's associated to the movie e.g. [3333] + * @property {string} backdrop_path Stores the background path for the movie (Only a partial path) + * @property {string} poster_path Stores the poster path for the movie (Only a partial path) + * @property {string} original_language - Stores the original language for the movie e.g. En + * @property {number} vote_average - Stores the vote average for the movie e.g. 45.553323 + * @property {number} vote_count Stores the vote count for the movie e.g. 34,000 + * @property {boolean} video Stores the video property (Not sure what this does actually :D ) + * @property {boolean} adult Stores the adult property (Not sure what this does actually :D ) + * @property {string} original_name Stores the original name for the movie e.g. Lucifer + * @property {string} name Stores the title for the movie e.g. Mad Max: Fury Road + * @property {string} first_air_date Stores the release date for the movie e.g. 09-20-2015 + * @property {number} id Stores the id for the movie e.g. 33243243232 + * @property {string} overview Stores the overview for the movie e.g. Awesome Movie Description + */ + +/** + * @typedef {Object} Show + * @property {number} id Stores the new id for the movie + * @property {string} name Stores the name for the movie (It's either the title or the original_title) + * @property {string} overview Stores the overview for the movie e.g. Awesome movie description + * @property {string} backgroundUrl Stores an absolute path to the background image for the movie + * @property {string} posterUrl Stores the absolute path to the poster image for the movie + * @property {number[]} genres Stores the genre ids associated to the movie + * @property {string} releaseDate Stores the release year of the movie (Transformed via a date util) + * @property {string} originalLanguage Stores the original language for the movie e.g. en + * @property {number} voteAverage Stores the average vote to zero decimal places e.g. 40, used to display a rating on the FE + */ + +/** + * @description This utility is used to create a new show array, this is used in the Upcoming, TopRated, Recommendations, Popular, NowPlaying and Discover resolvers. + * @param {IncomingShow[]} shows + * @returns {Show[]} + */ +const setShows = (shows) => { + /** + * @type {Show[]} + * @description This is the new Show object, the properties must match the properties defined in the schema + */ + const Shows = []; + + // Check to see if any shows + if (shows.length === 0) return []; + + // Loop through each show and created a new custom Show object + shows.forEach((show) => { + const Show = { + id: show.id ? show.id : 0, // Id is cast to a string to perform truthy/falsy checks + name: show.name || '', + overview: show.overview || '', + backgroundUrl: generateAbsolutePath(show.backdrop_path) || '', + posterUrl: generateAbsolutePath(show.poster_path) || '', + genres: show.genre_ids.length !== 0 ? show.genre_ids : [], // The array length is checked, an array is not a falsy value + releaseDate: formatDate(show.first_air_date, 'MMMM Do, YYYY') || '', + originalLanguage: show.original_language || '', + voteAverage: toPercentage(show.vote_average) || 0 + }; + + // When the name is blank + if (Show.name === '') { + Show.name = show.original_name; + } + + // Pushes the current object to the Shows array + Shows.push(Show); + }); + + // Return the new array to the GraphQL resolver + return Shows; +}; + +module.exports = setShows; diff --git a/utils/resolverUtils/Shows/setShows/index.test.js b/utils/resolverUtils/Shows/setShows/index.test.js new file mode 100644 index 0000000..84dc3b7 --- /dev/null +++ b/utils/resolverUtils/Shows/setShows/index.test.js @@ -0,0 +1,227 @@ +const setShows = require('./index'); + +describe('setShows', () => { + const shows = setShows([ + { + original_name: 'Lucifer', + genre_ids: [80, 10765], + name: 'Lucifer', + first_air_date: '2016-01-25', + backdrop_path: '/ta5oblpMlEcIPIS2YGcq9XEkWK2.jpg', + original_language: 'en', + id: 63174, + vote_average: 8.5, + overview: + "Bored and unhappy as the Lord of Hell, Lucifer Morningstar abandoned his throne and retired to Los Angeles, where he has teamed up with LAPD detective Chloe Decker to take down criminals. But the longer he's away from the underworld, the greater the threat that the worst of humanity could escape.", + poster_path: '/4EYPN5mVIhKLfxGruy7Dy41dTVn.jpg', + vote_count: 40, + popularity: 20000, + video: true, + adult: true + } + ]); + + const show = shows[0]; + + describe('id property', () => { + it('The id should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('id'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The id should match', () => { + // Arrange and act + const response = show.id; + const output = 63174; + + expect(response).toBe(output); + }); + }); + + describe('name property', () => { + it('The name property should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('name'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The name property should match (name)', () => { + // Arrange and act + const response = show.name; + const output = 'Lucifer'; + + expect(response).toBe(output); + }); + + it('The name property should match (original_name)', () => { + // Arrange and act + const response = setShows([ + { + // name: 'Lucifer', - The name is commented out so the name attribute uses the original_name instead + original_name: 'Lucifer', + genre_ids: [80, 10765], + first_air_date: '2016-01-25', + backdrop_path: '/ta5oblpMlEcIPIS2YGcq9XEkWK2.jpg', + original_language: 'en', + id: 63174, + vote_average: 8.5, + overview: + "Bored and unhappy as the Lord of Hell, Lucifer Morningstar abandoned his throne and retired to Los Angeles, where he has teamed up with LAPD detective Chloe Decker to take down criminals. But the longer he's away from the underworld, the greater the threat that the worst of humanity could escape.", + poster_path: '/4EYPN5mVIhKLfxGruy7Dy41dTVn.jpg' + } + ])[0].name; + const output = 'Lucifer'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('overview property', () => { + it('The overview should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('overview'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The overview should match', () => { + // Arrange and act + const response = show.overview; + const output = + "Bored and unhappy as the Lord of Hell, Lucifer Morningstar abandoned his throne and retired to Los Angeles, where he has teamed up with LAPD detective Chloe Decker to take down criminals. But the longer he's away from the underworld, the greater the threat that the worst of humanity could escape."; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('backgroundUrl property', () => { + it('The backgroundUrl should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('backgroundUrl'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The backgroundUrl should match', () => { + // Arrange and act + const response = show.backgroundUrl; + const output = 'https://image.tmdb.org/t/p/original/ta5oblpMlEcIPIS2YGcq9XEkWK2.jpg'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('posterUrl property', () => { + it('The posterUrl should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('posterUrl'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The posterUrl should match', () => { + // Arrange and act + const response = show.posterUrl; + const output = 'https://image.tmdb.org/t/p/original/4EYPN5mVIhKLfxGruy7Dy41dTVn.jpg'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('genres property', () => { + it('The genres property should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('genres'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The genres should match', () => { + // Arrange and act + const response = show.genres; + const output = [80, 10765]; + + // Assertion + expect(response).toStrictEqual(output); + }); + }); + + describe('releaseDate property', () => { + it('The releaseDate property should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('releaseDate'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The releaseDate should match', () => { + // Arrange and act + const response = show.releaseDate; + const output = 'January 25th, 2016'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('originalLanguage property', () => { + it('The originalLanguage property should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('originalLanguage'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The originalLanguage should match', () => { + // Arrange and act + const response = show.originalLanguage; + const output = 'en'; + + // Assertion + expect(response).toBe(output); + }); + }); + + describe('voteAverage property', () => { + it('The voteAverage property should exist', () => { + // Arrange and act + const response = show.hasOwnProperty('voteAverage'); + const output = true; + + // Assertion + expect(response).toBe(output); + }); + + it('The voteAverage should match', () => { + // Arrange and act + const response = show.voteAverage; + const output = 85; + + // Assertion + expect(response).toBe(output); + }); + }); +}); diff --git a/utils/resolverUtils/Social/setSocialLinks/index.js b/utils/resolverUtils/Social/setSocialLinks/index.js new file mode 100644 index 0000000..c52f362 --- /dev/null +++ b/utils/resolverUtils/Social/setSocialLinks/index.js @@ -0,0 +1,63 @@ +/** + * @typedef {Object} IncomingSocialLinks + * @property {string} [facebook_id] Stores the facebook id + * @property {string} [twitter_id] Stores the twitter id + * @property {string} [homepage] Stores the homepage + * @property {string} [instagram_id] Stores the instagram id + */ + +/** + * @typedef {Object} SocialLinks + * @property {string} facebook Stores the absolute facebook path for a person, show or movie + * @property {string} twitter Stores the absolute twitter path for a person, show or movie + * @property {string} homepage Stores the homepage for a person, show or movie + * @property {string} instagram Stores the absolute instagram path for a person, show or movie + */ + +/** + * @description Creates an object which stores references to a person's, show's or movie's social profiles (The object properties must match the Social model) + * @param {IncomingSocialLinks} data + * @param {string} resolverType + * @returns {SocialLinks} + */ +const setSocialLinks = (data, resolverType = 'entertainment') => { + /** + * @type {SocialLinks} + * @description Stores the social media references. They are are absolute paths which the front-end will use to link to the persons social profiles. + */ + const SocialLinks = { + facebook: data.facebook_id || '', + twitter: data.twitter_id || '', + instagram: data.instagram_id || '', + homepage: data.homepage || '' + }; + + // facebook and instagram + if (SocialLinks.facebook !== '') { + SocialLinks.facebook = `https://www.facebook.com/${data.facebook_id}`; + + // Only when the resolver being used is not a person type (Movie and Show Resolvers ONLY) use the facebook_id as the instagram id + if (resolverType === 'entertainment') { + SocialLinks.instagram = `https://www.instagram.com/${data.facebook_id}`.toLowerCase(); + } + } + + // When the resolver type is person and the instagram id isn't empty use the instagram id + if (SocialLinks.instagram !== '' && resolverType === 'person') { + SocialLinks.instagram = `https://www.instagram.com/${SocialLinks.instagram}`; + } + + // twitter + if (SocialLinks.twitter !== '') { + SocialLinks.twitter = `https://www.twitter.com/${data.twitter_id}`; + } + + // homepage (Needs to be present in the schema in order for it to be present in the schema) + if (SocialLinks.homepage !== '') { + SocialLinks.homepage = data.homepage; + } + + return SocialLinks; +}; + +module.exports = setSocialLinks; diff --git a/utils/resolverUtils/Social/setSocialLinks/index.test.js b/utils/resolverUtils/Social/setSocialLinks/index.test.js new file mode 100644 index 0000000..fd78ce5 --- /dev/null +++ b/utils/resolverUtils/Social/setSocialLinks/index.test.js @@ -0,0 +1,127 @@ +const setSocialLinks = require('./index'); + +describe('setSocialLinks', () => { + // Facebook and instagram link tests + describe('facebook and instagram links', () => { + describe('facebook', () => { + it('The url should exist', () => { + // Arrange and act + const response = setSocialLinks({ facebook_id: '1234' }); + const output = 'https://www.facebook.com/1234'; + + // Assertion + expect(response.facebook).toBe(output); + }); + + it('The url should be empty', () => { + // Arrange and act + const response = setSocialLinks({ facebook_id: '' }); + const output = ''; + + // Assertion + expect(response.facebook).toBe(output); + }); + }); + + describe('instagram', () => { + it('The url should exist', () => { + // Arrange and act + const response = setSocialLinks({ facebook_id: '1234' }); + const output = 'https://www.instagram.com/1234'; + + // Assertion + expect(response.instagram).toBe(output); + }); + + it('The url should not exist', () => { + // Arrange and act + const response = setSocialLinks({ facebook_id: '' }); + const output = ''; + + // Assertion + expect(response.instagram).toBe(output); + }); + }); + }); + + // Twitter + describe('twitter link', () => { + it('The url should exist', () => { + // Arrange and act + const response = setSocialLinks({ twitter_id: '1234' }); + const output = 'https://www.twitter.com/1234'; + + // Assertion + expect(response.twitter).toBe(output); + }); + + it('The url should be empty', () => { + // Arrange and act + const response = setSocialLinks({ twitter_id: '' }); + const output = ''; + + // Assertion + expect(response.twitter).toBe(output); + }); + }); + + // Homepage + describe('homepage', () => { + it('The url should exist', () => { + // Arrange and act + const response = setSocialLinks({ homepage: 'https://www.alexmachin.co.uk/' }); + const output = 'https://www.alexmachin.co.uk/'; + + // Assertion + expect(response.homepage).toBe(output); + }); + + it('The url should be empty', () => { + // Arrange and act + const response = setSocialLinks({ homepage: '' }); + const output = ''; + + // Assertion + expect(response.homepage).toBe(output); + }); + }); + + describe('resolverType === person', () => { + const socials = setSocialLinks( + { + twitter_id: 'therock', + facebook_id: 'DwayneJohnson', + instagram_id: 'therock', + homepage: '' + }, + 'person' + ); + + it('twitter id should match', () => { + // Arrange and act + const response = socials.twitter; + const output = 'https://www.twitter.com/therock'; + + // Assertion + expect(response).toBe(output); + }); + + it('instagram id should match', () => { + // Arrange and act + const response = socials.instagram; + const output = 'https://www.instagram.com/therock'; + + // Assertion + expect(response).toBe(output); + }); + + it('homepage should match', () => { + // Arrange and act + const response = socials.homepage; + const output = ''; + + // Assertion + expect(response).toBe(output); + }); + }); +}); diff --git a/utils/resolverUtils/Videos/setFeaturedVideo/index.js b/utils/resolverUtils/Videos/setFeaturedVideo/index.js new file mode 100644 index 0000000..5b56900 --- /dev/null +++ b/utils/resolverUtils/Videos/setFeaturedVideo/index.js @@ -0,0 +1,59 @@ +/** + * @typedef {Object} InputVideos + * @property {number} id Stores the id for the video + * @property {string} iso_639_1 Stores something, not exactly sure though.. + * @property {string} iso_3166_1 Stores something, not exactly sure though.. + * @property {string} key Stores a video key, this can be used to create the embedded youtube video url + * @property {string} name Stores the name of the url + * @property {string} site Stores the source of the video + * @property {number} size Stores the size of the video e.g. 1080, 720 + * @property {string} type Stores the type of video e.g. trailer, feature + */ + +/** + * @typedef {Object} Video + * @property {number} [id] Stores the id for the video + * @property {string} [name] Stores the name for the video e.g. BILL & TED FACE THE MUSIC Official Trailer #2 (2020) + * @property {string} [url] Stores the url for the video, this can be used for embedding the featured video e.g. https://www.youtube.com/watch?v=1gPGeAYo3yU + * @property {string} [type] Stores the type of video + * @property {string} [site] Stores the type of video e.g. trailer, feature + */ + +/** + * @description A utility function for getting a featured video, this is going to be used for the single movie or show page. + * @param {InputVideos[]} videos + * @returns {Video} + */ +const setFeaturedVideo = (videos) => { + // Checks to see if any Videos exist + if (videos.length === 0) return {}; + + // Store the Videos in a variable, this allows them to be modified + const availableVideos = videos.filter( + (video) => video.site === 'YouTube' && video.type === 'Trailer' + ); + + let selectedVideo; + + if (availableVideos.length !== 0) { + // eslint-disable-next-line prefer-destructuring + selectedVideo = availableVideos[0]; + } + + /** + * @type {Video} + * @description Stores the new featured video properties + */ + const Video = { + id: selectedVideo.id || 0, + name: selectedVideo.name || '', + url: selectedVideo.key ? `https://www.youtube.com/watch?v=${selectedVideo.key}` : '', + type: 'Trailer', + site: 'YouTube' + }; + + // Return the new Video object + return Video; +}; + +module.exports = setFeaturedVideo; diff --git a/utils/resolverUtils/Videos/setFeaturedVideo/index.test.js b/utils/resolverUtils/Videos/setFeaturedVideo/index.test.js new file mode 100644 index 0000000..88850d2 --- /dev/null +++ b/utils/resolverUtils/Videos/setFeaturedVideo/index.test.js @@ -0,0 +1,134 @@ +const setFeaturedVideo = require('./index'); + +describe('setFeaturedVideo', () => { + const billAndTedVideos = [ + { + id: '5edf93a6f36a32001d8edf04', + iso_639_1: 'en', + iso_3166_1: 'US', + key: '0hAL7emClFM', + name: 'BILL & TED FACE THE MUSIC Official Trailer #1 (2020)', + site: 'YouTube', + size: 1080, + type: 'Trailer' + }, + { + id: '5f199125db952d0035964faf', + iso_639_1: 'en', + iso_3166_1: 'US', + key: '1gPGeAYo3yU', + name: 'BILL & TED FACE THE MUSIC Official Trailer #2 (2020)', + site: 'YouTube', + size: 1080, + type: 'Trailer' + }, + { + id: '5f2c2c08fab3fa0036fecdec', + iso_639_1: 'en', + iso_3166_1: 'US', + key: 'yevysSJlRdQ', + name: 'BILL & TED FACE THE MUSIC: Behind the Scenes - A Most Triumphant Duo', + site: 'YouTube', + size: 1080, + type: 'Behind the Scenes' + } + ]; + + describe('id', () => { + it('Should not exist', () => { + // Arrange and act + const response = setFeaturedVideo([]); + + // Assertion + expect(response.id).toBeFalsy(); + // expect(true).toBe(true); + }); + + it('Should not be a blank id', () => { + // Arrange and act + const response = setFeaturedVideo(billAndTedVideos); + const output = '5edf93a6f36a32001d8edf04'; + + // Assertion + expect(response.id).toBe(output); + }); + }); + + describe('name', () => { + it('Should not exist', () => { + // Arrange and act + const response = setFeaturedVideo([]); + const output = ''; + + // Assertion + expect(response.name).toBeFalsy(); + }); + + it('Should not be a blank name', () => { + // Arrange and act + const response = setFeaturedVideo(billAndTedVideos); + const output = 'BILL & TED FACE THE MUSIC Official Trailer #1 (2020)'; + + // Assertion + expect(response.name).toBe(output); + }); + }); + + describe('url', () => { + it('Should not exist', () => { + // Arrange and act + const response = setFeaturedVideo([]); + const output = ''; + + // Assertion + expect(response.url).toBeFalsy(); + }); + + it('Should not be a blank url', () => { + // Arrange and act + const response = setFeaturedVideo(billAndTedVideos); + const output = 'https://www.youtube.com/watch?v=0hAL7emClFM'; + + // Assertion + expect(response.url).toBe(output); + }); + }); + + describe('type', () => { + it('Should not exist', () => { + // Arrange and act + const response = setFeaturedVideo([]); + + // Assertion + expect(response.type).toBeFalsy(); + }); + + it('Should not be a blank type', () => { + // Arrange and act + const response = setFeaturedVideo(billAndTedVideos); + const output = 'Trailer'; + + // Assertion + expect(response.type).toBe(output); + }); + }); + + describe('site', () => { + it('Should not exist', () => { + // Arrange and act + const response = setFeaturedVideo([]); + + // Assertion + expect(response.site).toBeFalsy(); + }); + + it('Should not be a blank site', () => { + // Arrange and act + const response = setFeaturedVideo(billAndTedVideos); + const output = 'YouTube'; + + // Assertion + expect(response.site).toBe(output); + }); + }); +});