diff --git a/.babelrc b/.babelrc index 32beabad5..6db8c8c05 100644 --- a/.babelrc +++ b/.babelrc @@ -5,7 +5,7 @@ "@babel/preset-env", { "modules": false, - "useBuiltIns": "usage" + "useBuiltIns": "entry" } ] ] diff --git a/.eslintrc.yml b/.eslintrc.yml index eb1b1779a..8e667de7c 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -24,7 +24,7 @@ rules: # no-cond-assign: error # no-console: off # no-constant-condition: error -# no-control-regex: error + no-control-regex: off # no-debugger: error # no-dupe-args: error # no-dupe-keys: error diff --git a/app/app.js b/app/app.js index acdee2add..db35643a2 100644 --- a/app/app.js +++ b/app/app.js @@ -1,8 +1,10 @@ import _ from 'lodash-es'; +import $ from 'jquery'; +import '@babel/polyfill' angular.module('portainer') -.run(['$rootScope', '$state', '$interval', 'Authentication', 'authManager', 'StateManager', 'EndpointProvider', 'Notifications', 'Analytics', 'SystemService', 'cfpLoadingBar', '$transitions', 'HttpRequestHelper', -function ($rootScope, $state, $interval, Authentication, authManager, StateManager, EndpointProvider, Notifications, Analytics, SystemService, cfpLoadingBar, $transitions, HttpRequestHelper) { +.run(['$rootScope', '$state', '$interval', 'LocalStorage', 'Authentication', 'authManager', 'StateManager', 'EndpointProvider', 'Notifications', 'Analytics', 'SystemService', 'cfpLoadingBar', '$transitions', 'HttpRequestHelper', +function ($rootScope, $state, $interval, LocalStorage, Authentication, authManager, StateManager, EndpointProvider, Notifications, Analytics, SystemService, cfpLoadingBar, $transitions, HttpRequestHelper) { 'use strict'; EndpointProvider.initialize(); @@ -40,6 +42,14 @@ function ($rootScope, $state, $interval, Authentication, authManager, StateManag ping(EndpointProvider, SystemService); }, 60 * 1000) + $(document).ajaxSend(function (event, jqXhr, jqOpts) { + const type = jqOpts.type === 'POST' || jqOpts.type === 'PUT' || jqOpts.type === 'PATCH'; + const hasNoContentType = jqOpts.contentType !== 'application/json' && jqOpts.headers && !jqOpts.headers['Content-Type']; + if (type && hasNoContentType) { + jqXhr.setRequestHeader('Content-Type', 'application/json'); + } + jqXhr.setRequestHeader('Authorization', 'Bearer ' + LocalStorage.getJWT()); + }); }]); function ping(EndpointProvider, SystemService) { diff --git a/app/docker/filters/filters.js b/app/docker/filters/filters.js index 3ba22ef50..3fd65f22a 100644 --- a/app/docker/filters/filters.js +++ b/app/docker/filters/filters.js @@ -278,6 +278,9 @@ angular.module('portainer.docker') .filter('trimshasum', function () { 'use strict'; return function (imageName) { + if (!imageName) { + return; + } if (imageName.indexOf('sha256:') === 0) { return imageName.substring(7, 19); } diff --git a/app/docker/helpers/imageHelper.js b/app/docker/helpers/imageHelper.js index b46951c83..78091aa5e 100644 --- a/app/docker/helpers/imageHelper.js +++ b/app/docker/helpers/imageHelper.js @@ -6,6 +6,12 @@ angular.module('portainer.docker') var helper = {}; + helper.isValidTag = isValidTag; + + function isValidTag(tag) { + return tag.match(/^(?![\.\-])([a-zA-Z0-9\_\.\-])+$/g); + } + helper.extractImageAndRegistryFromRepository = function(repository) { var slashCount = _.countBy(repository)['/']; var registry = null; diff --git a/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.html b/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.html index 8745cc2c9..b076acffd 100644 --- a/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.html +++ b/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.html @@ -8,7 +8,7 @@
@@ -22,16 +22,12 @@ - - + @@ -59,7 +55,6 @@ Items per page +
- Tags count - - -
{{ item.TagsCount }}
Loading...
@@ -32,25 +31,13 @@ - - - + + + - - + - - - + + - - + +
Os/Architecture - - Image ID - - - - - - Size - - - - ActionsImage IDCompressed sizeActions
@@ -60,15 +47,16 @@ {{ item.Name }} {{ item.Os }}/{{ item.Architecture }}{{ item.ImageId | truncate:40 }}{{ item.ImageId | trimshasum }} {{ item.Size | humansize }} + Retag + @@ -76,11 +64,11 @@
Loading...
Loading...
No tag available.
No tag available.
@@ -96,7 +84,6 @@ Items per page
@@ -58,10 +85,10 @@ - {{ $select.selected }} + {{ $select.selected | trimshasum }} - - {{ image }} + + {{ image | trimshasum }} @@ -83,6 +110,10 @@
+ order-by="Name" remove-action="removeTags" retag-action="retagAction" + advanced-features-available="short.Images.length > 0" + pagination-action="paginationAction" + loading="state.loading"> +
\ No newline at end of file diff --git a/app/extensions/registry-management/views/repositories/edit/registryRepositoryController.js b/app/extensions/registry-management/views/repositories/edit/registryRepositoryController.js index 03f0b961d..b37856c54 100644 --- a/app/extensions/registry-management/views/repositories/edit/registryRepositoryController.js +++ b/app/extensions/registry-management/views/repositories/edit/registryRepositoryController.js @@ -1,105 +1,335 @@ import _ from 'lodash-es'; +import { RepositoryTagViewModel, RepositoryShortTag } from '../../../models/repositoryTag'; angular.module('portainer.app') - .controller('RegistryRepositoryController', ['$q', '$scope', '$transition$', '$state', 'RegistryV2Service', 'RegistryService', 'ModalService', 'Notifications', - function ($q, $scope, $transition$, $state, RegistryV2Service, RegistryService, ModalService, Notifications) { + .controller('RegistryRepositoryController', ['$q', '$async', '$scope', '$uibModal', '$interval', '$transition$', '$state', 'RegistryV2Service', 'RegistryService', 'ModalService', 'Notifications', 'ImageHelper', + function ($q, $async, $scope, $uibModal, $interval, $transition$, $state, RegistryV2Service, RegistryService, ModalService, Notifications, ImageHelper) { $scope.state = { - actionInProgress: false + actionInProgress: false, + loading: false, + tagsRetrieval: { + auto: true, + running: false, + limit: 100, + progression: 0, + elapsedTime: 0, + asyncGenerator: null, + clock: null + }, + tagsRetag: { + running: false, + progression: 0, + elapsedTime: 0, + asyncGenerator: null, + clock: null + }, + tagsDelete: { + running: false, + progression: 0, + elapsedTime: 0, + asyncGenerator: null, + clock: null + }, }; $scope.formValues = { - Tag: '' + Tag: '' // new tag name on add feature + }; + $scope.tags = []; // RepositoryTagViewModel (for datatable) + $scope.short = { + Tags: [], // RepositoryShortTag + Images: [] // strings extracted from short.Tags }; - $scope.tags = []; $scope.repository = { - Name: [], - Tags: [], - Images: [] + Name: '', + Tags: [], // string list }; - $scope.$watch('tags.length', function () { - var images = $scope.tags.map(function (item) { - return item.ImageId; + function toSeconds(time) { + return time / 1000; + } + function toPercent(progress, total) { + return (progress / total * 100).toFixed(); + } + + function openModal(resolve) { + return $uibModal.open({ + component: 'progressionModal', + backdrop: 'static', + keyboard: false, + resolve: resolve }); - $scope.repository.Images = _.uniq(images); - }); + } + + $scope.paginationAction = function (tags) { + $scope.state.loading = true; + RegistryV2Service.getTagsDetails($scope.registryId, $scope.repository.Name, tags) + .then(function success(data) { + for (var i = 0; i < data.length; i++) { + var idx = _.findIndex($scope.tags, {'Name': data[i].Name}); + if (idx !== -1) { + $scope.tags[idx] = data[i]; + } + } + $scope.state.loading = false; + }).catch(function error(err) { + Notifications.error('Failure', err, 'Unable to retrieve tags details'); + }); + }; + + /** + * RETRIEVAL SECTION + */ + function updateRetrievalClock(startTime) { + $scope.state.tagsRetrieval.elapsedTime = toSeconds(Date.now() - startTime); + } + + function createRetrieveAsyncGenerator() { + $scope.state.tagsRetrieval.asyncGenerator = + RegistryV2Service.shortTagsWithProgress($scope.registryId, $scope.repository.Name, $scope.repository.Tags); + } + + function resetTagsRetrievalState() { + $scope.state.tagsRetrieval.running = false; + $scope.state.tagsRetrieval.progression = 0; + $scope.state.tagsRetrieval.elapsedTime = 0; + $scope.state.tagsRetrieval.clock = null; + } + + function computeImages() { + const images = _.map($scope.short.Tags, 'ImageId'); + $scope.short.Images = _.without(_.uniq(images), ''); + } + + $scope.startStopRetrieval = function () { + if ($scope.state.tagsRetrieval.running) { + $scope.state.tagsRetrieval.asyncGenerator.return(); + $interval.cancel($scope.state.tagsRetrieval.clock); + } else { + retrieveTags().then(() => { + createRetrieveAsyncGenerator(); + if ($scope.short.Tags.length === 0) { + resetTagsRetrievalState(); + } else { + computeImages(); + } + }); + } + }; + + function retrieveTags() { + return $async(retrieveTagsAsync); + } + + async function retrieveTagsAsync() { + $scope.state.tagsRetrieval.running = true; + const startTime = Date.now(); + $scope.state.tagsRetrieval.clock = $interval(updateRetrievalClock, 1000, 0, true, startTime); + for await (const partialResult of $scope.state.tagsRetrieval.asyncGenerator) { + if (typeof partialResult === 'number') { + $scope.state.tagsRetrieval.progression = toPercent(partialResult, $scope.repository.Tags.length); + } else { + $scope.short.Tags = _.sortBy(partialResult, 'Name'); + } + } + $scope.state.tagsRetrieval.running = false; + $interval.cancel($scope.state.tagsRetrieval.clock); + } + /** + * !END RETRIEVAL SECTION + */ + + /** + * ADD TAG SECTION + */ + + async function addTagAsync() { + try { + $scope.state.actionInProgress = true; + if (!ImageHelper.isValidTag($scope.formValues.Tag)) { + throw {msg: 'Invalid tag pattern, see info for more details on format.'} + } + const tag = $scope.short.Tags.find((item) => item.ImageId === $scope.formValues.SelectedImage); + const manifest = tag.ManifestV2; + await RegistryV2Service.addTag($scope.registryId, $scope.repository.Name, {tag: $scope.formValues.Tag, manifest: manifest}) + + Notifications.success('Success', 'Tag successfully added'); + $scope.short.Tags.push(new RepositoryShortTag($scope.formValues.Tag, tag.ImageId, tag.ImageDigest, tag.ManifestV2)); + + await loadRepositoryDetails(); + $scope.formValues.Tag = ''; + delete $scope.formValues.SelectedImage; + } catch (err) { + Notifications.error('Failure', err, 'Unable to add tag'); + } finally { + $scope.state.actionInProgress = false; + } + } $scope.addTag = function () { - var manifest = $scope.tags.find(function (item) { - return item.ImageId === $scope.formValues.SelectedImage; - }).ManifestV2; - RegistryV2Service.addTag($scope.registryId, $scope.repository.Name, $scope.formValues.Tag, manifest) - .then(function success() { - Notifications.success('Success', 'Tag successfully added'); - $state.reload(); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to add tag'); - }); + return $async(addTagAsync); }; + /** + * !END ADD TAG SECTION + */ - $scope.retagAction = function (tag) { - RegistryV2Service.deleteManifest($scope.registryId, $scope.repository.Name, tag.Digest) - .then(function success() { - var promises = []; - var tagsToAdd = $scope.tags.filter(function (item) { - return item.Digest === tag.Digest; - }); - tagsToAdd.map(function (item) { - var tagValue = item.Modified && item.Name !== item.NewName ? item.NewName : item.Name; - promises.push(RegistryV2Service.addTag($scope.registryId, $scope.repository.Name, tagValue, item.ManifestV2)); - }); - return $q.all(promises); - }) - .then(function success() { - Notifications.success('Success', 'Tag successfully modified'); - $state.reload(); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to modify tag'); - tag.Modified = false; - tag.NewValue = tag.Value; + /** + * RETAG SECTION + */ + function updateRetagClock(startTime) { + $scope.state.tagsRetag.elapsedTime = toSeconds(Date.now() - startTime); + } + + function createRetagAsyncGenerator(modifiedTags, modifiedDigests, impactedTags) { + $scope.state.tagsRetag.asyncGenerator = + RegistryV2Service.retagWithProgress($scope.registryId, $scope.repository.Name, modifiedTags, modifiedDigests, impactedTags); + } + + async function retagActionAsync() { + let modal = null; + try { + $scope.state.tagsRetag.running = true; + + const modifiedTags = _.filter($scope.tags, (item) => item.Modified === true); + for (const tag of modifiedTags) { + if (!ImageHelper.isValidTag(tag.NewName)) { + throw {msg: 'Invalid tag pattern, see info for more details on format.'} + } + } + modal = await openModal({ + message: () => 'Retag is in progress! Closing your browser or refreshing the page while this operation is in progress will result in loss of tags.', + progressLabel: () => 'Retag progress', + context: () => $scope.state.tagsRetag }); - }; + const modifiedDigests = _.uniq(_.map(modifiedTags, 'ImageDigest')); + const impactedTags = _.filter($scope.short.Tags, (item) => _.includes(modifiedDigests, item.ImageDigest)); - $scope.removeTags = function (selectedItems) { + const totalOps = modifiedDigests.length + impactedTags.length; + + createRetagAsyncGenerator(modifiedTags, modifiedDigests, impactedTags); + + const startTime = Date.now(); + $scope.state.tagsRetag.clock = $interval(updateRetagClock, 1000, 0, true, startTime); + for await (const partialResult of $scope.state.tagsRetag.asyncGenerator) { + if (typeof partialResult === 'number') { + $scope.state.tagsRetag.progression = toPercent(partialResult, totalOps); + } + } + + _.map(modifiedTags, (item) => { + const idx = _.findIndex($scope.short.Tags, (i) => i.Name === item.Name); + $scope.short.Tags[idx].Name = item.NewName; + }); + + Notifications.success('Success', 'Tags successfully renamed'); + + await loadRepositoryDetails(); + } catch (err) { + Notifications.error('Failure', err, 'Unable to rename tags'); + } finally { + $interval.cancel($scope.state.tagsRetag.clock); + $scope.state.tagsRetag.running = false; + if (modal) { + modal.close(); + } + } + } + + $scope.retagAction = function() { + return $async(retagActionAsync); + } + /** + * !END RETAG SECTION + */ + + /** + * REMOVE TAGS SECTION + */ + + function updateDeleteClock(startTime) { + $scope.state.tagsDelete.elapsedTime = toSeconds(Date.now() - startTime); + } + + function createDeleteAsyncGenerator(modifiedDigests, impactedTags) { + $scope.state.tagsDelete.asyncGenerator = + RegistryV2Service.deleteTagsWithProgress($scope.registryId, $scope.repository.Name, modifiedDigests, impactedTags); + } + + async function removeTagsAsync(selectedTags) { + let modal = null; + try { + $scope.state.tagsDelete.running = true; + modal = await openModal({ + message: () => 'Tag delete is in progress! Closing your browser or refreshing the page while this operation is in progress will result in loss of tags.', + progressLabel: () => 'Deletion progress', + context: () => $scope.state.tagsDelete + }); + + const deletedTagNames = _.map(selectedTags, 'Name'); + const deletedShortTags = _.filter($scope.short.Tags, (item) => _.includes(deletedTagNames, item.Name)); + const modifiedDigests = _.uniq(_.map(deletedShortTags, 'ImageDigest')); + const impactedTags = _.filter($scope.short.Tags, (item) => _.includes(modifiedDigests, item.ImageDigest)); + const tagsToKeep = _.without(impactedTags, ...deletedShortTags); + + const totalOps = modifiedDigests.length + tagsToKeep.length; + + createDeleteAsyncGenerator(modifiedDigests, tagsToKeep); + + const startTime = Date.now(); + $scope.state.tagsDelete.clock = $interval(updateDeleteClock, 1000, 0, true, startTime); + for await (const partialResult of $scope.state.tagsDelete.asyncGenerator) { + if (typeof partialResult === 'number') { + $scope.state.tagsDelete.progression = toPercent(partialResult, totalOps); + } + } + + _.pull($scope.short.Tags, ...deletedShortTags); + $scope.short.Images = _.map(_.uniqBy($scope.short.Tags, 'ImageId'), 'ImageId'); + + Notifications.success('Success', 'Tags successfully deleted'); + + if ($scope.short.Tags.length === 0) { + $state.go('portainer.registries.registry.repositories', {id: $scope.registryId}, {reload: true}); + } + await loadRepositoryDetails(); + } catch (err) { + Notifications.error('Failure', err, 'Unable to delete tags'); + } finally { + $interval.cancel($scope.state.tagsDelete.clock); + $scope.state.tagsDelete.running = false; + modal.close(); + } + } + + $scope.removeTags = function(selectedItems) { ModalService.confirmDeletion( 'Are you sure you want to remove the selected tags ?', - function onConfirm(confirmed) { + (confirmed) => { if (!confirmed) { return; } - var promises = []; - var uniqItems = _.uniqBy(selectedItems, 'Digest'); - uniqItems.map(function (item) { - promises.push(RegistryV2Service.deleteManifest($scope.registryId, $scope.repository.Name, item.Digest)); - }); - $q.all(promises) - .then(function success() { - var promises = []; - var tagsToReupload = _.differenceBy($scope.tags, selectedItems, 'Name'); - tagsToReupload.map(function (item) { - promises.push(RegistryV2Service.addTag($scope.registryId, $scope.repository.Name, item.Name, item.ManifestV2)); - }); - return $q.all(promises); - }) - .then(function success(data) { - Notifications.success('Success', 'Tags successfully deleted'); - if (data.length === 0) { - $state.go('portainer.registries.registry.repositories', { - id: $scope.registryId - }, { - reload: true - }); - } else { - $state.reload(); - } - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to delete tags'); - }); + return $async(removeTagsAsync, selectedItems); }); - }; + } + /** + * !END REMOVE TAGS SECTION + */ + + /** + * REMOVE REPOSITORY SECTION + */ + async function removeRepositoryAsync() { + try { + const digests = _.uniqBy($scope.short.Tags, 'ImageDigest'); + const promises = []; + _.map(digests, (item) => promises.push(RegistryV2Service.deleteManifest($scope.registryId, $scope.repository.Name, item.ImageDigest))); + await Promise.all(promises); + Notifications.success('Success', 'Repository sucessfully removed'); + $state.go('portainer.registries.registry.repositories', {id: $scope.registryId}, {reload: true}); + } catch (err) { + Notifications.error('Failure', err, 'Unable to delete repository'); + } + } $scope.removeRepository = function () { ModalService.confirmDeletion( @@ -108,53 +338,81 @@ angular.module('portainer.app') if (!confirmed) { return; } - var promises = []; - var uniqItems = _.uniqBy($scope.tags, 'Digest'); - uniqItems.map(function (item) { - promises.push(RegistryV2Service.deleteManifest($scope.registryId, $scope.repository.Name, item.Digest)); - }); - $q.all(promises) - .then(function success() { - Notifications.success('Success', 'Repository sucessfully removed'); - $state.go('portainer.registries.registry.repositories', { - id: $scope.registryId - }, { - reload: true - }); - }).catch(function error(err) { - Notifications.error('Failure', err, 'Unable to delete repository'); - }); + return $async(removeRepositoryAsync); } ); }; + /** + * !END REMOVE REPOSITORY SECTION + */ - function initView() { - var registryId = $scope.registryId = $transition$.params().id; - var repository = $scope.repository.Name = $transition$.params().repository; - $q.all({ - registry: RegistryService.registry(registryId), - tags: RegistryV2Service.tags(registryId, repository) - }) - .then(function success(data) { - $scope.registry = data.registry; - $scope.repository.Tags = [].concat(data.tags || []); - $scope.tags = []; - for (var i = 0; i < $scope.repository.Tags.length; i++) { - var tag = data.tags[i]; - RegistryV2Service.tag(registryId, repository, tag) - .then(function success(data) { - $scope.tags.push(data); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to retrieve tag information'); - }); - } - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to retrieve repository information'); - }); + /** + * INIT SECTION + */ + async function loadRepositoryDetails() { + try { + const registryId = $scope.registryId; + const repository = $scope.repository.Name; + const tags = await RegistryV2Service.tags(registryId, repository); + $scope.tags = []; + $scope.repository.Tags = []; + $scope.repository.Tags = _.sortBy(_.concat($scope.repository.Tags, _.without(tags.tags, null))); + _.map($scope.repository.Tags, (item) => $scope.tags.push(new RepositoryTagViewModel(item))); + } catch (err) { + Notifications.error('Failure', err, 'Unable to retrieve tags details'); + } } - initView(); + async function initView() { + try { + const registryId = $scope.registryId = $transition$.params().id; + $scope.repository.Name = $transition$.params().repository; + $scope.state.loading = true; + + $scope.registry = await RegistryService.registry(registryId); + await loadRepositoryDetails(); + if ($scope.repository.Tags.length > $scope.state.tagsRetrieval.limit) { + $scope.state.tagsRetrieval.auto = false; + } + createRetrieveAsyncGenerator(); + } catch (err) { + Notifications.error('Failure', err, 'Unable to retrieve repository information'); + } finally { + $scope.state.loading = false; + } + } + + $scope.$on('$destroy', () => { + if ($scope.state.tagsRetrieval.asyncGenerator) { + $scope.state.tagsRetrieval.asyncGenerator.return(); + } + if ($scope.state.tagsRetrieval.clock) { + $interval.cancel($scope.state.tagsRetrieval.clock); + } + if ($scope.state.tagsRetag.asyncGenerator) { + $scope.state.tagsRetag.asyncGenerator.return(); + } + if ($scope.state.tagsRetag.clock) { + $interval.cancel($scope.state.tagsRetag.clock); + } + if ($scope.state.tagsDelete.asyncGenerator) { + $scope.state.tagsDelete.asyncGenerator.return(); + } + if ($scope.state.tagsDelete.clock) { + $interval.cancel($scope.state.tagsDelete.clock); + } + }); + + this.$onInit = function() { + return $async(initView) + .then(() => { + if ($scope.state.tagsRetrieval.auto) { + $scope.startStopRetrieval(); + } + }); + }; + /** + * !END INIT SECTION + */ } - ]); + ]); \ No newline at end of file diff --git a/app/extensions/registry-management/views/repositories/registryRepositories.html b/app/extensions/registry-management/views/repositories/registryRepositories.html index 5e3210ca7..ec145445a 100644 --- a/app/extensions/registry-management/views/repositories/registryRepositories.html +++ b/app/extensions/registry-management/views/repositories/registryRepositories.html @@ -5,7 +5,7 @@ - Registries > {{ registry.Name }}{{ registry.Name}} > Repositories + Registries > {{ registry.Name }}{{ registry.Name}} > Repositories @@ -31,7 +31,7 @@ + order-by="Name" pagination-action="paginationAction" loading="state.loading"> diff --git a/app/extensions/registry-management/views/repositories/registryRepositoriesController.js b/app/extensions/registry-management/views/repositories/registryRepositoriesController.js index 0ff931eff..eace4f9f3 100644 --- a/app/extensions/registry-management/views/repositories/registryRepositoriesController.js +++ b/app/extensions/registry-management/views/repositories/registryRepositoriesController.js @@ -1,26 +1,49 @@ +import _ from 'lodash-es'; + angular.module('portainer.extensions.registrymanagement') .controller('RegistryRepositoriesController', ['$transition$', '$scope', 'RegistryService', 'RegistryV2Service', 'Notifications', 'Authentication', function ($transition$, $scope, RegistryService, RegistryV2Service, Notifications, Authentication) { $scope.state = { - displayInvalidConfigurationMessage: false + displayInvalidConfigurationMessage: false, + loading: false + }; + + $scope.paginationAction = function (repositories) { + $scope.state.loading = true; + RegistryV2Service.getRepositoriesDetails($scope.state.registryId, repositories) + .then(function success(data) { + for (var i = 0; i < data.length; i++) { + var idx = _.findIndex($scope.repositories, {'Name': data[i].Name}); + if (idx !== -1) { + if (data[i].TagsCount === 0) { + $scope.repositories.splice(idx, 1); + } else { + $scope.repositories[idx].TagsCount = data[i].TagsCount; + } + } + } + $scope.state.loading = false; + }).catch(function error(err) { + Notifications.error('Failure', err, 'Unable to retrieve repositories details'); + }); }; function initView() { - var registryId = $transition$.params().id; + $scope.state.registryId = $transition$.params().id; var authenticationEnabled = $scope.applicationState.application.authentication; if (authenticationEnabled) { $scope.isAdmin = Authentication.isAdmin(); } - RegistryService.registry(registryId) + RegistryService.registry($scope.state.registryId) .then(function success(data) { $scope.registry = data; - RegistryV2Service.ping(registryId, false) + RegistryV2Service.ping($scope.state.registryId, false) .then(function success() { - return RegistryV2Service.repositories(registryId); + return RegistryV2Service.catalog($scope.state.registryId); }) .then(function success(data) { $scope.repositories = data; diff --git a/app/portainer/components/datatables/genericDatatableController.js b/app/portainer/components/datatables/genericDatatableController.js index 4658c03ea..7ba8d75ce 100644 --- a/app/portainer/components/datatables/genericDatatableController.js +++ b/app/portainer/components/datatables/genericDatatableController.js @@ -27,6 +27,11 @@ function ($interval, PaginationService, DatatableService, PAGINATION_MAX_ITEMS) refreshRate: '30' } } + this.resetSelectionState = function() { + this.state.selectAll = false; + this.state.selectedItems = []; + _.map(this.state.filteredDataSet, (item) => item.Checked = false); + }; this.onTextFilterChange = function() { DatatableService.setDataTableTextFilters(this.tableKey, this.state.textFilter); diff --git a/app/portainer/services/modalService.js b/app/portainer/services/modalService.js index 4b896859d..9fa9cf1bc 100644 --- a/app/portainer/services/modalService.js +++ b/app/portainer/services/modalService.js @@ -98,6 +98,20 @@ angular.module('portainer.app') }); }; + service.cancelRegistryRepositoryAction = function(callback) { + service.confirm({ + title: 'Are you sure?', + message: 'WARNING: interrupting this operation before it has finished will result in the loss of all tags. Are you sure you want to do this?', + buttons: { + confirm: { + label: 'Stop', + className: 'btn-danger' + } + }, + callback: callback + }); + }; + service.confirmDeletion = function(message, callback) { message = $sanitize(message); service.confirm({ diff --git a/assets/css/app.css b/assets/css/app.css index 543eed1f7..f51d3576a 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -834,6 +834,26 @@ ul.sidebar .sidebar-list .sidebar-sublist a.active { margin: 20px auto 10px auto; } +.modal { + text-align: center; + padding: 0!important; +} + +.modal::before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; + margin-right: -4px; +} + +.modal-dialog { + display: inline-block; + text-align: left; + vertical-align: middle; +} + + /*bootbox override*/ .modal-open { padding-right: 0 !important; diff --git a/package.json b/package.json index a1713a5f1..aee21f9ac 100644 --- a/package.json +++ b/package.json @@ -95,8 +95,8 @@ "clean-webpack-plugin": "^0.1.19", "css-loader": "^1.0.0", "cssnano": "^3.10.0", - "eslint": "^3.19.0", - "eslint-loader": "^2.1.1", + "eslint": "5.16.0", + "eslint-loader": "^2.1.2", "file-loader": "^1.1.11", "grunt": "~0.4.0", "grunt-cli": "^1.2.0", diff --git a/yarn.lock b/yarn.lock index d5911ee68..94f426889 100644 --- a/yarn.lock +++ b/yarn.lock @@ -830,6 +830,11 @@ acorn-jsx@^3.0.0: dependencies: acorn "^3.0.4" +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" @@ -845,6 +850,11 @@ acorn@^5.2.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" integrity sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w== +acorn@^6.0.7: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== + active-x-obfuscator@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/active-x-obfuscator/-/active-x-obfuscator-0.0.1.tgz#089b89b37145ff1d9ec74af6530be5526cae1f1a" @@ -885,6 +895,16 @@ ajv@^6.1.0: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.9.1: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -1031,6 +1051,11 @@ ansi-escapes@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" @@ -1046,6 +1071,11 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -1058,7 +1088,7 @@ ansi-styles@^3.1.0: dependencies: color-convert "^1.9.0" -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1254,6 +1284,11 @@ ast-types@0.9.6: resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk= +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + async-done@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/async-done/-/async-done-0.4.0.tgz#ab8053f5f62290f8bfc58f37cd9b73070b3307b9" @@ -1954,6 +1989,11 @@ callsites@^0.2.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + camel-case@3.0.x: version "3.0.0" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" @@ -2063,6 +2103,15 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^2.1.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" @@ -2072,6 +2121,11 @@ chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + chart.js@~2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.6.0.tgz#308f9a4b0bfed5a154c14f5deb1d9470d22abe71" @@ -2210,6 +2264,13 @@ cli-cursor@^1.0.1: dependencies: restore-cursor "^1.0.1" +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -3022,6 +3083,13 @@ debug@^3.1.0, debug@^3.2.5: dependencies: ms "^2.1.1" +debug@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + debug@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" @@ -3368,6 +3436,13 @@ doctrine@^2.0.0: dependencies: esutils "^2.0.2" +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + dom-converter@~0.2: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" @@ -3576,6 +3651,11 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -3769,10 +3849,10 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-loader@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.1.1.tgz#2a9251523652430bfdd643efdb0afc1a2a89546a" - integrity sha512-1GrJFfSevQdYpoDzx8mEE2TDWsb/zmFuY09l6hURg1AeFIKQOvZ+vH0UPjzmd1CZIbfTV5HUkMeBmFiDBkgIsQ== +eslint-loader@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.1.2.tgz#453542a1230d6ffac90e4e7cb9cadba9d851be68" + integrity sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg== dependencies: loader-fs-cache "^1.0.0" loader-utils "^1.0.2" @@ -3788,7 +3868,67 @@ eslint-scope@^4.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint@^3.0.0, eslint@^3.19.0: +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@5.16.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.3" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.13.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" + +eslint@^3.0.0: version "3.19.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" integrity sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw= @@ -3837,6 +3977,15 @@ espree@^3.4.0: acorn "^5.2.1" acorn-jsx "^3.0.0" +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + esprima@1.0.x, "esprima@~ 1.0.2", esprima@~1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" @@ -3864,6 +4013,13 @@ esquery@^1.0.0: dependencies: estraverse "^4.0.0" +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + esrecurse@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" @@ -4157,6 +4313,15 @@ extend@^3.0.0: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= +external-editor@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -4245,6 +4410,13 @@ figures@^1.0.1, figures@^1.3.5: escape-string-regexp "^1.0.5" object-assign "^4.1.0" +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" @@ -4253,6 +4425,13 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + file-loader@^1.1.11: version "1.1.11" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" @@ -4519,6 +4698,20 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== + flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" @@ -4652,6 +4845,11 @@ function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -4873,6 +5071,18 @@ glob@^7.0.5, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.3: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@~3.1.21: version "3.1.21" resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" @@ -4910,6 +5120,11 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.8.0.tgz#c1ef45ee9bed6badf0663c5cb90e8d1adec1321d" integrity sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA== +globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^9.14.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -5772,7 +5987,7 @@ iconv-lite@0.4.23: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.4.4: +iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -5818,6 +6033,11 @@ ignore@^3.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" integrity sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA== +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + image-webpack-loader@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/image-webpack-loader/-/image-webpack-loader-4.5.0.tgz#ab0da4302a58f2bf7a2eb62f166c82c6495efe8d" @@ -5906,6 +6126,14 @@ import-cwd@^2.0.0: dependencies: import-from "^2.1.0" +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-from@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" @@ -5995,6 +6223,25 @@ inquirer@^0.12.0: strip-ansi "^3.0.0" through "^2.3.6" +inquirer@^6.2.2: + version "6.4.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.4.1.tgz#7bd9e5ab0567cd23b41b0180b68e0cfa82fc3c0b" + integrity sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.11" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + internal-ip@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-3.0.1.tgz#df5c99876e1d2eb2ea2d74f520e3f669a00ece27" @@ -6351,6 +6598,11 @@ is-primitive@^2.0.0: resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" @@ -6547,7 +6799,7 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@^3.12.0, js-yaml@^3.3.0, js-yaml@^3.5.1, js-yaml@^3.9.0, js-yaml@~3.13.1: +js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.3.0, js-yaml@^3.5.1, js-yaml@^3.9.0, js-yaml@~3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -6610,6 +6862,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" @@ -7064,7 +7321,7 @@ lodash@^4.17.10: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== -lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.0, lodash@~4.17.11: +lodash@^4.17.11, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.0, lodash@~4.17.11: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -7650,6 +7907,11 @@ mute-stream@0.0.5: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA= +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + nan@^2.9.2: version "2.11.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" @@ -8087,6 +8349,13 @@ onetime@^1.0.0: resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + opn@^5.1.0: version "5.4.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" @@ -8195,7 +8464,7 @@ os-locale@^3.0.0: lcid "^2.0.0" mem "^4.0.0" -os-tmpdir@^1.0.0: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= @@ -8347,6 +8616,13 @@ param-case@2.1.x: dependencies: no-case "^2.2.0" +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-asn1@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" @@ -8439,7 +8715,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -9001,6 +9277,11 @@ progress@^1.1.8: resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -9403,6 +9684,11 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + regexpu-core@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" @@ -9579,6 +9865,11 @@ resolve-from@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-pkg@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-0.1.0.tgz#02cc993410e2936962bd97166a1b077da9725531" @@ -9631,6 +9922,14 @@ restore-cursor@^1.0.1: exit-hook "^1.0.0" onetime "^1.0.0" +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -9643,6 +9942,13 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + rimraf@2.x.x, rimraf@^2.2.8, rimraf@~2.2.8: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" @@ -9682,6 +9988,13 @@ run-async@^0.1.0: dependencies: once "^1.3.0" +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" @@ -9694,6 +10007,13 @@ rx-lite@^3.1.2: resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= +rxjs@^6.4.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" + integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -9789,6 +10109,11 @@ semver@^5.4.1, semver@^5.6.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== +semver@^5.5.1: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + send@0.13.2: version "0.13.2" resolved "https://registry.yarnpkg.com/send/-/send-0.13.2.tgz#765e7607c8055452bba6f0b052595350986036de" @@ -9975,7 +10300,7 @@ sigmund@~1.0.0: resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= -signal-exit@^3.0.0: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= @@ -9990,6 +10315,15 @@ slice-ansi@0.0.4: resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -10347,7 +10681,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -10355,6 +10689,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + string_decoder@^1.0.0, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -10393,6 +10736,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-bom-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" @@ -10457,7 +10807,7 @@ strip-json-comments@1.0.x: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= -strip-json-comments@~2.0.1: +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -10555,6 +10905,16 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" +table@^5.2.3: + version "5.4.1" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.1.tgz#0691ae2ebe8259858efb63e550b6d5f9300171e8" + integrity sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w== + dependencies: + ajv "^6.9.1" + lodash "^4.17.11" + slice-ansi "^2.1.0" + string-width "^3.0.0" + tapable@^1.0.0, tapable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" @@ -10630,7 +10990,7 @@ terser@^3.8.1: source-map "~0.6.1" source-map-support "~0.5.6" -text-table@~0.2.0: +text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= @@ -10731,6 +11091,13 @@ tinycolor@0.x: resolved "https://registry.yarnpkg.com/tinycolor/-/tinycolor-0.0.1.tgz#320b5a52d83abb5978d81a3e887d4aefb15a6164" integrity sha1-MgtaUtg6u1l42Bo+iH1K77FaYWQ= +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + to-absolute-glob@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" @@ -11618,6 +11985,13 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"