From 052d53a3a3f770bdfc03501ffed328fdfd761106 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 21 May 2020 16:06:56 +0100 Subject: [PATCH 01/82] WIP --- .../edit-autoscaler-credential.component.ts | 1 - .../cloud-foundry/src/cf-entity-generator.ts | 5 + .../cloud-foundry/src/cloud-foundry.module.ts | 2 +- .../application-wall.component.ts | 4 +- .../application-tabs-base.component.ts | 4 +- .../tabs/build-tab/build-tab.component.ts | 10 +- .../applications/applications.module.ts | 4 +- .../deploy-application-steps.types.ts | 5 +- .../src/features/cloud-foundry/cf.helpers.ts | 15 +- .../cli-info-cloud-foundry.component.ts | 9 +- .../cloud-foundry-tabs-base.component.ts | 6 +- .../cloud-foundry/cloud-foundry.module.ts | 4 +- .../edit-organization-step.component.html | 7 +- .../quota-definition.component.ts | 4 +- .../space-quota-definition.component.ts | 4 +- ...dry-organization-space-quotas.component.ts | 4 +- ...d-foundry-organization-spaces.component.ts | 4 +- .../cloud-foundry-space-summary.component.ts | 6 +- .../cloud-foundry-space-users.component.ts | 4 +- ...-foundry-organization-summary.component.ts | 8 +- ...ud-foundry-organization-users.component.ts | 4 +- .../cloud-foundry-organizations.component.ts | 4 +- .../cloud-foundry-quotas.component.ts | 4 +- .../user-invites/user-invite.service.ts | 4 +- .../users/manage-users/cf-roles.service.ts | 4 +- .../manage-users-set-usernames.component.ts | 7 +- .../remove-user/remove-user.component.ts | 6 +- .../service-catalog/service-catalog.module.ts | 4 + .../service-tabs-base.component.ts | 6 +- .../services-wall/services-wall.component.ts | 6 +- .../src/features/services/services.module.ts | 4 + .../src/shared/cf-shared.module.ts | 2 + .../cf-role-checkbox.component.ts | 4 +- .../create-application-step1.component.ts | 4 +- .../cf-app-routes-list-config-base.ts | 4 +- .../app-service-binding-card.component.ts | 6 +- ...app-service-binding-list-config.service.ts | 8 +- .../cf-org-card/cf-org-card.component.ts | 6 +- .../cf-quotas-list-config.service.ts | 6 +- .../cf-routes-list-config.service.ts | 4 +- .../cf-service-instances-list-config.base.ts | 10 +- .../cf-user-service-instances-list-config.ts | 10 +- .../cf-space-quotas-list-config.service.ts | 6 +- .../cf-space-routes-list-config.service.ts | 4 +- .../cf-space-card/cf-space-card.component.ts | 6 +- .../cf-org-permission-cell.component.ts | 4 +- .../cf-space-permission-cell.component.ts | 4 +- .../cf-users/cf-user-list-config.service.ts | 4 +- .../service-instance-card.component.ts | 8 +- ...rovided-service-instance-card.component.ts | 8 +- .../src/store/cloud-foundry.store.module.ts | 4 + .../current-user-roles-changed.reducers.ts | 18 +- .../cf-current-user-role.selectors.ts | 17 +- .../cf-user-permissions-checkers.ts | 477 ++++++++++++++++++ .../packages/core/src/core/core.module.ts | 6 +- .../core/current-user-permissions.checker.ts | 367 ++++---------- .../core/current-user-permissions.config.ts | 150 +----- .../core/current-user-permissions.service.ts | 239 +++++---- .../endpoints-page.component.ts | 4 +- .../edit-profile-info.component.ts | 4 +- .../endpoint-card/endpoint-card.component.ts | 4 +- .../endpoint/endpoint-list.helpers.ts | 6 +- .../src/shared/user-permission.directive.ts | 6 +- .../src/entity-catalog/entity-catalog.ts | 9 + .../entity-catalog/entity-catalog.types.ts | 3 + .../current-user-role-session.reducer.ts | 12 +- .../current-user-roles.reducer.ts | 4 + .../selectors/current-user-role.selectors.ts | 39 +- .../packages/store/src/types/auth.types.ts | 11 +- .../src/types/current-user-roles.types.ts | 4 +- .../store/src/types/endpoint.types.ts | 4 +- 71 files changed, 971 insertions(+), 688 deletions(-) create mode 100644 src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts diff --git a/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-credential/edit-autoscaler-credential.component.ts b/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-credential/edit-autoscaler-credential.component.ts index b8446220fd..a0bb4d7364 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-credential/edit-autoscaler-credential.component.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-credential/edit-autoscaler-credential.component.ts @@ -114,7 +114,6 @@ export class EditAutoscalerCredentialComponent implements OnInit, OnDestroy { ); this.appAutoscalerCredential$ = updateAppAutoscalerCredentialService.entityObs$.pipe( filter(({ entity, entityRequestInfo }) => { - console.log(entity, entityRequestInfo) return entityRequestInfo && !entityRequestInfo.creating && !entityRequestInfo.deleting.busy; }), map(({ entity }) => entity ? entity.entity : null), diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts index 26a24ca124..ec6dcc7c40 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts @@ -364,6 +364,11 @@ export function generateCFEntities(): StratosBaseCatalogEntity[] { map(([beValue, userOverride]) => userOverride || beValue || entityTypeDefault) ); }, + }, + userRolesInit: () => of(false), // TODO: RC implement + userRolesReducer: () => { // TODO: RC implement + console.log('HELLO WORLD'); + return null; } }; return [ diff --git a/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts b/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts index 40bc688274..1b0d5ebf3f 100644 --- a/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts +++ b/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts @@ -41,7 +41,7 @@ import { CloudFoundryStoreModule } from './store/cloud-foundry.store.module'; CloudFoundryService, ServiceActionHelperService, LongRunningCfOperationsService, - CloudFoundryUserProvidedServicesService + CloudFoundryUserProvidedServicesService, ] }) export class CloudFoundryPackageModule { } diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.ts index e1bb9ccd14..c6cfa5d7dc 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.ts @@ -6,12 +6,12 @@ import { map } from 'rxjs/operators'; import { CFAppState } from '../../../../../cloud-foundry/src/cf-app-state'; import { applicationEntityType } from '../../../../../cloud-foundry/src/cf-entity-types'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { ListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; import { CfAppConfigService } from '../../../shared/components/list/list-types/app/cf-app-config.service'; import { CfAppsDataSource } from '../../../shared/components/list/list-types/app/cf-apps-data-source'; import { CfOrgSpaceDataService, initCfOrgSpaceService } from '../../../shared/data-services/cf-org-space-service.service'; import { CloudFoundryService } from '../../../shared/data-services/cloud-foundry.service'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; @Component({ selector: 'app-application-wall', @@ -52,7 +52,7 @@ export class ApplicationWallComponent implements OnDestroy { this.cfIds$ = cloudFoundryService.cFEndpoints$.pipe( map(endpoints => endpoints.map(endpoint => endpoint.guid)), ); - this.canCreateApplication = CurrentUserPermissions.APPLICATION_CREATE; + this.canCreateApplication = CfCurrentUserPermissions.APPLICATION_CREATE; this.haveConnectedCf$ = cloudFoundryService.connectedCFEndpoints$.pipe( map(endpoints => !!endpoints && endpoints.length > 0) diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts index d5b04d1268..6d383b1520 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts @@ -6,7 +6,6 @@ import { filter, first, map, startWith, switchMap, withLatestFrom } from 'rxjs/o import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state'; import { applicationEntityType } from '../../../../../../cloud-foundry/src/cf-entity-types'; import { IAppFavMetadata } from '../../../../../../cloud-foundry/src/cf-metadata-types'; -import { CurrentUserPermissions } from '../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { EndpointsService } from '../../../../../../core/src/core/endpoints.service'; import { @@ -37,6 +36,7 @@ import { IApp, IOrganization, ISpace } from '../../../../cf-api.types'; import { CF_ENDPOINT_TYPE } from '../../../../cf-types'; import { GitSCMService, GitSCMType } from '../../../../shared/data-services/scm/scm.service'; import { ApplicationStateData } from '../../../../shared/services/application-state.service'; +import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; import { ApplicationService } from '../../application.service'; import { ApplicationPollingService } from './application-polling.service'; @@ -91,7 +91,7 @@ export class ApplicationTabsBaseComponent implements OnInit, OnDestroy { ); const appDoesNotHaveEnvVars$ = this.applicationService.appSpace$.pipe( - switchMap(space => this.currentUserPermissionsService.can(CurrentUserPermissions.APPLICATION_VIEW_ENV_VARS, + switchMap(space => this.currentUserPermissionsService.can(CfCurrentUserPermissions.APPLICATION_VIEW_ENV_VARS, this.applicationService.cfGuid, space.metadata.guid) ), map(can => !can) diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts index 68a212bce7..ae232848ae 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts @@ -7,7 +7,6 @@ import { combineLatest, delay, distinct, filter, first, map, mergeMap, startWith import { AppMetadataTypes } from '../../../../../../../../cloud-foundry/src/actions/app-metadata.actions'; import { UpdateExistingApplication } from '../../../../../../../../cloud-foundry/src/actions/application.actions'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from '../../../../../../../../core/src/core/current-user-permissions.config'; import { getFullEndpointApiUrl } from '../../../../../../../../core/src/features/endpoints/endpoint-helpers'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -19,6 +18,7 @@ import { APIResource, EntityInfo } from '../../../../../../../../store/src/types import { IAppSummary } from '../../../../../../cf-api.types'; import { cfEntityCatalog } from '../../../../../../cf-entity-catalog'; import { GitSCMService, GitSCMType } from '../../../../../../shared/data-services/scm/scm.service'; +import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { ApplicationMonitorService } from '../../../../application-monitor.service'; import { ApplicationData, ApplicationService } from '../../../../application.service'; import { DEPLOY_TYPES_IDS } from '../../../../deploy-application/deploy-application-steps.types'; @@ -53,11 +53,17 @@ const appRestageConfirmation = new ConfirmationDialogConfig( styleUrls: ['./build-tab.component.scss'], providers: [ ApplicationMonitorService, + // { + // provide: CUSTOM_USER_PERMISSION_CHECKERS, + // useFactory: (store: Store) => [new CfUserPermissionsChecker(store)], + // deps: [Store] + // }, + // CurrentUserPermissionsService ] }) export class BuildTabComponent implements OnInit { public isBusyUpdating$: Observable<{ updating: boolean }>; - public manageAppPermission = CurrentUserPermissions.APPLICATION_MANAGE; + public manageAppPermission = CfCurrentUserPermissions.APPLICATION_MANAGE; constructor( public applicationService: ApplicationService, private scmService: GitSCMService, diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/applications.module.ts b/src/frontend/packages/cloud-foundry/src/features/applications/applications.module.ts index ec68b659c6..11b02a71f7 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/applications.module.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/applications.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; import { CoreModule } from '../../../../core/src/core/core.module'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { CloudFoundrySharedModule } from '../../shared/cf-shared.module'; +import { cfCurrentUserPermissionsService } from '../../user-permissions/cf-user-permissions-checkers'; import { ApplicationDeleteComponent } from './application-delete/application-delete.component'; import { DeleteAppServiceInstancesComponent, @@ -76,7 +77,8 @@ import { SshApplicationComponent } from './ssh-application/ssh-application.compo ApplicationEnvVarsHelper, ApplicationMonitorService, DatePipe, - ApplicationDeploySourceTypes + ApplicationDeploySourceTypes, + ...cfCurrentUserPermissionsService ] }) export class ApplicationsModule { } diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-steps.types.ts b/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-steps.types.ts index eee27ea9b6..c85f474a22 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-steps.types.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-steps.types.ts @@ -5,11 +5,12 @@ import { Observable, of } from 'rxjs'; import { filter, first, map, publishReplay, refCount, switchMap } from 'rxjs/operators'; import { SourceType } from '../../../../../cloud-foundry/src/store/types/deploy-application.types'; -import { PermissionConfig, PermissionTypes } from '../../../../../core/src/core/current-user-permissions.config'; +import { PermissionConfig } from '../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; import { CFFeatureFlagTypes } from '../../../cf-api.types'; import { CFAppState } from '../../../cf-app-state'; import { cfEntityCatalog } from '../../../cf-entity-catalog'; +import { CfPermissionTypes } from '../../../user-permissions/cf-user-permissions-checkers'; export enum DEPLOY_TYPES_IDS { GITLAB = 'gitlab', @@ -107,7 +108,7 @@ export class ApplicationDeploySourceTypes { ); const canDeployWithDocker$ = this.perms.can( - new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.diego_docker), cfId + new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.diego_docker), cfId ).pipe( publishReplay(1), refCount(), diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts index f94cb8b54a..adf3ee7c1c 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts @@ -19,11 +19,7 @@ import { UserRoleInSpace, } from '../../../../cloud-foundry/src/store/types/user.types'; import { UserRoleLabels } from '../../../../cloud-foundry/src/store/types/users-roles.types'; -import { - CurrentUserPermissions, - PermissionConfig, - PermissionTypes, -} from '../../../../core/src/core/current-user-permissions.config'; +import { PermissionConfig } from '../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../core/src/core/current-user-permissions.service'; import { getIdFromRoute, pathGet } from '../../../../core/src/core/utils.service'; import { @@ -43,6 +39,7 @@ import { IServiceInstance, IUserProvidedServiceInstance } from '../../cf-api-svc import { CFFeatureFlagTypes, ISpace } from '../../cf-api.types'; import { cfEntityFactory } from '../../cf-entity-factory'; import { CFEntityConfig } from '../../cf-types'; +import { CfCurrentUserPermissions, CfPermissionTypes } from '../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfCell, ActiveRouteCfOrgSpace } from './cf-page.types'; export interface IUserRole { @@ -275,8 +272,8 @@ export function canUpdateOrgSpaceRoles( orgGuid?: string, spaceGuid?: string): Observable { return combineLatest( - perms.can(CurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, cfGuid, orgGuid), - perms.can(CurrentUserPermissions.SPACE_CHANGE_ROLES, cfGuid, orgGuid, spaceGuid) + perms.can(CfCurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, cfGuid, orgGuid), + perms.can(CfCurrentUserPermissions.SPACE_CHANGE_ROLES, cfGuid, orgGuid, spaceGuid) ).pipe( map((checks: boolean[]) => checks.some(check => check)) ); @@ -286,7 +283,7 @@ export function canUpdateOrgRoles( perms: CurrentUserPermissionsService, cfGuid: string, orgGuid?: string): Observable { - return perms.can(CurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, cfGuid, orgGuid); + return perms.can(CfCurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, cfGuid, orgGuid); } export function waitForCFPermissions(store: Store, cfGuid: string): Observable { @@ -422,7 +419,7 @@ export function someFeatureFlags( ): Observable { return waitForCFPermissions(store, cfGuid).pipe( switchMap(() => combineLatest(ff.map(flag => { - const permConfig = new PermissionConfig(PermissionTypes.FEATURE_FLAG, flag); + const permConfig = new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, flag); return userPerms.can(permConfig, cfGuid); }))), map(results => results.some(result => !!result)) diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.ts index b8c6b5c2a8..03262cd82d 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.ts @@ -5,8 +5,6 @@ import { first, map } from 'rxjs/operators'; import { CFAppState } from '../../../../../cloud-foundry/src/cf-app-state'; import { CFAppCLIInfoContext } from '../../../../../cloud-foundry/src/shared/components/cli-info/cli-info.component'; -import { CurrentUserPermissionsChecker } from '../../../../../core/src/core/current-user-permissions.checker'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { getFullEndpointApiUrl } from '../../../../../core/src/features/endpoints/endpoint-helpers'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; import { RouterNav } from '../../../../../store/src/actions/router.actions'; @@ -17,6 +15,7 @@ import { IOrganization, ISpace } from '../../../cf-api.types'; import { CloudFoundryUserProvidedServicesService, } from '../../../shared/services/cloud-foundry-user-provided-services.service'; +import { CfCurrentUserPermissions, CfUserPermissionsChecker } from '../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../cf-page.types'; import { getActiveRouteCfOrgSpaceProvider } from '../cf.helpers'; import { CloudFoundryEndpointService } from '../services/cloud-foundry-endpoint.service'; @@ -38,8 +37,8 @@ import { CloudFoundrySpaceService } from '../services/cloud-foundry-space.servic }) export class CliInfoCloudFoundryComponent implements OnInit { - permsOrgEdit = CurrentUserPermissions.ORGANIZATION_EDIT; - permsSpaceEdit = CurrentUserPermissions.SPACE_EDIT; + permsOrgEdit = CfCurrentUserPermissions.ORGANIZATION_EDIT; + permsSpaceEdit = CfCurrentUserPermissions.SPACE_EDIT; orgGuid: string; spaceGuid: string; @@ -70,7 +69,7 @@ export class CliInfoCloudFoundryComponent implements OnInit { this.breadcrumbs$ = new BehaviorSubject([]); if (activeRouteCfOrgSpace.orgGuid) { this.orgGuid = activeRouteCfOrgSpace.orgGuid; - this.spaceGuid = activeRouteCfOrgSpace.spaceGuid || CurrentUserPermissionsChecker.ALL_SPACES; + this.spaceGuid = activeRouteCfOrgSpace.spaceGuid || CfUserPermissionsChecker.ALL_SPACES; } } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts index 6d8b45c1eb..9a489ffb31 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts @@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core'; import { Observable, of as observableOf } from 'rxjs'; import { first, map, startWith } from 'rxjs/operators'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; import { EndpointsService } from '../../../../../core/src/core/endpoints.service'; import { @@ -16,6 +15,7 @@ import { environment } from '../../../../../core/src/environments/environment.pr import { IPageSideNavTab } from '../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { FavoritesConfigMapper } from '../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { UserFavoriteEndpoint } from '../../../../../store/src/types/user-favorites.types'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; import { CloudFoundryEndpointService } from '../services/cloud-foundry-endpoint.service'; @Component({ @@ -54,7 +54,7 @@ export class CloudFoundryTabsBaseComponent implements OnInit { ); const firehoseHidden$ = this.currentUserPermissionsService - .can(CurrentUserPermissions.FIREHOSE_VIEW, this.cfEndpointService.cfGuid) + .can(CfCurrentUserPermissions.FIREHOSE_VIEW, this.cfEndpointService.cfGuid) .pipe(map(visible => !visible)); const usersHidden$ = cfEndpointService.usersCount$.pipe( @@ -101,7 +101,7 @@ export class CloudFoundryTabsBaseComponent implements OnInit { ngOnInit() { this.isFetching$ = observableOf(false); - this.canAddOrg$ = this.currentUserPermissionsService.can(CurrentUserPermissions.ORGANIZATION_CREATE, this.cfEndpointService.cfGuid); + this.canAddOrg$ = this.currentUserPermissionsService.can(CfCurrentUserPermissions.ORGANIZATION_CREATE, this.cfEndpointService.cfGuid); } } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry.module.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry.module.ts index 3e6a816d3e..9bffecd85b 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry.module.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry.module.ts @@ -8,6 +8,7 @@ import { CloudFoundrySharedModule } from '../../shared/cf-shared.module'; import { CFEndpointsListConfigService, } from '../../shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service'; +import { cfCurrentUserPermissionsService } from '../../user-permissions/cf-user-permissions-checkers'; import { AddOrganizationComponent } from './add-organization/add-organization.component'; import { CreateOrganizationStepComponent, @@ -227,7 +228,8 @@ import { RemoveUserComponent } from './users/remove-user/remove-user.component'; // CfRolesService, CloudFoundryCellService, UserInviteService, - UserInviteConfigureService + UserInviteConfigureService, + ...cfCurrentUserPermissionsService ], entryComponents: [ UserInviteConfigurationDialogComponent diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/edit-organization/edit-organization-step/edit-organization-step.component.html b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/edit-organization/edit-organization-step/edit-organization-step.component.html index d6594dbd8e..9dd3dc9c47 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/edit-organization/edit-organization-step/edit-organization-step.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/edit-organization/edit-organization-step/edit-organization-step.component.html @@ -8,10 +8,11 @@ - {{ quota.entity.name }} + + {{ quota.entity.name }} - + - + \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/quota-definition/quota-definition.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/quota-definition/quota-definition.component.ts index 4764ba5876..db0d5c75b7 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/quota-definition/quota-definition.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/quota-definition/quota-definition.component.ts @@ -4,7 +4,6 @@ import { Store } from '@ngrx/store'; import { Observable, of, Subscription } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; import { AppState } from '../../../../../store/src/app-state'; @@ -12,6 +11,7 @@ import { APIResource } from '../../../../../store/src/types/api.types'; import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { IOrganization, IOrgQuotaDefinition, ISpace } from '../../../cf-api.types'; import { cfEntityCatalog } from '../../../cf-entity-catalog'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../cf-page.types'; import { getActiveRouteCfOrgSpaceProvider } from '../cf.helpers'; import { QuotaDefinitionBaseComponent } from '../quota-definition-base/quota-definition-base.component'; @@ -51,7 +51,7 @@ export class QuotaDefinitionComponent extends QuotaDefinitionBaseComponent { super(store, activeRouteCfOrgSpace, activatedRoute); this.setupQuotaDefinitionObservable(); const { cfGuid, orgGuid } = activeRouteCfOrgSpace; - this.canEditQuota$ = currentUserPermissionsService.can(CurrentUserPermissions.QUOTA_EDIT, cfGuid); + this.canEditQuota$ = currentUserPermissionsService.can(CfCurrentUserPermissions.QUOTA_EDIT, cfGuid); this.isCf = !orgGuid; this.editParams = { [QUOTA_ORG_GUID]: orgGuid }; } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.ts index 41e3bb4f58..d5f5933067 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.ts @@ -4,7 +4,6 @@ import { Store } from '@ngrx/store'; import { Observable, of, Subscription } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; import { AppState } from '../../../../../store/src/app-state'; @@ -12,6 +11,7 @@ import { APIResource } from '../../../../../store/src/types/api.types'; import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { IOrganization, ISpace, ISpaceQuotaDefinition } from '../../../cf-api.types'; import { cfEntityCatalog } from '../../../cf-entity-catalog'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../cf-page.types'; import { getActiveRouteCfOrgSpaceProvider } from '../cf.helpers'; import { QuotaDefinitionBaseComponent } from '../quota-definition-base/quota-definition-base.component'; @@ -49,7 +49,7 @@ export class SpaceQuotaDefinitionComponent extends QuotaDefinitionBaseComponent super(store, activeRouteCfOrgSpace, activatedRoute); this.setupQuotaDefinitionObservable(); const { cfGuid, orgGuid, spaceGuid } = activeRouteCfOrgSpace; - this.canEditQuota$ = currentUserPermissionsService.can(CurrentUserPermissions.SPACE_QUOTA_EDIT, cfGuid, orgGuid); + this.canEditQuota$ = currentUserPermissionsService.can(CfCurrentUserPermissions.SPACE_QUOTA_EDIT, cfGuid, orgGuid); this.isOrg = !spaceGuid; this.editParams = { [QUOTA_SPACE_GUID]: spaceGuid }; } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organization-space-quotas/cloud-foundry-organization-space-quotas.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organization-space-quotas/cloud-foundry-organization-space-quotas.component.ts index 9c814c204c..c45c051ed2 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organization-space-quotas/cloud-foundry-organization-space-quotas.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organization-space-quotas/cloud-foundry-organization-space-quotas.component.ts @@ -1,12 +1,12 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { CurrentUserPermissions } from '../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { ListConfig } from '../../../../../../core/src/shared/components/list/list.component.types'; import { CfSpaceQuotasListConfigService, } from '../../../../shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service'; +import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; import { CloudFoundryEndpointService } from '../../services/cloud-foundry-endpoint.service'; @@ -30,6 +30,6 @@ export class CloudFoundryOrganizationSpaceQuotasComponent { currentUserPermissionsService: CurrentUserPermissionsService ) { const { cfGuid, orgGuid } = this.activeRouteCfOrgSpace; - this.canAddQuota$ = currentUserPermissionsService.can(CurrentUserPermissions.SPACE_QUOTA_CREATE, cfGuid, orgGuid); + this.canAddQuota$ = currentUserPermissionsService.can(CfCurrentUserPermissions.SPACE_QUOTA_CREATE, cfGuid, orgGuid); } } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.ts index ff410c7f87..fd744b2caf 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.ts @@ -1,10 +1,10 @@ import { Component } from '@angular/core'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { ListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { CfSpacesListConfigService, } from '../../../../../shared/components/list/list-types/cf-spaces/cf-spaces-list-config.service'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { CloudFoundryEndpointService } from '../../../services/cloud-foundry-endpoint.service'; import { CloudFoundryOrganizationService } from '../../../services/cloud-foundry-organization.service'; @@ -20,7 +20,7 @@ import { CloudFoundryOrganizationService } from '../../../services/cloud-foundry ] }) export class CloudFoundryOrganizationSpacesComponent { - public permsSpaceCreate = CurrentUserPermissions.SPACE_CREATE; + public permsSpaceCreate = CfCurrentUserPermissions.SPACE_CREATE; constructor( public cfEndpointService: CloudFoundryEndpointService, public cfOrgService: CloudFoundryOrganizationService diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-summary/cloud-foundry-space-summary.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-summary/cloud-foundry-space-summary.component.ts index 361689d6b3..5a5bf9eec0 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-summary/cloud-foundry-space-summary.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-summary/cloud-foundry-space-summary.component.ts @@ -4,7 +4,6 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable } from 'rxjs'; import { filter, first, map, pairwise, startWith, tap } from 'rxjs/operators'; -import { CurrentUserPermissions } from '../../../../../../../../../core/src/core/current-user-permissions.config'; import { ConfirmationDialogConfig } from '../../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService, @@ -15,6 +14,7 @@ import { entityCatalog } from '../../../../../../../../../store/src/entity-catal import { selectDeletionInfo } from '../../../../../../../../../store/src/selectors/api.selectors'; import { spaceEntityType } from '../../../../../../../cf-entity-types'; import { CF_ENDPOINT_TYPE } from '../../../../../../../cf-types'; +import { CfCurrentUserPermissions } from '../../../../../../../user-permissions/cf-user-permissions-checkers'; import { CloudFoundryEndpointService } from '../../../../../services/cloud-foundry-endpoint.service'; import { CloudFoundryOrganizationService } from '../../../../../services/cloud-foundry-organization.service'; import { CloudFoundrySpaceService } from '../../../../../services/cloud-foundry-space.service'; @@ -27,8 +27,8 @@ import { CloudFoundrySpaceService } from '../../../../../services/cloud-foundry- export class CloudFoundrySpaceSummaryComponent { detailsLoading$: Observable; name$: Observable; - public permsSpaceEdit = CurrentUserPermissions.SPACE_EDIT; - public permsSpaceDelete = CurrentUserPermissions.SPACE_DELETE; + public permsSpaceEdit = CfCurrentUserPermissions.SPACE_EDIT; + public permsSpaceDelete = CfCurrentUserPermissions.SPACE_DELETE; constructor( public cfEndpointService: CloudFoundryEndpointService, diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-users/cloud-foundry-space-users.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-users/cloud-foundry-space-users.component.ts index be30449c73..8c1ff64efc 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-users/cloud-foundry-space-users.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-users/cloud-foundry-space-users.component.ts @@ -1,7 +1,6 @@ import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { CFAppState } from 'frontend/packages/cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from 'frontend/packages/core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from 'frontend/packages/core/src/core/current-user-permissions.service'; import { combineLatest, Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; @@ -11,6 +10,7 @@ import { CFFeatureFlagTypes } from '../../../../../../../cf-api.types'; import { CfSpaceUsersListConfigService, } from '../../../../../../../shared/components/list/list-types/cf-space-users/cf-space-users-list-config.service'; +import { CfCurrentUserPermissions } from '../../../../../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../../../../../cf-page.types'; import { createCfOrgSpaceSteppersUrl, someFeatureFlags, waitForCFPermissions } from '../../../../../cf.helpers'; @@ -42,7 +42,7 @@ export class CloudFoundrySpaceUsersComponent { switchMap(() => combineLatest([ someFeatureFlags(requiredFeatureFlags, activeRouteCfOrgSpace.cfGuid, store, userPerms), userPerms.can( - CurrentUserPermissions.SPACE_CHANGE_ROLES, + CfCurrentUserPermissions.SPACE_CHANGE_ROLES, activeRouteCfOrgSpace.cfGuid, activeRouteCfOrgSpace.orgGuid, activeRouteCfOrgSpace.spaceGuid diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.ts index f3f7716510..d7ab64404a 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.ts @@ -5,14 +5,14 @@ import { combineLatest, Observable } from 'rxjs'; import { filter, first, map, pairwise, startWith, tap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { ConfirmationDialogConfig } from '../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; -import { entityCatalog } from '../../../../../../../store/src/entity-catalog/entity-catalog'; import { RouterNav } from '../../../../../../../store/src/actions/router.actions'; +import { entityCatalog } from '../../../../../../../store/src/entity-catalog/entity-catalog'; import { selectDeletionInfo } from '../../../../../../../store/src/selectors/api.selectors'; import { organizationEntityType } from '../../../../../cf-entity-types'; import { CF_ENDPOINT_TYPE } from '../../../../../cf-types'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { goToAppWall } from '../../../cf.helpers'; import { CloudFoundryEndpointService } from '../../../services/cloud-foundry-endpoint.service'; import { CloudFoundryOrganizationService } from '../../../services/cloud-foundry-organization.service'; @@ -26,8 +26,8 @@ import { CloudFoundryOrganizationService } from '../../../services/cloud-foundry export class CloudFoundryOrganizationSummaryComponent { appLink: () => void; detailsLoading$: Observable; - public permsOrgEdit = CurrentUserPermissions.ORGANIZATION_EDIT; - public permsOrgDelete = CurrentUserPermissions.ORGANIZATION_DELETE; + public permsOrgEdit = CfCurrentUserPermissions.ORGANIZATION_EDIT; + public permsOrgDelete = CfCurrentUserPermissions.ORGANIZATION_DELETE; constructor( private store: Store, diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-users/cloud-foundry-organization-users.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-users/cloud-foundry-organization-users.component.ts index df764482bc..e845dbdca2 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-users/cloud-foundry-organization-users.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-users/cloud-foundry-organization-users.component.ts @@ -3,7 +3,6 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { ListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { CFFeatureFlagTypes } from '../../../../../cf-api.types'; @@ -11,6 +10,7 @@ import { CFAppState } from '../../../../../cf-app-state'; import { CfOrgUsersListConfigService, } from '../../../../../shared/components/list/list-types/cf-org-users/cf-org-users-list-config.service'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../../../cf-page.types'; import { createCfOrgSpaceSteppersUrl, someFeatureFlags, waitForCFPermissions } from '../../../cf.helpers'; @@ -42,7 +42,7 @@ export class CloudFoundryOrganizationUsersComponent { this.addRolesByUsernameLink$ = waitForCFPermissions(store, activeRouteCfOrgSpace.cfGuid).pipe( switchMap(() => combineLatest([ someFeatureFlags(requiredFeatureFlags, activeRouteCfOrgSpace.cfGuid, store, userPerms), - userPerms.can(CurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, activeRouteCfOrgSpace.cfGuid, activeRouteCfOrgSpace.orgGuid) + userPerms.can(CfCurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, activeRouteCfOrgSpace.cfGuid, activeRouteCfOrgSpace.orgGuid) ])), map(([canSetRolesByUsername, canChangeOrgRole]) => { if (canSetRolesByUsername && canChangeOrgRole) { diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organizations.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organizations.component.ts index 035bfbf51d..851f02d6c7 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organizations.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organizations.component.ts @@ -1,11 +1,11 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { CurrentUserPermissions } from '../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { ListConfig } from '../../../../../../core/src/shared/components/list/list.component.types'; import { CfOrgCardComponent } from '../../../../shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component'; import { CfOrgsListConfigService } from '../../../../shared/components/list/list-types/cf-orgs/cf-orgs-list-config.service'; +import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; import { CloudFoundryEndpointService } from '../../services/cloud-foundry-endpoint.service'; @Component({ @@ -25,7 +25,7 @@ export class CloudFoundryOrganizationsComponent { public cfEndpointService: CloudFoundryEndpointService, currentUserPermissionsService: CurrentUserPermissionsService ) { - this.canAddOrg$ = currentUserPermissionsService.can(CurrentUserPermissions.ORGANIZATION_CREATE, this.cfEndpointService.cfGuid); + this.canAddOrg$ = currentUserPermissionsService.can(CfCurrentUserPermissions.ORGANIZATION_CREATE, this.cfEndpointService.cfGuid); } cardComponent = CfOrgCardComponent; } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-quotas/cloud-foundry-quotas.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-quotas/cloud-foundry-quotas.component.ts index 566ea33df0..97ae3654f9 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-quotas/cloud-foundry-quotas.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-quotas/cloud-foundry-quotas.component.ts @@ -1,12 +1,12 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { CurrentUserPermissions } from '../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { ListConfig } from '../../../../../../core/src/shared/components/list/list.component.types'; import { CfQuotasListConfigService, } from '../../../../shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service'; +import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; import { CloudFoundryEndpointService } from '../../services/cloud-foundry-endpoint.service'; @Component({ @@ -27,6 +27,6 @@ export class CloudFoundryQuotasComponent { public cfEndpointService: CloudFoundryEndpointService, currentUserPermissionsService: CurrentUserPermissionsService ) { - this.canAddQuota$ = currentUserPermissionsService.can(CurrentUserPermissions.QUOTA_CREATE, this.cfEndpointService.cfGuid); + this.canAddQuota$ = currentUserPermissionsService.can(CfCurrentUserPermissions.QUOTA_CREATE, this.cfEndpointService.cfGuid); } } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/user-invites/user-invite.service.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/user-invites/user-invite.service.ts index 676e0cb299..4866c7a447 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/user-invites/user-invite.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/user-invites/user-invite.service.ts @@ -6,12 +6,12 @@ import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; import { environment } from '../../../../../core/src/environments/environment.prod'; import { ConfirmationDialogConfig } from '../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../core/src/shared/components/confirmation-dialog.service'; import { GetSystemInfo } from '../../../../../store/src/actions/system.actions'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../cf-page.types'; import { waitForCFPermissions } from '../cf.helpers'; import { CloudFoundryEndpointService } from '../services/cloud-foundry-endpoint.service'; @@ -162,7 +162,7 @@ export class UserInviteService { switchMap(() => combineLatest( this.configured$, this.currentUserPermissionsService.can( - CurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, + CfCurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, cfGuid, orgGuid, spaceGuid diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts index 37cb95f700..bf735a998f 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts @@ -17,7 +17,6 @@ import { createEntityRelationKey, createEntityRelationPaginationKey, } from '../../../../../../cloud-foundry/src/entity-relations/entity-relations.types'; -import { CurrentUserPermissionsChecker } from '../../../../../../core/src/core/current-user-permissions.checker'; import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { endpointSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; import { @@ -35,6 +34,7 @@ import { CfUserService } from '../../../../shared/data-services/cf-user.service' import { createDefaultOrgRoles, createDefaultSpaceRoles } from '../../../../store/reducers/users-roles.reducer'; import { CfUser, IUserPermissionInOrg, UserRoleInOrg, UserRoleInSpace } from '../../../../store/types/user.types'; import { CfRoleChange, CfUserRolesSelected } from '../../../../store/types/users-roles.types'; +import { CfUserPermissionsChecker } from '../../../../user-permissions/cf-user-permissions-checkers'; import { canUpdateOrgSpaceRoles } from '../../cf.helpers'; @Injectable() @@ -63,7 +63,7 @@ export class CfRolesService { orgOrSpace.metadata.guid, orgOrSpace.entity.cfGuid, isOrg ? orgOrSpace.metadata.guid : (orgOrSpace as APIResource).entity.organization_guid, - isOrg ? CurrentUserPermissionsChecker.ALL_SPACES : orgOrSpace.metadata.guid, + isOrg ? CfUserPermissionsChecker.ALL_SPACES : orgOrSpace.metadata.guid, )))); }), // Filter out orgs than the current user cannot edit diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-set-usernames/manage-users-set-usernames.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-set-usernames/manage-users-set-usernames.component.ts index a2e80aff1e..99944529de 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-set-usernames/manage-users-set-usernames.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-set-usernames/manage-users-set-usernames.component.ts @@ -4,7 +4,7 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs'; import { first, map, publishReplay, refCount, startWith, switchMap, take, tap } from 'rxjs/operators'; -import { PermissionConfig, PermissionTypes } from '../../../../../../../core/src/core/current-user-permissions.config'; +import { PermissionConfig } from '../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { StackedInputActionConfig, @@ -22,6 +22,7 @@ import { import { CFFeatureFlagTypes } from '../../../../../cf-api.types'; import { CFAppState } from '../../../../../cf-app-state'; import { CfUser } from '../../../../../store/types/user.types'; +import { CfPermissionTypes } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../../../cf-page.types'; import { waitForCFPermissions } from '../../../cf.helpers'; @@ -67,8 +68,8 @@ export class ManageUsersSetUsernamesComponent implements OnInit { private activeRouteCfOrgSpace: ActiveRouteCfOrgSpace, userPerms: CurrentUserPermissionsService, ) { - const ffSetPermConfig = new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.set_roles_by_username); - const ffRemovePermConfig = new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.unset_roles_by_username); + const ffSetPermConfig = new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.set_roles_by_username); + const ffRemovePermConfig = new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.unset_roles_by_username); this.canAdd$ = waitForCFPermissions(store, activeRouteCfOrgSpace.cfGuid).pipe( switchMap(() => userPerms.can(ffSetPermConfig, activeRouteCfOrgSpace.cfGuid)), tap(canAdd => { diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts index cfccea2fa2..6faf039a10 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts @@ -4,7 +4,6 @@ import { Store } from '@ngrx/store'; import { combineLatest as obsCombineLatest, Observable, of as observableOf } from 'rxjs'; import { combineLatest, filter, first, map, startWith } from 'rxjs/operators'; -import { CurrentUserPermissions } from '../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { LoggerService } from '../../../../../../core/src/core/logger.service'; import { StepOnNextFunction } from '../../../../../../core/src/shared/components/stepper/step/step.component'; @@ -19,6 +18,7 @@ import { import { CfUserService } from '../../../../shared/data-services/cf-user.service'; import { CfUser, IUserPermissionInOrg, IUserPermissionInSpace } from '../../../../store/types/user.types'; import { CfRoleChange } from '../../../../store/types/users-roles.types'; +import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; import { getActiveRouteCfOrgSpaceProvider } from '../../cf.helpers'; import { CfRolesService } from '../manage-users/cf-roles.service'; @@ -114,12 +114,12 @@ export class RemoveUserComponent implements OnDestroy { const isOrgRole = !c.spaceGuid; if (isOrgRole) { - return this.userPerms.can(CurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, this.cfGuid, c.orgGuid).pipe( + return this.userPerms.can(CfCurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, this.cfGuid, c.orgGuid).pipe( map((can) => ({ can, change: c })) ); } - return this.userPerms.can(CurrentUserPermissions.SPACE_CHANGE_ROLES, this.cfGuid, c.orgGuid, c.spaceGuid).pipe( + return this.userPerms.can(CfCurrentUserPermissions.SPACE_CHANGE_ROLES, this.cfGuid, c.orgGuid, c.spaceGuid).pipe( map((can) => ({ can, change: c })) ); }); diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-catalog.module.ts b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-catalog.module.ts index 015bb2c5af..93f1c8d797 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-catalog.module.ts +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-catalog.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; import { CoreModule } from '../../../../core/src/core/core.module'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { CloudFoundrySharedModule } from '../../shared/cf-shared.module'; +import { cfCurrentUserPermissionsService } from '../../user-permissions/cf-user-permissions-checkers'; import { CreateApplicationModule } from '../applications/create-application/create-application.module'; import { ServiceBaseComponent } from './service-base/service-base.component'; import { ServiceCatalogPageComponent } from './service-catalog-page/service-catalog-page.component'; @@ -34,5 +35,8 @@ import { ServiceTabsBaseComponent } from './service-tabs-base/service-tabs-base. exports: [ ServiceTabsBaseComponent, ], + providers: [ + ...cfCurrentUserPermissionsService + ] }) export class ServiceCatalogModule { } diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.ts index b54de1291a..817f55a6e2 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.ts @@ -4,9 +4,9 @@ import { Observable, Subscription } from 'rxjs'; import { map, publishReplay, refCount } from 'rxjs/operators'; import { CFAppState } from '../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { IPageSideNavTab } from '../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; import { getServiceName } from '../services-helper'; import { ServicesService } from '../services.service'; @@ -16,7 +16,7 @@ import { ServicesService } from '../services.service'; styleUrls: ['./service-tabs-base.component.scss'], }) export class ServiceTabsBaseComponent { - canCreateServiceInstance: CurrentUserPermissions; + canCreateServiceInstance: CfCurrentUserPermissions; toolTipText$: Observable; hasVisiblePlans$: Observable; servicesSubscription: Subscription; @@ -50,7 +50,7 @@ export class ServiceTabsBaseComponent { constructor(private servicesService: ServicesService, private store: Store) { this.hasVisiblePlans$ = this.servicesService.servicePlans$.pipe( map(p => p.length > 0)); - this.canCreateServiceInstance = CurrentUserPermissions.SERVICE_INSTANCE_CREATE; + this.canCreateServiceInstance = CfCurrentUserPermissions.SERVICE_INSTANCE_CREATE; this.toolTipText$ = this.hasVisiblePlans$.pipe( map(hasPlans => { if (hasPlans) { diff --git a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.ts b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.ts index 4b36fab461..96d806b0c5 100644 --- a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.ts @@ -13,8 +13,8 @@ import { initCfOrgSpaceService, } from '../../../../../cloud-foundry/src/shared/data-services/cf-org-space-service.service'; import { CloudFoundryService } from '../../../../../cloud-foundry/src/shared/data-services/cloud-foundry.service'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { ListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; @Component({ selector: 'app-services-wall', @@ -32,7 +32,7 @@ export class ServicesWallComponent implements OnDestroy { public haveConnectedCf$: Observable; - canCreateServiceInstance: CurrentUserPermissions; + canCreateServiceInstance: CfCurrentUserPermissions; initCfOrgSpaceService: Subscription; cfIds$: Observable; @@ -41,7 +41,7 @@ export class ServicesWallComponent implements OnDestroy { public store: Store, private cfOrgSpaceService: CfOrgSpaceDataService) { - this.canCreateServiceInstance = CurrentUserPermissions.SERVICE_INSTANCE_CREATE; + this.canCreateServiceInstance = CfCurrentUserPermissions.SERVICE_INSTANCE_CREATE; this.cfIds$ = cloudFoundryService.cFEndpoints$.pipe( map(endpoints => endpoints .filter(endpoint => endpoint.connectionStatus === 'connected') diff --git a/src/frontend/packages/cloud-foundry/src/features/services/services.module.ts b/src/frontend/packages/cloud-foundry/src/features/services/services.module.ts index 628dced999..ae6a9ca71d 100644 --- a/src/frontend/packages/cloud-foundry/src/features/services/services.module.ts +++ b/src/frontend/packages/cloud-foundry/src/features/services/services.module.ts @@ -8,6 +8,7 @@ import { ServiceCatalogModule } from '../../../../cloud-foundry/src/features/ser import { CoreModule } from '../../../../core/src/core/core.module'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { CloudFoundrySharedModule } from '../../shared/cf-shared.module'; +import { cfCurrentUserPermissionsService } from '../../user-permissions/cf-user-permissions-checkers'; import { DetachAppsComponent } from './detach-service-instance/detach-apps/detach-apps.component'; import { DetachServiceInstanceComponent } from './detach-service-instance/detach-service-instance.component'; import { ServicesWallComponent } from './services-wall/services-wall.component'; @@ -27,6 +28,9 @@ import { ServicesRoutingModule } from './services.routing'; ServicesWallComponent, DetachServiceInstanceComponent, DetachAppsComponent + ], + providers: [ + ...cfCurrentUserPermissionsService ] }) export class ServicesModule { } diff --git a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts index c024e84633..ae83e851a0 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts @@ -8,6 +8,7 @@ import { SharedModule } from '../../../core/src/shared/shared.module'; import { ApplicationInstanceChartComponent, } from '../features/applications/application/application-instance-chart/application-instance-chart.component'; +import { cfCurrentUserPermissionsService } from '../user-permissions/cf-user-permissions-checkers'; import { AddServiceInstanceBaseStepComponent, } from './components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component'; @@ -377,6 +378,7 @@ const cfListCards: Type>[] = [ ApplicationStateService, GitSCMService, CloudFoundryUserProvidedServicesService, + ...cfCurrentUserPermissionsService // TODO: RC bring in via endpoint??? ] }) export class CloudFoundrySharedModule { } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts index a4652f892f..21394e9762 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts @@ -13,7 +13,6 @@ import { SpaceUserRoleNames, } from '../../../../../cloud-foundry/src/store/types/user.types'; import { CfUserRolesSelected } from '../../../../../cloud-foundry/src/store/types/users-roles.types'; -import { CurrentUserPermissions } from '../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; import { selectUsersIsRemove, @@ -22,6 +21,7 @@ import { } from '../../../../../store/src/selectors/users-roles.selector'; import { canUpdateOrgSpaceRoles } from '../../../features/cloud-foundry/cf.helpers'; import { CfRolesService } from '../../../features/cloud-foundry/users/manage-users/cf-roles.service'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; enum CfRoleCheckboxMode { @@ -254,7 +254,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { // If setting an org role user must be admin or org manager. // If setting a space role user must be admin, org manager or space manager const canEditRole$ = this.isOrgRole ? - this.userPerms.can(CurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, this.cfGuid, this.orgGuid) : + this.userPerms.can(CfCurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, this.cfGuid, this.orgGuid) : canUpdateOrgSpaceRoles( this.userPerms, this.cfGuid, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/create-application/create-application-step1/create-application-step1.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/create-application/create-application-step1/create-application-step1.component.ts index e455fddee4..1e3dd731a4 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/create-application/create-application-step1/create-application-step1.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/create-application/create-application-step1/create-application-step1.component.ts @@ -5,12 +5,12 @@ import { Store } from '@ngrx/store'; import { asapScheduler, Observable, of } from 'rxjs'; import { map, observeOn, startWith, switchMap, withLatestFrom } from 'rxjs/operators'; -import { PermissionStrings } from '../../../../../../core/src/core/current-user-permissions.config'; import { StepOnNextFunction } from '../../../../../../core/src/shared/components/stepper/step/step.component'; import { SetCFDetails } from '../../../../actions/create-applications-page.actions'; import { ISpace } from '../../../../cf-api.types'; import { CFAppState } from '../../../../cf-app-state'; import { getSpacesFromOrgWithRole } from '../../../../store/selectors/cf-current-user-role.selectors'; +import { CfPermissionStrings } from '../../../../user-permissions/cf-user-permissions-checkers'; import { CfOrgSpaceDataService } from '../../../data-services/cf-org-space-service.service'; @Component({ @@ -83,7 +83,7 @@ export class CreateApplicationStep1Component implements OnInit, AfterContentInit return this.cfOrgSpaceService.org.select.pipe( withLatestFrom(this.cfOrgSpaceService.cf.select), switchMap(([orgGuid, endpointGuid]) => { - return this.store.select(getSpacesFromOrgWithRole(endpointGuid, orgGuid, PermissionStrings.SPACE_DEVELOPER)); + return this.store.select(getSpacesFromOrgWithRole(endpointGuid, orgGuid, CfPermissionStrings.SPACE_DEVELOPER)); }), switchMap((spacesOrAll => { if (spacesOrAll === 'all') { diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts index 2f970c7cfa..f53772ea22 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts @@ -5,7 +5,6 @@ import { publishReplay, refCount, switchMap } from 'rxjs/operators'; import { GetAppRoutes } from '../../../../../../../cloud-foundry/src/actions/application-service-routes.actions'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { IListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; @@ -13,6 +12,7 @@ import { APIResource } from '../../../../../../../store/src/types/api.types'; import { PaginatedAction } from '../../../../../../../store/src/types/pagination.types'; import { cfEntityCatalog } from '../../../../../cf-entity-catalog'; import { ApplicationService } from '../../../../../features/applications/application.service'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { CfRoutesListConfigBase } from '../cf-routes/cf-routes-list-config-base'; import { CfAppRoutesDataSource } from './cf-app-routes-data-source'; @@ -42,7 +42,7 @@ export abstract class CfAppRoutesListConfigServiceBase extends CfRoutesListConfi ) { const canEditAppsInSpace = hasActions ? appService.app$.pipe( switchMap(app => currentUserPermissionsService.can( - CurrentUserPermissions.APPLICATION_EDIT, + CfCurrentUserPermissions.APPLICATION_EDIT, appService.cfGuid, app.entity.entity.space_guid )), diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts index f3219c6d18..fb6de7c08c 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts @@ -4,7 +4,6 @@ import { MatDialog } from '@angular/material/dialog'; import { combineLatest as observableCombineLatest, Observable, of as observableOf, of } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; -import { CurrentUserPermissions } from '../../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; import { @@ -31,6 +30,7 @@ import { getServiceSummaryUrl, } from '../../../../../../features/service-catalog/services-helper'; import { AppEnvVarsState } from '../../../../../../store/types/app-metadata.types'; +import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../../data-services/service-action-helper.service'; import { EnvVarViewComponent } from '../../../../env-var-view/env-var-view.component'; @@ -77,7 +77,7 @@ export class AppServiceBindingCardComponent extends CardCell this.currentUserPermissionsService.can( - CurrentUserPermissions.SERVICE_BINDING_EDIT, + CfCurrentUserPermissions.SERVICE_BINDING_EDIT, this.appService.cfGuid, app.entity.entity.space_guid ))) @@ -87,7 +87,7 @@ export class AppServiceBindingCardComponent extends CardCell this.currentUserPermissionsService.can( - CurrentUserPermissions.SERVICE_BINDING_EDIT, + CfCurrentUserPermissions.SERVICE_BINDING_EDIT, this.appService.cfGuid, app.entity.entity.space_guid ))) diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts index a11dc7151d..bf592133df 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts @@ -4,7 +4,6 @@ import { Store } from '@ngrx/store'; import { switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { DataFunctionDefinition, @@ -22,6 +21,7 @@ import { GetAppServiceBindings } from '../../../../../actions/application-servic import { IServiceBinding } from '../../../../../cf-api-svc.types'; import { ApplicationService } from '../../../../../features/applications/application.service'; import { isServiceInstance, isUserProvidedServiceInstance } from '../../../../../features/cloud-foundry/cf.helpers'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; import { BaseCfListConfig } from '../base-cf/base-cf-list-config'; import { @@ -46,7 +46,7 @@ export class AppServiceBindingListConfigService extends BaseCfListConfig this.currentUserPermissionsService.can( - CurrentUserPermissions.SERVICE_INSTANCE_CREATE, + CfCurrentUserPermissions.SERVICE_INSTANCE_CREATE, this.appService.cfGuid, app.entity.entity.space_guid )) @@ -70,7 +70,7 @@ export class AppServiceBindingListConfigService extends BaseCfListConfig this.appService.waitForAppEntity$.pipe( switchMap(app => this.currentUserPermissionsService.can( - CurrentUserPermissions.SERVICE_BINDING_EDIT, + CfCurrentUserPermissions.SERVICE_BINDING_EDIT, this.appService.cfGuid, app.entity.entity.space_guid )) @@ -91,7 +91,7 @@ export class AppServiceBindingListConfigService extends BaseCfListConfig this.appService.waitForAppEntity$.pipe( switchMap(app => this.currentUserPermissionsService.can( - CurrentUserPermissions.SERVICE_BINDING_EDIT, + CfCurrentUserPermissions.SERVICE_BINDING_EDIT, this.appService.cfGuid, app.entity.entity.space_guid )) diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts index c229dd2e8d..b0bcef5edb 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts @@ -6,7 +6,6 @@ import { map, publishReplay, refCount, switchMap, tap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { organizationEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; import { createUserRoleInOrg } from '../../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissions } from '../../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; import { getFavoriteFromEntity } from '../../../../../../../../core/src/core/user-favorite-helpers'; import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; @@ -37,6 +36,7 @@ import { OrgQuotaHelper } from '../../../../../../features/cloud-foundry/service import { createOrgQuotaDefinition, } from '../../../../../../features/cloud-foundry/services/cloud-foundry-organization.service'; +import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { CfUserService } from '../../../../../data-services/cf-user.service'; import { CF_ENDPOINT_TYPE } from './../../../../../../cf-types'; @@ -78,12 +78,12 @@ export class CfOrgCardComponent extends CardCell> imp { label: 'Edit', action: this.edit, - can: this.currentUserPermissionsService.can(CurrentUserPermissions.ORGANIZATION_EDIT, this.cfEndpointService.cfGuid) + can: this.currentUserPermissionsService.can(CfCurrentUserPermissions.ORGANIZATION_EDIT, this.cfEndpointService.cfGuid) }, { label: 'Delete', action: this.delete, - can: this.currentUserPermissionsService.can(CurrentUserPermissions.ORGANIZATION_DELETE, this.cfEndpointService.cfGuid) + can: this.currentUserPermissionsService.can(CfCurrentUserPermissions.ORGANIZATION_DELETE, this.cfEndpointService.cfGuid) } ]; } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service.ts index 9840ba444f..3c7b16cc75 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service.ts @@ -9,7 +9,6 @@ import { ActiveRouteCfOrgSpace } from '../../../../../../../cloud-foundry/src/fe import { BaseCfListConfig, } from '../../../../../../../cloud-foundry/src/shared/components/list/list-types/base-cf/base-cf-list-config'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { ConfirmationDialogConfig } from '../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -18,6 +17,7 @@ import { IListAction, ListViewTypes } from '../../../../../../../core/src/shared import { RouterNav } from '../../../../../../../store/src/actions/router.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { IQuotaDefinition } from '../../../../../cf-api.types'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { CfQuotasDataSourceService } from './cf-quotas-data-source.service'; import { TableCellQuotaComponent } from './table-cell-quota/table-cell-quota.component'; @@ -39,8 +39,8 @@ export class CfQuotasListConfigService extends BaseCfListConfig>) => { return route$.pipe( switchMap(route => currentUserPermissionsService.can( - CurrentUserPermissions.APPLICATION_EDIT, + CfCurrentUserPermissions.APPLICATION_EDIT, route.entity.cfGuid, route.entity.space_guid )), diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts index 0587430dbe..229c489fae 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts @@ -5,7 +5,6 @@ import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { ListDataSource, @@ -20,6 +19,7 @@ import { import { ListView } from '../../../../../../../store/src/actions/list.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { IServiceInstance } from '../../../../../cf-api-svc.types'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; import { CANCEL_ORG_ID_PARAM, CANCEL_SPACE_ID_PARAM } from '../../../add-service-instance/csi-mode.service'; import { @@ -127,7 +127,7 @@ export class CfServiceInstancesListConfigBase implements IListConfig>) => row$.pipe( switchMap( - row => this.can(this.canDeleteCache, CurrentUserPermissions.SERVICE_INSTANCE_DELETE, row.entity.cfGuid, row.entity.space_guid) + row => this.can(this.canDeleteCache, CfCurrentUserPermissions.SERVICE_INSTANCE_DELETE, row.entity.cfGuid, row.entity.space_guid) ) ) }; @@ -140,7 +140,7 @@ export class CfServiceInstancesListConfigBase implements IListConfig>) => row$.pipe( switchMap( - row => this.can(this.canDetachCache, CurrentUserPermissions.SERVICE_BINDING_EDIT, row.entity.cfGuid, row.entity.space_guid) + row => this.can(this.canDetachCache, CfCurrentUserPermissions.SERVICE_BINDING_EDIT, row.entity.cfGuid, row.entity.space_guid) ) ) }; @@ -156,12 +156,12 @@ export class CfServiceInstancesListConfigBase implements IListConfig>) => row$.pipe( switchMap( - row => this.can(this.canDetachCache, CurrentUserPermissions.SERVICE_BINDING_EDIT, row.entity.cfGuid, row.entity.space_guid) + row => this.can(this.canDetachCache, CfCurrentUserPermissions.SERVICE_BINDING_EDIT, row.entity.cfGuid, row.entity.space_guid) ) ) }; - private can(cache: CanCache, perm: CurrentUserPermissions, cfGuid: string, spaceGuid: string): Observable { + private can(cache: CanCache, perm: CfCurrentUserPermissions, cfGuid: string, spaceGuid: string): Observable { let can = cache[spaceGuid]; if (!can) { can = this.currentUserPermissionsService.can(perm, cfGuid, spaceGuid); diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts index 9c20d74796..054824d011 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts @@ -5,7 +5,6 @@ import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { ListDataSource, @@ -21,6 +20,7 @@ import { ListView } from '../../../../../../../store/src/actions/list.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { IUserProvidedServiceInstance } from '../../../../../cf-api-svc.types'; import { CloudFoundrySpaceService } from '../../../../../features/cloud-foundry/services/cloud-foundry-space.service'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; import { CANCEL_ORG_ID_PARAM, @@ -123,7 +123,7 @@ export class CfUserServiceInstancesListConfigBase implements IListConfig>) => row$.pipe( switchMap( - row => this.can(this.canDeleteCache, CurrentUserPermissions.SERVICE_INSTANCE_DELETE, row.entity.cfGuid, row.entity.space_guid) + row => this.can(this.canDeleteCache, CfCurrentUserPermissions.SERVICE_INSTANCE_DELETE, row.entity.cfGuid, row.entity.space_guid) ) ) }; @@ -137,7 +137,7 @@ export class CfUserServiceInstancesListConfigBase implements IListConfig>) => row$.pipe( switchMap( - row => this.can(this.canDetachCache, CurrentUserPermissions.SERVICE_BINDING_EDIT, row.entity.cfGuid, row.entity.space_guid) + row => this.can(this.canDetachCache, CfCurrentUserPermissions.SERVICE_BINDING_EDIT, row.entity.cfGuid, row.entity.space_guid) ) ) }; @@ -158,12 +158,12 @@ export class CfUserServiceInstancesListConfigBase implements IListConfig>) => row$.pipe( switchMap( - row => this.can(this.canDetachCache, CurrentUserPermissions.SERVICE_BINDING_EDIT, row.entity.cfGuid, row.entity.space_guid) + row => this.can(this.canDetachCache, CfCurrentUserPermissions.SERVICE_BINDING_EDIT, row.entity.cfGuid, row.entity.space_guid) ) ) }; - private can(cache: CanCache, perm: CurrentUserPermissions, cfGuid: string, spaceGuid: string): Observable { + private can(cache: CanCache, perm: CfCurrentUserPermissions, cfGuid: string, spaceGuid: string): Observable { let can = cache[spaceGuid]; if (!can) { can = this.currentUserPermissionsService.can(perm, cfGuid, spaceGuid); diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service.ts index 3cfc6e83c1..301fccd563 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service.ts @@ -3,7 +3,6 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable, Subscription } from 'rxjs'; -import { CurrentUserPermissions } from '../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { ConfirmationDialogConfig } from '../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -15,6 +14,7 @@ import { DeleteSpaceQuotaDefinition } from '../../../../../actions/quota-definit import { IQuotaDefinition } from '../../../../../cf-api.types'; import { CFAppState } from '../../../../../cf-app-state'; import { ActiveRouteCfOrgSpace } from '../../../../../features/cloud-foundry/cf-page.types'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { BaseCfListConfig } from '../base-cf/base-cf-list-config'; import { QUOTA_FROM_LIST } from '../cf-quotas/cf-quotas-list-config.service'; import { TableCellQuotaComponent } from '../cf-quotas/table-cell-quota/table-cell-quota.component'; @@ -37,8 +37,8 @@ export class CfSpaceQuotasListConfigService extends BaseCfListConfig> implemen label: 'Edit', action: this.edit, can: this.currentUserPermissionsService.can( - CurrentUserPermissions.SPACE_EDIT, + CfCurrentUserPermissions.SPACE_EDIT, this.cfEndpointService.cfGuid, this.orgGuid, this.spaceGuid @@ -97,7 +97,7 @@ export class CfSpaceCardComponent extends CardCell> implemen label: 'Delete', action: this.delete, can: this.currentUserPermissionsService.can( - CurrentUserPermissions.SPACE_DELETE, + CfCurrentUserPermissions.SPACE_DELETE, this.cfEndpointService.cfGuid, this.orgGuid ) diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-org-permission-cell/cf-org-permission-cell.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-org-permission-cell/cf-org-permission-cell.component.ts index f28255ba44..3990c51575 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-org-permission-cell/cf-org-permission-cell.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-org-permission-cell/cf-org-permission-cell.component.ts @@ -11,7 +11,6 @@ import { IUserPermissionInOrg, OrgUserRoleNames, } from '../../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissions } from '../../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; import { arrayHelper } from '../../../../../../../../core/src/core/helper-classes/array.helper'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; @@ -21,6 +20,7 @@ import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { IOrganization } from '../../../../../../cf-api.types'; import { CF_ENDPOINT_TYPE } from '../../../../../../cf-types'; import { getOrgRoles } from '../../../../../../features/cloud-foundry/cf.helpers'; +import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { CfUserService } from '../../../../../data-services/cf-user.service'; import { CfPermissionCell, ICellPermissionList } from '../cf-permission-cell'; @@ -98,6 +98,6 @@ export class CfOrgPermissionCellComponent extends CfPermissionCell - this.userPerms.can(CurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, cfGuid, orgGuid) + this.userPerms.can(CfCurrentUserPermissions.ORGANIZATION_CHANGE_ROLES, cfGuid, orgGuid) } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts index b03582d3f8..1f2d051af9 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts @@ -12,7 +12,6 @@ import { IUserPermissionInSpace, SpaceUserRoleNames, } from '../../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissions } from '../../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; import { arrayHelper } from '../../../../../../../../core/src/core/helper-classes/array.helper'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -21,6 +20,7 @@ import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { IOrganization, ISpace } from '../../../../../../cf-api.types'; import { CF_ENDPOINT_TYPE } from '../../../../../../cf-types'; import { getSpaceRoles } from '../../../../../../features/cloud-foundry/cf.helpers'; +import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { CfUserService } from '../../../../../data-services/cf-user.service'; import { CfPermissionCell, ICellPermissionList } from '../cf-permission-cell'; @@ -156,5 +156,5 @@ export class CfSpacePermissionCellComponent extends CfPermissionCell - this.userPerms.can(CurrentUserPermissions.SPACE_CHANGE_ROLES, cfGuid, orgGuid, spaceGuid) + this.userPerms.can(CfCurrentUserPermissions.SPACE_CHANGE_ROLES, cfGuid, orgGuid, spaceGuid) } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts index f070370166..00d67cac51 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts @@ -7,7 +7,6 @@ import { UsersRolesSetUsers } from '../../../../../../../cloud-foundry/src/actio import { GetAllUsersAsAdmin } from '../../../../../../../cloud-foundry/src/actions/users.actions'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; import { CfUser } from '../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissionsChecker } from '../../../../../../../core/src/core/current-user-permissions.checker'; import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; import { ITableColumn, ITableText } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; import { @@ -33,6 +32,7 @@ import { hasSpaceRoleWithinOrg, waitForCFPermissions, } from '../../../../../features/cloud-foundry/cf.helpers'; +import { CfUserPermissionsChecker } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { CfUserService } from './../../../../data-services/cf-user.service'; import { CfOrgPermissionCellComponent } from './cf-org-permission-cell/cf-org-permission-cell.component'; import { CfSpacePermissionCellComponent } from './cf-space-permission-cell/cf-space-permission-cell.component'; @@ -348,7 +348,7 @@ export class CfUserListConfigService extends ListConfig> { this.activeRouteCfOrgSpace.cfGuid, this.activeRouteCfOrgSpace.orgGuid, this.activeRouteCfOrgSpace.orgGuid && !this.activeRouteCfOrgSpace.spaceGuid ? - CurrentUserPermissionsChecker.ALL_SPACES : this.activeRouteCfOrgSpace.spaceGuid) + CfUserPermissionsChecker.ALL_SPACES : this.activeRouteCfOrgSpace.spaceGuid) private createCanUpdateOrgRoles = () => canUpdateOrgSpaceRoles( this.userPerms, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts index 0d82e721ec..80a69f7fbd 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts @@ -4,7 +4,6 @@ import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { serviceInstancesEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; -import { CurrentUserPermissions } from '../../../../../../../../core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; import { @@ -21,6 +20,7 @@ import { getServicePlanName, getServiceSummaryUrl, } from '../../../../../../features/service-catalog/services-helper'; +import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../../data-services/service-action-helper.service'; import { CfOrgSpaceLabelService } from '../../../../../services/cf-org-space-label.service'; @@ -48,7 +48,7 @@ export class ServiceInstanceCardComponent extends CardCell (state: ICfRolesState) => { +const selectSpaceWithRoleFromOrg = (role: CfPermissionStrings, orgId: string) => (state: ICfRolesState) => { if (!state) { return 'all'; } @@ -101,8 +98,8 @@ export const getCurrentUserCFEndpointScopesState = (endpointGuid: string) => com // Has endpoint scopes // ============================ -export const getCurrentUserCFEndpointHasScope = (endpointGuid: string, scope: ScopeStrings) => compose( - selectCurrentUserCFGlobalHasScopes(scope), +export const getCurrentUserCFEndpointHasScope = (endpointGuid: string, scope: CfScopeStrings) => compose( + selectCurrentUserGlobalHasScopes(scope), getCurrentUserCFEndpointScopesState(endpointGuid) ); // ============================ @@ -142,7 +139,7 @@ export const getCurrentUserCFOrgRolesState = (endpointGuid: string, orgId: strin // Get an array of space guid that have a particular role // anf from a particular org // ============================ -export const getSpacesFromOrgWithRole = (endpointGuid: string, orgId: string, role: PermissionStrings) => compose( +export const getSpacesFromOrgWithRole = (endpointGuid: string, orgId: string, role: CfPermissionStrings) => compose( selectSpaceWithRoleFromOrg(role, orgId), getCurrentUserCFEndpointRolesState(endpointGuid) ); diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts new file mode 100644 index 0000000000..087e0f31b4 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts @@ -0,0 +1,477 @@ +import { Store } from '@ngrx/store'; +import { combineLatest, Observable, of } from 'rxjs'; +import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; + +import { + BaseCurrentUserPermissionsChecker, + ICheckCombiner, + IConfigGroup, + ICurrentUserPermissionsChecker, +} from '../../../core/src/core/current-user-permissions.checker'; +import { + IPermissionConfigs, + PermissionConfig, + PermissionConfigLink, + PermissionTypes, + PermissionValues, +} from '../../../core/src/core/current-user-permissions.config'; +import { + CurrentUserPermissionsService, + CUSTOM_USER_PERMISSION_CHECKERS, +} from '../../../core/src/core/current-user-permissions.service'; +import { GeneralEntityAppState } from '../../../store/src/app-state'; +import { connectedEndpointsSelector } from '../../../store/src/selectors/endpoint.selectors'; +import { CFFeatureFlagTypes, IFeatureFlag } from '../cf-api.types'; +import { cfEntityCatalog } from '../cf-entity-catalog'; +import { + getCurrentUserCFEndpointHasScope, + getCurrentUserCFEndpointRolesState, + getCurrentUserCFGlobalState, +} from '../store/selectors/cf-current-user-role.selectors'; +import { IOrgRoleState, ISpaceRoleState, ISpacesRoleState } from '../store/types/cf-current-user-roles.types'; + +export const cfCurrentUserPermissionsService = [ + { + provide: CUSTOM_USER_PERMISSION_CHECKERS, + useFactory: (store: Store) => [new CfUserPermissionsChecker(store)], + deps: [Store] + }, + CurrentUserPermissionsService, +] + +// TODO: RC +// type Enum = Record; +// export const cfCurrentUserPermissions2: Enum = { +// a: '1', +// b: '2', +// } + +export enum CfCurrentUserPermissions { + APPLICATION_VIEW = 'view.application', + APPLICATION_EDIT = 'edit.application', + APPLICATION_CREATE = 'create.application', + APPLICATION_MANAGE = 'manage.application', + APPLICATION_VIEW_ENV_VARS = 'env-vars.view.application', + SPACE_VIEW = 'view.space', + SPACE_CREATE = 'create.space', + SPACE_DELETE = 'delete.space', + SPACE_EDIT = 'edit.space', + SPACE_CHANGE_ROLES = 'change-roles.space', + ROUTE_CREATE = 'create.route', + // ROUTE_BINDING_CREATE = 'create.binding.route', + QUOTA_CREATE = 'create.quota', + QUOTA_EDIT = 'edit.quota', + QUOTA_DELETE = 'delete.quota', + SPACE_QUOTA_CREATE = 'create.space-quota', + SPACE_QUOTA_EDIT = 'edit.space-quota', + SPACE_QUOTA_DELETE = 'delete.space-quota', + ORGANIZATION_CREATE = 'create.org', + ORGANIZATION_DELETE = 'delete.org', + ORGANIZATION_EDIT = 'edit.org', + ORGANIZATION_SUSPEND = 'suspend.org', + ORGANIZATION_CHANGE_ROLES = 'change-roles.org', + SERVICE_INSTANCE_DELETE = 'delete.service-instance', + SERVICE_INSTANCE_CREATE = 'create.service-instance', + SERVICE_BINDING_EDIT = 'edit.service-binding', + FIREHOSE_VIEW = 'view-firehose', + SERVICE_INSTANCE_EDIT = 'edit.service-instance' +} + +export enum CfPermissionStrings { + _GLOBAL_ = 'global', + SPACE_MANAGER = 'isManager', + SPACE_AUDITOR = 'isAuditor', + SPACE_DEVELOPER = 'isDeveloper', + ORG_MANAGER = 'isManager', + ORG_AUDITOR = 'isAuditor', + ORG_BILLING_MANAGER = 'isBillingManager', + ORG_USER = 'isUser', +} + +export enum CfScopeStrings { + CF_ADMIN_GROUP = 'cloud_controller.admin', + CF_READ_ONLY_ADMIN_GROUP = 'cloud_controller.admin_read_only', + CF_ADMIN_GLOBAL_AUDITOR_GROUP = 'cloud_controller.global_auditor', + CF_WRITE_SCOPE = 'cloud_controller.write', + CF_READ_SCOPE = 'cloud_controller.write', +} + +export enum CfPermissionTypes { + SPACE = 'spaces', + ORGANIZATION = 'organizations', + ENDPOINT = 'endpoint', + ENDPOINT_SCOPE = 'endpoint-scope', + FEATURE_FLAG = 'feature-flag', +} + +// For each set permissions are checked by permission types of ENDPOINT, ENDPOINT_SCOPE, STRATOS_SCOPE, FEATURE_FLAG or a random bag. +// Every group result must be true in order for the permission to be true. A group result is true if all or some of it's permissions are +// true (see `getCheckFromConfig`). +export const cfPermissionConfigs: IPermissionConfigs = { + [CfCurrentUserPermissions.APPLICATION_VIEW]: [ + // See #2186 + new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_READ_ONLY_ADMIN_GROUP), + new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP), + new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_MANAGER), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_AUDITOR), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER) + ], + [CfCurrentUserPermissions.APPLICATION_CREATE]: new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER), + [CfCurrentUserPermissions.APPLICATION_MANAGE]: new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER), + [CfCurrentUserPermissions.APPLICATION_EDIT]: new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER), + [CfCurrentUserPermissions.APPLICATION_VIEW_ENV_VARS]: new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER), + [CfCurrentUserPermissions.SPACE_VIEW]: [ + // See #2186 + new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_READ_ONLY_ADMIN_GROUP), + new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP), + new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_MANAGER), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_AUDITOR), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER) + ], + [CfCurrentUserPermissions.SPACE_CREATE]: new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + [CfCurrentUserPermissions.SPACE_DELETE]: new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + [CfCurrentUserPermissions.SPACE_EDIT]: [ + new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_MANAGER), + ], + [CfCurrentUserPermissions.SPACE_CHANGE_ROLES]: [ + new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_MANAGER) + ], + // TODO: See #4189. Wire in. Can be org manager? + [CfCurrentUserPermissions.ROUTE_CREATE]: [ + new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.route_creation), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER) + ], + [CfCurrentUserPermissions.QUOTA_CREATE]: new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_ADMIN_GROUP), + [CfCurrentUserPermissions.QUOTA_EDIT]: new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_ADMIN_GROUP), + [CfCurrentUserPermissions.QUOTA_DELETE]: new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_ADMIN_GROUP), + [CfCurrentUserPermissions.SPACE_QUOTA_CREATE]: new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + [CfCurrentUserPermissions.SPACE_QUOTA_EDIT]: new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + [CfCurrentUserPermissions.SPACE_QUOTA_DELETE]: new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + [CfCurrentUserPermissions.ORGANIZATION_CREATE]: [ + // is admin (checked for everything) or FF is on and user has a role + new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.user_org_creation), + new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_AUDITOR), + new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_BILLING_MANAGER), + new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_USER), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_MANAGER), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_AUDITOR), + new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER) + ], + [CfCurrentUserPermissions.ORGANIZATION_DELETE]: new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_ADMIN_GROUP), + [CfCurrentUserPermissions.ORGANIZATION_EDIT]: new PermissionConfigLink(CfCurrentUserPermissions.ORGANIZATION_DELETE), + [CfCurrentUserPermissions.ORGANIZATION_SUSPEND]: new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_ADMIN_GROUP), + [CfCurrentUserPermissions.ORGANIZATION_CHANGE_ROLES]: new PermissionConfig(CfPermissionTypes.ORGANIZATION, CfPermissionStrings.ORG_MANAGER), + [CfCurrentUserPermissions.SERVICE_INSTANCE_DELETE]: new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER), + [CfCurrentUserPermissions.SERVICE_INSTANCE_CREATE]: new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER), + [CfCurrentUserPermissions.SERVICE_INSTANCE_EDIT]: new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER), + [CfCurrentUserPermissions.SERVICE_BINDING_EDIT]: new PermissionConfig(CfPermissionTypes.SPACE, CfPermissionStrings.SPACE_DEVELOPER), + [CfCurrentUserPermissions.FIREHOSE_VIEW]: [ + new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, CfScopeStrings.CF_READ_ONLY_ADMIN_GROUP) + ], +}; + +export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker implements ICurrentUserPermissionsChecker { + static readonly ALL_SPACES = 'PERMISSIONS__ALL_SPACES_PLEASE'; + + constructor(private store: Store) { + super(); + } + + getPermissionConfig(action: string) { + return cfPermissionConfigs[action]; + } + + private check( + type: PermissionTypes, + permission: PermissionValues, + endpointGuid?: string, + orgOrSpaceGuid?: string, + allSpacesWithinOrg = false + ) { + if (type === CfPermissionTypes.ENDPOINT_SCOPE) { + if (!endpointGuid) { + return of(false); + } + return this.store.select(getCurrentUserCFEndpointHasScope(endpointGuid, permission as CfScopeStrings)); + } + + if (type === CfPermissionTypes.ENDPOINT) { + return this.store.select(getCurrentUserCFGlobalState(endpointGuid, permission)); + } + + return this.getCfEndpointState(endpointGuid).pipe( + filter(state => !!state), + map(state => { + const permissionString = permission as CfPermissionStrings; + if (allSpacesWithinOrg) { + const spaceState = state[CfPermissionTypes.SPACE]; + return this.checkAllSpacesInOrg(state[CfPermissionTypes.ORGANIZATION][orgOrSpaceGuid], spaceState, permissionString); + } + return this.selectPermission(state[type][orgOrSpaceGuid], permissionString); + }), + distinctUntilChanged(), + ); + }; + + /** + * @param permissionConfig Single permission to be checked + */ + public getSimpleCheck(permissionConfig: PermissionConfig, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string) { + const check$ = this.getBaseSimpleCheck(permissionConfig, endpointGuid, orgOrSpaceGuid, spaceGuid); + if (permissionConfig.type === CfPermissionTypes.ORGANIZATION || permissionConfig.type === CfPermissionTypes.SPACE) { + return this.applyAdminCheck(check$, endpointGuid); + } + return check$; + } + + private getBaseSimpleCheck(permissionConfig: PermissionConfig, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string) { + switch (permissionConfig.type) { + case (CfPermissionTypes.FEATURE_FLAG): + return this.getFeatureFlagCheck(permissionConfig, endpointGuid); + case (CfPermissionTypes.ORGANIZATION): + case (CfPermissionTypes.SPACE): + case (CfPermissionTypes.ENDPOINT): + return this.getCfCheck(permissionConfig, endpointGuid, orgOrSpaceGuid, spaceGuid); + case (CfPermissionTypes.ENDPOINT_SCOPE): + return this.getEndpointScopesCheck(permissionConfig.permission as CfScopeStrings, endpointGuid); + } + } + + private getEndpointScopesCheck(permission: CfScopeStrings, endpointGuid?: string) { + const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); + return endpointGuids$.pipe( + switchMap(guids => combineLatest(guids.map(guid => this.check(CfPermissionTypes.ENDPOINT_SCOPE, permission, endpointGuid)))), + map(checks => checks.some(check => check)), + distinctUntilChanged() + ); + } + + private getEndpointScopesChecks( + configs: PermissionConfig[], + endpoint?: string + ) { + return configs.map(config => { + const { permission } = config; + return this.getEndpointScopesCheck(permission as CfScopeStrings, endpoint); + }); + } + + private getCfChecks( + configs: PermissionConfig[], + endpointGuid?: string, + orgOrSpaceGuid?: string, + spaceGuid?: string + ): Observable[] { + return configs.map(config => this.getCfCheck(config, endpointGuid, orgOrSpaceGuid, spaceGuid)); + } + + private getCfCheck(config: PermissionConfig, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string): Observable { + const { type, permission } = config; + const checkAllSpaces = spaceGuid === CfUserPermissionsChecker.ALL_SPACES; + const actualGuid = type === CfPermissionTypes.SPACE && spaceGuid && !checkAllSpaces ? spaceGuid : orgOrSpaceGuid; + const cfPermissions = permission as CfPermissionStrings; + if (type === CfPermissionTypes.ENDPOINT || (endpointGuid && actualGuid)) { + return this.check(type, cfPermissions, endpointGuid, actualGuid, checkAllSpaces); + } else if (!actualGuid) { + const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); + return endpointGuids$.pipe( + switchMap(guids => combineLatest(guids.map(guid => this.checkAllOfType(guid, type as CfPermissionTypes, cfPermissions)))), + map(checks => checks.some(check => check)), + distinctUntilChanged() + ); + } + return of(false); + } + + private getFeatureFlagChecks(configs: PermissionConfig[], endpointGuid?: string): Observable[] { + return configs.map(config => { + return this.getFeatureFlagCheck(config, endpointGuid); + }); + } + + private getFeatureFlagCheck(config: PermissionConfig, endpointGuid?: string): Observable { + const permission = config.permission as CFFeatureFlagTypes; + const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); + return endpointGuids$.pipe( + switchMap(guids => { + const createFFObs = guid => + // For admins we don't have the ff list which is usually fetched right at the start, + // so this can't be a pagination monitor on its own (which doesn't fetch if list is missing) + cfEntityCatalog.featureFlag.store.getPaginationService(guid).entities$; + return combineLatest(guids.map(createFFObs)); + }), + map(endpointFeatureFlags => endpointFeatureFlags.some(featureFlags => this.checkFeatureFlag(featureFlags, permission))), + // startWith(false), // Don't start with anything, this ensures first value out can be trusted. Should never get to the point where + // nothing is returned + distinctUntilChanged(), + ); + } + + private checkFeatureFlag(featureFlags: IFeatureFlag[], permission: CFFeatureFlagTypes) { + const flag = featureFlags.find(ff => ff.name === permission.toString()); + if (!flag) { + return false; + } + return flag.enabled; + } + + private getAdminChecks(endpointGuid?: string) { + const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); + return endpointGuids$.pipe( + map(guids => guids.map(guid => this.getCfAdminCheck(guid))), + switchMap(checks => BaseCurrentUserPermissionsChecker.reduceChecks(checks)), + ); + } + + /** + * Includes read only admins, global auditors and users that don't have the cloud_controller.write scope + */ + private getReadOnlyCheck(endpointGuid: string) { + return this.getCfEndpointState(endpointGuid).pipe( + map( + cfPermissions => ( + cfPermissions && ( + cfPermissions.global.isGlobalAuditor || + cfPermissions.global.isReadOnlyAdmin || + !cfPermissions.global.canWrite + ) + ) + ), + distinctUntilChanged() + ); + } + + private applyAdminCheck(check$: Observable, endpointGuid?: string): Observable { + const adminCheck$ = this.getAdminChecks(endpointGuid); + const readOnlyCheck$ = this.getReadOnlyChecks(endpointGuid); + return combineLatest( + adminCheck$, + readOnlyCheck$ + ).pipe( + distinctUntilChanged(), + switchMap(([isAdmin, isReadOnly]) => { + if (isAdmin) { + return of(true); + } + if (isReadOnly) { + return of(false); + } + return check$; + }) + ); + } + + /** + * If no endpoint is passed, check them all + */ + private getReadOnlyChecks(endpointGuid?: string) { + const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); + return endpointGuids$.pipe( + map(guids => guids.map(guid => this.getReadOnlyCheck(guid))), + switchMap(checks => BaseCurrentUserPermissionsChecker.reduceChecks(checks, '&&')) + ); + } + + private getCfAdminCheck(endpointGuid: string) { + return this.getCfEndpointState(endpointGuid).pipe( + filter(cfPermissions => !!cfPermissions), + map(cfPermissions => cfPermissions.global.isAdmin) + ); + } + + private checkAllOfType(endpointGuid: string, type: CfPermissionTypes, permission: CfPermissionStrings, orgGuid?: string) { + return this.getCfEndpointState(endpointGuid).pipe( + map(state => { + if (!state || !state[type]) { + return false; + } + return Object.keys(state[type]).some(guid => { + return this.selectPermission(state[type][guid], permission); + }); + }) + ); + } + + private getAllEndpointGuids() { + return this.store.select(connectedEndpointsSelector).pipe( + map(endpoints => Object.values(endpoints).filter(e => e.cnsi_type === 'cf').map(endpoint => endpoint.guid)) + ); + } + + private getEndpointGuidObservable(endpointGuid: string) { + return !endpointGuid ? this.getAllEndpointGuids() : of([endpointGuid]); + } + + private selectPermission(state: IOrgRoleState | ISpaceRoleState, permission: CfPermissionStrings): boolean { + return state ? state[permission] || false : false; + } + + private checkAllSpacesInOrg(orgState: IOrgRoleState, endpointSpaces: ISpacesRoleState, permission: CfPermissionStrings) { + const spaceGuids = !!orgState && orgState.spaceGuids ? orgState.spaceGuids : []; + return spaceGuids.map(spaceGuid => { + const space = endpointSpaces[spaceGuid]; + return space ? space[permission] || false : false; + }).some(check => check); + + } + + private getCfEndpointState(endpointGuid: string) { + return this.store.select(getCurrentUserCFEndpointRolesState(endpointGuid)); + } + + public getCheckFromConfig( + configGroup: IConfigGroup, + permission: CfPermissionTypes, + endpointGuid?: string, + orgOrSpaceGuid?: string, + spaceGuid?: string + ): ICheckCombiner { + const checkCombiner = this.getBaseCheckFromConfig(configGroup, permission, endpointGuid, orgOrSpaceGuid, spaceGuid) + if (checkCombiner) { + checkCombiner.checks = checkCombiner.checks.map(check$ => this.applyAdminCheck(check$, endpointGuid)) + } + return checkCombiner; + } + + private getBaseCheckFromConfig( + configGroup: IConfigGroup, + permission: CfPermissionTypes, + endpointGuid?: string, + orgOrSpaceGuid?: string, + spaceGuid?: string + ): ICheckCombiner { + switch (permission) { + // case cfPermissionTypes.ENDPOINT: + // return { + // checks: this.getInternalScopesChecks(configGroup), // TODO: RC not right?? + // }; + case CfPermissionTypes.ENDPOINT_SCOPE: + return { + checks: this.getEndpointScopesChecks(configGroup, endpointGuid), + }; + case CfPermissionTypes.FEATURE_FLAG: + return { + checks: this.getFeatureFlagChecks(configGroup, endpointGuid), + combineType: '&&' + }; + case CfPermissionTypes.ORGANIZATION: + return { + checks: this.getCfChecks(configGroup, endpointGuid, orgOrSpaceGuid, spaceGuid) + }; + case CfPermissionTypes.SPACE: + return { + checks: this.getCfChecks(configGroup, endpointGuid, orgOrSpaceGuid, spaceGuid) + }; + } + } + + public getFallbackPermission(endpointGuid: string) { + return this.getCfAdminCheck(endpointGuid); + }; + +} \ No newline at end of file diff --git a/src/frontend/packages/core/src/core/core.module.ts b/src/frontend/packages/core/src/core/core.module.ts index e3ee91c394..31a4ba159f 100644 --- a/src/frontend/packages/core/src/core/core.module.ts +++ b/src/frontend/packages/core/src/core/core.module.ts @@ -17,7 +17,7 @@ import { ButtonBlurOnClickDirective } from './button-blur-on-click.directive'; import { BytesToHumanSize, MegaBytesToHumanSize } from './byte-formatters.pipe'; import { ClickStopPropagationDirective } from './click-stop-propagation.directive'; import { APP_TITLE, appTitleFactory } from './core.types'; -import { CurrentUserPermissionsService } from './current-user-permissions.service'; +import { CurrentUserPermissionsService, CUSTOM_USER_PERMISSION_CHECKERS } from './current-user-permissions.service'; import { DisableRouterLinkDirective } from './disable-router-link.directive'; import { DotContentComponent } from './dot-content/dot-content.component'; import { EndpointsService } from './endpoints.service'; @@ -85,6 +85,10 @@ import { WindowRef } from './window-ref/window-ref.service'; PaginationMonitorFactory, UserProfileService, EntityServiceFactory, + { + provide: CUSTOM_USER_PERMISSION_CHECKERS, + useValue: [] + }, CurrentUserPermissionsService, { provide: APP_TITLE, diff --git a/src/frontend/packages/core/src/core/current-user-permissions.checker.ts b/src/frontend/packages/core/src/core/current-user-permissions.checker.ts index 1d50f368f4..2a203d4b5c 100644 --- a/src/frontend/packages/core/src/core/current-user-permissions.checker.ts +++ b/src/frontend/packages/core/src/core/current-user-permissions.checker.ts @@ -1,317 +1,156 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf } from 'rxjs'; -import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; +import { distinctUntilChanged, map } from 'rxjs/operators'; -import { CFFeatureFlagTypes, IFeatureFlag } from '../../../cloud-foundry/src/cf-api.types'; -import { cfEntityCatalog } from '../../../cloud-foundry/src/cf-entity-catalog'; -import { - getCurrentUserCFEndpointHasScope, - getCurrentUserCFEndpointRolesState, - getCurrentUserCFGlobalState, -} from '../../../cloud-foundry/src/store/selectors/cf-current-user-role.selectors'; -import { - IOrgRoleState, - ISpaceRoleState, - ISpacesRoleState, -} from '../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; import { GeneralEntityAppState } from '../../../store/src/app-state'; import { getCurrentUserStratosHasScope, getCurrentUserStratosRole, } from '../../../store/src/selectors/current-user-role.selectors'; -import { connectedEndpointsSelector } from '../../../store/src/selectors/endpoint.selectors'; import { + IPermissionConfigs, PermissionConfig, - PermissionStrings, + PermissionConfigType, PermissionTypes, PermissionValues, - ScopeStrings, } from './current-user-permissions.config'; export interface IConfigGroups { [permissionType: string]: IConfigGroup; } -export enum CHECKER_GROUPS { - CF_GROUP = '__CF_TYPE__' -} export type IConfigGroup = PermissionConfig[]; -export class CurrentUserPermissionsChecker { - static readonly ALL_SPACES = 'PERMISSIONS__ALL_SPACES_PLEASE'; - constructor(private store: Store, ) { } - public check( - type: PermissionTypes, - permission: PermissionValues, - endpointGuid?: string, - orgOrSpaceGuid?: string, - allSpacesWithinOrg = false - ) { - if (type === PermissionTypes.STRATOS) { - return this.store.select(getCurrentUserStratosRole(permission)); - } - - if (type === PermissionTypes.STRATOS_SCOPE) { - return this.store.select(getCurrentUserStratosHasScope(permission as ScopeStrings)); - } - if (type === PermissionTypes.ENDPOINT_SCOPE) { - if (!endpointGuid) { - return observableOf(false); - } - return this.store.select(getCurrentUserCFEndpointHasScope(endpointGuid, permission as ScopeStrings)); - } - - if (type === PermissionTypes.ENDPOINT) { - return this.store.select(getCurrentUserCFGlobalState(endpointGuid, permission)); +// TODO: RC name +export interface ICheckCombiner { + checks: Observable[]; + combineType?: '&&'; +} +export interface ICurrentUserPermissionsChecker { + // TODO: RC comments + getPermissionConfig: (action: string) => PermissionConfigType + getSimpleCheck: ( + permissionConfig: PermissionConfig, + endpointGuid?: string, + ...args: any + ) => Observable; + getCheckFromConfig: ( + configGroup: IConfigGroup, + permission: PermissionTypes, + ...args: any[] + ) => ICheckCombiner; + getFallbackPermission: ( + endpointGuid: string + ) => Observable; +} +export abstract class BaseCurrentUserPermissionsChecker { + public static reduceChecks(checks: Observable[], type: '||' | '&&' = '||') { + const func = type === '||' ? 'some' : 'every'; + if (!checks || !checks.length) { + return observableOf(true); } - return this.getEndpointState(endpointGuid).pipe( - filter(state => !!state), - map(state => { - const permissionString = permission as PermissionStrings; - if (allSpacesWithinOrg) { - const spaceState = state[PermissionTypes.SPACE]; - return this.checkAllSpacesInOrg(state[PermissionTypes.ORGANIZATION][orgOrSpaceGuid], spaceState, permissionString); - } - return this.selectPermission(state[type][orgOrSpaceGuid], permissionString); - }), - distinctUntilChanged(), + return combineLatest(checks).pipe( + map(flags => flags[func](flag => flag)), + distinctUntilChanged() ); } - /** - * @param permissionConfig Single permission to be checked - */ - public getSimpleCheck(permissionConfig: PermissionConfig, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string) { - switch (permissionConfig.type) { - case (PermissionTypes.FEATURE_FLAG): - return this.getFeatureFlagCheck(permissionConfig, endpointGuid); - case (PermissionTypes.ORGANIZATION): - case (PermissionTypes.SPACE): - case (PermissionTypes.ENDPOINT): - return this.getCfCheck(permissionConfig, endpointGuid, orgOrSpaceGuid, spaceGuid); - case (PermissionTypes.STRATOS): - return this.getInternalCheck(permissionConfig.permission as PermissionStrings); - case (PermissionTypes.STRATOS_SCOPE): - return this.getInternalScopesCheck(permissionConfig.permission as ScopeStrings); - case (PermissionTypes.ENDPOINT_SCOPE): - return this.getEndpointScopesCheck(permissionConfig.permission as ScopeStrings, endpointGuid); - } - } +} - private checkAllSpacesInOrg(orgState: IOrgRoleState, endpointSpaces: ISpacesRoleState, permission: PermissionStrings) { - const spaceGuids = !!orgState && orgState.spaceGuids ? orgState.spaceGuids : []; - return spaceGuids.map(spaceGuid => { - const space = endpointSpaces[spaceGuid]; - return space ? space[permission] || false : false; - }).some(check => check); - } +export enum StratosCurrentUserPermissions { + ENDPOINT_REGISTER = 'register.endpoint', + PASSWORD_CHANGE = 'change-password', +} - public getInternalChecks( - configs: PermissionConfig[] - ) { - return configs.map(config => { - const { permission } = config; - return this.getInternalCheck(permission as PermissionStrings); - }); - } +// TODO: RC filename +export enum StratosPermissionStrings { + _GLOBAL_ = 'global', // TODO: RC + STRATOS_ADMIN = 'isAdmin' +} - public getInternalCheck(permission: PermissionStrings) { - return this.check(PermissionTypes.STRATOS, permission); - } - public getInternalScopesChecks( - configs: PermissionConfig[] - ) { - return configs.map(config => { - const { permission } = config; - return this.getInternalScopesCheck(permission as ScopeStrings); - }); - } +export enum StratosScopeStrings { + STRATOS_CHANGE_PASSWORD = 'password.write', + SCIM_READ = 'scim.read' +} - public getEndpointScopesCheck(permission: ScopeStrings, endpointGuid?: string) { - const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); - return endpointGuids$.pipe( - switchMap(guids => combineLatest(guids.map(guid => this.check(PermissionTypes.ENDPOINT_SCOPE, permission, endpointGuid)))), - map(checks => checks.some(check => check)), - distinctUntilChanged() - ); - } +export enum StratosPermissionTypes { + STRATOS = 'internal', + STRATOS_SCOPE = 'internal-scope' +} - public getEndpointScopesChecks( - configs: PermissionConfig[], - endpoint?: string - ) { - return configs.map(config => { - const { permission } = config; - return this.getEndpointScopesCheck(permission as ScopeStrings, endpoint); - }); - } +// For each set permissions are checked by permission types of ENDPOINT, ENDPOINT_SCOPE, STRATOS_SCOPE, FEATURE_FLAG or a random bag. +// Every group result must be true in order for the permission to be true. A group result is true if all or some of it's permissions are +// true (see `getCheckFromConfig`). +export const stratosPermissionConfigs: IPermissionConfigs = { + [StratosCurrentUserPermissions.ENDPOINT_REGISTER]: new PermissionConfig(StratosPermissionTypes.STRATOS, StratosPermissionStrings.STRATOS_ADMIN), + [StratosCurrentUserPermissions.PASSWORD_CHANGE]: new PermissionConfig(StratosPermissionTypes.STRATOS_SCOPE, StratosScopeStrings.STRATOS_CHANGE_PASSWORD), +}; - public getInternalScopesCheck(permission: ScopeStrings) { - return this.check(PermissionTypes.STRATOS_SCOPE, permission); +export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChecker implements ICurrentUserPermissionsChecker { + constructor(private store: Store, ) { + super() } - public getCfChecks( - configs: PermissionConfig[], - endpointGuid?: string, - orgOrSpaceGuid?: string, - spaceGuid?: string - ): Observable[] { - return configs.map(config => this.getCfCheck(config, endpointGuid, orgOrSpaceGuid, spaceGuid)); + getPermissionConfig(action: string) { + return stratosPermissionConfigs[action]; } - public getCfCheck(config: PermissionConfig, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string): Observable { - const { type, permission } = config; - const checkAllSpaces = spaceGuid === CurrentUserPermissionsChecker.ALL_SPACES; - const actualGuid = type === PermissionTypes.SPACE && spaceGuid && !checkAllSpaces ? spaceGuid : orgOrSpaceGuid; - const cfPermissions = permission as PermissionStrings; - if (type === PermissionTypes.ENDPOINT || (endpointGuid && actualGuid)) { - return this.check(type, cfPermissions, endpointGuid, actualGuid, checkAllSpaces); - } else if (!actualGuid) { - const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); - return endpointGuids$.pipe( - switchMap(guids => combineLatest(guids.map(guid => this.checkAllOfType(guid, type, cfPermissions)))), - map(checks => checks.some(check => check)), - distinctUntilChanged() - ); + private check( + type: PermissionTypes, + permission: PermissionValues, + ) { + if (type === StratosPermissionTypes.STRATOS) { + return this.store.select(getCurrentUserStratosRole(permission)); } - return observableOf(false); - } - public getFeatureFlagChecks(configs: PermissionConfig[], endpointGuid?: string): Observable[] { - return configs.map(config => { - return this.getFeatureFlagCheck(config, endpointGuid); - }); - } - - public getFeatureFlagCheck(config: PermissionConfig, endpointGuid?: string): Observable { - const permission = config.permission as CFFeatureFlagTypes; - const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); - return endpointGuids$.pipe( - switchMap(guids => { - const createFFObs = guid => - // For admins we don't have the ff list which is usually fetched right at the start, - // so this can't be a pagination monitor on its own (which doesn't fetch if list is missing) - cfEntityCatalog.featureFlag.store.getPaginationService(guid).entities$; - return combineLatest(guids.map(createFFObs)); - }), - map(endpointFeatureFlags => endpointFeatureFlags.some(featureFlags => this.checkFeatureFlag(featureFlags, permission))), - // startWith(false), // Don't start with anything, this ensures first value out can be trusted. Should never get to the point where - // nothing is returned - distinctUntilChanged(), - ); - } - - public checkFeatureFlag(featureFlags: IFeatureFlag[], permission: CFFeatureFlagTypes) { - const flag = featureFlags.find(ff => ff.name === permission.toString()); - if (!flag) { - return false; + if (type === StratosPermissionTypes.STRATOS_SCOPE) { + return this.store.select(getCurrentUserStratosHasScope(permission as StratosScopeStrings)); } - return flag.enabled; - } - - public getAdminCheck(endpointGuid: string) { - return this.getEndpointState(endpointGuid).pipe( - filter(cfPermissions => !!cfPermissions), - map(cfPermissions => cfPermissions.global.isAdmin) - ); - } - - public getAdminChecks(endpointGuid?: string) { - const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); - return endpointGuids$.pipe( - map(guids => guids.map(guid => this.getAdminCheck(guid))), - switchMap(checks => this.reduceChecks(checks)) - ); - } - - /** - * Includes read only admins, global auditors and users that don't have the cloud_controller.write scope - */ - public getReadOnlyCheck(endpointGuid: string) { - return this.getEndpointState(endpointGuid).pipe( - map( - cfPermissions => ( - cfPermissions && ( - cfPermissions.global.isGlobalAuditor || - cfPermissions.global.isReadOnlyAdmin || - !cfPermissions.global.canWrite - ) - ) - ), - distinctUntilChanged() - ); } /** - * If no endpoint is passed, check them all + * @param permissionConfig Single permission to be checked */ - public getReadOnlyChecks(endpointGuid?: string) { - const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid); - return endpointGuids$.pipe( - map(guids => guids.map(guid => this.getReadOnlyCheck(guid))), - switchMap(checks => this.reduceChecks(checks, '&&')) - ); - } - - public reduceChecks(checks: Observable[], type: '||' | '&&' = '||') { - const func = type === '||' ? 'some' : 'every'; - if (!checks || !checks.length) { - return observableOf(true); - } - return combineLatest(checks).pipe( - map(flags => flags[func](flag => flag)), - distinctUntilChanged() - ); - } - - public groupConfigs(configs: PermissionConfig[]): IConfigGroups { - return configs.reduce((grouped, config) => { - const type = this.getGroupType(config); - return { - ...grouped, - [type]: [ - ...(grouped[type] || []), - config - ] - }; - }, {}); - } - - private getGroupType(config: PermissionConfig) { - if (config.type === PermissionTypes.ORGANIZATION || config.type === PermissionTypes.SPACE) { - return CHECKER_GROUPS.CF_GROUP; + public getSimpleCheck(permissionConfig: PermissionConfig): Observable { + switch (permissionConfig.type) { + case (StratosPermissionTypes.STRATOS): + return this.getInternalCheck(permissionConfig.permission as StratosPermissionStrings); + case (StratosPermissionTypes.STRATOS_SCOPE): + return this.getInternalScopesCheck(permissionConfig.permission as StratosScopeStrings); } - return config.type; } - private checkAllOfType(endpointGuid: string, type: PermissionTypes, permission: PermissionStrings, orgGuid?: string) { - return this.getEndpointState(endpointGuid).pipe( - map(state => { - if (!state || !state[type]) { - return false; - } - return Object.keys(state[type]).some(guid => { - return this.selectPermission(state[type][guid], permission); - }); - }) - ); + private getInternalCheck(permission: StratosPermissionStrings) { + return this.check(StratosPermissionTypes.STRATOS, permission); } - private getAllEndpointGuids() { - return this.store.select(connectedEndpointsSelector).pipe( - map(endpoints => Object.values(endpoints).filter(e => e.cnsi_type === 'cf').map(endpoint => endpoint.guid)) - ); + private getInternalScopesChecks( + configs: PermissionConfig[] + ) { + return configs.map(config => { + const { permission } = config; + return this.getInternalScopesCheck(permission as StratosScopeStrings); + }); } - private getEndpointGuidObservable(endpointGuid: string) { - return !endpointGuid ? this.getAllEndpointGuids() : observableOf([endpointGuid]); + private getInternalScopesCheck(permission: StratosScopeStrings) { + return this.check(StratosPermissionTypes.STRATOS_SCOPE, permission); } - private selectPermission(state: IOrgRoleState | ISpaceRoleState, permission: PermissionStrings): boolean { - return state ? state[permission] || false : false; + public getCheckFromConfig( + configGroup: IConfigGroup, + permission: PermissionTypes, + ...args: any[] + ): ICheckCombiner { + switch (permission) { + case StratosPermissionTypes.STRATOS_SCOPE: + return { + checks: this.getInternalScopesChecks(configGroup), + }; + } } + public getFallbackPermission(endpointGuid: string): Observable { + return null; + }; - private getEndpointState(endpointGuid: string) { - return this.store.select(getCurrentUserCFEndpointRolesState(endpointGuid)); - } } diff --git a/src/frontend/packages/core/src/core/current-user-permissions.config.ts b/src/frontend/packages/core/src/core/current-user-permissions.config.ts index 3781f1ca24..be00d89736 100644 --- a/src/frontend/packages/core/src/core/current-user-permissions.config.ts +++ b/src/frontend/packages/core/src/core/current-user-permissions.config.ts @@ -1,83 +1,19 @@ -import { CFFeatureFlagTypes } from '../../../cloud-foundry/src/cf-api.types'; - -export enum CurrentUserPermissions { - APPLICATION_VIEW = 'view.application', - APPLICATION_EDIT = 'edit.application', - APPLICATION_CREATE = 'create.application', - APPLICATION_MANAGE = 'manage.application', - APPLICATION_VIEW_ENV_VARS = 'env-vars.view.application', - SPACE_VIEW = 'view.space', - SPACE_CREATE = 'create.space', - SPACE_DELETE = 'delete.space', - SPACE_EDIT = 'edit.space', - SPACE_CHANGE_ROLES = 'change-roles.space', - ROUTE_CREATE = 'create.route', - // ROUTE_BINDING_CREATE = 'create.binding.route', - QUOTA_CREATE = 'create.quota', - QUOTA_EDIT = 'edit.quota', - QUOTA_DELETE = 'delete.quota', - SPACE_QUOTA_CREATE = 'create.space-quota', - SPACE_QUOTA_EDIT = 'edit.space-quota', - SPACE_QUOTA_DELETE = 'delete.space-quota', - ORGANIZATION_CREATE = 'create.org', - ORGANIZATION_DELETE = 'delete.org', - ORGANIZATION_EDIT = 'edit.org', - ORGANIZATION_SUSPEND = 'suspend.org', - ORGANIZATION_CHANGE_ROLES = 'change-roles.org', - SERVICE_INSTANCE_DELETE = 'delete.service-instance', - SERVICE_INSTANCE_CREATE = 'create.service-instance', - SERVICE_BINDING_EDIT = 'edit.service-binding', - FIREHOSE_VIEW = 'view-firehose', - ENDPOINT_REGISTER = 'register.endpoint', - PASSWORD_CHANGE = 'change-password', - SERVICE_INSTANCE_EDIT = 'edit.service-instance' -} export type PermissionConfigType = PermissionConfig[] | PermissionConfig | PermissionConfigLink; export interface IPermissionConfigs { [permissionString: string]: PermissionConfigType; } -export enum PermissionStrings { - _GLOBAL_ = 'global', - SPACE_MANAGER = 'isManager', - SPACE_AUDITOR = 'isAuditor', - SPACE_DEVELOPER = 'isDeveloper', - ORG_MANAGER = 'isManager', - ORG_AUDITOR = 'isAuditor', - ORG_BILLING_MANAGER = 'isBillingManager', - ORG_USER = 'isUser', - STRATOS_ADMIN = 'isAdmin' -} - -export enum ScopeStrings { - CF_ADMIN_GROUP = 'cloud_controller.admin', - CF_READ_ONLY_ADMIN_GROUP = 'cloud_controller.admin_read_only', - CF_ADMIN_GLOBAL_AUDITOR_GROUP = 'cloud_controller.global_auditor', - CF_WRITE_SCOPE = 'cloud_controller.write', - CF_READ_SCOPE = 'cloud_controller.write', - STRATOS_CHANGE_PASSWORD = 'password.write', - SCIM_READ = 'scim.read' -} - -export enum PermissionTypes { - SPACE = 'spaces', - ORGANIZATION = 'organizations', - ENDPOINT = 'endpoint', - ENDPOINT_SCOPE = 'endpoint-scope', - FEATURE_FLAG = 'feature-flag', - STRATOS = 'internal', - STRATOS_SCOPE = 'internal-scope' -} +export type PermissionTypes = string; +export type CurrentUserPermissions = string; +export type ScopeStrings = string; -export enum StratosPermissionTypes { - ADMIN = 'isAdmin' -} - -export type PermissionValues = StratosPermissionTypes | ScopeStrings | CFFeatureFlagTypes | PermissionStrings; +// export type PermissionValues = StratosPermissionTypes | ScopeStrings | CFFeatureFlagTypes | PermissionStrings; +export type PermissionValues = string; export class PermissionConfig { constructor( public type: PermissionTypes, - public permission: PermissionValues = PermissionStrings._GLOBAL_ + public permission: PermissionValues, + // public permission: PermissionValues = StratosPermissionStrings._GLOBAL_ ) { } } export class PermissionConfigLink { @@ -85,75 +21,3 @@ export class PermissionConfigLink { public link: CurrentUserPermissions ) { } } - -// For each set permissions are checked by permission types of ENDPOINT, ENDPOINT_SCOPE, STRATOS_SCOPE, FEATURE_FLAG or a random bag. -// Every group result must be true in order for the permission to be true. A group result is true if all or some of it's permissions are -// true (see `getCheckFromConfig`). -export const permissionConfigs: IPermissionConfigs = { - [CurrentUserPermissions.APPLICATION_VIEW]: [ - // See #2186 - new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_READ_ONLY_ADMIN_GROUP), - new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP), - new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_MANAGER), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_AUDITOR), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER) - ], - [CurrentUserPermissions.APPLICATION_CREATE]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER), - [CurrentUserPermissions.APPLICATION_MANAGE]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER), - [CurrentUserPermissions.APPLICATION_EDIT]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER), - [CurrentUserPermissions.APPLICATION_VIEW_ENV_VARS]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER), - [CurrentUserPermissions.SPACE_VIEW]: [ - // See #2186 - new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_READ_ONLY_ADMIN_GROUP), - new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP), - new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_MANAGER), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_AUDITOR), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER) - ], - [CurrentUserPermissions.SPACE_CREATE]: new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - [CurrentUserPermissions.SPACE_DELETE]: new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - [CurrentUserPermissions.SPACE_EDIT]: [ - new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_MANAGER), - ], - [CurrentUserPermissions.SPACE_CHANGE_ROLES]: [ - new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_MANAGER) - ], - // TODO: See #4189. Wire in. Can be org manager? - [CurrentUserPermissions.ROUTE_CREATE]: [ - new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.route_creation), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER) - ], - [CurrentUserPermissions.QUOTA_CREATE]: new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GROUP), - [CurrentUserPermissions.QUOTA_EDIT]: new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GROUP), - [CurrentUserPermissions.QUOTA_DELETE]: new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GROUP), - [CurrentUserPermissions.SPACE_QUOTA_CREATE]: new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - [CurrentUserPermissions.SPACE_QUOTA_EDIT]: new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - [CurrentUserPermissions.SPACE_QUOTA_DELETE]: new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - [CurrentUserPermissions.ORGANIZATION_CREATE]: [ - new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.user_org_creation), - new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_AUDITOR), - new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_BILLING_MANAGER), - new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_USER), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_MANAGER), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_AUDITOR), - new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER) - ], - [CurrentUserPermissions.ORGANIZATION_DELETE]: new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GROUP), - [CurrentUserPermissions.ORGANIZATION_EDIT]: new PermissionConfigLink(CurrentUserPermissions.ORGANIZATION_DELETE), - [CurrentUserPermissions.ORGANIZATION_SUSPEND]: new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GROUP), - [CurrentUserPermissions.ORGANIZATION_CHANGE_ROLES]: new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER), - [CurrentUserPermissions.SERVICE_INSTANCE_DELETE]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER), - [CurrentUserPermissions.SERVICE_INSTANCE_CREATE]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER), - [CurrentUserPermissions.SERVICE_INSTANCE_EDIT]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER), - [CurrentUserPermissions.SERVICE_BINDING_EDIT]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER), - [CurrentUserPermissions.FIREHOSE_VIEW]: [ - new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_READ_ONLY_ADMIN_GROUP) - ], - [CurrentUserPermissions.ENDPOINT_REGISTER]: new PermissionConfig(PermissionTypes.STRATOS, PermissionStrings.STRATOS_ADMIN), - [CurrentUserPermissions.PASSWORD_CHANGE]: new PermissionConfig(PermissionTypes.STRATOS_SCOPE, ScopeStrings.STRATOS_CHANGE_PASSWORD), -}; diff --git a/src/frontend/packages/core/src/core/current-user-permissions.service.ts b/src/frontend/packages/core/src/core/current-user-permissions.service.ts index be56d540db..0674d421cc 100644 --- a/src/frontend/packages/core/src/core/current-user-permissions.service.ts +++ b/src/frontend/packages/core/src/core/current-user-permissions.service.ts @@ -1,36 +1,45 @@ -import { Injectable } from '@angular/core'; +import { Inject, Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { combineLatest, Observable, of as observableOf } from 'rxjs'; -import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; +import { combineLatest, Observable, of } from 'rxjs'; +import { distinctUntilChanged, map } from 'rxjs/operators'; import { InternalAppState } from '../../../store/src/app-state'; import { - CHECKER_GROUPS, - CurrentUserPermissionsChecker, + BaseCurrentUserPermissionsChecker, IConfigGroup, IConfigGroups, + ICurrentUserPermissionsChecker, + StratosUserPermissionsChecker, } from './current-user-permissions.checker'; import { CurrentUserPermissions, PermissionConfig, PermissionConfigLink, - permissionConfigs, PermissionConfigType, PermissionTypes, } from './current-user-permissions.config'; +import { LoggerService } from './logger.service'; interface ICheckCombiner { checks: Observable[]; combineType?: '&&'; } +export const CUSTOM_USER_PERMISSION_CHECKERS = 'custom_user_perm_checkers' + @Injectable() export class CurrentUserPermissionsService { - private checker: CurrentUserPermissionsChecker; + // private checker: StratosUserPermissionsChecker; + private allCheckers: ICurrentUserPermissionsChecker[]; constructor( - store: Store + store: Store, + @Inject(CUSTOM_USER_PERMISSION_CHECKERS) customCheckers: ICurrentUserPermissionsChecker[], + private logger: LoggerService ) { - this.checker = new CurrentUserPermissionsChecker(store); + this.allCheckers = [ + new StratosUserPermissionsChecker(store), + ...customCheckers + ] } /** * @param action The action we're going to check the user's access to. @@ -44,81 +53,110 @@ export class CurrentUserPermissionsService { public can( action: CurrentUserPermissions | PermissionConfigType, endpointGuid?: string, - orgOrSpaceGuid?: string, - spaceGuid?: string + ...args: any[] ): Observable { - const actionConfig = this.getConfig(typeof action === 'string' ? permissionConfigs[action] : action); - const obs$ = this.getCanObservable(actionConfig, endpointGuid, orgOrSpaceGuid, spaceGuid); - return obs$ ? obs$.pipe( - distinctUntilChanged(), - ) : observableOf(false); + let actionConfig; + if (typeof action === 'string') { + let permConfigType = this.getPermissionConfig(action); + if (!permConfigType) { + return of(false); // Logging handled in getPermissionConfig + } + actionConfig = this.getConfig(permConfigType); + } else { + actionConfig = this.getConfig(action) + } + const obs$ = this.getCanObservable(actionConfig, endpointGuid, ...args); + return obs$ ? + obs$.pipe(distinctUntilChanged()) : + of(false); } private getCanObservable( actionConfig: PermissionConfig[] | PermissionConfig, endpointGuid: string, - orgOrSpaceGuid?: string, - spaceGuid?: string): Observable { + ...args: any[]): Observable { if (Array.isArray(actionConfig)) { - return this.getComplexPermission(actionConfig, endpointGuid, orgOrSpaceGuid, spaceGuid); + return this.getComplexPermission(actionConfig, endpointGuid, ...args); } else if (actionConfig) { - return this.getSimplePermission(actionConfig, endpointGuid, orgOrSpaceGuid, spaceGuid); + return this.getSimplePermission(actionConfig, endpointGuid, ...args); } else if (endpointGuid) { - return this.checker.getAdminCheck(endpointGuid); + return this.getFallbackPermission(endpointGuid); } return null; } - private getSimplePermission(actionConfig: PermissionConfig, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string) { - const check$ = this.checker.getSimpleCheck(actionConfig, endpointGuid, orgOrSpaceGuid, spaceGuid); - if (actionConfig.type === PermissionTypes.ORGANIZATION || actionConfig.type === PermissionTypes.SPACE) { - return this.applyAdminCheck(check$, endpointGuid); - } - return check$; + private getSimplePermission(actionConfig: PermissionConfig, endpointGuid: string, ...args: any[]): Observable { + return this.findChecker>( + (checker: ICurrentUserPermissionsChecker) => checker.getSimpleCheck(actionConfig, endpointGuid, ...args), + 'permissions check', + actionConfig.type, + of(false) + ) + } + + private getComplexPermission(actionConfigs: PermissionConfig[], endpointGuid?: string, ...args: any[]) { + const groupedChecks = this.groupConfigs(actionConfigs); + const checks = this.getChecksFromConfigGroups(groupedChecks, endpointGuid, ...args); + return this.combineChecks(checks); } - private getComplexPermission(actionConfigs: PermissionConfig[], endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string) { - const groupedChecks = this.checker.groupConfigs(actionConfigs); - const checks = this.getChecksFromConfigGroups(groupedChecks, endpointGuid, orgOrSpaceGuid, spaceGuid); - return this.combineChecks(checks, endpointGuid); + private groupConfigs(configs: PermissionConfig[]): IConfigGroups { + return configs.reduce((grouped, config) => { + const type = config.type; + return { + ...grouped, + [type]: [ + ...(grouped[type] || []), + config + ] + }; + }, {}); } - private getChecksFromConfigGroups(groups: IConfigGroups, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string) { + private getChecksFromConfigGroups(groups: IConfigGroups, endpointGuid?: string, ...args: any[]) { return Object.keys(groups).map((permission: PermissionTypes) => { - return this.getCheckFromConfig(groups[permission], permission, endpointGuid, orgOrSpaceGuid, spaceGuid); + return this.getCheckFromConfig(groups[permission], permission, endpointGuid, ...args); }); } private getCheckFromConfig( configGroup: IConfigGroup, - permission: PermissionTypes | CHECKER_GROUPS, - endpointGuid?: string, - orgOrSpaceGuid?: string, - spaceGuid?: string + permission: PermissionTypes, + endpointGuid: string, + ...args: any[] ): ICheckCombiner { - switch (permission) { - case PermissionTypes.ENDPOINT: - return { - checks: this.checker.getInternalScopesChecks(configGroup), - }; - case PermissionTypes.ENDPOINT_SCOPE: - return { - checks: this.checker.getEndpointScopesChecks(configGroup, endpointGuid), - }; - case PermissionTypes.STRATOS_SCOPE: - return { - checks: this.checker.getInternalScopesChecks(configGroup), - }; - case PermissionTypes.FEATURE_FLAG: - return { - checks: this.checker.getFeatureFlagChecks(configGroup, endpointGuid), - combineType: '&&' - }; - case CHECKER_GROUPS.CF_GROUP: - return { - checks: this.checker.getCfChecks(configGroup, endpointGuid, orgOrSpaceGuid, spaceGuid) - }; - } + return this.findChecker( + (checker: ICurrentUserPermissionsChecker) => checker.getCheckFromConfig(configGroup, permission, endpointGuid, ...args), + 'permissions check', + permission, + { + checks: [of(false)] + } + ) + + // switch (permission) { + // case PermissionTypes.ENDPOINT: + // return { + // checks: this.checker.getInternalScopesChecks(configGroup), + // }; + // case PermissionTypes.ENDPOINT_SCOPE: + // return { + // checks: this.checker.getEndpointScopesChecks(configGroup, endpointGuid), + // }; + // case PermissionTypes.STRATOS_SCOPE: + // return { + // checks: this.checker.getInternalScopesChecks(configGroup), + // }; + // case PermissionTypes.FEATURE_FLAG: + // return { + // checks: this.checker.getFeatureFlagChecks(configGroup, endpointGuid), + // combineType: '&&' + // }; + // case CHECKER_GROUPS.CF_GROUP: //PermissionTypes.ORGANIZATION || config.type === PermissionTypes.SPACE + // return { + // checks: this.checker.getCfChecks(configGroup, endpointGuid, orgOrSpaceGuid, spaceGuid) + // }; + // } } private getConfig(config: PermissionConfigType, tries = 0): PermissionConfig[] | PermissionConfig { @@ -136,39 +174,64 @@ export class CurrentUserPermissionsService { } private getLinkedPermissionConfig(linkConfig: PermissionConfigLink, tries = 0) { - return this.getConfig(permissionConfigs[linkConfig.link]); - } - - private applyAdminCheck(check$: Observable, endpointGuid?: string) { - const adminCheck$ = this.checker.getAdminChecks(endpointGuid); - const readOnlyCheck$ = this.checker.getReadOnlyChecks(endpointGuid); - return combineLatest( - adminCheck$, - readOnlyCheck$ - ).pipe( - distinctUntilChanged(), - switchMap(([isAdmin, isReadOnly]) => { - if (isAdmin) { - return observableOf(true); - } - if (isReadOnly) { - return observableOf(false); - } - return check$; - }) - ); + return this.getConfig(this.getPermissionConfig(linkConfig.link), tries); } private combineChecks( checkCombiners: ICheckCombiner[], - endpointGuid?: string ) { - const reducedChecks = checkCombiners.map(combiner => this.checker.reduceChecks(combiner.checks, combiner.combineType)); - const check$ = combineLatest(reducedChecks).pipe( - map(checks => { - return checks.every(check => check); - }) + const reducedChecks = checkCombiners.map(combiner => BaseCurrentUserPermissionsChecker.reduceChecks(combiner.checks, combiner.combineType)); + return combineLatest(reducedChecks).pipe( + map(checks => checks.every(check => check)) ); - return this.applyAdminCheck(check$, endpointGuid); + } + + private getFallbackPermission(endpointGuid: string): Observable { + return this.findChecker>( + (checker: ICurrentUserPermissionsChecker) => checker.getFallbackPermission(endpointGuid), + 'fallback permission', + 'N/A', + of(null) + ) + } + + private getPermissionConfig(key: CurrentUserPermissions): PermissionConfigType { + return this.findChecker( + (checker: ICurrentUserPermissionsChecker) => checker.getPermissionConfig(key), + 'permissions checker', + key, + null + ) + } + + /** + * Search through all known checkers for a single result + * If none are found log warning (hints at bug/misconfigure). + * If more than one is found log warning (hints re bug/misconfigure/devious plugin) + */ + private findChecker( + checkFn: (checker: ICurrentUserPermissionsChecker) => T, + checkNoun: string, + checkType: string, + failureValue: T + ): T { + const res: T[] = []; + for (let i = 0; i < this.allCheckers.length; i++) { + const checkerRes = checkFn(this.allCheckers[i]); + if (checkerRes) { + res.push(checkerRes); + } + } + if (res.length == 0) { + this.logger.warn(`Permissions: Failed to find a '${checkNoun}' for '${checkType}'. Permission Denied.`); + return failureValue; + } + if (res.length === 1) { + return res[0]; + } + if (res.length > 1) { + this.logger.warn(`Permissions: Found too many '${checkNoun}' for '${checkType}'. Permission Denied.`); + return failureValue; + } } } diff --git a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts index 969a5a5dd1..3e7c65a533 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts @@ -18,7 +18,7 @@ import { delay, first, map, tap } from 'rxjs/operators'; import { RouterNav } from '../../../../../store/src/actions/router.actions'; import { EndpointOnlyAppState } from '../../../../../store/src/app-state'; import { selectDashboardState } from '../../../../../store/src/selectors/dashboard.selectors'; -import { CurrentUserPermissions } from '../../../core/current-user-permissions.config'; +import { StratosCurrentUserPermissions } from '../../../core/current-user-permissions.checker'; import { CustomizationService, CustomizationsMetadata } from '../../../core/customizations.types'; import { EndpointsService } from '../../../core/endpoints.service'; import { @@ -43,7 +43,7 @@ import { ListConfig } from '../../../shared/components/list/list.component.types }, EndpointListHelper] }) export class EndpointsPageComponent implements AfterViewInit, OnDestroy, OnInit { - public canRegisterEndpoint = CurrentUserPermissions.ENDPOINT_REGISTER; + public canRegisterEndpoint = StratosCurrentUserPermissions.ENDPOINT_REGISTER; private healthCheckTimeout: number; @ViewChild('customNoEndpoints', { read: ViewContainerRef, static: true }) customNoEndpointsContainer; diff --git a/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.ts b/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.ts index 8f14434f3a..78092a04b6 100644 --- a/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.ts +++ b/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.ts @@ -5,7 +5,7 @@ import { Subscription } from 'rxjs'; import { first, map, take, tap } from 'rxjs/operators'; import { UserProfileInfo, UserProfileInfoUpdates } from '../../../../../store/src/types/user-profile.types'; -import { CurrentUserPermissions } from '../../../core/current-user-permissions.config'; +import { StratosCurrentUserPermissions } from '../../../core/current-user-permissions.checker'; import { CurrentUserPermissionsService } from '../../../core/current-user-permissions.service'; import { UserProfileService } from '../../../core/user-profile.service'; import { StepOnNextFunction } from '../../../shared/components/stepper/step/step.component'; @@ -53,7 +53,7 @@ export class EditProfileInfoComponent implements OnInit, OnDestroy { // Only allow password change if user has the 'password.write' group - public canChangePassword = this.currentUserPermissionsService.can(CurrentUserPermissions.PASSWORD_CHANGE); + public canChangePassword = this.currentUserPermissionsService.can(StratosCurrentUserPermissions.PASSWORD_CHANGE); public passwordRequired = false; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts index 42cdbed9bf..d6d8aeb6f3 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts @@ -9,7 +9,6 @@ import { ViewContainerRef, } from '@angular/core'; import { Store } from '@ngrx/store'; -import { CurrentUserPermissions } from 'frontend/packages/core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from 'frontend/packages/core/src/core/current-user-permissions.service'; import { AppState } from 'frontend/packages/store/src/app-state'; import { Observable, of, ReplaySubject, Subscription } from 'rxjs'; @@ -21,6 +20,7 @@ import { } from '../../../../../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types'; +import { StratosCurrentUserPermissions } from '../../../../../../core/current-user-permissions.checker'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; import { coreEndpointListDetailsComponents, @@ -111,7 +111,7 @@ export class EndpointCardComponent extends CardCell implements On this.cardMenu.push({ label: 'Edit endpoint', action: () => this.editEndpoint(), - can: this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER) + can: this.currentUserPermissionsService.can(StratosCurrentUserPermissions.ENDPOINT_REGISTER) }); this.cardMenu.push(createMetaCardMenuItemSeparator()); diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts index d785fb066b..f6134fa41d 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts @@ -14,7 +14,7 @@ import { endpointSchemaKey } from '../../../../../../../store/src/helpers/entity import { selectDeletionInfo, selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors'; import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; import { STRATOS_ENDPOINT_TYPE } from '../../../../../base-entity-schemas'; -import { CurrentUserPermissions } from '../../../../../core/current-user-permissions.config'; +import { StratosCurrentUserPermissions } from '../../../../../core/current-user-permissions.checker'; import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; import { LoggerService } from '../../../../../core/logger.service'; import { @@ -72,7 +72,7 @@ export class EndpointListHelper { label: 'Disconnect', description: ``, // Description depends on console user permission createVisible: (row$: Observable) => combineLatest( - this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER), + this.currentUserPermissionsService.can(StratosCurrentUserPermissions.ENDPOINT_REGISTER), row$ ).pipe( map(([isAdmin, row]) => { @@ -119,7 +119,7 @@ export class EndpointListHelper { }, label: 'Unregister', description: 'Remove the endpoint', - createVisible: () => this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER) + createVisible: () => this.currentUserPermissionsService.can(StratosCurrentUserPermissions.ENDPOINT_REGISTER) } ]; } diff --git a/src/frontend/packages/core/src/shared/user-permission.directive.ts b/src/frontend/packages/core/src/shared/user-permission.directive.ts index 6cb7102f04..9ef787cb02 100644 --- a/src/frontend/packages/core/src/shared/user-permission.directive.ts +++ b/src/frontend/packages/core/src/shared/user-permission.directive.ts @@ -4,17 +4,17 @@ import { Observable, of as observableOf, Subscription } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { waitForCFPermissions } from '../../../cloud-foundry/src/features/cloud-foundry/cf.helpers'; +import { CfCurrentUserPermissions } from '../../../cloud-foundry/src/user-permissions/cf-user-permissions-checkers'; import { AppState } from '../../../store/src/app-state'; -import { CurrentUserPermissions } from '../core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../core/current-user-permissions.service'; @Directive({ selector: '[appUserPermission]' }) export class UserPermissionDirective implements OnDestroy, OnInit { - + // TODO: move @Input() - public appUserPermission: CurrentUserPermissions; + public appUserPermission: CfCurrentUserPermissions; @Input() public appUserPermissionEndpointGuid: string; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts index d10b67359f..a3754b6e1c 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts @@ -200,6 +200,15 @@ class EntityCatalog { return allEntityReducers; }, {} as ExtraApiReducers>); } + + public getAllCurrentUserReducers() { + const endpoints = this.getAllEndpointTypes(); + endpoints.forEach(endpoint => { + if (endpoint.definition.userRolesReducer) { + console.log(endpoint.type) // TODO: RC + } + }) + } } // Only to be used for tests diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index 130194253b..368fdb409d 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -20,6 +20,7 @@ import { PaginationPageIteratorConfig, } from '../entity-request-pipeline/pagination-request-base-handlers/pagination-iterator.pipe'; import { EntitySchema } from '../helpers/entity-schema'; +import { ICurrentUserRolesState } from '../types/current-user-roles.types'; import { UserFavorite } from '../types/user-favorites.types'; export interface EntityCatalogEntityConfig { @@ -129,6 +130,8 @@ export interface IStratosEndpointDefinition( entity: any, entityKey: string, favoritesConfigMapper: FavoritesConfigMapper ) => UserFavorite; + readonly userRolesInit?: () => Observable // TODO: RC Comment + readonly userRolesReducer?: () => ICurrentUserRolesState // TODO: RC Comment } export interface StratosEndpointExtensionDefinition extends Omit { } diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts index 8e41424bf8..a2b1be5a6c 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts @@ -3,7 +3,7 @@ import { ICfRolesState, IGlobalRolesState, } from '../../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; -import { ScopeStrings } from '../../../../core/src/core/current-user-permissions.config'; +import { CfScopeStrings } from '../../../../cloud-foundry/src/user-permissions/cf-user-permissions-checkers'; import { VerifiedSession } from '../../actions/auth.actions'; import { EndpointActionComplete } from '../../actions/endpoint.actions'; import { SessionUser } from '../../types/auth.types'; @@ -84,19 +84,19 @@ function getEndpointRoles(scopes: string[], globalEndpointState: IGlobalRolesSta scopes }; return scopes.reduce((roles, scope) => { - if (scope === ScopeStrings.CF_ADMIN_GROUP) { + if (scope === CfScopeStrings.CF_ADMIN_GROUP) { roles.isAdmin = true; } - if (scope === ScopeStrings.CF_READ_ONLY_ADMIN_GROUP) { + if (scope === CfScopeStrings.CF_READ_ONLY_ADMIN_GROUP) { roles.isReadOnlyAdmin = true; } - if (scope === ScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP) { + if (scope === CfScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP) { roles.isGlobalAuditor = true; } - if (scope === ScopeStrings.CF_READ_SCOPE) { + if (scope === CfScopeStrings.CF_READ_SCOPE) { roles.canRead = true; } - if (scope === ScopeStrings.CF_WRITE_SCOPE) { + if (scope === CfScopeStrings.CF_WRITE_SCOPE) { roles.canWrite = true; } return roles; diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts index a6b8e15508..78d91fd386 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts @@ -28,6 +28,7 @@ import { REGISTER_ENDPOINTS_SUCCESS, UNREGISTER_ENDPOINTS_SUCCESS, } from '../../actions/endpoint.actions'; +import { entityCatalog } from '../../entity-catalog/entity-catalog'; import { getDefaultRolesRequestState, ICurrentUserRolesState } from '../../types/current-user-roles.types'; import { APISuccessOrFailedAction } from '../../types/request.types'; import { @@ -73,6 +74,9 @@ export function currentUserRolesReducer(state: ICurrentUserRolesState = getDefau case GET_CURRENT_USER_RELATIONS: case GET_CURRENT_USER_RELATIONS_SUCCESS: case GET_CURRENT_USER_RELATIONS_FAILED: + // TODO: RC Comment. can cause issues if plugins have same action type names. Should use same method as + // requestData in entity-catalog.module + entityCatalog.getAllCurrentUserReducers(); return { ...state, state: currentUserRolesRequestStateReducer(state.state, action.type) diff --git a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts index 5f52c49b13..f142466a1a 100644 --- a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts +++ b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts @@ -1,35 +1,36 @@ import { compose } from '@ngrx/store'; -import { ICfRolesState, RoleEntities } from '../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; -import { PermissionStrings, PermissionValues, ScopeStrings } from '../../../core/src/core/current-user-permissions.config'; +import { ICfRolesState } from '../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; +import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; +import { PermissionValues, ScopeStrings } from '../../../core/src/core/current-user-permissions.config'; import { CurrentUserRolesAppState } from '../app-state'; import { ICurrentUserRolesState, IStratosRolesState } from '../types/current-user-roles.types'; export const selectCurrentUserRolesState = (state: CurrentUserRolesAppState) => state.currentUserRoles; -export const selectCurrentUserStratosRolesState = (state: ICurrentUserRolesState) => state.internal; +const selectCurrentUserStratosRolesState = (state: ICurrentUserRolesState) => state.internal; -export const selectCurrentUserStratosRoles = (role: PermissionValues) => (state: Omit) => { +const selectCurrentUserStratosRoles = (role: PermissionValues) => (state: Omit) => { // Note - should not cover `scopes` return state[role] || false; }; -export const selectEntityWithRole = (role: PermissionStrings, type: RoleEntities) => (state: ICfRolesState) => { - const entityType = state[type]; - return Object.keys(entityType).filter(entity => entityType[entity][role]); -}; +// TODO: RC tidy +// export const selectEntityWithRole = (role: PermissionStrings, type: RoleEntities) => (state: ICfRolesState) => { +// const entityType = state[type]; +// return Object.keys(entityType).filter(entity => entityType[entity][role]); +// }; export const selectCurrentUserRequestState = (state: ICurrentUserRolesState | ICfRolesState) => state.state; -// TODO: CF code in this file - needs to be moved out - #3769 -export const selectCurrentUserCFGlobalHasScopes = (scope: ScopeStrings) => (scopes: ScopeStrings[]) => scopes.includes(scope); -export const selectCurrentUserCFStratosScopesState = (state: IStratosRolesState) => state.scopes; +export const selectCurrentUserGlobalHasScopes = (scope: ScopeStrings) => (scopes: ScopeStrings[]) => scopes.includes(scope); +const selectCurrentUserStratosScopesState = (state: IStratosRolesState) => state.scopes; // Top level stratos endpoint role objects // ============================ -export const getCurrentUserStratosRolesState = compose( +const getCurrentUserStratosRolesState = compose( selectCurrentUserStratosRolesState, selectCurrentUserRolesState ); @@ -45,9 +46,9 @@ export const getCurrentUserStratosRole = (role: PermissionValues) => compose( // Top level stratos endpoint scopes // ============================ -export const getCurrentUserStratosHasScope = (scope: ScopeStrings) => compose( - selectCurrentUserCFGlobalHasScopes(scope), - selectCurrentUserCFStratosScopesState, +export const getCurrentUserStratosHasScope = (scope: StratosScopeStrings) => compose( + selectCurrentUserGlobalHasScopes(scope), + selectCurrentUserStratosScopesState, // TODO: RC cf stuff shouldn't be getCurrentUserStratosRolesState ); // ============================ @@ -55,9 +56,9 @@ export const getCurrentUserStratosHasScope = (scope: ScopeStrings) => compose( // Top level request state // ============================ -export const getCurrentUserRequestState = compose( - selectCurrentUserRequestState, - selectCurrentUserRolesState -); +// export const getCurrentUserRequestState = compose( +// selectCurrentUserRequestState, +// selectCurrentUserRolesState +// ); // ============================ diff --git a/src/frontend/packages/store/src/types/auth.types.ts b/src/frontend/packages/store/src/types/auth.types.ts index de78d33feb..9800f2eb91 100644 --- a/src/frontend/packages/store/src/types/auth.types.ts +++ b/src/frontend/packages/store/src/types/auth.types.ts @@ -1,22 +1,17 @@ -import { ScopeStrings } from '../../../core/src/core/current-user-permissions.config'; +import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; export interface SessionDataEndpoint { guid: string; name: string; version: string; - user: { - admin: boolean, - guid: string, - name: string, - scopes: ScopeStrings[]; - }; + user: SessionUser; type: string; } export interface SessionUser { admin: boolean; guid: string; name: string; - scopes: ScopeStrings[]; + scopes: StratosScopeStrings[]; // TODO: RC check } export interface PluginConfig { userInvitationsEnabled: 'true' | 'false'; diff --git a/src/frontend/packages/store/src/types/current-user-roles.types.ts b/src/frontend/packages/store/src/types/current-user-roles.types.ts index c79f4c25e1..7eb2d22878 100644 --- a/src/frontend/packages/store/src/types/current-user-roles.types.ts +++ b/src/frontend/packages/store/src/types/current-user-roles.types.ts @@ -1,5 +1,5 @@ import { IAllCfRolesState, ICfRolesState } from '../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; -import { ScopeStrings } from '../../../core/src/core/current-user-permissions.config'; +import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; export interface RolesRequestState { initialised: boolean; @@ -37,7 +37,7 @@ export function getDefaultEndpointRoles(): ICfRolesState { export interface IStratosRolesState { isAdmin: boolean; - scopes: ScopeStrings[]; + scopes: StratosScopeStrings[]; } export interface ICurrentUserRolesState { diff --git a/src/frontend/packages/store/src/types/endpoint.types.ts b/src/frontend/packages/store/src/types/endpoint.types.ts index aedd7673fd..eb0f6a175b 100644 --- a/src/frontend/packages/store/src/types/endpoint.types.ts +++ b/src/frontend/packages/store/src/types/endpoint.types.ts @@ -1,4 +1,4 @@ -import { ScopeStrings } from '../../../core/src/core/current-user-permissions.config'; +import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; import { EndpointType } from '../../../core/src/core/extension/extension-types'; import { MetricsAPITargets, MetricsStratosInfo } from '../actions/metrics-api.actions'; import { endpointSchemaKey } from '../helpers/entity-factory'; @@ -68,7 +68,7 @@ export interface EndpointUser { guid: string; name: string; admin: boolean; - scopes?: ScopeStrings[]; + scopes?: StratosScopeStrings[]; // TODO: RC } export interface EndpointState { From cc35806e5a0bbb7415ab9ac737cb4cd20dbe3d73 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Fri, 22 May 2020 16:14:30 +0100 Subject: [PATCH 02/82] First pass at permission effects --- .../src/actions/permissions.actions.ts | 4 +- .../cloud-foundry/src/cf-entity-generator.ts | 3 +- .../src/store/cloud-foundry.store.module.ts | 3 +- .../src/store/effects/permissions.effect.ts | 274 ------------------ .../src/store/effects/roles.effects.ts | 28 ++ .../user-permissions/cf-user-roles-fetch.ts | 215 ++++++++++++++ .../store/src/effects/permissions.effect.ts | 64 ++++ .../entity-catalog/entity-catalog.types.ts | 3 +- .../entity-request-pipeline.types.ts | 13 +- .../packages/store/src/entity-service.ts | 82 ++++-- .../pagination-reducer.helper.ts | 6 +- .../packages/store/src/store.module.ts | 4 +- 12 files changed, 385 insertions(+), 314 deletions(-) delete mode 100644 src/frontend/packages/cloud-foundry/src/store/effects/permissions.effect.ts create mode 100644 src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts create mode 100644 src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts create mode 100644 src/frontend/packages/store/src/effects/permissions.effect.ts diff --git a/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts index 1cd3efeb4e..0abc15b0d2 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts @@ -1,8 +1,8 @@ +import { HttpRequest } from '@angular/common/http'; import { Action } from '@ngrx/store'; import { APIResource } from '../../../store/src/types/api.types'; import { organizationEntityType, spaceEntityType } from '../cf-entity-types'; -import { HttpRequest } from '@angular/common/http'; export const GET_AUDITED_ORG_CURRENT_USER_RELATIONS = '[Current User] Get audited org Relations'; export const GET_AUDITED_ORG_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get audited org Relations success'; @@ -40,10 +40,12 @@ export const GET_CURRENT_USER_RELATIONS = '[Current User] Get relations'; export const GET_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get relations success'; export const GET_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get relations failed'; +// TODO: RC MOVE export const GET_CURRENT_USER_CF_RELATIONS = '[Current User] Get CF relations'; export const GET_CURRENT_USER_CF_RELATIONS_SUCCESS = '[Current User] Get CF relations success'; export const GET_CURRENT_USER_CF_RELATIONS_FAILED = '[Current User] Get CF relations failed'; +// TODO: RC RENAME ALL THIS export class GetCurrentUsersRelations implements Action { type = GET_CURRENT_USER_RELATIONS; } diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts index ec6dcc7c40..f227313a5b 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts @@ -176,6 +176,7 @@ import { AppStat } from './store/types/app-metadata.types'; import { CFResponse } from './store/types/cf-api.types'; import { GitBranch, GitCommit, GitRepo } from './store/types/git.types'; import { CfUser } from './store/types/user.types'; +import { cfUserRolesFetch } from './user-permissions/cf-user-roles-fetch'; function safePopulatePaginationFromParent(store: Store, action: PaginatedAction): Observable { return populatePaginationFromParent(store, action).pipe( @@ -365,7 +366,7 @@ export function generateCFEntities(): StratosBaseCatalogEntity[] { ); }, }, - userRolesInit: () => of(false), // TODO: RC implement + userRolesFetch: cfUserRolesFetch, // TODO: RC implement userRolesReducer: () => { // TODO: RC implement console.log('HELLO WORLD'); return null; diff --git a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts index 682951856c..4d79871526 100644 --- a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts +++ b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts @@ -9,8 +9,8 @@ import { CloudFoundryEffects } from './effects/cloud-foundry.effects'; import { CreateAppPageEffects } from './effects/create-app-effects'; import { DeployAppEffects } from './effects/deploy-app.effects'; import { GithubEffects } from './effects/github.effects'; -import { PermissionEffects, PermissionsEffects } from './effects/permissions.effect'; import { CfValidateEffects } from './effects/request.effects'; +import { PermissionEffects } from './effects/roles.effects'; import { RouteEffect } from './effects/route.effects'; import { ServiceInstanceEffects } from './effects/service-instance.effects'; import { UpdateAppEffects } from './effects/update-app-effects'; @@ -25,7 +25,6 @@ import { UpdateAppEffects } from './effects/update-app-effects'; GithubEffects, CloudFoundryEffects, RouteEffect, - PermissionsEffects, PermissionEffects, ServiceInstanceEffects, AppEffects, diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/permissions.effect.ts b/src/frontend/packages/cloud-foundry/src/store/effects/permissions.effect.ts deleted file mode 100644 index 8c713def7c..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/effects/permissions.effect.ts +++ /dev/null @@ -1,274 +0,0 @@ -import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; -import { Action, Store } from '@ngrx/store'; -import { endpointsCfEntitiesConnectedSelector } from 'frontend/packages/store/src/selectors/endpoint.selectors'; -import { combineLatest, Observable, of as observableOf } from 'rxjs'; -import { - catchError, - first, - map, - mergeMap, - pairwise, - share, - skipWhile, - switchMap, - tap, - withLatestFrom, -} from 'rxjs/operators'; - -import { LoggerService } from '../../../../core/src/core/logger.service'; -import { CONNECT_ENDPOINTS_SUCCESS, EndpointActionComplete } from '../../../../store/src/actions/endpoint.actions'; -import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog'; -import { - BaseHttpClientFetcher, - flattenPagination, - PaginationFlattener, -} from '../../../../store/src/helpers/paginated-request-helpers'; -import { ActionState } from '../../../../store/src/reducers/api-request-reducer/types'; -import { selectPaginationState } from '../../../../store/src/selectors/pagination.selectors'; -import { EndpointModel, INewlyConnectedEndpointInfo } from '../../../../store/src/types/endpoint.types'; -import { BasePaginatedAction, PaginationEntityState } from '../../../../store/src/types/pagination.types'; -import { - GET_CURRENT_USER_CF_RELATIONS, - GET_CURRENT_USER_CF_RELATIONS_FAILED, - GET_CURRENT_USER_CF_RELATIONS_SUCCESS, - GET_CURRENT_USER_RELATION, - GET_CURRENT_USER_RELATIONS, - GET_CURRENT_USER_RELATIONS_FAILED, - GET_CURRENT_USER_RELATIONS_SUCCESS, - GetCurrentUserRelationsComplete, - GetCurrentUsersRelations, - GetUserCfRelations, - GetUserRelations, - UserRelationTypes, -} from '../../actions/permissions.actions'; -import { CFAppState } from '../../cf-app-state'; -import { cfEntityCatalog } from '../../cf-entity-catalog'; -import { CFResponse } from '../types/cf-api.types'; - -class PermissionFlattener extends BaseHttpClientFetcher implements PaginationFlattener { - - constructor(httpClient: HttpClient, public url, public requestOptions: { [key: string]: any }) { - super(httpClient, url, requestOptions, 'page'); - } - public getTotalPages = (res: CFResponse) => res.total_pages; - - public mergePages = (res: CFResponse[]) => { - const firstRes = res.shift(); - const final = res.reduce((finalRes, currentRes) => { - finalRes.resources = [ - ...finalRes.resources, - ]; - return finalRes; - }, firstRes); - return final; - } - public getTotalResults = (res: CFResponse): number => res.total_results; - public clearResults = (res: CFResponse) => observableOf(res); -} - -interface CfsRequestState { - [cfGuid: string]: Observable[]; -} - -interface IEndpointConnectionInfo { - guid: string; - userGuid: string; -} - -const successAction: Action = { type: GET_CURRENT_USER_RELATIONS_SUCCESS }; -const failedAction: Action = { type: GET_CURRENT_USER_RELATIONS_FAILED }; - -function fetchCfUserRole(store: Store, action: GetUserRelations, httpClient: HttpClient): Observable { - const url = `pp/v1/proxy/v2/users/${action.guid}/${action.relationType}`; - const params = { - headers: { - 'x-cap-cnsi-list': action.endpointGuid, - 'x-cap-passthrough': 'true' - }, - params: { - 'results-per-page': '100' - } - }; - const get$ = httpClient.get( - url, - params - ); - return flattenPagination( - (flatAction: Action) => this.store.dispatch(flatAction), - get$, - new PermissionFlattener(httpClient, url, params) - ).pipe( - map(data => { - store.dispatch(new GetCurrentUserRelationsComplete(action.relationType, action.endpointGuid, data.resources)); - return true; - }), - first(), - catchError(err => observableOf(false)), - share() - ); -} - -const fetchPaginationStateFromAction = (store: Store, action: BasePaginatedAction) => { - const entityKey = entityCatalog.getEntityKey(action); - return store.select(selectPaginationState(entityKey, action.paginationKey)); -}; - -/** - * Using the given action wait until the associated pagination section changes from busy to not busy - */ -const createPaginationCompleteWatcher = (store: Store, action: BasePaginatedAction): Observable => - fetchPaginationStateFromAction(store, action).pipe( - map((paginationState: PaginationEntityState) => { - const pageRequest: ActionState = - paginationState && paginationState.pageRequests && paginationState.pageRequests[paginationState.currentPage]; - return pageRequest ? pageRequest.busy : true; - }), - pairwise(), - map(([oldFetching, newFetching]) => { - return oldFetching === true && newFetching === false; - }), - skipWhile(completed => !completed), - first(), - ); - -@Injectable() -export class PermissionsEffects { - constructor( - private httpClient: HttpClient, - private actions$: Actions, - private store: Store, - private logService: LoggerService - ) { } - - @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( - ofType(GET_CURRENT_USER_RELATIONS), - withLatestFrom(this.store.select(endpointsCfEntitiesConnectedSelector)), - switchMap(([action, endpoints]) => { - const endpointsArray = Object.values(endpoints); - const isAllAdmins = endpointsArray.every(endpoint => !!endpoint.user.admin); - - // If all endpoints are connected as admin, there's no permissions to fetch. So only update the permission state to initialised - if (isAllAdmins) { - return [ - successAction, - ...endpointsArray.map(endpoint => new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS)) - ]; - } - - // If some endpoints are not connected as admin, go out and fetch the current user's specific roles - const flagsAndRoleRequests = this.dispatchRoleRequests(endpointsArray); - const allRequestsCompleted = this.handleCfRequests(flagsAndRoleRequests); - return combineLatest(allRequestsCompleted).pipe( - switchMap(succeeds => succeeds.every(succeeded => !!succeeded) ? [successAction] : [failedAction]) - ); - }), - catchError(err => { - this.logService.warn('Failed to fetch current user permissions: ', err); - return observableOf([failedAction]); - }) - ); - - - @Effect() getPermissionForNewlyConnectedEndpoint$ = this.actions$.pipe( - ofType(CONNECT_ENDPOINTS_SUCCESS), - switchMap(action => { - const endpoint = action.endpoint as INewlyConnectedEndpointInfo; - if (endpoint.user.admin || action.endpointType !== 'cf') { - return endpoint.user.admin ? [new GetUserCfRelations(action.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS)] : []; - } - - // START fetching cf roles for current user - this.store.dispatch(new GetUserCfRelations(action.guid, GET_CURRENT_USER_CF_RELATIONS)); - - return combineLatest(this.fetchCfUserRoles({ guid: action.guid, userGuid: endpoint.user.guid })).pipe( - // FINISH fetching cf roles for current user - mergeMap(succeeds => [new GetUserCfRelations( - action.guid, - succeeds.every(succeeded => !!succeeded) ? GET_CURRENT_USER_CF_RELATIONS_SUCCESS : GET_CURRENT_USER_CF_RELATIONS_FAILED - )]), - catchError(err => { - this.logService.warn('Failed to fetch current user permissions for a cf: ', err); - return [new GetUserCfRelations(action.guid, GET_CURRENT_USER_CF_RELATIONS_FAILED)]; - }) - ); - }) - ); - - - private dispatchRoleRequests(endpoints: EndpointModel[]): CfsRequestState { - const requests: CfsRequestState = {}; - - // Per endpoint fetch feature flags and user roles (unless admin, where we don't need to), then mark endpoint as initialised - endpoints.forEach(endpoint => { - if (endpoint.user.admin) { - // We don't need permissions for admin users (they can do everything) - requests[endpoint.guid] = [observableOf(true)]; - this.store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS)); - } else { - // START fetching cf roles for current user - this.store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS)); - - // Dispatch feature flags fetch actions - const ffAction = cfEntityCatalog.featureFlag.actions.getMultiple(endpoint.guid) - requests[endpoint.guid] = [createPaginationCompleteWatcher(this.store, ffAction)]; - this.store.dispatch(ffAction); - - // Dispatch requests to fetch roles per role type for current user - requests[endpoint.guid].push(...this.fetchCfUserRoles({ guid: endpoint.guid, userGuid: endpoint.user.guid })); - - // FINISH fetching cf roles for current user - combineLatest(requests[endpoint.guid]).pipe( - first(), - tap(succeeds => { - this.store.dispatch(new GetUserCfRelations( - endpoint.guid, - succeeds.every(succeeded => !!succeeded) ? GET_CURRENT_USER_CF_RELATIONS_SUCCESS : GET_CURRENT_USER_CF_RELATIONS_FAILED) - ); - }), - catchError(err => { - this.logService.warn('Failed to fetch current user permissions for a cf: ', err); - this.store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_FAILED)); - return observableOf(err); - }) - ).subscribe(); - } - }); - return requests; - } - - private handleCfRequests(requests: CfsRequestState): Observable[] { - const allCompleted: Observable[] = []; - Object.keys(requests).forEach(cfGuid => { - const successes = requests[cfGuid]; - allCompleted.push(...successes); - }); - return allCompleted; - } - - fetchCfUserRoles(endpoint: IEndpointConnectionInfo): Observable[] { - return Object.values(UserRelationTypes).map((type: UserRelationTypes) => { - const relAction = new GetUserRelations(endpoint.userGuid, type, endpoint.guid); - return fetchCfUserRole(this.store, relAction, this.httpClient); - }); - } -} - -@Injectable() -export class PermissionEffects { - constructor( - private httpClient: HttpClient, - private actions$: Actions, - private store: Store - ) { } - - @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( - ofType(GET_CURRENT_USER_RELATION), - map(action => { - return fetchCfUserRole(this.store, action, this.httpClient).pipe( - map((success) => ({ type: action.actions[1] })) - ); - }) - ); -} diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts new file mode 100644 index 0000000000..2770acc86f --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts @@ -0,0 +1,28 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Store } from '@ngrx/store'; +import { map } from 'rxjs/operators'; + +import { GET_CURRENT_USER_RELATION, GetUserRelations } from '../../actions/permissions.actions'; +import { CFAppState } from '../../cf-app-state'; +import { fetchCfUserRole } from '../../user-permissions/cf-user-roles-fetch'; + +// TODO: RC MOVE all GET_CURRENT_USER_RELATION +@Injectable() +export class PermissionEffects { + constructor( + private httpClient: HttpClient, + private actions$: Actions, + private store: Store + ) { } + + @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( + ofType(GET_CURRENT_USER_RELATION), + map(action => { + return fetchCfUserRole(this.store, action, this.httpClient).pipe( + map((success) => ({ type: action.actions[1] })) + ); + }) + ); +} \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts new file mode 100644 index 0000000000..90e0646454 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts @@ -0,0 +1,215 @@ +import { HttpClient } from '@angular/common/http'; +import { Action, Store } from '@ngrx/store'; +import { combineLatest, Observable, of } from 'rxjs'; +import { catchError, first, map, pairwise, share, skipWhile, switchMap, tap } from 'rxjs/operators'; + +import { LoggerService } from '../../../core/src/core/logger.service'; +import { AppState } from '../../../store/src/app-state'; +import { entityCatalog } from '../../../store/src/entity-catalog/entity-catalog'; +import { EntityUserRolesFetch } from '../../../store/src/entity-request-pipeline/entity-request-pipeline.types'; +import { + BaseHttpClientFetcher, + flattenPagination, + PaginationFlattener, +} from '../../../store/src/helpers/paginated-request-helpers'; +import { ActionState } from '../../../store/src/reducers/api-request-reducer/types'; +import { endpointsCfEntitiesConnectedSelector } from '../../../store/src/selectors/endpoint.selectors'; +import { selectPaginationState } from '../../../store/src/selectors/pagination.selectors'; +import { EndpointModel } from '../../../store/src/types/endpoint.types'; +import { BasePaginatedAction, PaginationEntityState } from '../../../store/src/types/pagination.types'; +import { + GET_CURRENT_USER_CF_RELATIONS, + GET_CURRENT_USER_CF_RELATIONS_FAILED, + GET_CURRENT_USER_CF_RELATIONS_SUCCESS, + GetCurrentUserRelationsComplete, + GetUserCfRelations, + GetUserRelations, + UserRelationTypes, +} from '../actions/permissions.actions'; +import { cfEntityCatalog } from '../cf-entity-catalog'; +import { CFResponse } from '../store/types/cf-api.types'; + +// map(cfEndpoints => +// Object +// .entries(cfEndpoints) +// .filter(([id, endpoint]) => { +// const validId = endpointIds.length === 0 || endpointIds.find(endpointId => endpointId === id); +// const isAdmin = endpoint.user.admin; +// return validId && !isAdmin +// }) +// .map(([, endpoint]) => endpoint) +// ), + +export const cfUserRolesFetch: EntityUserRolesFetch = ( + endpointIds: string[], + store: Store, + logService: LoggerService, + httpClient: HttpClient +) => { + return store.select(endpointsCfEntitiesConnectedSelector).pipe( + first(), + map(cfEndpoints => endpointIds.length === 0 ? + Object.values(cfEndpoints) : + Object.values(cfEndpoints).filter(cfEndpoint => endpointIds.find(endpointId => endpointId === cfEndpoint.guid))), + switchMap((cfEndpoints: EndpointModel[]) => { + const isAllAdmins = cfEndpoints.every(endpoint => !!endpoint.user.admin); + // If all endpoints are connected as admin, there's no permissions to fetch. So only update the permission state to initialised + if (isAllAdmins) { + cfEndpoints.map(endpoint => new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS)) + } else { + // If some endpoints are not connected as admin, go out and fetch the current user's specific roles + const flagsAndRoleRequests = dispatchRoleRequests(cfEndpoints, store, logService, httpClient); + const allRequestsCompleted = handleCfRequests(flagsAndRoleRequests); + return combineLatest(allRequestsCompleted).pipe( + map(succeeds => succeeds.every(succeeded => !!succeeded)), + ); + } + return of(true); + }) + ) +} + +interface CfsRequestState { + [cfGuid: string]: Observable[]; +} + +interface IEndpointConnectionInfo { + guid: string; + userGuid: string; +} + +function dispatchRoleRequests( + endpoints: EndpointModel[], + store: Store, + logService: LoggerService, + httpClient: HttpClient +): CfsRequestState { + const requests: CfsRequestState = {}; + + // Per endpoint fetch feature flags and user roles (unless admin, where we don't need to), then mark endpoint as initialised + endpoints.forEach(endpoint => { + if (endpoint.user.admin) { + // We don't need permissions for admin users (they can do everything) + requests[endpoint.guid] = [of(true)]; + store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS)); + } else { + // START fetching cf roles for current user + store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS)); + + // Dispatch feature flags fetch actions + const ffAction = cfEntityCatalog.featureFlag.actions.getMultiple(endpoint.guid) + requests[endpoint.guid] = [createPaginationCompleteWatcher(store, ffAction)]; + store.dispatch(ffAction); + + // Dispatch requests to fetch roles per role type for current user + requests[endpoint.guid].push(...fetchCfUserRoles({ guid: endpoint.guid, userGuid: endpoint.user.guid }, store, httpClient)); + + // FINISH fetching cf roles for current user + combineLatest(requests[endpoint.guid]).pipe( + first(), + tap(succeeds => { + store.dispatch(new GetUserCfRelations( + endpoint.guid, + succeeds.every(succeeded => !!succeeded) ? GET_CURRENT_USER_CF_RELATIONS_SUCCESS : GET_CURRENT_USER_CF_RELATIONS_FAILED) + ); + }), + catchError(err => { + logService.warn('Failed to fetch current user permissions for a cf: ', err); + store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_FAILED)); + return of(err); + }) + ).subscribe(); + } + }); + return requests; +} + +function handleCfRequests(requests: CfsRequestState): Observable[] { + const allCompleted: Observable[] = []; + Object.keys(requests).forEach(cfGuid => { + const successes = requests[cfGuid]; + allCompleted.push(...successes); + }); + return allCompleted; +} + +function fetchCfUserRoles(endpoint: IEndpointConnectionInfo, store: Store, httpClient: HttpClient): Observable[] { + return Object.values(UserRelationTypes).map((type: UserRelationTypes) => { + const relAction = new GetUserRelations(endpoint.userGuid, type, endpoint.guid); + return fetchCfUserRole(store, relAction, httpClient); + }); +} + +class PermissionFlattener extends BaseHttpClientFetcher implements PaginationFlattener { + + constructor(httpClient: HttpClient, public url, public requestOptions: { [key: string]: any }) { + super(httpClient, url, requestOptions, 'page'); + } + public getTotalPages = (res: CFResponse) => res.total_pages; + + public mergePages = (res: CFResponse[]) => { + const firstRes = res.shift(); + const final = res.reduce((finalRes, currentRes) => { + finalRes.resources = [ + ...finalRes.resources, + ]; + return finalRes; + }, firstRes); + return final; + } + public getTotalResults = (res: CFResponse): number => res.total_results; + public clearResults = (res: CFResponse) => of(res); +} + +export function fetchCfUserRole(store: Store, action: GetUserRelations, httpClient: HttpClient): Observable { + const url = `pp/v1/proxy/v2/users/${action.guid}/${action.relationType}`; + const params = { + headers: { + 'x-cap-cnsi-list': action.endpointGuid, + 'x-cap-passthrough': 'true' + }, + params: { + 'results-per-page': '100' + } + }; + const get$ = httpClient.get( + url, + params + ); + return flattenPagination( + (flatAction: Action) => store.dispatch(flatAction), + get$, + new PermissionFlattener(httpClient, url, params) + ).pipe( + map(data => { + store.dispatch(new GetCurrentUserRelationsComplete(action.relationType, action.endpointGuid, data.resources)); + return true; + }), + first(), + catchError(err => of(false)), + share() + ); +} + +const fetchPaginationStateFromAction = (store: Store, action: BasePaginatedAction) => { + const entityKey = entityCatalog.getEntityKey(action); + return store.select(selectPaginationState(entityKey, action.paginationKey)); +}; + +/** + * Using the given action wait until the associated pagination section changes from busy to not busy + */ +const createPaginationCompleteWatcher = (store: Store, action: BasePaginatedAction): Observable => + fetchPaginationStateFromAction(store, action).pipe( + map((paginationState: PaginationEntityState) => { + const pageRequest: ActionState = + paginationState && paginationState.pageRequests && paginationState.pageRequests[paginationState.currentPage]; + return pageRequest ? pageRequest.busy : true; + }), + pairwise(), + map(([oldFetching, newFetching]) => { + return oldFetching === true && newFetching === false; + }), + skipWhile(completed => !completed), + first(), + ); \ No newline at end of file diff --git a/src/frontend/packages/store/src/effects/permissions.effect.ts b/src/frontend/packages/store/src/effects/permissions.effect.ts new file mode 100644 index 0000000000..acba8d5c92 --- /dev/null +++ b/src/frontend/packages/store/src/effects/permissions.effect.ts @@ -0,0 +1,64 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Action, Store } from '@ngrx/store'; +import { combineLatest, of as observableOf, of } from 'rxjs'; +import { catchError, map, switchMap } from 'rxjs/operators'; + +import { + GET_CURRENT_USER_RELATIONS, + GET_CURRENT_USER_RELATIONS_FAILED, + GET_CURRENT_USER_RELATIONS_SUCCESS, + GetCurrentUsersRelations, +} from '../../../cloud-foundry/src/actions/permissions.actions'; +import { LoggerService } from '../../../core/src/core/logger.service'; +import { CONNECT_ENDPOINTS_SUCCESS, EndpointActionComplete } from '../actions/endpoint.actions'; +import { AppState } from '../app-state'; +import { entityCatalog } from '../entity-catalog/entity-catalog'; + +const successAction: Action = { type: GET_CURRENT_USER_RELATIONS_SUCCESS }; +const failedAction: Action = { type: GET_CURRENT_USER_RELATIONS_FAILED }; + + +@Injectable() +export class PermissionsEffects { + constructor( + private httpClient: HttpClient, + private actions$: Actions, + private store: Store, + private logService: LoggerService + ) { } + + @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( + ofType(GET_CURRENT_USER_RELATIONS), + switchMap(action => { + const allRequestsCompleted = entityCatalog.getAllBaseEndpointTypes().reduce((res, endpointType) => { + if (endpointType.definition.userRolesFetch) { + res.push(endpointType.definition.userRolesFetch([], this.store, this.logService, this.httpClient)); + } + return res; + }, []); + return combineLatest(allRequestsCompleted).pipe( + switchMap(succeeds => succeeds.every(succeeded => !!succeeded) ? [successAction] : [failedAction]) + ); + }), + catchError(err => { + this.logService.warn('Failed to fetch current user permissions: ', err); + return observableOf([failedAction]); + }) + ); + + + @Effect() getPermissionForNewlyConnectedEndpoint$ = this.actions$.pipe( + ofType(CONNECT_ENDPOINTS_SUCCESS), + switchMap(action => { + const endpointType = entityCatalog.getEndpoint(action.endpointType) + if (!endpointType.definition.userRolesFetch) { + return of([]); + } + return endpointType.definition.userRolesFetch([action.guid], this.store, this.logService, this.httpClient).pipe( + map(() => []) + ); + }) + ); +} diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index 368fdb409d..928c0699ed 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -12,6 +12,7 @@ import { EntitiesInfoHandler, EntityFetchHandler, EntityInfoHandler, + EntityUserRolesFetch, PreApiRequest, PrePaginationApiRequest, SuccessfulApiResponseDataMapper, @@ -130,7 +131,7 @@ export interface IStratosEndpointDefinition( entity: any, entityKey: string, favoritesConfigMapper: FavoritesConfigMapper ) => UserFavorite; - readonly userRolesInit?: () => Observable // TODO: RC Comment + readonly userRolesFetch?: EntityUserRolesFetch // TODO: RC Comment readonly userRolesReducer?: () => ICurrentUserRolesState // TODO: RC Comment } diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts index 31c9d8ae63..4080547785 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts @@ -1,7 +1,8 @@ -import { HttpRequest } from '@angular/common/http'; +import { HttpClient, HttpRequest } from '@angular/common/http'; import { Action, Store } from '@ngrx/store'; import { Observable } from 'rxjs'; +import { LoggerService } from '../../../core/src/core/logger.service'; import { JetStreamErrorResponse } from '../../../core/src/jetstream.helpers'; import { AppState, GeneralEntityAppState, InternalAppState } from '../app-state'; import { @@ -132,5 +133,13 @@ export type EntitiesInfoHandler = ( ) => void; -export type EntityFetchHandler = (store: Store, action: EntityRequestAction) => (entity: T) => void; +export type EntityFetch = (entity: T) => void; +export type EntityFetchHandler = (store: Store, action: EntityRequestAction) => EntityFetch; export type EntitiesFetchHandler = (store: Store, actions: PaginatedAction[]) => () => void; + +export type EntityUserRolesFetch = ( + endpointIds: string[], + store: Store, + logService: LoggerService, + httpClient: HttpClient +) => Observable; \ No newline at end of file diff --git a/src/frontend/packages/store/src/entity-service.ts b/src/frontend/packages/store/src/entity-service.ts index 3cc234e8d4..5d583342dd 100644 --- a/src/frontend/packages/store/src/entity-service.ts +++ b/src/frontend/packages/store/src/entity-service.ts @@ -4,10 +4,12 @@ import { filter, first, map, publishReplay, refCount, switchMap, tap, withLatest import { GeneralEntityAppState } from './app-state'; import { entityCatalog } from './entity-catalog/entity-catalog'; +import { StratosBaseCatalogEntity } from './entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { EntityActionBuilderEntityConfig } from './entity-catalog/entity-catalog.types'; +import { EntityFetch, EntityFetchHandler } from './entity-request-pipeline/entity-request-pipeline.types'; import { EntityMonitor } from './monitors/entity-monitor'; import { RequestInfoState, UpdatingSection } from './reducers/api-request-reducer/types'; -import { getEntityUpdateSections, getUpdateSectionById } from './selectors/api.selectors'; +import { getEntityUpdateSections, getUpdateSectionById, selectEntity } from './selectors/api.selectors'; import { EntityInfo } from './types/api.types'; import { EntityRequestAction } from './types/request.types'; @@ -21,16 +23,34 @@ export function isEntityBlocked(entityRequestInfo: RequestInfoState) { entityRequestInfo.deleting.deleted; } -const dispatcherFactory = (store: Store, action: EntityRequestAction) => (updatingKey?: string) => { - if (updatingKey) { - store.dispatch({ +type ActionDispatcher = (updatingKey?: string, fetchEntity?: boolean) => EntityFetch; +const dispatcherFactory = ( + store: Store, + action: EntityRequestAction, + catalogEntity: StratosBaseCatalogEntity, + +): ActionDispatcher => + (updatingKey?: string, fetchEntity?: boolean) => { + // If we're dispatching the action in the updating world ensure the key is set + const updatedAction = { ...action, updatingKey - }); - } else { - store.dispatch(action); - } -}; + } + + // Do we have a fetch handler defined by the endpoint/entity? + const entityFetchHandler: EntityFetchHandler = catalogEntity.getEntityFetchHandler() + const fetchHandler = entityFetchHandler ? + entityFetchHandler(store, updatedAction) : + (entity: T) => store.dispatch(updatedAction); + + // Fetch handler requires the entity, this may be missing or stale to update if required + return fetchEntity ? (entity: T) => { + // Entity may be null or stale + store.select(selectEntity(catalogEntity.entityKey, action.guid)).pipe(first()).subscribe(entity => fetchHandler(entity)) + fetchHandler(entity) + } : fetchHandler; + }; + /** * Designed to be used in a service factory provider @@ -43,32 +63,32 @@ export class EntityService { actionOrConfig: EntityRequestAction | EntityActionBuilderEntityConfig, ) { this.action = this.getAction(actionOrConfig); - const entityInfoHandlerBuilder = entityCatalog.getEntity(this.action).getEntityEmitHandler(); - const actionInfoHandler = entityInfoHandlerBuilder ? entityInfoHandlerBuilder( + const catalogEntity = entityCatalog.getEntity(this.action); + + // Setup Fetch Handler + this.actionDispatch = dispatcherFactory(store, this.action, catalogEntity); + + // Setup Emit Handler + const entityEmitHandlerBuilder = catalogEntity.getEntityEmitHandler(); + const entityEmitHandler = entityEmitHandlerBuilder ? entityEmitHandlerBuilder( this.action, (action) => store.dispatch(action) ) : () => { }; - this.actionDispatch = dispatcherFactory(store, this.action); + this.updateEntity = () => { - this.actionDispatch(this.refreshKey); + this.actionDispatch(this.refreshKey, true)(null); }; - const catalogEntity = entityCatalog.getEntity(this.action); - const entityFetchHandler = catalogEntity.getEntityFetchHandler(); - const fetchHandler = entityFetchHandler ? - entityFetchHandler(store, this.action) : - (entity: T) => this.actionDispatch(''); - this.updatingSection$ = entityMonitor.updatingSection$; this.isDeletingEntity$ = entityMonitor.isDeletingEntity$; this.isFetchingEntity$ = entityMonitor.isFetchingEntity$; this.entityObs$ = this.getEntityObservable( entityMonitor, - fetchHandler, + this.actionDispatch(), ).pipe( publishReplay(1), refCount(), - tap(actionInfoHandler) + tap(entityEmitHandler) ); this.waitForEntity$ = this.entityObs$.pipe( @@ -83,7 +103,7 @@ export class EntityService { refreshKey = 'updating'; - private actionDispatch: (key: string) => void; + private actionDispatch: ActionDispatcher; updateEntity: () => void; @@ -98,15 +118,15 @@ export class EntityService { updatingSection$: Observable; private getEntityObservable = ( entityMonitor: EntityMonitor, - actionDispatch: (entity: T) => void + actionDispatch: EntityFetch ): Observable => { const cleanEntityInfo$ = this.getCleanEntityInfoObs(entityMonitor); return entityMonitor.entityRequest$.pipe( withLatestFrom(entityMonitor.entity$), tap(([entityRequestInfo, entity]) => { - if (actionDispatch && this.shouldCallAction(entityRequestInfo, entity)) { - actionDispatch(entity);; + if (this.shouldCallAction(entityRequestInfo, entity)) { + actionDispatch(entity); } }), first(), @@ -163,9 +183,13 @@ export class EntityService { * @param updateKey - The store updating key for the poll */ poll(interval = 10000, updateKey = this.refreshKey) { - return this.entityMonitor.poll(interval, () => this.actionDispatch(updateKey), compose( - getUpdateSectionById(updateKey), - getEntityUpdateSections - )); + return this.entityMonitor.poll( + interval, + () => this.actionDispatch(updateKey, true)(null), + compose( + getUpdateSectionById(updateKey), + getEntityUpdateSections + ) + ); } } diff --git a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer.helper.ts b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer.helper.ts index 68d27c5974..56a5e0bef4 100644 --- a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer.helper.ts +++ b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer.helper.ts @@ -192,8 +192,8 @@ function getObservables( map(([, newPag]) => newPag) ); - const entitiesInfoHandlerBuilder = entity.getEntitiesEmitHandler(); - const actionInfoHandler = entitiesInfoHandlerBuilder ? entitiesInfoHandlerBuilder( + const entitiesEmitHandlerBuilder = entity.getEntitiesEmitHandler(); + const actionEmitHandler = entitiesEmitHandlerBuilder ? entitiesEmitHandlerBuilder( paginationAction, (action) => store.dispatch(action) ) : () => { }; @@ -206,7 +206,7 @@ function getObservables( filter(([, pagination]) => !!pagination && isPageReady(pagination, isLocal)), publishReplay(1), refCount(), - tap(([, pagination]) => actionInfoHandler(pagination)), + tap(([, pagination]) => actionEmitHandler(pagination)), switchMap(() => paginationMonitor.currentPage$), ); diff --git a/src/frontend/packages/store/src/store.module.ts b/src/frontend/packages/store/src/store.module.ts index a29f7e5e41..0f57fd8946 100644 --- a/src/frontend/packages/store/src/store.module.ts +++ b/src/frontend/packages/store/src/store.module.ts @@ -10,6 +10,7 @@ import { EndpointApiError } from './effects/endpoint-api-errors.effects'; import { EndpointsEffect } from './effects/endpoint.effects'; import { MetricsEffect } from './effects/metrics.effects'; import { PaginationEffects } from './effects/pagination.effects'; +import { PermissionsEffects } from './effects/permissions.effect'; import { RecursiveDeleteEffect } from './effects/recursive-entity-delete.effect'; import { RouterEffect } from './effects/router.effects'; import { SetClientFilterEffect } from './effects/set-client-filter.effect'; @@ -47,7 +48,8 @@ import { AppReducersModule } from './reducers.module'; UserProfileEffect, UsersRolesEffects, RecursiveDeleteEffect, - UserFavoritesEffect + UserFavoritesEffect, + PermissionsEffects ]) ] }) From 94135c1a054167bb69e5d6e9a9036d81397347b4 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Fri, 22 May 2020 18:06:44 +0100 Subject: [PATCH 03/82] First pass at reducer --- .../src/actions/permissions.actions.ts | 8 +- .../cloud-foundry/src/cf-entity-generator.ts | 6 +- .../users/manage-users/cf-roles.service.ts | 10 +- .../manage-users-confirm.component.ts | 5 +- .../manage-users-modify.component.ts | 14 +-- .../manage-users/manage-users.component.ts | 2 +- .../remove-user/remove-user.component.ts | 2 +- .../cf-role-checkbox.component.ts | 6 +- ...f-users-space-roles-list-config.service.ts | 2 +- .../table-cell-select-org.component.ts | 2 +- .../src/store/cloud-foundry.store.module.ts | 4 +- .../src/store/effects/roles.effects.ts | 2 +- .../src/store}/effects/users-roles.effects.ts | 34 +++-- .../current-user-base-cf-role.reducer.ts | 2 +- .../current-user-role-session.reducer.ts | 31 +++-- .../current-user-roles-clear.reducers.ts | 111 ++++++++++++++++ .../current-user-roles.reducer.ts | 98 +++++++++++++++ .../cf-current-user-role.selectors.ts | 4 +- .../store}/selectors/users-roles.selector.ts | 7 +- .../types/cf-current-user-roles.types.ts | 2 +- .../store/types/current-user-roles.types.ts | 19 +++ .../dashboard-base.component.ts | 2 +- .../store/src/actions/permissions.actions.ts | 9 ++ .../store/src/effects/permissions.effect.ts | 6 +- .../src/entity-catalog/entity-catalog.ts | 16 ++- .../entity-catalog/entity-catalog.types.ts | 6 +- .../entity-request-pipeline.types.ts | 4 +- .../current-user-request-state.reducers.ts | 50 -------- .../current-user-roles-clear.reducers.ts | 119 ------------------ .../current-user-roles.reducer.ts | 109 +++++++--------- .../selectors/current-user-role.selectors.ts | 6 - .../packages/store/src/store.module.ts | 2 - .../src/types/current-user-roles.types.ts | 27 +--- 33 files changed, 377 insertions(+), 350 deletions(-) rename src/frontend/packages/{store/src => cloud-foundry/src/store}/effects/users-roles.effects.ts (87%) rename src/frontend/packages/{store/src => cloud-foundry/src/store}/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts (72%) create mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts create mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts rename src/frontend/packages/{store/src => cloud-foundry/src/store}/selectors/users-roles.selector.ts (83%) create mode 100644 src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts create mode 100644 src/frontend/packages/store/src/actions/permissions.actions.ts delete mode 100644 src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-request-state.reducers.ts delete mode 100644 src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts diff --git a/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts index 0abc15b0d2..c1097d9f29 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts @@ -36,19 +36,13 @@ export const GET_CURRENT_USER_RELATION = '[Current User] Get relation'; export const GET_CURRENT_USER_RELATION_SUCCESS = '[Current User] Get relation success'; export const GET_CURRENT_USER_RELATION_FAILED = '[Current User] Get relation failed'; -export const GET_CURRENT_USER_RELATIONS = '[Current User] Get relations'; -export const GET_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get relations success'; -export const GET_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get relations failed'; -// TODO: RC MOVE export const GET_CURRENT_USER_CF_RELATIONS = '[Current User] Get CF relations'; export const GET_CURRENT_USER_CF_RELATIONS_SUCCESS = '[Current User] Get CF relations success'; export const GET_CURRENT_USER_CF_RELATIONS_FAILED = '[Current User] Get CF relations failed'; // TODO: RC RENAME ALL THIS -export class GetCurrentUsersRelations implements Action { - type = GET_CURRENT_USER_RELATIONS; -} + export enum UserRelationTypes { AUDITED_ORGANIZATIONS = 'audited_organizations', diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts index f227313a5b..79cd3b5c9f 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts @@ -165,6 +165,7 @@ import { populatePaginationFromParent } from './entity-relations/entity-relation import { isEntityInlineParentAction } from './entity-relations/entity-relations.types'; import { CfEndpointDetailsComponent } from './shared/components/cf-endpoint-details/cf-endpoint-details.component'; import { updateApplicationRoutesReducer } from './store/reducers/application-route.reducer'; +import { currentCfUserRolesReducer } from './store/reducers/current-user-roles-reducer/current-user-roles.reducer'; import { endpointDisconnectRemoveEntitiesReducer } from './store/reducers/endpoint-disconnect-application.reducer'; import { updateOrganizationQuotaReducer } from './store/reducers/organization-quota.reducer'; import { updateOrganizationSpaceReducer } from './store/reducers/organization-space.reducer'; @@ -367,10 +368,7 @@ export function generateCFEntities(): StratosBaseCatalogEntity[] { }, }, userRolesFetch: cfUserRolesFetch, // TODO: RC implement - userRolesReducer: () => { // TODO: RC implement - console.log('HELLO WORLD'); - return null; - } + userRolesReducer: currentCfUserRolesReducer }; return [ generateCfEndpointEntity(endpointDefinition), diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts index bf735a998f..4a5d0f4b95 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts @@ -19,11 +19,6 @@ import { } from '../../../../../../cloud-foundry/src/entity-relations/entity-relations.types'; import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { endpointSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; -import { - selectUsersRolesCf, - selectUsersRolesPicked, - selectUsersRolesRoles, -} from '../../../../../../store/src/selectors/users-roles.selector'; import { APIResource, EntityInfo } from '../../../../../../store/src/types/api.types'; import { UsersRolesSetChanges } from '../../../../actions/users-roles.actions'; import { IOrganization, ISpace } from '../../../../cf-api.types'; @@ -32,6 +27,11 @@ import { cfEntityCatalog } from '../../../../cf-entity-catalog'; import { organizationEntityType, spaceEntityType } from '../../../../cf-entity-types'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; import { createDefaultOrgRoles, createDefaultSpaceRoles } from '../../../../store/reducers/users-roles.reducer'; +import { + selectUsersRolesCf, + selectUsersRolesPicked, + selectUsersRolesRoles, +} from '../../../../store/selectors/users-roles.selector'; import { CfUser, IUserPermissionInOrg, UserRoleInOrg, UserRoleInSpace } from '../../../../store/types/user.types'; import { CfRoleChange, CfUserRolesSelected } from '../../../../store/types/users-roles.types'; import { CfUserPermissionsChecker } from '../../../../user-permissions/cf-user-permissions-checkers'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts index c3360df331..76fdc3d38b 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts @@ -11,10 +11,6 @@ import { } from '../../../../../../../core/src/shared/components/list/list-table/table-cell-request-monitor-icon/table-cell-request-monitor-icon.component'; import { ITableColumn } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; import { entityCatalog } from '../../../../../../../store/src/entity-catalog/entity-catalog'; -import { - selectUsersRoles, - selectUsersRolesChangedRoles, -} from '../../../../../../../store/src/selectors/users-roles.selector'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { UsersRolesClearUpdateState } from '../../../../../actions/users-roles.actions'; import { ChangeUserRole } from '../../../../../actions/users.actions'; @@ -29,6 +25,7 @@ import { TableCellConfirmRoleAddRemComponent, } from '../../../../../shared/components/list/list-types/cf-confirm-roles/table-cell-confirm-role-add-rem/table-cell-confirm-role-add-rem.component'; import { CfUserService } from '../../../../../shared/data-services/cf-user.service'; +import { selectUsersRoles, selectUsersRolesChangedRoles } from '../../../../../store/selectors/users-roles.selector'; import { CfUser, OrgUserRoleNames, SpaceUserRoleNames } from '../../../../../store/types/user.types'; import { CfRoleChangeWithNames, UserRoleLabels } from '../../../../../store/types/users-roles.types'; import { ManageUsersSetUsernamesHelper } from '../manage-users-set-usernames/manage-users-set-usernames.component'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts index 4a03a0182b..5eab2957f5 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts @@ -32,13 +32,6 @@ import { ITableListDataSource, } from '../../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source-types'; import { ITableColumn } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; -import { - selectUsersIsRemove, - selectUsersIsSetByUsername, - selectUsersRolesOrgGuid, - selectUsersRolesPicked, - selectUsersRolesRoles, -} from '../../../../../../../store/src/selectors/users-roles.selector'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { UsersRolesFlipSetRoles, UsersRolesSetOrg } from '../../../../../actions/users-roles.actions'; import { IOrganization } from '../../../../../cf-api.types'; @@ -49,6 +42,13 @@ import { import { TableCellSelectOrgComponent, } from '../../../../../shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component'; +import { + selectUsersIsRemove, + selectUsersIsSetByUsername, + selectUsersRolesOrgGuid, + selectUsersRolesPicked, + selectUsersRolesRoles, +} from '../../../../../store/selectors/users-roles.selector'; import { CfUser, OrgUserRoleNames } from '../../../../../store/types/user.types'; import { ActiveRouteCfOrgSpace } from '../../../cf-page.types'; import { CfRolesService } from '../cf-roles.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users.component.ts index 3470759dcb..df4b52c516 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users.component.ts @@ -5,10 +5,10 @@ import { Observable, of as observableOf, of } from 'rxjs'; import { combineLatest, filter, first, map } from 'rxjs/operators'; import { StepOnNextFunction } from '../../../../../../core/src/shared/components/stepper/step/step.component'; -import { selectUsersRoles, selectUsersRolesPicked } from '../../../../../../store/src/selectors/users-roles.selector'; import { UsersRolesClear, UsersRolesExecuteChanges, UsersRolesSetUsers } from '../../../../actions/users-roles.actions'; import { CFAppState } from '../../../../cf-app-state'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; +import { selectUsersRoles, selectUsersRolesPicked } from '../../../../store/selectors/users-roles.selector'; import { CfUser } from '../../../../store/types/user.types'; import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; import { getActiveRouteCfOrgSpaceProvider } from '../../cf.helpers'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts index 6faf039a10..0ddc4aabcd 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts @@ -8,7 +8,6 @@ import { CurrentUserPermissionsService } from '../../../../../../core/src/core/c import { LoggerService } from '../../../../../../core/src/core/logger.service'; import { StepOnNextFunction } from '../../../../../../core/src/shared/components/stepper/step/step.component'; import { AppState } from '../../../../../../store/src/app-state'; -import { selectUsersRoles } from '../../../../../../store/src/selectors/users-roles.selector'; import { UsersRolesClear, UsersRolesExecuteChanges, @@ -16,6 +15,7 @@ import { UsersRolesSetUsers, } from '../../../../actions/users-roles.actions'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; +import { selectUsersRoles } from '../../../../store/selectors/users-roles.selector'; import { CfUser, IUserPermissionInOrg, IUserPermissionInSpace } from '../../../../store/types/user.types'; import { CfRoleChange } from '../../../../store/types/users-roles.types'; import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts index 21394e9762..d431149d29 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts @@ -14,13 +14,13 @@ import { } from '../../../../../cloud-foundry/src/store/types/user.types'; import { CfUserRolesSelected } from '../../../../../cloud-foundry/src/store/types/users-roles.types'; import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; +import { canUpdateOrgSpaceRoles } from '../../../features/cloud-foundry/cf.helpers'; +import { CfRolesService } from '../../../features/cloud-foundry/users/manage-users/cf-roles.service'; import { selectUsersIsRemove, selectUsersIsSetByUsername, selectUsersRolesPicked, -} from '../../../../../store/src/selectors/users-roles.selector'; -import { canUpdateOrgSpaceRoles } from '../../../features/cloud-foundry/cf.helpers'; -import { CfRolesService } from '../../../features/cloud-foundry/users/manage-users/cf-roles.service'; +} from '../../../store/selectors/users-roles.selector'; import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-list-config.service.ts index 17f384dd8c..b9b9aa22a3 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-list-config.service.ts @@ -8,9 +8,9 @@ import { CurrentUserPermissionsService } from '../../../../../../../core/src/cor import { ITableColumn } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; import { IListConfig, ListViewTypes } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { ListView } from '../../../../../../../store/src/actions/list.actions'; -import { selectUsersRolesRoles } from '../../../../../../../store/src/selectors/users-roles.selector'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { ISpace } from '../../../../../cf-api.types'; +import { selectUsersRolesRoles } from '../../../../../store/selectors/users-roles.selector'; import { CfUsersSpaceRolesDataSourceService } from './cf-users-space-roles-data-source.service'; import { TableCellRoleOrgSpaceComponent } from './table-cell-org-space-role/table-cell-org-space-role.component'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts index 1f8f147977..7c9d9eacb5 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts @@ -6,11 +6,11 @@ import { first, map } from 'rxjs/operators'; import { UsersRolesSetOrg } from '../../../../../../../../cloud-foundry/src/actions/users-roles.actions'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { TableCellCustom } from '../../../../../../../../core/src/shared/components/list/list.types'; -import { selectUsersRolesOrgGuid } from '../../../../../../../../store/src/selectors/users-roles.selector'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { IOrganization } from '../../../../../../cf-api.types'; import { ActiveRouteCfOrgSpace } from '../../../../../../features/cloud-foundry/cf-page.types'; import { CfRolesService } from '../../../../../../features/cloud-foundry/users/manage-users/cf-roles.service'; +import { selectUsersRolesOrgGuid } from '../../../../../../store/selectors/users-roles.selector'; @Component({ selector: 'app-table-cell-select-org', diff --git a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts index 4d79871526..45ddef3acb 100644 --- a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts +++ b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts @@ -14,6 +14,7 @@ import { PermissionEffects } from './effects/roles.effects'; import { RouteEffect } from './effects/route.effects'; import { ServiceInstanceEffects } from './effects/service-instance.effects'; import { UpdateAppEffects } from './effects/update-app-effects'; +import { UsersRolesEffects } from './effects/users-roles.effects'; @NgModule({ imports: [ @@ -29,7 +30,8 @@ import { UpdateAppEffects } from './effects/update-app-effects'; ServiceInstanceEffects, AppEffects, UpdateAppEffects, - CfValidateEffects + CfValidateEffects, + UsersRolesEffects ]) ], providers: [ diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts index 2770acc86f..f15fddc33f 100644 --- a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts +++ b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts @@ -21,7 +21,7 @@ export class PermissionEffects { ofType(GET_CURRENT_USER_RELATION), map(action => { return fetchCfUserRole(this.store, action, this.httpClient).pipe( - map((success) => ({ type: action.actions[1] })) + map((success) => ({ type: action.actions[1] })) // TODO: RC FIX error handling ); }) ); diff --git a/src/frontend/packages/store/src/effects/users-roles.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts similarity index 87% rename from src/frontend/packages/store/src/effects/users-roles.effects.ts rename to src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts index 640bebb891..585a4a7295 100644 --- a/src/frontend/packages/store/src/effects/users-roles.effects.ts +++ b/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts @@ -7,26 +7,22 @@ import { import { combineLatest as observableCombineLatest, combineLatest, Observable, of as observableOf, of } from 'rxjs'; import { catchError, filter, first, map, mergeMap, pairwise, switchMap, tap, withLatestFrom } from 'rxjs/operators'; -import { - UsersRolesActions, - UsersRolesClearUpdateState, - UsersRolesExecuteChanges, -} from '../../../cloud-foundry/src/actions/users-roles.actions'; -import { AddUserRole, ChangeUserRole, RemoveUserRole } from '../../../cloud-foundry/src/actions/users.actions'; -import { CFAppState } from '../../../cloud-foundry/src/cf-app-state'; -import { organizationEntityType, spaceEntityType } from '../../../cloud-foundry/src/cf-entity-types'; -import { CF_ENDPOINT_TYPE } from '../../../cloud-foundry/src/cf-types'; -import { CfUserService } from '../../../cloud-foundry/src/shared/data-services/cf-user.service'; -import { OrgUserRoleNames } from '../../../cloud-foundry/src/store/types/user.types'; -import { CfRoleChange, UsersRolesState } from '../../../cloud-foundry/src/store/types/users-roles.types'; -import { ResetPagination } from '../actions/pagination.actions'; -import { entityCatalog } from '../entity-catalog/entity-catalog'; -import { ActionState } from '../reducers/api-request-reducer/types'; -import { selectSessionData } from '../reducers/auth.reducer'; +import { ResetPagination } from '../../../../store/src/actions/pagination.actions'; +import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog'; +import { ActionState } from '../../../../store/src/reducers/api-request-reducer/types'; +import { selectSessionData } from '../../../../store/src/reducers/auth.reducer'; +import { SessionDataEndpoint } from '../../../../store/src/types/auth.types'; +import { PaginatedAction } from '../../../../store/src/types/pagination.types'; +import { ICFAction, UpdateCfAction } from '../../../../store/src/types/request.types'; +import { UsersRolesActions, UsersRolesClearUpdateState, UsersRolesExecuteChanges } from '../../actions/users-roles.actions'; +import { AddUserRole, ChangeUserRole, RemoveUserRole } from '../../actions/users.actions'; +import { CFAppState } from '../../cf-app-state'; +import { organizationEntityType, spaceEntityType } from '../../cf-entity-types'; +import { CF_ENDPOINT_TYPE } from '../../cf-types'; +import { CfUserService } from '../../shared/data-services/cf-user.service'; import { selectUsersRoles } from '../selectors/users-roles.selector'; -import { SessionDataEndpoint } from '../types/auth.types'; -import { PaginatedAction } from '../types/pagination.types'; -import { ICFAction, UpdateCfAction } from '../types/request.types'; +import { OrgUserRoleNames } from '../types/user.types'; +import { CfRoleChange, UsersRolesState } from '../types/users-roles.types'; @Injectable() diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts index 0e9832beb1..dd36dadb56 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts @@ -1,6 +1,6 @@ -import { getDefaultEndpointRoles } from '../../../../../store/src/types/current-user-roles.types'; import { GetCurrentUserRelationsComplete } from '../../../actions/permissions.actions'; import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; +import { getDefaultEndpointRoles } from '../../types/current-user-roles.types'; import { currentUserCFRolesReducer } from './current-user-cf-roles.reducer'; export function currentUserBaseCFRolesReducer(state: IAllCfRolesState = {}, action: GetCurrentUserRelationsComplete): IAllCfRolesState { diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts similarity index 72% rename from src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts index a2b1be5a6c..9cb664e877 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts @@ -1,14 +1,10 @@ -import { - IAllCfRolesState, - ICfRolesState, - IGlobalRolesState, -} from '../../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; -import { CfScopeStrings } from '../../../../cloud-foundry/src/user-permissions/cf-user-permissions-checkers'; -import { VerifiedSession } from '../../actions/auth.actions'; -import { EndpointActionComplete } from '../../actions/endpoint.actions'; -import { SessionUser } from '../../types/auth.types'; -import { getDefaultEndpointRoles, ICurrentUserRolesState } from '../../types/current-user-roles.types'; -import { EndpointUser, INewlyConnectedEndpointInfo } from '../../types/endpoint.types'; +import { VerifiedSession } from '../../../../../store/src/actions/auth.actions'; +import { EndpointActionComplete } from '../../../../../store/src/actions/endpoint.actions'; +import { SessionUser } from '../../../../../store/src/types/auth.types'; +import { EndpointUser, INewlyConnectedEndpointInfo } from '../../../../../store/src/types/endpoint.types'; +import { CfScopeStrings } from '../../../user-permissions/cf-user-permissions-checkers'; +import { IAllCfRolesState, ICfRolesState, IGlobalRolesState } from '../../types/cf-current-user-roles.types'; +import { getDefaultEndpointRoles } from '../../types/current-user-roles.types'; interface PartialEndpoint { user: EndpointUser | SessionUser; @@ -16,18 +12,18 @@ interface PartialEndpoint { } export function roleInfoFromSessionReducer( - state: ICurrentUserRolesState, + state: IAllCfRolesState, action: VerifiedSession -): ICurrentUserRolesState { +): IAllCfRolesState { const { user, endpoints } = action.sessionData; - const cfRoles = propagateEndpointsAdminPermissions(state.cf, Object.values(endpoints.cf)); + const cfRoles = propagateEndpointsAdminPermissions(state, Object.values(endpoints.cf)); return applyInternalScopes(state, cfRoles, user); } export function updateNewlyConnectedEndpoint( - state: ICurrentUserRolesState, + state: IAllCfRolesState, action: EndpointActionComplete -): ICurrentUserRolesState { +): IAllCfRolesState { if (action.endpointType !== 'cf') { return state; } @@ -42,7 +38,8 @@ export function updateNewlyConnectedEndpoint( }; } -function applyInternalScopes(state: ICurrentUserRolesState, cfRoles: IAllCfRolesState, user?: SessionUser | EndpointUser) { +// TODO: RC huh +function applyInternalScopes(state: IAllCfRolesState, cfRoles: IAllCfRolesState, user?: SessionUser | EndpointUser) { const internalRoles = { ...state.internal }; if (user) { internalRoles.scopes = user.scopes || []; diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts new file mode 100644 index 0000000000..1135f366e4 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts @@ -0,0 +1,111 @@ +import { EndpointActionComplete } from '../../../../../store/src/actions/endpoint.actions'; +import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; +import { APISuccessOrFailedAction } from '../../../../../store/src/types/request.types'; +import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; +import { getDefaultEndpointRoles } from '../../types/current-user-roles.types'; + +export function removeEndpointRoles(state: IAllCfRolesState, action: EndpointActionComplete) { + const cfState = { + ...state + }; + if (!cfState[action.guid]) { + return state; + } + delete cfState[action.guid]; + return { + ...state, + cf: cfState + }; +} + +export function addEndpoint(state: IAllCfRolesState, action: EndpointActionComplete) { + const endpoint = action.endpoint as EndpointModel; + const guid = endpoint.guid; + if (state[guid]) { + return state; + } + const cfState = { + ...state + }; + + cfState[guid] = getDefaultEndpointRoles(); + return { + ...state, + cf: cfState + }; +} + +export function removeSpaceRoles(state: IAllCfRolesState, action: APISuccessOrFailedAction) { + const { endpointGuid, guid } = action.apiAction; + const removedOrgOrSpaceState = removeOrgOrSpaceRoles(state, endpointGuid as string, guid, 'spaces'); // TODO: RC HUH + return removeSpaceIdFromOrg(state, endpointGuid as string, guid); +} + +function removeSpaceIdFromOrg(state: IAllCfRolesState, endpointGuid: string, spaceGuid: string) { + const space = state[endpointGuid].spaces[spaceGuid]; + if (!space) { + return state; + } + const { orgId } = space; + return { + ...state, + [endpointGuid]: { + ...state[endpointGuid], + organizations: { + ...state[endpointGuid].organizations, + [orgId]: { + ...state[endpointGuid].organizations[orgId], + spaceGuids: state[endpointGuid].organizations[orgId].spaceGuids.filter(id => id !== spaceGuid) + } + } + } + }; +} + +export function removeOrgRoles(state: IAllCfRolesState, action: APISuccessOrFailedAction) { + const { endpointGuid, guid } = action.apiAction; + if (!state[endpointGuid as string].organizations[guid]) { + return state; + } + // const spaceIds = state.cf[endpointGuid].organizations[guid].spaceIds; + const spaceIds = []; + const newState = removeOrgOrSpaceRoles(state, endpointGuid, guid, 'organizations'); + return cleanUpOrgSpaces(newState, spaceIds, endpointGuid); +} + +function removeOrgOrSpaceRoles( + state: IAllCfRolesState, + endpointGuid: string, + orgOrSpaceId: string, + type: 'organizations' | 'spaces' +) { + if (!state[endpointGuid][type][orgOrSpaceId]) { + return state; + } + // Remove orgOrSpaceId + const { + [orgOrSpaceId]: omit, + ...newTypeState + } = state[endpointGuid][type]; + + const newState = { + ...state, + [endpointGuid]: { + ...state[endpointGuid], + [type]: newTypeState + } + }; + return newState; +} + +function cleanUpOrgSpaces(state: IAllCfRolesState, spaceIds: string[], endpointGuid: string) { + if (!spaceIds || spaceIds.length === 0 || !state[endpointGuid]) { + return state; + } + return spaceIds.reduce((newState, spaceId) => { + if (newState[endpointGuid].spaces[spaceId]) { + delete newState[endpointGuid].spaces[spaceId]; + } + return newState; + }, { ...state }); +} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts new file mode 100644 index 0000000000..8fa8d51b3a --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts @@ -0,0 +1,98 @@ +import { Action } from '@ngrx/store'; + +import { SESSION_VERIFIED, VerifiedSession } from '../../../../../store/src/actions/auth.actions'; +import { + CONNECT_ENDPOINTS_SUCCESS, + DISCONNECT_ENDPOINTS_SUCCESS, + EndpointActionComplete, + REGISTER_ENDPOINTS_SUCCESS, + UNREGISTER_ENDPOINTS_SUCCESS, +} from '../../../../../store/src/actions/endpoint.actions'; +import { EntityUserRolesReducer } from '../../../../../store/src/entity-request-pipeline/entity-request-pipeline.types'; +import { + roleInfoFromSessionReducer, + updateNewlyConnectedEndpoint, +} from '../../../../../store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer'; +import { + currentUserRolesRequestStateReducer, + RolesRequestStateStage, +} from '../../../../../store/src/reducers/current-user-roles-reducer/current-user-roles.reducer'; +import { APISuccessOrFailedAction } from '../../../../../store/src/types/request.types'; +import { DELETE_ORGANIZATION_SUCCESS } from '../../../actions/organization.actions'; +import { + GET_CURRENT_USER_CF_RELATIONS, + GET_CURRENT_USER_CF_RELATIONS_FAILED, + GET_CURRENT_USER_CF_RELATIONS_SUCCESS, + GET_CURRENT_USER_RELATION_SUCCESS, + GetCurrentUserRelationsComplete, + GetUserCfRelations, +} from '../../../actions/permissions.actions'; +import { DELETE_SPACE_SUCCESS } from '../../../actions/space.actions'; +import { ADD_ROLE_SUCCESS, REMOVE_ROLE_SUCCESS } from '../../../actions/users.actions'; +import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; +import { currentUserBaseCFRolesReducer } from './current-user-base-cf-role.reducer'; +import { updateAfterRoleChange } from './current-user-roles-changed.reducers'; +import { addEndpoint, removeEndpointRoles, removeOrgRoles, removeSpaceRoles } from './current-user-roles-clear.reducers'; + +// TODO: RC TUESDAY HERE + + +// TODO: RC go through each, where are they? +// TODO: RC RENAME +export const currentCfUserRolesReducer: EntityUserRolesReducer = ( + state: IAllCfRolesState, + action: Action +): IAllCfRolesState => { + switch (action.type) { + case GET_CURRENT_USER_RELATION_SUCCESS: // TODO: RC CF Only. VS GET_CURRENT_USER_CF_RELATIONS + return { + ...state, + cf: currentUserBaseCFRolesReducer(state, action as GetCurrentUserRelationsComplete) + }; + case SESSION_VERIFIED:// TODO: RC CF Only + return roleInfoFromSessionReducer(state, action as VerifiedSession); + case REGISTER_ENDPOINTS_SUCCESS:// TODO: RC CF Only + return addEndpoint(state, action as EndpointActionComplete); + case CONNECT_ENDPOINTS_SUCCESS:// TODO: RC CF Only + return updateNewlyConnectedEndpoint(state, action as EndpointActionComplete); + case DISCONNECT_ENDPOINTS_SUCCESS:// TODO: RC CF Only + case UNREGISTER_ENDPOINTS_SUCCESS:// TODO: RC CF Only + return removeEndpointRoles(state, action as EndpointActionComplete); + case DELETE_ORGANIZATION_SUCCESS:// TODO: RC CF Only + return removeOrgRoles(state, action as APISuccessOrFailedAction); + case DELETE_SPACE_SUCCESS:// TODO: RC CF Only + return removeSpaceRoles(state, action as APISuccessOrFailedAction); + case ADD_ROLE_SUCCESS:// TODO: RC CF Only + return updateAfterRoleChange(state, true, action as APISuccessOrFailedAction); + case REMOVE_ROLE_SUCCESS:// TODO: RC CF Only + return updateAfterRoleChange(state, false, action as APISuccessOrFailedAction); + case GET_CURRENT_USER_CF_RELATIONS:// TODO: RC CF Only + case GET_CURRENT_USER_CF_RELATIONS_SUCCESS: + case GET_CURRENT_USER_CF_RELATIONS_FAILED: + return { + ...state, + cf: currentUserCfRolesRequestStateReducer(state.cf, action as GetUserCfRelations) + }; + } + return null; +} + +export function currentUserCfRolesRequestStateReducer(cf: IAllCfRolesState = {}, action: GetUserCfRelations) { + const cfGuid = (action as GetUserCfRelations).cfGuid; + + const type = action.type === GET_CURRENT_USER_CF_RELATIONS ? + RolesRequestStateStage.START : + action.type === GET_CURRENT_USER_CF_RELATIONS_SUCCESS ? RolesRequestStateStage.SUCCESS : + action.type === GET_CURRENT_USER_CF_RELATIONS_FAILED ? RolesRequestStateStage.FAILURE : + RolesRequestStateStage.OTHER + return { + ...cf, + [cfGuid]: { + ...cf[cfGuid], + state: { + ...cf[cfGuid].state, + ...currentUserRolesRequestStateReducer(cf[cfGuid].state, type) + } + } + }; +} diff --git a/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts b/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts index ed27f639a6..55ac65cf22 100644 --- a/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts +++ b/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts @@ -3,7 +3,6 @@ import { compose } from '@ngrx/store'; import { PermissionValues } from '../../../../core/src/core/current-user-permissions.config'; import { selectCurrentUserGlobalHasScopes, - selectCurrentUserRequestState, selectCurrentUserRolesState, } from '../../../../store/src/selectors/current-user-role.selectors'; import { ICurrentUserRolesState } from '../../../../store/src/types/current-user-roles.types'; @@ -16,6 +15,9 @@ import { ISpacesRoleState, } from '../types/cf-current-user-roles.types'; + +export const selectCurrentUserRequestState = (state: ICurrentUserRolesState | ICfRolesState) => state.state; + const selectSpaceWithRoleFromOrg = (role: CfPermissionStrings, orgId: string) => (state: ICfRolesState) => { if (!state) { return 'all'; diff --git a/src/frontend/packages/store/src/selectors/users-roles.selector.ts b/src/frontend/packages/cloud-foundry/src/store/selectors/users-roles.selector.ts similarity index 83% rename from src/frontend/packages/store/src/selectors/users-roles.selector.ts rename to src/frontend/packages/cloud-foundry/src/store/selectors/users-roles.selector.ts index 7c868a7768..2f16a71704 100644 --- a/src/frontend/packages/store/src/selectors/users-roles.selector.ts +++ b/src/frontend/packages/cloud-foundry/src/store/selectors/users-roles.selector.ts @@ -1,9 +1,10 @@ import { compose } from '@ngrx/store'; -import { CFAppState } from '../../../cloud-foundry/src/cf-app-state'; -import { IUserPermissionInOrg } from '../../../cloud-foundry/src/store/types/user.types'; -import { UsersRolesState } from '../../../cloud-foundry/src/store/types/users-roles.types'; +import { CFAppState } from '../../cf-app-state'; +import { IUserPermissionInOrg } from '../types/user.types'; +import { UsersRolesState } from '../types/users-roles.types'; +// TODO: RC export const selectUsersRoles = (state: CFAppState): UsersRolesState => state.manageUsersRoles; const selectUsers = (usersRoles: UsersRolesState) => usersRoles.users; diff --git a/src/frontend/packages/cloud-foundry/src/store/types/cf-current-user-roles.types.ts b/src/frontend/packages/cloud-foundry/src/store/types/cf-current-user-roles.types.ts index f535579799..af56d71ac8 100644 --- a/src/frontend/packages/cloud-foundry/src/store/types/cf-current-user-roles.types.ts +++ b/src/frontend/packages/cloud-foundry/src/store/types/cf-current-user-roles.types.ts @@ -40,5 +40,5 @@ export interface ICfRolesState { } export interface IAllCfRolesState { - [guid: string]: ICfRolesState; + [guid: string]: ICfRolesState } diff --git a/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts b/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts new file mode 100644 index 0000000000..9717e2eac9 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts @@ -0,0 +1,19 @@ +export function getDefaultEndpointRoles(): ICfRolesState { + return { + global: { + isAdmin: false, + isReadOnlyAdmin: false, + isGlobalAuditor: false, + canRead: false, + canWrite: false, + scopes: [] + }, + spaces: { + + }, + organizations: { + + }, + state: getDefaultRolesRequestState() + }; +} \ No newline at end of file diff --git a/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.ts b/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.ts index 5f0dd43422..302c125dfe 100644 --- a/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.ts +++ b/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.ts @@ -7,8 +7,8 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of, Subscription } from 'rxjs'; import { distinctUntilChanged, filter, map, startWith, withLatestFrom } from 'rxjs/operators'; -import { GetCurrentUsersRelations } from '../../../../../cloud-foundry/src/actions/permissions.actions'; import { CloseSideNav, DisableMobileNav, EnableMobileNav } from '../../../../../store/src/actions/dashboard-actions'; +import { GetCurrentUsersRelations } from '../../../../../store/src/actions/permissions.actions'; import { GetUserFavoritesAction } from '../../../../../store/src/actions/user-favourites-actions/get-user-favorites-action'; import { DashboardOnlyAppState } from '../../../../../store/src/app-state'; import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; diff --git a/src/frontend/packages/store/src/actions/permissions.actions.ts b/src/frontend/packages/store/src/actions/permissions.actions.ts new file mode 100644 index 0000000000..0fd84d207b --- /dev/null +++ b/src/frontend/packages/store/src/actions/permissions.actions.ts @@ -0,0 +1,9 @@ +import { Action } from '@ngrx/store'; + +export const GET_CURRENT_USER_RELATIONS = '[Current User] Get relations'; +export const GET_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get relations success'; +export const GET_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get relations failed'; + +export class GetCurrentUsersRelations implements Action { + type = GET_CURRENT_USER_RELATIONS; +} \ No newline at end of file diff --git a/src/frontend/packages/store/src/effects/permissions.effect.ts b/src/frontend/packages/store/src/effects/permissions.effect.ts index acba8d5c92..d3b29a31e8 100644 --- a/src/frontend/packages/store/src/effects/permissions.effect.ts +++ b/src/frontend/packages/store/src/effects/permissions.effect.ts @@ -5,14 +5,14 @@ import { Action, Store } from '@ngrx/store'; import { combineLatest, of as observableOf, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; +import { LoggerService } from '../../../core/src/core/logger.service'; +import { CONNECT_ENDPOINTS_SUCCESS, EndpointActionComplete } from '../actions/endpoint.actions'; import { GET_CURRENT_USER_RELATIONS, GET_CURRENT_USER_RELATIONS_FAILED, GET_CURRENT_USER_RELATIONS_SUCCESS, GetCurrentUsersRelations, -} from '../../../cloud-foundry/src/actions/permissions.actions'; -import { LoggerService } from '../../../core/src/core/logger.service'; -import { CONNECT_ENDPOINTS_SUCCESS, EndpointActionComplete } from '../actions/endpoint.actions'; +} from '../actions/permissions.actions'; import { AppState } from '../app-state'; import { entityCatalog } from '../entity-catalog/entity-catalog'; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts index a3754b6e1c..0f0bc7914c 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts @@ -1,6 +1,9 @@ +import { Action } from '@ngrx/store'; + import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; import { IRequestEntityTypeState } from '../app-state'; import { ExtraApiReducers } from '../reducers/api-request-reducers.generator.helpers'; +import { ICurrentUserRolesState } from '../types/current-user-roles.types'; import { OrchestratedActionBuilders } from './action-orchestrator/action-orchestrator'; import { StratosBaseCatalogEntity, @@ -201,13 +204,22 @@ class EntityCatalog { }, {} as ExtraApiReducers>); } - public getAllCurrentUserReducers() { + public getAllCurrentUserReducers(state: ICurrentUserRolesState, action: Action): ICurrentUserRolesState { const endpoints = this.getAllEndpointTypes(); + let oneChanged = false; endpoints.forEach(endpoint => { if (endpoint.definition.userRolesReducer) { - console.log(endpoint.type) // TODO: RC + // TODO: RC does this churn? + const newState = endpoint.definition.userRolesReducer(state.endpoints[endpoint.type], action); + oneChanged = oneChanged || !!newState; + if (!!newState) { + state.endpoints[endpoint.type] = newState; + } } }) + return oneChanged ? { + ...state + } : state; } } diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index 928c0699ed..34a20a037a 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -13,6 +13,7 @@ import { EntityFetchHandler, EntityInfoHandler, EntityUserRolesFetch, + EntityUserRolesReducer, PreApiRequest, PrePaginationApiRequest, SuccessfulApiResponseDataMapper, @@ -21,7 +22,6 @@ import { PaginationPageIteratorConfig, } from '../entity-request-pipeline/pagination-request-base-handlers/pagination-iterator.pipe'; import { EntitySchema } from '../helpers/entity-schema'; -import { ICurrentUserRolesState } from '../types/current-user-roles.types'; import { UserFavorite } from '../types/user-favorites.types'; export interface EntityCatalogEntityConfig { @@ -95,8 +95,6 @@ export interface IStratosBaseEntityDefinition UserFavorite; readonly userRolesFetch?: EntityUserRolesFetch // TODO: RC Comment - readonly userRolesReducer?: () => ICurrentUserRolesState // TODO: RC Comment + readonly userRolesReducer?: EntityUserRolesReducer // TODO: RC Comment } export interface StratosEndpointExtensionDefinition extends Omit { } diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts index 4080547785..69218ebec9 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts @@ -142,4 +142,6 @@ export type EntityUserRolesFetch = ( store: Store, logService: LoggerService, httpClient: HttpClient -) => Observable; \ No newline at end of file +) => Observable; + +export type EntityUserRolesReducer = (state: T, action: Action) => T; \ No newline at end of file diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-request-state.reducers.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-request-state.reducers.ts deleted file mode 100644 index 1deb05551d..0000000000 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-request-state.reducers.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - GET_CURRENT_USER_CF_RELATIONS, - GET_CURRENT_USER_CF_RELATIONS_FAILED, - GET_CURRENT_USER_CF_RELATIONS_SUCCESS, - GET_CURRENT_USER_RELATIONS, - GET_CURRENT_USER_RELATIONS_FAILED, - GET_CURRENT_USER_RELATIONS_SUCCESS, - GetUserCfRelations, -} from '../../../../cloud-foundry/src/actions/permissions.actions'; -import { IAllCfRolesState } from '../../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; -import { getDefaultRolesRequestState, RolesRequestState } from '../../types/current-user-roles.types'; - -export function currentUserRolesRequestStateReducer(state: RolesRequestState = getDefaultRolesRequestState(), type: string) { - switch (type) { - case GET_CURRENT_USER_RELATIONS: - case GET_CURRENT_USER_CF_RELATIONS: - return { - ...state, - fetching: true - }; - case GET_CURRENT_USER_RELATIONS_SUCCESS: - case GET_CURRENT_USER_CF_RELATIONS_SUCCESS: - return { - ...state, - initialised: true, - fetching: false - }; - case GET_CURRENT_USER_RELATIONS_FAILED: - case GET_CURRENT_USER_CF_RELATIONS_FAILED: - return { - ...state, - fetching: false, - error: true - }; - } -} - -export function currentUserCfRolesRequestStateReducer(cf: IAllCfRolesState = {}, action: GetUserCfRelations) { - const cfGuid = (action as GetUserCfRelations).cfGuid; - return { - ...cf, - [cfGuid]: { - ...cf[cfGuid], - state: { - ...cf[cfGuid].state, - ...currentUserRolesRequestStateReducer(cf[cfGuid].state, action.type) - } - } - }; -} diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts deleted file mode 100644 index feb787a9fd..0000000000 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { EndpointActionComplete } from '../../actions/endpoint.actions'; -import { getDefaultEndpointRoles, ICurrentUserRolesState } from '../../types/current-user-roles.types'; -import { EndpointModel } from '../../types/endpoint.types'; -import { APISuccessOrFailedAction } from '../../types/request.types'; - -export function removeEndpointRoles(state: ICurrentUserRolesState, action: EndpointActionComplete) { - const cfState = { - ...state.cf - }; - if (action.endpointType !== 'cf' || !cfState[action.guid]) { - return state; - } - delete cfState[action.guid]; - return { - ...state, - cf: cfState - }; -} - -export function addEndpoint(state: ICurrentUserRolesState, action: EndpointActionComplete) { - const endpoint = action.endpoint as EndpointModel; - const guid = endpoint.guid; - if (action.endpointType !== 'cf' || state[guid]) { - return state; - } - const cfState = { - ...state.cf - }; - - cfState[guid] = getDefaultEndpointRoles(); - return { - ...state, - cf: cfState - }; -} - -export function removeSpaceRoles(state: ICurrentUserRolesState, action: APISuccessOrFailedAction) { - const { endpointGuid, guid } = action.apiAction; - const removedOrgOrSpaceState = removeOrgOrSpaceRoles(state, endpointGuid as string, guid, 'spaces'); - return removeSpaceIdFromOrg(state, endpointGuid as string, guid); -} - -function removeSpaceIdFromOrg(state: ICurrentUserRolesState, endpointGuid: string, spaceGuid: string) { - const space = state.cf[endpointGuid].spaces[spaceGuid]; - if (!space) { - return state; - } - const { orgId } = space; - return { - ...state, - cf: { - ...state.cf, - [endpointGuid]: { - ...state.cf[endpointGuid], - organizations: { - ...state.cf[endpointGuid].organizations, - [orgId]: { - ...state.cf[endpointGuid].organizations[orgId], - spaceGuids: state.cf[endpointGuid].organizations[orgId].spaceGuids.filter(id => id !== spaceGuid) - } - } - } - } - }; -} - -export function removeOrgRoles(state: ICurrentUserRolesState, action: APISuccessOrFailedAction) { - const { endpointGuid, guid } = action.apiAction; - if (!state.cf[endpointGuid as string].organizations[guid]) { - return state; - } - // const spaceIds = state.cf[endpointGuid].organizations[guid].spaceIds; - const spaceIds = []; - const newState = removeOrgOrSpaceRoles(state, endpointGuid, guid, 'organizations'); - return cleanUpOrgSpaces(newState, spaceIds, endpointGuid); -} - -function removeOrgOrSpaceRoles( - state: ICurrentUserRolesState, - endpointGuid: string, - orgOrSpaceId: string, - type: 'organizations' | 'spaces' -) { - if (!state.cf[endpointGuid][type][orgOrSpaceId]) { - return state; - } - // Remove orgOrSpaceId - const { - [orgOrSpaceId]: omit, - ...newTypeState - } = state.cf[endpointGuid][type]; - - const newState = { - ...state, - cf: { - ...state.cf, - [endpointGuid]: { - ...state.cf[endpointGuid], - [type]: newTypeState - } - } - }; - return newState; -} - -function cleanUpOrgSpaces(state: ICurrentUserRolesState, spaceIds: string[], endpointGuid: string) { - if (!spaceIds || spaceIds.length === 0 || !state.cf[endpointGuid]) { - return state; - } - return spaceIds.reduce((newState, spaceId) => { - if (newState.cf[endpointGuid].spaces[spaceId]) { - delete newState.cf[endpointGuid].spaces[spaceId]; - } - return newState; - }, { ...state }); -} - - - diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts index 78d91fd386..53577246d6 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts @@ -1,93 +1,80 @@ import { Action } from '@ngrx/store'; -import { DELETE_ORGANIZATION_SUCCESS } from '../../../../cloud-foundry/src/actions/organization.actions'; import { - GET_CURRENT_USER_CF_RELATIONS, - GET_CURRENT_USER_CF_RELATIONS_FAILED, - GET_CURRENT_USER_CF_RELATIONS_SUCCESS, - GET_CURRENT_USER_RELATION_SUCCESS, GET_CURRENT_USER_RELATIONS, GET_CURRENT_USER_RELATIONS_FAILED, GET_CURRENT_USER_RELATIONS_SUCCESS, - GetCurrentUserRelationsComplete, - GetUserCfRelations, -} from '../../../../cloud-foundry/src/actions/permissions.actions'; -import { DELETE_SPACE_SUCCESS } from '../../../../cloud-foundry/src/actions/space.actions'; -import { ADD_ROLE_SUCCESS, REMOVE_ROLE_SUCCESS } from '../../../../cloud-foundry/src/actions/users.actions'; -import { - currentUserBaseCFRolesReducer, -} from '../../../../cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer'; -import { - updateAfterRoleChange, -} from '../../../../cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-changed.reducers'; -import { SESSION_VERIFIED, VerifiedSession } from '../../actions/auth.actions'; -import { - CONNECT_ENDPOINTS_SUCCESS, - DISCONNECT_ENDPOINTS_SUCCESS, - EndpointActionComplete, - REGISTER_ENDPOINTS_SUCCESS, - UNREGISTER_ENDPOINTS_SUCCESS, -} from '../../actions/endpoint.actions'; +} from '../../actions/permissions.actions'; import { entityCatalog } from '../../entity-catalog/entity-catalog'; -import { getDefaultRolesRequestState, ICurrentUserRolesState } from '../../types/current-user-roles.types'; -import { APISuccessOrFailedAction } from '../../types/request.types'; import { - currentUserCfRolesRequestStateReducer, - currentUserRolesRequestStateReducer, -} from './current-user-request-state.reducers'; -import { roleInfoFromSessionReducer, updateNewlyConnectedEndpoint } from './current-user-role-session.reducer'; -import { addEndpoint, removeEndpointRoles, removeOrgRoles, removeSpaceRoles } from './current-user-roles-clear.reducers'; + getDefaultRolesRequestState, + ICurrentUserRolesState, + RolesRequestState, +} from '../../types/current-user-roles.types'; const getDefaultState = () => ({ internal: { isAdmin: false, scopes: [] }, - cf: {}, + endpoints: {}, state: getDefaultRolesRequestState() }); export function currentUserRolesReducer(state: ICurrentUserRolesState = getDefaultState(), action: Action): ICurrentUserRolesState { switch (action.type) { - case GET_CURRENT_USER_RELATION_SUCCESS: + case GET_CURRENT_USER_RELATIONS:// TODO: RC NOT CF!!!!!!!!!!!! but has in + return { + ...state, + state: currentUserRolesRequestStateReducer(state.state, RolesRequestStateStage.START) + }; + case GET_CURRENT_USER_RELATIONS_SUCCESS:// TODO: RC NOT CF!!!!!!!!!!!! but has in return { ...state, - cf: currentUserBaseCFRolesReducer(state.cf, action as GetCurrentUserRelationsComplete) + state: currentUserRolesRequestStateReducer(state.state, RolesRequestStateStage.SUCCESS) }; - case SESSION_VERIFIED: - return roleInfoFromSessionReducer(state, action as VerifiedSession); - case REGISTER_ENDPOINTS_SUCCESS: - return addEndpoint(state, action as EndpointActionComplete); - case CONNECT_ENDPOINTS_SUCCESS: - return updateNewlyConnectedEndpoint(state, action as EndpointActionComplete); - case DISCONNECT_ENDPOINTS_SUCCESS: - case UNREGISTER_ENDPOINTS_SUCCESS: - return removeEndpointRoles(state, action as EndpointActionComplete); - case DELETE_ORGANIZATION_SUCCESS: - return removeOrgRoles(state, action as APISuccessOrFailedAction); - case DELETE_SPACE_SUCCESS: - return removeSpaceRoles(state, action as APISuccessOrFailedAction); - case ADD_ROLE_SUCCESS: - return updateAfterRoleChange(state, true, action as APISuccessOrFailedAction); - case REMOVE_ROLE_SUCCESS: - return updateAfterRoleChange(state, false, action as APISuccessOrFailedAction); - case GET_CURRENT_USER_RELATIONS: - case GET_CURRENT_USER_RELATIONS_SUCCESS: - case GET_CURRENT_USER_RELATIONS_FAILED: + case GET_CURRENT_USER_RELATIONS_FAILED:// TODO: RC NOT CF!!!!!!!!!!!! but has in + return { + ...state, + state: currentUserRolesRequestStateReducer(state.state, RolesRequestStateStage.FAILURE) + }; + default: { // TODO: RC Comment. can cause issues if plugins have same action type names. Should use same method as // requestData in entity-catalog.module - entityCatalog.getAllCurrentUserReducers(); return { ...state, - state: currentUserRolesRequestStateReducer(state.state, action.type) + ...entityCatalog.getAllCurrentUserReducers(state, action) + }; + } + } + return state; +} + +export enum RolesRequestStateStage { + START, + SUCCESS, + FAILURE, + OTHER +} + +export function currentUserRolesRequestStateReducer(state: RolesRequestState = getDefaultRolesRequestState(), stage: RolesRequestStateStage) { + switch (stage) { + case RolesRequestStateStage.START: + return { + ...state, + fetching: true }; - case GET_CURRENT_USER_CF_RELATIONS: - case GET_CURRENT_USER_CF_RELATIONS_SUCCESS: - case GET_CURRENT_USER_CF_RELATIONS_FAILED: + case RolesRequestStateStage.SUCCESS: return { ...state, - cf: currentUserCfRolesRequestStateReducer(state.cf, action as GetUserCfRelations) + initialised: true, + fetching: false + }; + case RolesRequestStateStage.FAILURE: + return { + ...state, + fetching: false, + error: true }; } - return state; } diff --git a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts index f142466a1a..a5f6c359d4 100644 --- a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts +++ b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts @@ -1,6 +1,5 @@ import { compose } from '@ngrx/store'; -import { ICfRolesState } from '../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; import { PermissionValues, ScopeStrings } from '../../../core/src/core/current-user-permissions.config'; import { CurrentUserRolesAppState } from '../app-state'; @@ -17,12 +16,7 @@ const selectCurrentUserStratosRoles = (role: PermissionValues) => (state: Omit (state: ICfRolesState) => { -// const entityType = state[type]; -// return Object.keys(entityType).filter(entity => entityType[entity][role]); -// }; -export const selectCurrentUserRequestState = (state: ICurrentUserRolesState | ICfRolesState) => state.state; export const selectCurrentUserGlobalHasScopes = (scope: ScopeStrings) => (scopes: ScopeStrings[]) => scopes.includes(scope); const selectCurrentUserStratosScopesState = (state: IStratosRolesState) => state.scopes; diff --git a/src/frontend/packages/store/src/store.module.ts b/src/frontend/packages/store/src/store.module.ts index 0f57fd8946..d66eb95791 100644 --- a/src/frontend/packages/store/src/store.module.ts +++ b/src/frontend/packages/store/src/store.module.ts @@ -19,7 +19,6 @@ import { SystemEffects } from './effects/system.effects'; import { UAASetupEffect } from './effects/uaa-setup.effects'; import { UserFavoritesEffect } from './effects/user-favorites-effect'; import { UserProfileEffect } from './effects/user-profile.effects'; -import { UsersRolesEffects } from './effects/users-roles.effects'; import { PipelineHttpClient } from './entity-request-pipeline/pipline-http-client.service'; import { AppReducersModule } from './reducers.module'; @@ -46,7 +45,6 @@ import { AppReducersModule } from './reducers.module'; SetClientFilterEffect, MetricsEffect, UserProfileEffect, - UsersRolesEffects, RecursiveDeleteEffect, UserFavoritesEffect, PermissionsEffects diff --git a/src/frontend/packages/store/src/types/current-user-roles.types.ts b/src/frontend/packages/store/src/types/current-user-roles.types.ts index 7eb2d22878..1b1eaed25e 100644 --- a/src/frontend/packages/store/src/types/current-user-roles.types.ts +++ b/src/frontend/packages/store/src/types/current-user-roles.types.ts @@ -1,4 +1,3 @@ -import { IAllCfRolesState, ICfRolesState } from '../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; export interface RolesRequestState { @@ -15,33 +14,15 @@ export function getDefaultRolesRequestState(): RolesRequestState { }; } -export function getDefaultEndpointRoles(): ICfRolesState { - return { - global: { - isAdmin: false, - isReadOnlyAdmin: false, - isGlobalAuditor: false, - canRead: false, - canWrite: false, - scopes: [] - }, - spaces: { - - }, - organizations: { - - }, - state: getDefaultRolesRequestState() - }; -} - export interface IStratosRolesState { isAdmin: boolean; scopes: StratosScopeStrings[]; } -export interface ICurrentUserRolesState { +export interface ICurrentUserRolesState { internal: IStratosRolesState; - cf: IAllCfRolesState; + endpoints: { + [endpointType: string]: T // T could be different types, but it makes it nicer when using for an single endpoint type + } state: RolesRequestState; } From eca176d80100acb454a4e2051cfd43a55cba66ac Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 26 May 2020 17:17:14 +0100 Subject: [PATCH 04/82] Final set of cloud-foundry code out of common --- .../application-wall.component.html | 2 +- .../tabs/build-tab/build-tab.component.html | 19 ++-- .../tabs/build-tab/build-tab.component.ts | 1 + .../src/features/cloud-foundry/cf.helpers.ts | 2 + .../cli-info-cloud-foundry.component.html | 30 ++++--- ...foundry-organization-spaces.component.html | 2 +- ...cloud-foundry-space-summary.component.html | 4 +- ...oundry-organization-summary.component.html | 4 +- .../service-tabs-base.component.html | 7 +- .../services-wall.component.html | 12 ++- .../src/shared/cf-shared.module.ts | 7 +- .../user-permission.directive.spec.ts | 33 +++++++ .../user-permission.directive.ts | 83 ++++++++++++++++++ .../current-user-base-cf-role.reducer.ts | 87 ++++++++++++++++++- .../current-user-cf-roles.reducer.ts | 62 +------------ .../current-user-reducer.helpers.ts | 7 +- .../current-user-role-session.reducer.ts | 29 ++----- .../current-user-roles-changed.reducers.ts | 22 ++--- .../current-user-roles-clear.reducers.ts | 10 +-- .../current-user-roles-orgs.reducer.ts | 5 +- .../current-user-roles-spaces.reducer.ts | 5 +- .../current-user-roles.reducer.ts | 26 ++---- .../cf-current-user-role.selectors.ts | 9 +- .../types/cf-current-user-roles.types.ts | 1 - .../store/types/current-user-roles.types.ts | 20 +---- .../cf-user-permissions-checkers.ts | 2 +- .../user-permissions/cf-user-roles-fetch.ts | 3 +- .../packages/core/src/shared/shared.module.ts | 1 - .../src/shared/user-permission.directive.ts | 61 +++---------- .../src/entity-catalog/entity-catalog.ts | 8 +- .../success-entity-request.handler.ts | 18 ++-- .../entity-request-pipeline.types.ts | 2 +- .../current-user-roles.reducer.ts | 40 ++++++--- .../src/types/current-user-roles.types.ts | 3 +- 34 files changed, 361 insertions(+), 266 deletions(-) create mode 100644 src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.spec.ts create mode 100644 src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.ts rename src/frontend/packages/{store/src => cloud-foundry/src/store}/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts (86%) diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.html b/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.html index 67660b76fd..34ef360c0f 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.html @@ -1,7 +1,7 @@

Applications

- + diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html index 97501ccc56..a1ceaa6f53 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html @@ -2,7 +2,7 @@
+ *appCfUserPermission="manageAppPermission;spaceGuid:space.metadata.guid;endpointGuid:applicationService.cfGuid"> - + +
@@ -17,13 +17,17 @@

Organization Commands

- + - + - +
@@ -32,13 +36,17 @@

Space Commands

- + - + - + - + \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.html b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.html index bc6510ee2a..54a6d00f8e 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.html @@ -1,6 +1,6 @@ diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.html b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.html index aca6cf5016..c1565ef97b 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.html @@ -1,11 +1,11 @@ - diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.html b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.html index 839286509e..f6b4c53c11 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.html @@ -3,8 +3,9 @@ {{ getServiceLabel() | async }}
- - @@ -12,4 +13,4 @@ - + \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.html b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.html index 8fb67cc7bd..cf6322f5e7 100644 --- a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.html @@ -2,7 +2,7 @@

Services

- + @@ -12,15 +12,19 @@

Services

- - - + + \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts index ae83e851a0..4c3001c6d4 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts @@ -205,6 +205,7 @@ import { ServicePlanPriceComponent } from './components/service-plan-price/servi import { ServicePlanPublicComponent } from './components/service-plan-public/service-plan-public.component'; import { GitSCMService } from './data-services/scm/scm.service'; import { AppNameUniqueDirective } from './directives/app-name-unique.directive/app-name-unique.directive'; +import { CfUserPermissionDirective } from './directives/user-permission/user-permission.directive'; import { ApplicationStateService } from './services/application-state.service'; import { CloudFoundryUserProvidedServicesService } from './services/cloud-foundry-user-provided-services.service'; @@ -322,7 +323,8 @@ const cfListCards: Type>[] = [ AppNameUniqueDirective, ApplicationInstanceChartComponent, GithubCommitAuthorComponent, - EnvVarViewComponent + EnvVarViewComponent, + CfUserPermissionDirective ], exports: [ ServiceIconComponent, @@ -364,7 +366,8 @@ const cfListCards: Type>[] = [ AppNameUniqueDirective, ApplicationInstanceChartComponent, GithubCommitAuthorComponent, - EnvVarViewComponent + EnvVarViewComponent, + CfUserPermissionDirective ], entryComponents: [ CfEndpointDetailsComponent, diff --git a/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.spec.ts new file mode 100644 index 0000000000..86d356647a --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.spec.ts @@ -0,0 +1,33 @@ +import { Component, TemplateRef } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BaseTestModules } from '../../test-framework/core-test.helper'; + +@Component({ + template: `` +}) +class TestUserPermissionComponent { +} + +class MockTemplateRef { } + +describe('UserPermissionDirective', () => { + let component: TestUserPermissionComponent; + let fixture: ComponentFixture; + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + ...BaseTestModules + ], + providers: [ + { provide: TemplateRef, useClass: MockTemplateRef }, + ], + declarations: [TestUserPermissionComponent] + }); + fixture = TestBed.createComponent(TestUserPermissionComponent); + component = fixture.componentInstance; + }); + it('should create an instance', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.ts b/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.ts new file mode 100644 index 0000000000..61e0878519 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.ts @@ -0,0 +1,83 @@ +import { Directive, Input, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { Observable, of as observableOf, Subscription } from 'rxjs'; +import { switchMap, tap } from 'rxjs/operators'; + +import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; +import { AppState } from '../../../../../store/src/app-state'; +import { waitForCFPermissions } from '../../../features/cloud-foundry/cf.helpers'; +import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; + +// TODO: RC test +// TODO: RC filename +@Directive({ + selector: '[appCfUserPermission]' +}) +export class CfUserPermissionDirective implements OnDestroy, OnInit { + @Input() + public appCfUserPermission: CfCurrentUserPermissions; + + @Input() + public appCfUserPermissionEndpointGuid: string; + + @Input() + private appCfUserPermissionOrganizationGuid: string; + + @Input() + private appCfUserPermissionSpaceGuid: string; + + private canSub: Subscription; + + constructor( + private store: Store, + private templateRef: TemplateRef, + private viewContainer: ViewContainerRef, + private currentUserPermissionsService: CurrentUserPermissionsService, + ) { } + + public ngOnInit() { + this.canSub = this.waitForEndpointPermissions(this.appCfUserPermissionEndpointGuid).pipe( + tap(console.log), + switchMap(() => this.currentUserPermissionsService.can( + this.appCfUserPermission, + this.appCfUserPermissionEndpointGuid, + this.getOrgOrSpaceGuid(), + this.getSpaceGuid() + )) + ).subscribe( + can => { + if (can) { + this.viewContainer.createEmbeddedView(this.templateRef); + } else { + this.viewContainer.clear(); + } + } + ); + } + + private waitForEndpointPermissions(endpointGuid: string): Observable { + return endpointGuid && endpointGuid.length > 0 ? waitForCFPermissions(this.store, endpointGuid) : observableOf(true); + } + + public ngOnDestroy() { + if (this.canSub) { + this.canSub.unsubscribe(); + } + } + + private getOrgOrSpaceGuid() { + if (this.appCfUserPermissionSpaceGuid && !this.appCfUserPermissionOrganizationGuid) { + return this.appCfUserPermissionSpaceGuid; + } + return this.appCfUserPermissionOrganizationGuid; + } + + private getSpaceGuid() { + if (this.appCfUserPermissionOrganizationGuid) { + return this.appCfUserPermissionSpaceGuid; + } + return null; + } + + +} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts index dd36dadb56..e4557f5ef7 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts @@ -1,7 +1,32 @@ -import { GetCurrentUserRelationsComplete } from '../../../actions/permissions.actions'; -import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; -import { getDefaultEndpointRoles } from '../../types/current-user-roles.types'; -import { currentUserCFRolesReducer } from './current-user-cf-roles.reducer'; +import { APIResource } from '../../../../../store/src/types/api.types'; +import { getDefaultRolesRequestState } from '../../../../../store/src/types/current-user-roles.types'; +import { GetCurrentUserRelationsComplete, UserRelationTypes } from '../../../actions/permissions.actions'; +import { ISpace } from '../../../cf-api.types'; +import { IAllCfRolesState, ICfRolesState, IOrgsRoleState } from '../../types/cf-current-user-roles.types'; +import { createOrgRoleStateState } from './current-user-roles-org.reducer'; +import { currentUserOrgRolesReducer } from './current-user-roles-orgs.reducer'; +import { currentUserSpaceRolesReducer } from './current-user-roles-spaces.reducer'; + +// TODO: RC RENAME +export function getDefaultEndpointRoles(): ICfRolesState { + return { + global: { + isAdmin: false, + isReadOnlyAdmin: false, + isGlobalAuditor: false, + canRead: false, + canWrite: false, + scopes: [] + }, + spaces: { + + }, + organizations: { + + }, + state: getDefaultRolesRequestState() + }; +} export function currentUserBaseCFRolesReducer(state: IAllCfRolesState = {}, action: GetCurrentUserRelationsComplete): IAllCfRolesState { if (!state[action.endpointGuid]) { @@ -15,3 +40,57 @@ export function currentUserBaseCFRolesReducer(state: IAllCfRolesState = {}, acti [action.endpointGuid]: currentUserCFRolesReducer(state[action.endpointGuid], action) }; } + +function currentUserCFRolesReducer( + state: ICfRolesState = getDefaultEndpointRoles(), + action: GetCurrentUserRelationsComplete): ICfRolesState { + if (isOrgRelation(action.relationType)) { + return { + ...state, + organizations: currentUserOrgRolesReducer(state.organizations, action) + }; + } + if (isSpaceRelation(action.relationType)) { + return { + ...state, + spaces: currentUserSpaceRolesReducer(state.spaces, action), + organizations: assignSpaceToOrg(state.organizations, action.data) + }; + } + return state; +} + +function assignSpaceToOrg(organizations: IOrgsRoleState = {}, spaces: APIResource[]): IOrgsRoleState { + return spaces.reduce((newOrganizations: IOrgsRoleState, space) => { + const orgGuid = space.entity.organization_guid; + const org = newOrganizations[orgGuid] || createOrgRoleStateState(); + const spaceGuids = org.spaceGuids || []; + if (spaceGuids.includes(space.metadata.guid)) { + return newOrganizations; + } + return { + ...newOrganizations, + [orgGuid]: { + ...org, + spaceGuids: [ + ...spaceGuids, + space.metadata.guid + ] + } + }; + }, organizations); +} + + +function isOrgRelation(relationType: UserRelationTypes) { + return relationType === UserRelationTypes.AUDITED_ORGANIZATIONS || + relationType === UserRelationTypes.BILLING_MANAGED_ORGANIZATION || + relationType === UserRelationTypes.MANAGED_ORGANIZATION || + relationType === UserRelationTypes.ORGANIZATIONS; +} + +function isSpaceRelation(relationType: UserRelationTypes) { + return relationType === UserRelationTypes.AUDITED_SPACES || + relationType === UserRelationTypes.MANAGED_SPACES || + relationType === UserRelationTypes.SPACES; +} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-cf-roles.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-cf-roles.reducer.ts index 3cb9fbf328..a4e80f1682 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-cf-roles.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-cf-roles.reducer.ts @@ -1,62 +1,2 @@ -import { APIResource } from '../../../../../store/src/types/api.types'; -import { getDefaultEndpointRoles } from '../../../../../store/src/types/current-user-roles.types'; -import { GetCurrentUserRelationsComplete, UserRelationTypes } from '../../../actions/permissions.actions'; -import { ISpace } from '../../../cf-api.types'; -import { ICfRolesState, IOrgsRoleState } from '../../types/cf-current-user-roles.types'; -import { createOrgRoleStateState } from './current-user-roles-org.reducer'; -import { currentUserOrgRolesReducer } from './current-user-roles-orgs.reducer'; -import { currentUserSpaceRolesReducer } from './current-user-roles-spaces.reducer'; -export function currentUserCFRolesReducer( - state: ICfRolesState = getDefaultEndpointRoles(), - action: GetCurrentUserRelationsComplete): ICfRolesState { - if (isOrgRelation(action.relationType)) { - return { - ...state, - organizations: currentUserOrgRolesReducer(state.organizations, action) - }; - } - if (isSpaceRelation(action.relationType)) { - return { - ...state, - spaces: currentUserSpaceRolesReducer(state.spaces, action), - organizations: assignSpaceToOrg(state.organizations, action.data) - }; - } - return state; -} - -function assignSpaceToOrg(organizations: IOrgsRoleState = {}, spaces: APIResource[]): IOrgsRoleState { - return spaces.reduce((newOrganizations: IOrgsRoleState, space) => { - const orgGuid = space.entity.organization_guid; - const org = newOrganizations[orgGuid] || createOrgRoleStateState(); - const spaceGuids = org.spaceGuids || []; - if (spaceGuids.includes(space.metadata.guid)) { - return newOrganizations; - } - return { - ...newOrganizations, - [orgGuid]: { - ...org, - spaceGuids: [ - ...spaceGuids, - space.metadata.guid - ] - } - }; - }, organizations); -} - - -function isOrgRelation(relationType: UserRelationTypes) { - return relationType === UserRelationTypes.AUDITED_ORGANIZATIONS || - relationType === UserRelationTypes.BILLING_MANAGED_ORGANIZATION || - relationType === UserRelationTypes.MANAGED_ORGANIZATION || - relationType === UserRelationTypes.ORGANIZATIONS; -} - -function isSpaceRelation(relationType: UserRelationTypes) { - return relationType === UserRelationTypes.AUDITED_SPACES || - relationType === UserRelationTypes.MANAGED_SPACES || - relationType === UserRelationTypes.SPACES; -} +// TODO: RC DELETE \ No newline at end of file diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts similarity index 86% rename from src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts index 61459783c7..8d2608a56c 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts @@ -1,8 +1,5 @@ -import { - GetCurrentUserRelationsComplete, - UserRelationTypes, -} from '../../../../cloud-foundry/src/actions/permissions.actions'; -import { APIResource } from '../../types/api.types'; +import { APIResource } from '../../../../../store/src/types/api.types'; +import { GetCurrentUserRelationsComplete, UserRelationTypes } from '../../../actions/permissions.actions'; export interface IKeyedByIDObject { [id: string]: T; diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts index 9cb664e877..cf48b55f76 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts @@ -4,8 +4,9 @@ import { SessionUser } from '../../../../../store/src/types/auth.types'; import { EndpointUser, INewlyConnectedEndpointInfo } from '../../../../../store/src/types/endpoint.types'; import { CfScopeStrings } from '../../../user-permissions/cf-user-permissions-checkers'; import { IAllCfRolesState, ICfRolesState, IGlobalRolesState } from '../../types/cf-current-user-roles.types'; -import { getDefaultEndpointRoles } from '../../types/current-user-roles.types'; +import { getDefaultEndpointRoles } from './current-user-base-cf-role.reducer'; +// TODO: RC used interface PartialEndpoint { user: EndpointUser | SessionUser; guid: string; @@ -15,44 +16,28 @@ export function roleInfoFromSessionReducer( state: IAllCfRolesState, action: VerifiedSession ): IAllCfRolesState { - const { user, endpoints } = action.sessionData; - const cfRoles = propagateEndpointsAdminPermissions(state, Object.values(endpoints.cf)); - return applyInternalScopes(state, cfRoles, user); + const { endpoints } = action.sessionData; + return propagateEndpointsAdminPermissions(state, Object.values(endpoints.cf)); } export function updateNewlyConnectedEndpoint( state: IAllCfRolesState, action: EndpointActionComplete ): IAllCfRolesState { + // TODO: RC have at start if (action.endpointType !== 'cf') { return state; } const endpoint = action.endpoint as INewlyConnectedEndpointInfo; - const cfRoles = propagateEndpointsAdminPermissions(state.cf, [{ + const cfRoles = propagateEndpointsAdminPermissions(state, [{ user: endpoint.user, guid: action.guid }]); return { - ...state, - cf: cfRoles + ...cfRoles, }; } -// TODO: RC huh -function applyInternalScopes(state: IAllCfRolesState, cfRoles: IAllCfRolesState, user?: SessionUser | EndpointUser) { - const internalRoles = { ...state.internal }; - if (user) { - internalRoles.scopes = user.scopes || []; - // The admin scope is configurable - so look at the flag provided by the backend - internalRoles.isAdmin = user.admin; - } - - return { - ...state, - cf: cfRoles, - internal: internalRoles - }; -} function propagateEndpointsAdminPermissions( cfState: IAllCfRolesState, diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-changed.reducers.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-changed.reducers.ts index 788fa96f42..1c32e5b8f8 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-changed.reducers.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-changed.reducers.ts @@ -1,16 +1,15 @@ -import { ICurrentUserRolesState } from '../../../../../store/src/types/current-user-roles.types'; import { APISuccessOrFailedAction } from '../../../../../store/src/types/request.types'; import { ChangeUserRole } from '../../../actions/users.actions'; import { CfPermissionStrings } from '../../../user-permissions/cf-user-permissions-checkers'; -import { ICfRolesState, IOrgRoleState, ISpaceRoleState } from '../../types/cf-current-user-roles.types'; +import { IAllCfRolesState, ICfRolesState, IOrgRoleState, ISpaceRoleState } from '../../types/cf-current-user-roles.types'; import { OrgUserRoleNames, SpaceUserRoleNames } from '../../types/user.types'; import { defaultUserOrgRoleState } from './current-user-roles-org.reducer'; import { defaultUserSpaceRoleState } from './current-user-roles-space.reducer'; export function updateAfterRoleChange( - state: ICurrentUserRolesState, + state: IAllCfRolesState, isAdd: boolean, - action: APISuccessOrFailedAction): ICurrentUserRolesState { + action: APISuccessOrFailedAction): IAllCfRolesState { const changePerm = action.apiAction as ChangeUserRole; if (!changePerm.updateConnectedUser) { // We haven't changed the user connected to this cf or the connected user is an admin. No need to update the permission roles @@ -19,7 +18,7 @@ export function updateAfterRoleChange( const entityType = changePerm.isSpace ? 'spaces' : 'organizations'; - const cf = state.cf[changePerm.endpointGuid]; + const cf = state[changePerm.endpointGuid]; const entity = cf[entityType][changePerm.entityGuid] || createEmptyState(changePerm.isSpace, changePerm.orgGuid); const permissionType = userRoleNameToPermissionName(changePerm.permissionTypeKey); @@ -73,7 +72,7 @@ function userRoleNameToPermissionName(roleName: OrgUserRoleNames | SpaceUserRole } function handleOrgRoleChange( - state: ICurrentUserRolesState, + state: IAllCfRolesState, endpointGuid: string, cf: ICfRolesState, orgGuid: string, @@ -95,7 +94,7 @@ function handleOrgRoleChange( * Update the space role AND org space guids list */ function handleSpaceRoleChange( - state: ICurrentUserRolesState, + state: IAllCfRolesState, endpointGuid: string, cf: ICfRolesState, orgGuid: string, @@ -135,14 +134,11 @@ function handleSpaceRoleChange( }); } -function spreadState(state: ICurrentUserRolesState, cfGuid: string, cf: ICfRolesState): ICurrentUserRolesState { +function spreadState(state: IAllCfRolesState, cfGuid: string, cf: ICfRolesState): IAllCfRolesState { return { ...state, - cf: { - ...state.cf, - [cfGuid]: { - ...cf - } + [cfGuid]: { + ...cf } }; } diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts index 1135f366e4..5cbd0c212f 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts @@ -2,7 +2,7 @@ import { EndpointActionComplete } from '../../../../../store/src/actions/endpoin import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { APISuccessOrFailedAction } from '../../../../../store/src/types/request.types'; import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; -import { getDefaultEndpointRoles } from '../../types/current-user-roles.types'; +import { getDefaultEndpointRoles } from './current-user-base-cf-role.reducer'; export function removeEndpointRoles(state: IAllCfRolesState, action: EndpointActionComplete) { const cfState = { @@ -13,8 +13,7 @@ export function removeEndpointRoles(state: IAllCfRolesState, action: EndpointAct } delete cfState[action.guid]; return { - ...state, - cf: cfState + ...cfState, }; } @@ -29,10 +28,7 @@ export function addEndpoint(state: IAllCfRolesState, action: EndpointActionCompl }; cfState[guid] = getDefaultEndpointRoles(); - return { - ...state, - cf: cfState - }; + return cfState; } export function removeSpaceRoles(state: IAllCfRolesState, action: APISuccessOrFailedAction) { diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-orgs.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-orgs.reducer.ts index b7d39d94bb..8961575c0d 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-orgs.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-orgs.reducer.ts @@ -1,9 +1,6 @@ -import { - addNewRoles, - removeOldRoles, -} from '../../../../../store/src/reducers/current-user-roles-reducer/current-user-reducer.helpers'; import { GetCurrentUserRelationsComplete } from '../../../actions/permissions.actions'; import { IOrgsRoleState } from '../../types/cf-current-user-roles.types'; +import { addNewRoles, removeOldRoles } from './current-user-reducer.helpers'; import { currentUserOrgRoleReducer } from './current-user-roles-org.reducer'; export function currentUserOrgRolesReducer(state: IOrgsRoleState = {}, action: GetCurrentUserRelationsComplete) { diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-spaces.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-spaces.reducer.ts index 5660bca4ef..6575cd241e 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-spaces.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-spaces.reducer.ts @@ -1,9 +1,6 @@ -import { - addNewRoles, - removeOldRoles, -} from '../../../../../store/src/reducers/current-user-roles-reducer/current-user-reducer.helpers'; import { GetCurrentUserRelationsComplete } from '../../../actions/permissions.actions'; import { ISpacesRoleState } from '../../types/cf-current-user-roles.types'; +import { addNewRoles, removeOldRoles } from './current-user-reducer.helpers'; import { currentUserSpaceRoleReducer } from './current-user-roles-space.reducer'; export function currentUserSpaceRolesReducer(state: ISpacesRoleState = {}, action: GetCurrentUserRelationsComplete) { diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts index 8fa8d51b3a..96760d7a1a 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts @@ -9,10 +9,6 @@ import { UNREGISTER_ENDPOINTS_SUCCESS, } from '../../../../../store/src/actions/endpoint.actions'; import { EntityUserRolesReducer } from '../../../../../store/src/entity-request-pipeline/entity-request-pipeline.types'; -import { - roleInfoFromSessionReducer, - updateNewlyConnectedEndpoint, -} from '../../../../../store/src/reducers/current-user-roles-reducer/current-user-role-session.reducer'; import { currentUserRolesRequestStateReducer, RolesRequestStateStage, @@ -31,24 +27,21 @@ import { DELETE_SPACE_SUCCESS } from '../../../actions/space.actions'; import { ADD_ROLE_SUCCESS, REMOVE_ROLE_SUCCESS } from '../../../actions/users.actions'; import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; import { currentUserBaseCFRolesReducer } from './current-user-base-cf-role.reducer'; +import { roleInfoFromSessionReducer, updateNewlyConnectedEndpoint } from './current-user-role-session.reducer'; import { updateAfterRoleChange } from './current-user-roles-changed.reducers'; import { addEndpoint, removeEndpointRoles, removeOrgRoles, removeSpaceRoles } from './current-user-roles-clear.reducers'; -// TODO: RC TUESDAY HERE - - -// TODO: RC go through each, where are they? -// TODO: RC RENAME -export const currentCfUserRolesReducer: EntityUserRolesReducer = ( +// TODO: RC TUESDAY HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// TODO: RC RENAME file +// TODO: RC check each type, abort if not anything to do with cf +export const currentCfUserRolesReducer: EntityUserRolesReducer = ( state: IAllCfRolesState, action: Action ): IAllCfRolesState => { switch (action.type) { case GET_CURRENT_USER_RELATION_SUCCESS: // TODO: RC CF Only. VS GET_CURRENT_USER_CF_RELATIONS - return { - ...state, - cf: currentUserBaseCFRolesReducer(state, action as GetCurrentUserRelationsComplete) - }; + const gcursAction = action as GetCurrentUserRelationsComplete + return currentUserBaseCFRolesReducer(state, gcursAction); case SESSION_VERIFIED:// TODO: RC CF Only return roleInfoFromSessionReducer(state, action as VerifiedSession); case REGISTER_ENDPOINTS_SUCCESS:// TODO: RC CF Only @@ -69,10 +62,7 @@ export const currentCfUserRolesReducer: EntityUserRolesReducer = }, []); }; -export const selectCurrentUserCFRolesState = (state: ICurrentUserRolesState) => state.cf; +export const selectCurrentUserCFRolesState = (state: ICurrentUserRolesState) => state.endpoints[CF_ENDPOINT_TYPE]; export const selectCurrentUserCFEndpointRolesState = (endpointGuid: string) => (state: IAllCfRolesState) => state ? state[endpointGuid] : null; @@ -61,8 +62,12 @@ export const getCurrentUserCFRolesState = compose( // Specific endpoint roles // ============================ export const getCurrentUserCFEndpointRolesState = (endpointGuid: string) => compose( + (a) => { + console.log('3: ', a) + return a; + }, selectCurrentUserCFEndpointRolesState(endpointGuid), - getCurrentUserCFRolesState + getCurrentUserCFRolesState, ); // ============================ diff --git a/src/frontend/packages/cloud-foundry/src/store/types/cf-current-user-roles.types.ts b/src/frontend/packages/cloud-foundry/src/store/types/cf-current-user-roles.types.ts index af56d71ac8..83640a6cf8 100644 --- a/src/frontend/packages/cloud-foundry/src/store/types/cf-current-user-roles.types.ts +++ b/src/frontend/packages/cloud-foundry/src/store/types/cf-current-user-roles.types.ts @@ -1,6 +1,5 @@ import { RolesRequestState } from '../../../../store/src/types/current-user-roles.types'; - export enum RoleEntities { ORGS = 'organizations', SPACES = 'spaces' diff --git a/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts b/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts index 9717e2eac9..40701be98b 100644 --- a/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts +++ b/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts @@ -1,19 +1 @@ -export function getDefaultEndpointRoles(): ICfRolesState { - return { - global: { - isAdmin: false, - isReadOnlyAdmin: false, - isGlobalAuditor: false, - canRead: false, - canWrite: false, - scopes: [] - }, - spaces: { - - }, - organizations: { - - }, - state: getDefaultRolesRequestState() - }; -} \ No newline at end of file +// TODO: RC DELETE ME \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts index 087e0f31b4..6331099941 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts @@ -45,7 +45,7 @@ export const cfCurrentUserPermissionsService = [ // a: '1', // b: '2', // } - +// TODO: RC of type PermissionTypes export enum CfCurrentUserPermissions { APPLICATION_VIEW = 'view.application', APPLICATION_EDIT = 'edit.application', diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts index 90e0646454..bbe95ce980 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts @@ -29,6 +29,7 @@ import { import { cfEntityCatalog } from '../cf-entity-catalog'; import { CFResponse } from '../store/types/cf-api.types'; +// TODO: RC // map(cfEndpoints => // Object // .entries(cfEndpoints) @@ -55,7 +56,7 @@ export const cfUserRolesFetch: EntityUserRolesFetch = ( const isAllAdmins = cfEndpoints.every(endpoint => !!endpoint.user.admin); // If all endpoints are connected as admin, there's no permissions to fetch. So only update the permission state to initialised if (isAllAdmins) { - cfEndpoints.map(endpoint => new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS)) + cfEndpoints.forEach(endpoint => store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS))) } else { // If some endpoints are not connected as admin, go out and fetch the current user's specific roles const flagsAndRoleRequests = dispatchRoleRequests(cfEndpoints, store, logService, httpClient); diff --git a/src/frontend/packages/core/src/shared/shared.module.ts b/src/frontend/packages/core/src/shared/shared.module.ts index b218f0e621..d5ab5af42e 100644 --- a/src/frontend/packages/core/src/shared/shared.module.ts +++ b/src/frontend/packages/core/src/shared/shared.module.ts @@ -278,7 +278,6 @@ import { UserPermissionDirective } from './user-permission.directive'; UserPermissionDirective, BooleanIndicatorComponent, TableComponent, - UserPermissionDirective, CapitalizeFirstPipe, RoutingIndicatorComponent, DateTimeComponent, diff --git a/src/frontend/packages/core/src/shared/user-permission.directive.ts b/src/frontend/packages/core/src/shared/user-permission.directive.ts index 9ef787cb02..13cb71db8c 100644 --- a/src/frontend/packages/core/src/shared/user-permission.directive.ts +++ b/src/frontend/packages/core/src/shared/user-permission.directive.ts @@ -1,60 +1,38 @@ import { Directive, Input, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; -import { Store } from '@ngrx/store'; -import { Observable, of as observableOf, Subscription } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { Subscription } from 'rxjs'; -import { waitForCFPermissions } from '../../../cloud-foundry/src/features/cloud-foundry/cf.helpers'; -import { CfCurrentUserPermissions } from '../../../cloud-foundry/src/user-permissions/cf-user-permissions-checkers'; -import { AppState } from '../../../store/src/app-state'; +import { PermissionTypes } from '../core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../core/current-user-permissions.service'; @Directive({ selector: '[appUserPermission]' }) export class UserPermissionDirective implements OnDestroy, OnInit { - // TODO: move @Input() - public appUserPermission: CfCurrentUserPermissions; + public appUserPermission: PermissionTypes; @Input() public appUserPermissionEndpointGuid: string; - @Input() - private appUserPermissionOrganizationGuid: string; - - @Input() - private appUserPermissionSpaceGuid: string; - private canSub: Subscription; constructor( - private store: Store, private templateRef: TemplateRef, private viewContainer: ViewContainerRef, private currentUserPermissionsService: CurrentUserPermissionsService, ) { } public ngOnInit() { - this.canSub = this.waitForEndpointPermissions(this.appUserPermissionEndpointGuid).pipe( - switchMap(() => this.currentUserPermissionsService.can( - this.appUserPermission, - this.appUserPermissionEndpointGuid, - this.getOrgOrSpaceGuid(), - this.getSpaceGuid() - )) - ).subscribe( - can => { - if (can) { - this.viewContainer.createEmbeddedView(this.templateRef); - } else { - this.viewContainer.clear(); - } + this.canSub = this.currentUserPermissionsService.can( + this.appUserPermission, + this.appUserPermissionEndpointGuid, + ).subscribe(can => { + if (can) { + this.viewContainer.createEmbeddedView(this.templateRef); + } else { + this.viewContainer.clear(); } - ); - } - - private waitForEndpointPermissions(endpointGuid: string): Observable { - return endpointGuid && endpointGuid.length > 0 ? waitForCFPermissions(this.store, endpointGuid) : observableOf(true); + }); } public ngOnDestroy() { @@ -63,19 +41,4 @@ export class UserPermissionDirective implements OnDestroy, OnInit { } } - private getOrgOrSpaceGuid() { - if (this.appUserPermissionSpaceGuid && !this.appUserPermissionOrganizationGuid) { - return this.appUserPermissionSpaceGuid; - } - return this.appUserPermissionOrganizationGuid; - } - - private getSpaceGuid() { - if (this.appUserPermissionOrganizationGuid) { - return this.appUserPermissionSpaceGuid; - } - return null; - } - - } diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts index 0f0bc7914c..66bb0bd211 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts @@ -213,7 +213,13 @@ class EntityCatalog { const newState = endpoint.definition.userRolesReducer(state.endpoints[endpoint.type], action); oneChanged = oneChanged || !!newState; if (!!newState) { - state.endpoints[endpoint.type] = newState; + state = { + ...state, + endpoints: { + ...state.endpoints, + [endpoint.type]: newState + } + } } } }) diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/success-entity-request.handler.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/success-entity-request.handler.ts index 9302a6a42c..4c6867b467 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/success-entity-request.handler.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/success-entity-request.handler.ts @@ -1,16 +1,20 @@ -import { CF_ENDPOINT_TYPE } from '../../../../cloud-foundry/src/cf-types'; +import { Action } from '@ngrx/store'; + import { ClearPaginationOfEntity, ClearPaginationOfType } from '../../actions/pagination.actions'; import { RecursiveDeleteComplete } from '../../effects/recursive-entity-delete.effect'; import { entityCatalog } from '../../entity-catalog/entity-catalog'; import { StratosBaseCatalogEntity } from '../../entity-catalog/entity-catalog-entity/entity-catalog-entity'; -import { WrapperRequestActionSuccess } from '../../types/request.types'; +import { ApiRequestTypes } from '../../reducers/api-request-reducer/request-helpers'; +import { EntityRequestAction, WrapperRequestActionSuccess } from '../../types/request.types'; +import { PipelineResult } from '../entity-request-pipeline.types'; + export function successEntityHandler( - actionDispatcher, + actionDispatcher: (actionToDispatch: Action) => void, catalogEntity: StratosBaseCatalogEntity, - requestType, - action, - result, + requestType: ApiRequestTypes, + action: EntityRequestAction, + result: PipelineResult, recursivelyDeleting = false ) { const entityAction = catalogEntity.getRequestAction('success', action, requestType, result.response); @@ -29,7 +33,7 @@ export function successEntityHandler( if (Array.isArray(action.clearPaginationEntityKeys)) { // If clearPaginationEntityKeys is an array then clear the pagination sections regardless of removeEntityOnDelete action.clearPaginationEntityKeys.forEach(key => { - const entityConfig = entityCatalog.getEntity(CF_ENDPOINT_TYPE, key); + const entityConfig = entityCatalog.getEntity(action.endpointType, key); // TODO: RC test actionDispatcher(new ClearPaginationOfType(entityConfig.getSchema())); }); } diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts index 69218ebec9..4ce8c8e61f 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts @@ -144,4 +144,4 @@ export type EntityUserRolesFetch = ( httpClient: HttpClient ) => Observable; -export type EntityUserRolesReducer = (state: T, action: Action) => T; \ No newline at end of file +export type EntityUserRolesReducer = (state: T, action: Action) => T; \ No newline at end of file diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts index 53577246d6..bbafbbb2a0 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts @@ -1,11 +1,13 @@ import { Action } from '@ngrx/store'; +import { SESSION_VERIFIED, VerifiedSession } from '../../actions/auth.actions'; import { GET_CURRENT_USER_RELATIONS, GET_CURRENT_USER_RELATIONS_FAILED, GET_CURRENT_USER_RELATIONS_SUCCESS, } from '../../actions/permissions.actions'; import { entityCatalog } from '../../entity-catalog/entity-catalog'; +import { SessionUser } from '../../types/auth.types'; import { getDefaultRolesRequestState, ICurrentUserRolesState, @@ -22,30 +24,32 @@ const getDefaultState = () => ({ }); export function currentUserRolesReducer(state: ICurrentUserRolesState = getDefaultState(), action: Action): ICurrentUserRolesState { + const stateAfterStratosChanges = coreCurrentUserRolesReducer(state, action); + // TODO: RC Comment. can cause issues if plugins have same action type names. Should use same method as + // requestData in entity-catalog.module + return entityCatalog.getAllCurrentUserReducers(stateAfterStratosChanges, action); +} + +function coreCurrentUserRolesReducer(state: ICurrentUserRolesState, action: Action): ICurrentUserRolesState { switch (action.type) { - case GET_CURRENT_USER_RELATIONS:// TODO: RC NOT CF!!!!!!!!!!!! but has in + case GET_CURRENT_USER_RELATIONS: return { ...state, state: currentUserRolesRequestStateReducer(state.state, RolesRequestStateStage.START) }; - case GET_CURRENT_USER_RELATIONS_SUCCESS:// TODO: RC NOT CF!!!!!!!!!!!! but has in + case GET_CURRENT_USER_RELATIONS_SUCCESS: return { ...state, state: currentUserRolesRequestStateReducer(state.state, RolesRequestStateStage.SUCCESS) }; - case GET_CURRENT_USER_RELATIONS_FAILED:// TODO: RC NOT CF!!!!!!!!!!!! but has in + case GET_CURRENT_USER_RELATIONS_FAILED: return { ...state, state: currentUserRolesRequestStateReducer(state.state, RolesRequestStateStage.FAILURE) }; - default: { - // TODO: RC Comment. can cause issues if plugins have same action type names. Should use same method as - // requestData in entity-catalog.module - return { - ...state, - ...entityCatalog.getAllCurrentUserReducers(state, action) - }; - } + case SESSION_VERIFIED: + const svAction = action as VerifiedSession + return applyInternalScopes(state, svAction.sessionData.user); } return state; } @@ -78,3 +82,17 @@ export function currentUserRolesRequestStateReducer(state: RolesRequestState = g }; } } + +function applyInternalScopes(state: ICurrentUserRolesState, user: SessionUser): ICurrentUserRolesState { + const internalRoles = { ...state.internal }; + if (user) { + internalRoles.scopes = user.scopes || []; + // The admin scope is configurable - so look at the flag provided by the backend + internalRoles.isAdmin = user.admin; + } + + return { + ...state, + internal: internalRoles + }; +} \ No newline at end of file diff --git a/src/frontend/packages/store/src/types/current-user-roles.types.ts b/src/frontend/packages/store/src/types/current-user-roles.types.ts index 1b1eaed25e..efdfedda08 100644 --- a/src/frontend/packages/store/src/types/current-user-roles.types.ts +++ b/src/frontend/packages/store/src/types/current-user-roles.types.ts @@ -22,7 +22,8 @@ export interface IStratosRolesState { export interface ICurrentUserRolesState { internal: IStratosRolesState; endpoints: { - [endpointType: string]: T // T could be different types, but it makes it nicer when using for an single endpoint type + // T could be different in each endpoint type, however supplying a type makes it nicer to use when looking at a specific type + [endpointType: string]: T } state: RolesRequestState; } From 790b889d5f402bbf8e69a60766fab35218c928ce Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 27 May 2020 13:45:49 +0100 Subject: [PATCH 05/82] Renames, todos --- .../src/actions/application.actions.ts | 48 +++--- .../src/actions/organization.actions.ts | 4 +- .../src/actions/permissions.actions.ts | 159 +++++++++--------- .../src/actions/users-roles.actions.ts | 2 +- .../src/actions/users.actions.ts | 50 +++--- .../cloud-foundry/src/cf-api.types.ts | 2 +- .../cloud-foundry/src/cf-entity-catalog.ts | 2 +- .../cloud-foundry/src/cf-entity-factory.ts | 2 +- .../cloud-foundry/src/cf-entity-generator.ts | 10 +- .../cloud-foundry/src/cf-entity-types.ts | 2 +- .../user.action-builders.ts | 10 +- .../processors/org-space-post-processor.ts | 2 +- ...te-instances-routes-list-config.service.ts | 2 +- .../app-delete-routes-list-config.service.ts | 2 +- .../application-tabs-base.component.ts | 2 +- .../tabs/build-tab/build-tab.component.ts | 7 - .../routes-tab/routes-tab.component.ts | 4 +- .../deploy-application-steps.types.ts | 4 +- .../src/features/cloud-foundry/cf.helpers.ts | 20 +-- .../cloud-foundry-tabs-base.component.ts | 2 +- .../quota-definition.component.ts | 2 +- .../cloud-foundry-organization.service.ts | 2 +- .../services/cloud-foundry-space.service.ts | 2 +- .../space-quota-definition.component.ts | 2 +- .../cf-admin-add-user-warning.component.ts | 4 +- ...dry-organization-space-quotas.component.ts | 2 +- .../cloud-foundry-space-users.component.ts | 2 +- ...ud-foundry-organization-users.component.ts | 4 +- .../cloud-foundry-organizations.component.ts | 2 +- .../cloud-foundry-quotas.component.ts | 2 +- .../cloud-foundry-users.component.ts | 2 +- .../user-invites/user-invite.service.ts | 2 +- .../invite-users-create.component.ts | 2 +- .../users/manage-users/cf-roles.service.ts | 22 +-- .../manage-users-confirm.component.ts | 16 +- .../manage-users-modify.component.ts | 30 ++-- .../space-roles-list-wrapper.component.ts | 4 +- .../manage-users-select.component.ts | 2 +- .../manage-users-set-usernames.component.ts | 8 +- .../manage-users/manage-users.component.ts | 8 +- .../remove-user/remove-user.component.ts | 8 +- .../src/shared/cf-shared.module.ts | 5 +- .../cf-role-checkbox.component.ts | 28 +-- .../cf-app-map-routes-list-config.service.ts | 4 +- .../cf-app-routes-list-config-base.ts | 4 +- .../cf-app-routes-list-config.service.spec.ts | 4 +- .../cf-app-routes-list-config.service.ts | 4 +- .../app-service-binding-card.component.ts | 4 +- ...app-service-binding-list-config.service.ts | 4 +- ...ell-confirm-role-add-rem.component.spec.ts | 2 +- .../cf-org-users-list-config.service.ts | 6 +- .../cf-org-card/cf-org-card.component.ts | 6 +- .../cf-quotas-list-config.service.ts | 4 +- .../cf-routes-list-config.service.ts | 4 +- .../cf-select-users-list-config.service.ts | 2 +- .../cf-service-instances-list-config.base.ts | 4 +- .../cf-user-service-instances-list-config.ts | 4 +- .../cf-space-quotas-list-config.service.ts | 4 +- .../cf-space-routes-list-config.service.ts | 4 +- .../cf-space-users-list-config.service.ts | 6 +- ...s-service-instances-list-config.service.ts | 4 +- .../cf-space-card/cf-space-card.component.ts | 4 +- ...f-users-space-roles-data-source.service.ts | 4 +- ...f-users-space-roles-list-config.service.ts | 10 +- .../table-cell-select-org.component.ts | 4 +- .../cf-org-permission-cell.component.ts | 16 +- .../list-types/cf-users/cf-permission-cell.ts | 2 +- .../cf-space-permission-cell.component.ts | 16 +- .../cf-users/cf-user-data-source.service.ts | 2 +- .../cf-user-list-config.service.spec.ts | 4 +- .../cf-users/cf-user-list-config.service.ts | 10 +- .../cf-users/cf-user-list-helpers.ts | 2 +- .../service-instances-list-config.service.ts | 4 +- .../service-instance-card.component.ts | 4 +- ...vice-instances-wall-list-config.service.ts | 4 +- ...rovided-service-instance-card.component.ts | 4 +- .../shared/data-services/cf-user.service.ts | 18 +- .../cf-user-permission.directive.spec.ts} | 0 .../cf-user-permission.directive.ts} | 6 +- .../store/cloud-foundry.reducers.module.ts | 8 +- .../src/store/effects/app.effects.ts | 4 +- .../src/store/effects/roles.effects.ts | 10 +- .../src/store/effects/update-app-effects.ts | 4 +- .../src/store/effects/users-roles.effects.ts | 18 +- ...s.reducer.ts => cf-users-roles.reducer.ts} | 4 +- .../{users.reducer.ts => cf-users.reducer.ts} | 32 ++-- .../current-cf-user-base-cf-role.reducer.ts} | 43 +++-- .../current-cf-user-reducer.helpers.ts} | 16 +- .../current-cf-user-role-session.reducer.ts} | 16 +- ...current-cf-user-roles-changed.reducers.ts} | 16 +- .../current-cf-user-roles-clear.reducers.ts} | 26 +-- .../current-cf-user-roles-org.reducer.ts | 47 ++++++ .../current-cf-user-roles-orgs.reducer.ts | 9 + .../current-cf-user-roles-space.reducer.ts} | 20 +-- .../current-cf-user-roles-spaces.reducer.ts | 9 + .../current-cf-user-roles.reducer.ts | 90 ++++++++++ .../current-user-cf-roles.reducer.ts | 2 - .../current-user-roles-org.reducer.ts | 47 ------ .../current-user-roles-orgs.reducer.ts | 9 - .../current-user-roles-spaces.reducer.ts | 9 - .../current-user-roles.reducer.ts | 88 ---------- .../cf-current-user-role.selectors.ts | 6 +- ...selector.ts => cf-users-roles.selector.ts} | 33 ++-- .../types/{user.types.ts => cf-user.types.ts} | 0 .../store/types/current-user-roles.types.ts | 1 - .../src/store/types/users-roles.types.ts | 2 +- .../cf-user-permissions-checkers.ts | 38 ++--- .../user-permissions/cf-user-roles-fetch.ts | 46 ++--- .../cloud-foundry-endpoint-service.helper.ts | 2 +- .../packages/core/src/core/core.module.ts | 5 +- .../current-user-permissions.config.ts | 3 - .../current-user-permissions.service.spec.ts | 28 +-- .../current-user-permissions.service.ts | 77 ++++----- .../stratos-user-permissions.checker.ts} | 47 ++++-- .../endpoints-page.component.ts | 2 +- .../edit-profile-info.component.ts | 4 +- .../endpoint-card/endpoint-card.component.ts | 4 +- .../endpoint/endpoint-list.helpers.ts | 4 +- .../src/shared/user-permission.directive.ts | 4 +- .../src/entity-catalog/entity-catalog.ts | 9 +- .../entity-catalog/entity-catalog.types.ts | 10 +- .../current-user-roles.reducer.spec.ts | 44 ++--- .../current-user-roles.reducer.ts | 2 - .../selectors/current-user-role.selectors.ts | 18 +- .../packages/store/src/types/auth.types.ts | 4 +- .../src/types/current-user-roles.types.ts | 2 +- .../store/src/types/endpoint.types.ts | 4 +- ...nage-users-by-username-stepper-e2e.spec.ts | 2 +- .../cloud-foundry/users-removal-e2e.helper.ts | 2 +- src/test-e2e/helpers/cf-helpers.ts | 2 +- 130 files changed, 811 insertions(+), 806 deletions(-) rename src/frontend/packages/cloud-foundry/src/shared/directives/{user-permission/user-permission.directive.spec.ts => cf-user-permission/cf-user-permission.directive.spec.ts} (100%) rename src/frontend/packages/cloud-foundry/src/shared/directives/{user-permission/user-permission.directive.ts => cf-user-permission/cf-user-permission.directive.ts} (94%) rename src/frontend/packages/cloud-foundry/src/store/reducers/{users-roles.reducer.ts => cf-users-roles.reducer.ts} (97%) rename src/frontend/packages/cloud-foundry/src/store/reducers/{users.reducer.ts => cf-users.reducer.ts} (90%) rename src/frontend/packages/cloud-foundry/src/store/reducers/{current-user-roles-reducer/current-user-base-cf-role.reducer.ts => current-cf-user-roles-reducer/current-cf-user-base-cf-role.reducer.ts} (54%) rename src/frontend/packages/cloud-foundry/src/store/reducers/{current-user-roles-reducer/current-user-reducer.helpers.ts => current-cf-user-roles-reducer/current-cf-user-reducer.helpers.ts} (71%) rename src/frontend/packages/cloud-foundry/src/store/reducers/{current-user-roles-reducer/current-user-role-session.reducer.ts => current-cf-user-roles-reducer/current-cf-user-role-session.reducer.ts} (85%) rename src/frontend/packages/cloud-foundry/src/store/reducers/{current-user-roles-reducer/current-user-roles-changed.reducers.ts => current-cf-user-roles-reducer/current-cf-user-roles-changed.reducers.ts} (90%) rename src/frontend/packages/cloud-foundry/src/store/reducers/{current-user-roles-reducer/current-user-roles-clear.reducers.ts => current-cf-user-roles-reducer/current-cf-user-roles-clear.reducers.ts} (77%) create mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-org.reducer.ts create mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-orgs.reducer.ts rename src/frontend/packages/cloud-foundry/src/store/reducers/{current-user-roles-reducer/current-user-roles-space.reducer.ts => current-cf-user-roles-reducer/current-cf-user-roles-space.reducer.ts} (67%) create mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-spaces.reducer.ts create mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.ts delete mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-cf-roles.reducer.ts delete mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-org.reducer.ts delete mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-orgs.reducer.ts delete mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-spaces.reducer.ts delete mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts rename src/frontend/packages/cloud-foundry/src/store/selectors/{users-roles.selector.ts => cf-users-roles.selector.ts} (56%) rename src/frontend/packages/cloud-foundry/src/store/types/{user.types.ts => cf-user.types.ts} (100%) delete mode 100644 src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts rename src/frontend/packages/core/src/core/{ => permissions}/current-user-permissions.config.ts (74%) rename src/frontend/packages/core/src/core/{ => permissions}/current-user-permissions.service.spec.ts (96%) rename src/frontend/packages/core/src/core/{ => permissions}/current-user-permissions.service.ts (79%) rename src/frontend/packages/core/src/core/{current-user-permissions.checker.ts => permissions/stratos-user-permissions.checker.ts} (78%) diff --git a/src/frontend/packages/cloud-foundry/src/actions/application.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/application.actions.ts index 50488bd836..a3bd914226 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/application.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/application.actions.ts @@ -12,37 +12,33 @@ import { createEntityRelationPaginationKey, EntityInlineParentAction } from '../ import { AppMetadataTypes } from './app-metadata.actions'; import { CFStartAction } from './cf-action.types'; -export const GET_ALL = '[Application] Get all'; -export const GET_ALL_SUCCESS = '[Application] Get all success'; -export const GET_ALL_FAILED = '[Application] Get all failed'; +const GET_ALL = '[Application] Get all'; +const GET_ALL_SUCCESS = '[Application] Get all success'; +const GET_ALL_FAILED = '[Application] Get all failed'; -export const GET = '[Application] Get one'; -export const GET_SUCCESS = '[Application] Get one success'; -export const GET_FAILED = '[Application] Get one failed'; +const GET = '[Application] Get one'; +const GET_SUCCESS = '[Application] Get one success'; +const GET_FAILED = '[Application] Get one failed'; -export const GET_SUMMARY = '[Application] Get summary'; -export const GET_SUMMARY_SUCCESS = '[Application] Get summary success'; -export const GET_SUMMARY_FAILED = '[Application] Get summary failed'; +const CREATE = '[Application] Create'; +const CREATE_SUCCESS = '[Application] Create success'; +const CREATE_FAILED = '[Application] Create failed'; -export const CREATE = '[Application] Create'; -export const CREATE_SUCCESS = '[Application] Create success'; -export const CREATE_FAILED = '[Application] Create failed'; +export const CF_APP_UPDATE = '[Application] Update'; +export const CF_APP_UPDATE_SUCCESS = '[Application] Update success'; +export const CF_APP_UPDATE_FAILED = '[Application] Update failed'; -export const UPDATE = '[Application] Update'; -export const UPDATE_SUCCESS = '[Application] Update success'; -export const UPDATE_FAILED = '[Application] Update failed'; +const DELETE = '[Application] Delete'; +const DELETE_SUCCESS = '[Application] Delete success'; +const DELETE_FAILED = '[Application] Delete failed'; -export const DELETE = '[Application] Delete'; -export const DELETE_SUCCESS = '[Application] Delete success'; -export const DELETE_FAILED = '[Application] Delete failed'; +const DELETE_INSTANCE = '[Application Instance] Delete'; +const DELETE_INSTANCE_SUCCESS = '[Application Instance] Delete success'; +const DELETE_INSTANCE_FAILED = '[Application Instance] Delete failed'; -export const DELETE_INSTANCE = '[Application Instance] Delete'; -export const DELETE_INSTANCE_SUCCESS = '[Application Instance] Delete success'; -export const DELETE_INSTANCE_FAILED = '[Application Instance] Delete failed'; - -export const RESTAGE = '[Application] Restage'; -export const RESTAGE_SUCCESS = '[Application] Restage success'; -export const RESTAGE_FAILED = '[Application] Restage failed'; +const RESTAGE = '[Application] Restage'; +const RESTAGE_SUCCESS = '[Application] Restage success'; +const RESTAGE_FAILED = '[Application] Restage failed'; const applicationEntitySchema = cfEntityFactory(applicationEntityType); @@ -140,7 +136,7 @@ export class UpdateExistingApplication extends CFStartAction implements ICFActio newApplication ); } - actions = [UPDATE, UPDATE_SUCCESS, UPDATE_FAILED]; + actions = [CF_APP_UPDATE, CF_APP_UPDATE_SUCCESS, CF_APP_UPDATE_FAILED]; entity = [applicationEntitySchema]; entityType = applicationEntityType; options: HttpRequest; diff --git a/src/frontend/packages/cloud-foundry/src/actions/organization.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/organization.actions.ts index ff01a09be0..0603548dcf 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/organization.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/organization.actions.ts @@ -19,7 +19,7 @@ import { EntityInlineParentAction, } from '../entity-relations/entity-relations.types'; import { CFStartAction } from './cf-action.types'; -import { createDefaultUserRelations } from './users.actions'; +import { createDefaultCfUserRelations } from './users.actions'; export const GET_ORGANIZATION = '[Organization] Get one'; export const GET_ORGANIZATION_SUCCESS = '[Organization] Get one success'; @@ -231,7 +231,7 @@ export class GetAllOrgUsers extends CFStartAction implements PaginatedAction, En public paginationKey: string, public endpointGuid: string, public isAdmin: boolean, - public includeRelations: string[] = createDefaultUserRelations()) { + public includeRelations: string[] = createDefaultCfUserRelations()) { super(); this.options = new HttpRequest( 'GET', diff --git a/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts index c1097d9f29..15f3cafc93 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/permissions.actions.ts @@ -4,47 +4,44 @@ import { Action } from '@ngrx/store'; import { APIResource } from '../../../store/src/types/api.types'; import { organizationEntityType, spaceEntityType } from '../cf-entity-types'; -export const GET_AUDITED_ORG_CURRENT_USER_RELATIONS = '[Current User] Get audited org Relations'; -export const GET_AUDITED_ORG_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get audited org Relations success'; -export const GET_AUDITED_ORG_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get audited org Relations failed'; +export const GET_AUDITED_ORG_CURRENT_CF_USER_RELATIONS = '[Current User] Get audited org Relations'; +export const GET_AUDITED_ORG_CURRENT_CF_USER_RELATIONS_SUCCESS = '[Current User] Get audited org Relations success'; +export const GET_AUDITED_ORG_CURRENT_CF_USER_RELATIONS_FAILED = '[Current User] Get audited org Relations failed'; -export const GET_BILLING_MANAGED_ORG_CURRENT_USER_RELATIONS = '[Current User] Get BILLING_MANAGED org Relations'; -export const GET_BILLING_MANAGED_ORG_CURRENT_USER_RELATIONS_SUCCESS = '[Users] Get BILLING_MANAGED org Relations success'; -export const GET_BILLING_MANAGED_ORG_CURRENT_USER_RELATIONS_FAILED = '[Users] Get BILLING_MANAGED org Relations failed'; +export const GET_BILLING_MANAGED_ORG_CURRENT_CF_USER_RELATIONS = '[Current User] Get BILLING_MANAGED org Relations'; +export const GET_BILLING_MANAGED_ORG_CURRENT_CF_USER_RELATIONS_SUCCESS = '[Users] Get BILLING_MANAGED org Relations success'; +export const GET_BILLING_MANAGED_ORG_CURRENT_CF_USER_RELATIONS_FAILED = '[Users] Get BILLING_MANAGED org Relations failed'; -export const GET_MANAGED_ORG_CURRENT_USER_RELATIONS = '[Current User] Get MANAGED org Relations'; -export const GET_MANAGED_ORG_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get MANAGED org Relations success'; -export const GET_MANAGED_ORG_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get MANAGED org Relations failed'; +export const GET_MANAGED_ORG_CURRENT_CF_USER_RELATIONS = '[Current User] Get MANAGED org Relations'; +export const GET_MANAGED_ORG_CURRENT_CF_USER_RELATIONS_SUCCESS = '[Current User] Get MANAGED org Relations success'; +export const GET_MANAGED_ORG_CURRENT_CF_USER_RELATIONS_FAILED = '[Current User] Get MANAGED org Relations failed'; -export const GET_ORG_CURRENT_USER_RELATIONS = '[Current User] Get org Relations'; -export const GET_ORG_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get org Relations success'; -export const GET_ORG_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get org Relations failed'; +export const GET_ORG_CURRENT_CF_USER_RELATIONS = '[Current User] Get org Relations'; +export const GET_ORG_CURRENT_CF_USER_RELATIONS_SUCCESS = '[Current User] Get org Relations success'; +export const GET_ORG_CURRENT_CF_USER_RELATIONS_FAILED = '[Current User] Get org Relations failed'; -export const GET_AUDITED_SPACE_CURRENT_USER_RELATIONS = '[Current User] Get AUDITED_SPACE Relations'; -export const GET_AUDITED_SPACE_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get AUDITED_SPACE Relations success'; -export const GET_AUDITED_SPACE_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get AUDITED_SPACE Relations failed'; +export const GET_AUDITED_SPACE_CURRENT_CF_USER_RELATIONS = '[Current User] Get AUDITED_SPACE Relations'; +export const GET_AUDITED_SPACE_CURRENT_CF_USER_RELATIONS_SUCCESS = '[Current User] Get AUDITED_SPACE Relations success'; +export const GET_AUDITED_SPACE_CURRENT_CF_USER_RELATIONS_FAILED = '[Current User] Get AUDITED_SPACE Relations failed'; -export const GET_MANAGED_SPACE_CURRENT_USER_RELATIONS = '[Current User] Get MANAGED_SPACE Relations'; -export const GET_MANAGED_SPACE_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get MANAGED_SPACE Relations success'; -export const GET_MANAGED_SPACE_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get MANAGED_SPACE Relations failed'; +export const GET_MANAGED_SPACE_CURRENT_CF_USER_RELATIONS = '[Current User] Get MANAGED_SPACE Relations'; +export const GET_MANAGED_SPACE_CURRENT_CF_USER_RELATIONS_SUCCESS = '[Current User] Get MANAGED_SPACE Relations success'; +export const GET_MANAGED_SPACE_CURRENT_CF_USER_RELATIONS_FAILED = '[Current User] Get MANAGED_SPACE Relations failed'; -export const GET_SPACE_CURRENT_USER_RELATIONS = '[Current User] Get SPACE Relations'; -export const GET_SPACE_CURRENT_USER_RELATIONS_SUCCESS = '[Current User] Get SPACE Relations success'; -export const GET_SPACE_CURRENT_USER_RELATIONS_FAILED = '[Current User] Get SPACE Relations failed'; +export const GET_SPACE_CURRENT_CF_USER_RELATIONS = '[Current User] Get SPACE Relations'; +export const GET_SPACE_CURRENT_CF_USER_RELATIONS_SUCCESS = '[Current User] Get SPACE Relations success'; +export const GET_SPACE_CURRENT_CF_USER_RELATIONS_FAILED = '[Current User] Get SPACE Relations failed'; -export const GET_CURRENT_USER_RELATION = '[Current User] Get relation'; -export const GET_CURRENT_USER_RELATION_SUCCESS = '[Current User] Get relation success'; -export const GET_CURRENT_USER_RELATION_FAILED = '[Current User] Get relation failed'; +export const GET_CURRENT_CF_USER_RELATION = '[Current User] Get relation'; +export const GET_CURRENT_CF_USER_RELATION_SUCCESS = '[Current User] Get relation success'; +export const GET_CURRENT_CF_USER_RELATION_FAILED = '[Current User] Get relation failed'; -export const GET_CURRENT_USER_CF_RELATIONS = '[Current User] Get CF relations'; -export const GET_CURRENT_USER_CF_RELATIONS_SUCCESS = '[Current User] Get CF relations success'; -export const GET_CURRENT_USER_CF_RELATIONS_FAILED = '[Current User] Get CF relations failed'; +export const GET_CURRENT_CF_USER_RELATIONS = '[Current User] Get CF relations'; +export const GET_CURRENT_CF_USER_RELATIONS_SUCCESS = '[Current User] Get CF relations success'; +export const GET_CURRENT_CF_USER_RELATIONS_FAILED = '[Current User] Get CF relations failed'; -// TODO: RC RENAME ALL THIS - - -export enum UserRelationTypes { +export enum CfUserRelationTypes { AUDITED_ORGANIZATIONS = 'audited_organizations', BILLING_MANAGED_ORGANIZATION = 'billing_managed_organizations', MANAGED_ORGANIZATION = 'managed_organizations', @@ -54,7 +51,7 @@ export enum UserRelationTypes { SPACES = 'spaces' } -export interface IUserRelationTypes { +export interface ICfUserRelationTypes { [key: string]: { actions: [ string, @@ -65,128 +62,128 @@ export interface IUserRelationTypes { }; } -export class GetUserCfRelations implements Action { +export class GetCfUserRelations implements Action { constructor(public cfGuid: string, public type: string) { } } /** * Used in conjunction with `permissions.effects.ts` to fetch roles of a user connected to a cf that power the permissions model */ -export class GetUserRelations implements Action { - public type = GET_CURRENT_USER_RELATION; +export class GetCurrentCfUserRelations implements Action { + public type = GET_CURRENT_CF_USER_RELATION; public actions: string[]; public options: HttpRequest; - constructor(public guid: string, public relationType: UserRelationTypes, public endpointGuid: string) { + constructor(public guid: string, public relationType: CfUserRelationTypes, public endpointGuid: string) { const typeOptions = this.types[relationType]; this.options = new HttpRequest( 'GET', `users/${guid}/${relationType}` ); this.actions = typeOptions.actions; - this.type = GET_CURRENT_USER_RELATION; + this.type = GET_CURRENT_CF_USER_RELATION; } - private types: IUserRelationTypes = { - [UserRelationTypes.AUDITED_ORGANIZATIONS]: { + private types: ICfUserRelationTypes = { + [CfUserRelationTypes.AUDITED_ORGANIZATIONS]: { actions: [ - GET_AUDITED_ORG_CURRENT_USER_RELATIONS, - GET_AUDITED_ORG_CURRENT_USER_RELATIONS_SUCCESS, - GET_AUDITED_ORG_CURRENT_USER_RELATIONS_FAILED + GET_AUDITED_ORG_CURRENT_CF_USER_RELATIONS, + GET_AUDITED_ORG_CURRENT_CF_USER_RELATIONS_SUCCESS, + GET_AUDITED_ORG_CURRENT_CF_USER_RELATIONS_FAILED ], entityType: organizationEntityType }, - [UserRelationTypes.BILLING_MANAGED_ORGANIZATION]: { + [CfUserRelationTypes.BILLING_MANAGED_ORGANIZATION]: { actions: [ - GET_BILLING_MANAGED_ORG_CURRENT_USER_RELATIONS, - GET_BILLING_MANAGED_ORG_CURRENT_USER_RELATIONS_SUCCESS, - GET_BILLING_MANAGED_ORG_CURRENT_USER_RELATIONS_FAILED + GET_BILLING_MANAGED_ORG_CURRENT_CF_USER_RELATIONS, + GET_BILLING_MANAGED_ORG_CURRENT_CF_USER_RELATIONS_SUCCESS, + GET_BILLING_MANAGED_ORG_CURRENT_CF_USER_RELATIONS_FAILED ], entityType: organizationEntityType }, - [UserRelationTypes.MANAGED_ORGANIZATION]: { + [CfUserRelationTypes.MANAGED_ORGANIZATION]: { actions: [ - GET_MANAGED_ORG_CURRENT_USER_RELATIONS, - GET_MANAGED_ORG_CURRENT_USER_RELATIONS_SUCCESS, - GET_MANAGED_ORG_CURRENT_USER_RELATIONS_FAILED + GET_MANAGED_ORG_CURRENT_CF_USER_RELATIONS, + GET_MANAGED_ORG_CURRENT_CF_USER_RELATIONS_SUCCESS, + GET_MANAGED_ORG_CURRENT_CF_USER_RELATIONS_FAILED ], entityType: organizationEntityType }, - [UserRelationTypes.ORGANIZATIONS]: { - actions: [GET_ORG_CURRENT_USER_RELATIONS, GET_ORG_CURRENT_USER_RELATIONS_SUCCESS, GET_ORG_CURRENT_USER_RELATIONS_FAILED], + [CfUserRelationTypes.ORGANIZATIONS]: { + actions: [GET_ORG_CURRENT_CF_USER_RELATIONS, GET_ORG_CURRENT_CF_USER_RELATIONS_SUCCESS, GET_ORG_CURRENT_CF_USER_RELATIONS_FAILED], entityType: organizationEntityType }, - [UserRelationTypes.AUDITED_SPACES]: { + [CfUserRelationTypes.AUDITED_SPACES]: { actions: [ - GET_AUDITED_SPACE_CURRENT_USER_RELATIONS, - GET_AUDITED_SPACE_CURRENT_USER_RELATIONS_SUCCESS, - GET_AUDITED_SPACE_CURRENT_USER_RELATIONS_FAILED + GET_AUDITED_SPACE_CURRENT_CF_USER_RELATIONS, + GET_AUDITED_SPACE_CURRENT_CF_USER_RELATIONS_SUCCESS, + GET_AUDITED_SPACE_CURRENT_CF_USER_RELATIONS_FAILED ], entityType: spaceEntityType }, - [UserRelationTypes.MANAGED_SPACES]: { + [CfUserRelationTypes.MANAGED_SPACES]: { actions: [ - GET_MANAGED_SPACE_CURRENT_USER_RELATIONS, - GET_MANAGED_SPACE_CURRENT_USER_RELATIONS_SUCCESS, - GET_MANAGED_SPACE_CURRENT_USER_RELATIONS_FAILED + GET_MANAGED_SPACE_CURRENT_CF_USER_RELATIONS, + GET_MANAGED_SPACE_CURRENT_CF_USER_RELATIONS_SUCCESS, + GET_MANAGED_SPACE_CURRENT_CF_USER_RELATIONS_FAILED ], entityType: spaceEntityType }, - [UserRelationTypes.SPACES]: { + [CfUserRelationTypes.SPACES]: { actions: [ - GET_SPACE_CURRENT_USER_RELATIONS, - GET_SPACE_CURRENT_USER_RELATIONS_SUCCESS, - GET_SPACE_CURRENT_USER_RELATIONS_SUCCESS + GET_SPACE_CURRENT_CF_USER_RELATIONS, + GET_SPACE_CURRENT_CF_USER_RELATIONS_SUCCESS, + GET_SPACE_CURRENT_CF_USER_RELATIONS_SUCCESS ], entityType: spaceEntityType } }; } -export class GetCurrentUserRelationsComplete { - public type = GET_CURRENT_USER_RELATION_SUCCESS; +export class GetCurrentCfUserRelationsComplete { + public type = GET_CURRENT_CF_USER_RELATION_SUCCESS; constructor( - public relationType: UserRelationTypes, public endpointGuid: string, public data: APIResource[] + public relationType: CfUserRelationTypes, public endpointGuid: string, public data: APIResource[] ) { } } -export class GetCurrentUsersAuditedOrganizations extends GetUserRelations { +export class GetCurrentCfUsersAuditedOrganizations extends GetCurrentCfUserRelations { constructor(public guid: string, endpointGuid: string) { - super(guid, UserRelationTypes.AUDITED_ORGANIZATIONS, endpointGuid); + super(guid, CfUserRelationTypes.AUDITED_ORGANIZATIONS, endpointGuid); } } -export class GetCurrentUsersBillingOrganizations extends GetUserRelations { +export class GetCurrentCfUsersBillingOrganizations extends GetCurrentCfUserRelations { constructor(public guid: string, endpointGuid: string) { - super(guid, UserRelationTypes.BILLING_MANAGED_ORGANIZATION, endpointGuid); + super(guid, CfUserRelationTypes.BILLING_MANAGED_ORGANIZATION, endpointGuid); } } -export class GetCurrentUsersManagedOrganizations extends GetUserRelations { +export class GetCurrentCfUsersManagedOrganizations extends GetCurrentCfUserRelations { constructor(public guid: string, endpointGuid: string) { - super(guid, UserRelationTypes.MANAGED_ORGANIZATION, endpointGuid); + super(guid, CfUserRelationTypes.MANAGED_ORGANIZATION, endpointGuid); } } -export class GetCurrentUsersOrganizations extends GetUserRelations { +export class GetCurrentCfUsersOrganizations extends GetCurrentCfUserRelations { constructor(public guid: string, endpointGuid: string) { - super(guid, UserRelationTypes.ORGANIZATIONS, endpointGuid); + super(guid, CfUserRelationTypes.ORGANIZATIONS, endpointGuid); } } -export class GetCurrentUsersAuditedSpaces extends GetUserRelations { +export class GetCurrentCfUsersAuditedSpaces extends GetCurrentCfUserRelations { constructor(public guid: string, endpointGuid: string) { - super(guid, UserRelationTypes.AUDITED_SPACES, endpointGuid); + super(guid, CfUserRelationTypes.AUDITED_SPACES, endpointGuid); } } -export class GetCurrentUsersManagedSpaces extends GetUserRelations { +export class GetCurrentCfUsersManagedSpaces extends GetCurrentCfUserRelations { constructor(public guid: string, endpointGuid: string) { - super(guid, UserRelationTypes.MANAGED_SPACES, endpointGuid); + super(guid, CfUserRelationTypes.MANAGED_SPACES, endpointGuid); } } -export class GetCurrentUsersSpaces extends GetUserRelations { +export class GetCurrentCfUsersSpaces extends GetCurrentCfUserRelations { constructor(public guid: string, endpointGuid: string) { - super(guid, UserRelationTypes.SPACES, endpointGuid); + super(guid, CfUserRelationTypes.SPACES, endpointGuid); } } diff --git a/src/frontend/packages/cloud-foundry/src/actions/users-roles.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/users-roles.actions.ts index 66d36f8827..4682fd67ed 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/users-roles.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/users-roles.actions.ts @@ -1,6 +1,6 @@ import { Action } from '@ngrx/store'; -import { CfUser } from '../store/types/user.types'; +import { CfUser } from '../store/types/cf-user.types'; import { CfRoleChange } from '../store/types/users-roles.types'; export const UsersRolesActions = { diff --git a/src/frontend/packages/cloud-foundry/src/actions/users.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/users.actions.ts index 8aa7e4be31..40f7d57afc 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/users.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/users.actions.ts @@ -12,29 +12,23 @@ import { createEntityRelationPaginationKey, EntityInlineParentAction, } from '../entity-relations/entity-relations.types'; -import { CfUserRoleParams, OrgUserRoleNames, SpaceUserRoleNames } from '../store/types/user.types'; +import { CfUserRoleParams, OrgUserRoleNames, SpaceUserRoleNames } from '../store/types/cf-user.types'; import { CFStartAction } from './cf-action.types'; -export const GET_ALL = '[Users] Get all'; -export const GET_ALL_SUCCESS = '[Users] Get all success'; -export const GET_ALL_FAILED = '[Users] Get all failed'; +export const GET_ALL_CF_USERS = '[Users] Get all'; +export const GET_ALL_CF_USERS_SUCCESS = '[Users] Get all success'; +export const GET_ALL_CF_USERS_FAILED = '[Users] Get all failed'; -export const REMOVE_ROLE = '[Users] Remove role'; -export const REMOVE_ROLE_SUCCESS = '[Users] Remove role success'; -export const REMOVE_ROLE_FAILED = '[Users] Remove role failed'; +export const REMOVE_CF_ROLE = '[Users] Remove role'; +export const REMOVE_CF_ROLE_SUCCESS = '[Users] Remove role success'; +export const REMOVE_CF_ROLE_FAILED = '[Users] Remove role failed'; -export const ADD_ROLE = '[Users] Add role'; -export const ADD_ROLE_SUCCESS = '[Users] Add role success'; -export const ADD_ROLE_FAILED = '[Users] Add role failed'; +export const ADD_CF_ROLE = '[Users] Add role'; +export const ADD_CF_ROLE_SUCCESS = '[Users] Add role success'; +export const ADD_CF_ROLE_FAILED = '[Users] Add role failed'; -export const GET_CF_USER = '[Users] Get cf user '; -export const GET_CF_USER_SUCCESS = '[Users] Get cf user success'; -export const GET_CF_USER_FAILED = '[Users] Get cf user failed'; -export const GET_CF_USERS_AS_NON_ADMIN = '[Users] Get cf users by org '; -export const GET_CF_USERS_AS_NON_ADMIN_SUCCESS = '[Users] Get cf users by org success'; - -export function createDefaultUserRelations() { +export function createDefaultCfUserRelations() { return [ createEntityRelationKey(cfUserEntityType, CfUserRoleParams.ORGANIZATIONS), createEntityRelationKey(cfUserEntityType, CfUserRoleParams.AUDITED_ORGS), @@ -47,12 +41,12 @@ export function createDefaultUserRelations() { } -export class GetAllUsersAsAdmin extends CFStartAction implements PaginatedAction, EntityInlineParentAction { +export class GetAllCfUsersAsAdmin extends CFStartAction implements PaginatedAction, EntityInlineParentAction { isGetAllUsersAsAdmin = true; paginationKey: string; constructor( public endpointGuid: string, - public includeRelations: string[] = createDefaultUserRelations(), + public includeRelations: string[] = createDefaultCfUserRelations(), public populateMissing = true, paginationKey?: string ) { @@ -63,7 +57,7 @@ export class GetAllUsersAsAdmin extends CFStartAction implements PaginatedAction 'users' ); } - actions = [GET_ALL, GET_ALL_SUCCESS, GET_ALL_FAILED]; + actions = [GET_ALL_CF_USERS, GET_ALL_CF_USERS_SUCCESS, GET_ALL_CF_USERS_FAILED]; entity = [cfEntityFactory(cfUserEntityType)]; entityType = cfUserEntityType; options: HttpRequest; @@ -98,7 +92,7 @@ enum ChangeUserRoleType { /** * Add or remove a user's role, either by user guid or name */ -export class ChangeUserRole extends CFStartAction implements EntityRequestAction { +export class ChangeCfUserRole extends CFStartAction implements EntityRequestAction { public endpointType = 'cf'; constructor( public endpointGuid: string, @@ -115,7 +109,7 @@ export class ChangeUserRole extends CFStartAction implements EntityRequestAction ) { super(); this.guid = entityGuid; - this.updatingKey = ChangeUserRole.generateUpdatingKey(permissionTypeKey, userGuid); + this.updatingKey = ChangeCfUserRole.generateUpdatingKey(permissionTypeKey, userGuid); this.options = new HttpRequest( this.createMethod(), this.createUrl(), @@ -166,7 +160,7 @@ export class ChangeUserRole extends CFStartAction implements EntityRequestAction } } -export class AddUserRole extends ChangeUserRole { +export class AddCfUserRole extends ChangeCfUserRole { constructor( endpointGuid: string, userGuid: string, @@ -182,7 +176,7 @@ export class AddUserRole extends ChangeUserRole { endpointGuid, userGuid, ChangeUserRoleType.ADD, - [ADD_ROLE, ADD_ROLE_SUCCESS, ADD_ROLE_FAILED], + [ADD_CF_ROLE, ADD_CF_ROLE_SUCCESS, ADD_CF_ROLE_FAILED], permissionTypeKey, entityGuid, isSpace, @@ -194,7 +188,7 @@ export class AddUserRole extends ChangeUserRole { } } -export class RemoveUserRole extends ChangeUserRole { +export class RemoveCfUserRole extends ChangeCfUserRole { constructor( endpointGuid: string, userGuid: string, @@ -210,7 +204,7 @@ export class RemoveUserRole extends ChangeUserRole { endpointGuid, userGuid, ChangeUserRoleType.REMOVE, - [REMOVE_ROLE, REMOVE_ROLE_SUCCESS, REMOVE_ROLE_FAILED], + [REMOVE_CF_ROLE, REMOVE_CF_ROLE_SUCCESS, REMOVE_CF_ROLE_FAILED], permissionTypeKey, entityGuid, isSpace, @@ -222,11 +216,11 @@ export class RemoveUserRole extends ChangeUserRole { } } -export class GetUser extends CFStartAction { +export class GetCfUser extends CFStartAction { constructor( public endpointGuid: string, public guid: string, - public includeRelations: string[] = createDefaultUserRelations(), + public includeRelations: string[] = createDefaultCfUserRelations(), public populateMissing = true) { super(); this.options = new HttpRequest( diff --git a/src/frontend/packages/cloud-foundry/src/cf-api.types.ts b/src/frontend/packages/cloud-foundry/src/cf-api.types.ts index 0ccae9e71a..0449db54d5 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-api.types.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-api.types.ts @@ -1,6 +1,6 @@ import { APIResource } from '../../store/src/types/api.types'; import { IService, IServiceBinding } from './cf-api-svc.types'; -import { CfUser } from './store/types/user.types'; +import { CfUser } from './store/types/cf-user.types'; export interface StratosCFEntity { cfGuid: string; diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-catalog.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-catalog.ts index 380c47cce7..a3db99e684 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-catalog.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-catalog.ts @@ -61,8 +61,8 @@ import { StackActionBuilders } from './entity-action-builders/stack-action-build import { UserProvidedServiceActionBuilder } from './entity-action-builders/user-provided-service.action-builders'; import { UserActionBuilders } from './entity-action-builders/user.action-builders'; import { AppStat } from './store/types/app-metadata.types'; +import { CfUser } from './store/types/cf-user.types'; import { GitBranch, GitCommit, GitRepo } from './store/types/git.types'; -import { CfUser } from './store/types/user.types'; /** * A strongly typed collection of Cloud Foundry Catalog Entities. diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-factory.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-factory.ts index 0f2d1ebb9e..1112888031 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-factory.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-factory.ts @@ -46,7 +46,7 @@ import { userProvidedServiceInstanceEntityType, } from './cf-entity-types'; import { getAPIResourceGuid } from './store/selectors/api.selectors'; -import { CfUser, CfUserRoleParams, OrgUserRoleNames, SpaceUserRoleNames } from './store/types/user.types'; +import { CfUser, CfUserRoleParams, OrgUserRoleNames, SpaceUserRoleNames } from './store/types/cf-user.types'; const entityCache: { [key: string]: EntitySchema diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts index 79cd3b5c9f..587e99c9cb 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts @@ -165,18 +165,18 @@ import { populatePaginationFromParent } from './entity-relations/entity-relation import { isEntityInlineParentAction } from './entity-relations/entity-relations.types'; import { CfEndpointDetailsComponent } from './shared/components/cf-endpoint-details/cf-endpoint-details.component'; import { updateApplicationRoutesReducer } from './store/reducers/application-route.reducer'; -import { currentCfUserRolesReducer } from './store/reducers/current-user-roles-reducer/current-user-roles.reducer'; +import { cfUserReducer, endpointDisconnectUserReducer, userSpaceOrgReducer } from './store/reducers/cf-users.reducer'; +import { currentCfUserRolesReducer } from './store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer'; import { endpointDisconnectRemoveEntitiesReducer } from './store/reducers/endpoint-disconnect-application.reducer'; import { updateOrganizationQuotaReducer } from './store/reducers/organization-quota.reducer'; import { updateOrganizationSpaceReducer } from './store/reducers/organization-space.reducer'; import { routeReducer, updateAppSummaryRoutesReducer } from './store/reducers/routes.reducer'; import { serviceInstanceReducer } from './store/reducers/service-instance.reducer'; import { updateSpaceQuotaReducer } from './store/reducers/space-quota.reducer'; -import { endpointDisconnectUserReducer, userReducer, userSpaceOrgReducer } from './store/reducers/users.reducer'; import { AppStat } from './store/types/app-metadata.types'; import { CFResponse } from './store/types/cf-api.types'; +import { CfUser } from './store/types/cf-user.types'; import { GitBranch, GitCommit, GitRepo } from './store/types/git.types'; -import { CfUser } from './store/types/user.types'; import { cfUserRolesFetch } from './user-permissions/cf-user-roles-fetch'; function safePopulatePaginationFromParent(store: Store, action: PaginatedAction): Observable { @@ -367,7 +367,7 @@ export function generateCFEntities(): StratosBaseCatalogEntity[] { ); }, }, - userRolesFetch: cfUserRolesFetch, // TODO: RC implement + userRolesFetch: cfUserRolesFetch, userRolesReducer: currentCfUserRolesReducer }; return [ @@ -850,7 +850,7 @@ function generateCFUserEntity(endpointDefinition: StratosEndpointExtensionDefini definition, { actionBuilders: userActionBuilders, - dataReducers: [userReducer, endpointDisconnectUserReducer], + dataReducers: [cfUserReducer, endpointDisconnectUserReducer], entityBuilder: { getMetadata: ent => ({ name: ent.entity.username || ent.entity.guid || ent.metadata.guid, diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-types.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-types.ts index 91555203d5..4175b2d4e4 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-types.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-types.ts @@ -25,8 +25,8 @@ import { IStack, } from './cf-api.types'; import { AppStats } from './store/types/app-metadata.types'; +import { CfUser } from './store/types/cf-user.types'; import { GitBranch, GitCommit, GitRepo } from './store/types/git.types'; -import { CfUser } from './store/types/user.types'; export const applicationEntityType = 'application'; export const stackEntityType = 'stack'; diff --git a/src/frontend/packages/cloud-foundry/src/entity-action-builders/user.action-builders.ts b/src/frontend/packages/cloud-foundry/src/entity-action-builders/user.action-builders.ts index 174a9105a0..7c3ba84717 100644 --- a/src/frontend/packages/cloud-foundry/src/entity-action-builders/user.action-builders.ts +++ b/src/frontend/packages/cloud-foundry/src/entity-action-builders/user.action-builders.ts @@ -1,20 +1,20 @@ import { OrchestratedActionBuilders } from '../../../store/src/entity-catalog/action-orchestrator/action-orchestrator'; import { GetAllOrgUsers } from '../actions/organization.actions'; import { GetAllSpaceUsers } from '../actions/space.actions'; -import { GetAllUsersAsAdmin, GetUser } from '../actions/users.actions'; +import { GetAllCfUsersAsAdmin, GetCfUser } from '../actions/users.actions'; import { CFBasePipelineRequestActionMeta } from '../cf-entity-generator'; export interface UserActionBuilders extends OrchestratedActionBuilders { get: ( guid: string, endpointGuid: string - ) => GetUser; + ) => GetCfUser; // Must be admin user for this to succeed. getMultiple: ( endpointGuid: string, paginationKey: string, { includeRelations, populateMissing }?: CFBasePipelineRequestActionMeta - ) => GetAllUsersAsAdmin; + ) => GetAllCfUsersAsAdmin; getAllInOrganization: ( guid: string, endpointGuid: string, @@ -35,13 +35,13 @@ export const userActionBuilders: UserActionBuilders = { get: ( guid, endpointGuid - ) => new GetUser(endpointGuid, guid), + ) => new GetCfUser(endpointGuid, guid), // Must be admin user for this to succeed. getMultiple: ( endpointGuid: string, paginationKey: string, { includeRelations, populateMissing }: CFBasePipelineRequestActionMeta = {} - ) => new GetAllUsersAsAdmin(endpointGuid, includeRelations, populateMissing, paginationKey), + ) => new GetAllCfUsersAsAdmin(endpointGuid, includeRelations, populateMissing, paginationKey), getAllInOrganization: ( guid: string, endpointGuid: string, diff --git a/src/frontend/packages/cloud-foundry/src/entity-relations/processors/org-space-post-processor.ts b/src/frontend/packages/cloud-foundry/src/entity-relations/processors/org-space-post-processor.ts index 557e5ef776..687e7323be 100644 --- a/src/frontend/packages/cloud-foundry/src/entity-relations/processors/org-space-post-processor.ts +++ b/src/frontend/packages/cloud-foundry/src/entity-relations/processors/org-space-post-processor.ts @@ -14,7 +14,7 @@ import { GetSpace } from '../../actions/space.actions'; import { getCFEntityKey } from '../../cf-entity-helpers'; import { cfUserEntityType, organizationEntityType, spaceEntityType } from '../../cf-entity-types'; import { CF_ENDPOINT_TYPE } from '../../cf-types'; -import { CfUser, CfUserRoleParams, OrgUserRoleNames, SpaceUserRoleNames } from '../../store/types/user.types'; +import { CfUser, CfUserRoleParams, OrgUserRoleNames, SpaceUserRoleNames } from '../../store/types/cf-user.types'; import { createEntityRelationPaginationKey, ValidateEntityResult, diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application-delete/delete-app-instances/app-delete-instances-routes-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application-delete/delete-app-instances/app-delete-instances-routes-list-config.service.ts index 9c2f0d8ea2..91f805f77c 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application-delete/delete-app-instances/app-delete-instances-routes-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application-delete/delete-app-instances/app-delete-instances-routes-list-config.service.ts @@ -9,7 +9,7 @@ import { serviceBindingEntityType } from '../../../../../../cloud-foundry/src/cf import { createEntityRelationPaginationKey, } from '../../../../../../cloud-foundry/src/entity-relations/entity-relations.types'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { RowState } from '../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source-types'; import { ListViewTypes } from '../../../../../../core/src/shared/components/list/list.component.types'; import { endpointSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application-delete/delete-app-routes/app-delete-routes-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application-delete/delete-app-routes/app-delete-routes-list-config.service.ts index e99d7c41c8..f8bc8de0cf 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application-delete/delete-app-routes/app-delete-routes-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application-delete/delete-app-routes/app-delete-routes-list-config.service.ts @@ -4,7 +4,7 @@ import { Store } from '@ngrx/store'; import { Observable, of as observableOf } from 'rxjs'; import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../core/src/shared/components/confirmation-dialog.service'; import { RowState } from '../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source-types'; import { IListConfig } from '../../../../../../core/src/shared/components/list/list.component.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts index 6d383b1520..ca2194ba6e 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts @@ -6,7 +6,6 @@ import { filter, first, map, startWith, switchMap, withLatestFrom } from 'rxjs/o import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state'; import { applicationEntityType } from '../../../../../../cloud-foundry/src/cf-entity-types'; import { IAppFavMetadata } from '../../../../../../cloud-foundry/src/cf-metadata-types'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { EndpointsService } from '../../../../../../core/src/core/endpoints.service'; import { getActionsFromExtensions, @@ -15,6 +14,7 @@ import { StratosActionType, StratosTabType, } from '../../../../../../core/src/core/extension/extension-service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { getFavoriteFromEntity } from '../../../../../../core/src/core/user-favorite-helpers'; import { safeUnsubscribe } from '../../../../../../core/src/core/utils.service'; import { IPageSideNavTab } from '../../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts index f6f4e12dce..57c88faeb4 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts @@ -53,13 +53,6 @@ const appRestageConfirmation = new ConfirmationDialogConfig( styleUrls: ['./build-tab.component.scss'], providers: [ ApplicationMonitorService, - // TODO: RC - // { - // provide: CUSTOM_USER_PERMISSION_CHECKERS, - // useFactory: (store: Store) => [new CfUserPermissionsChecker(store)], - // deps: [Store] - // }, - // CurrentUserPermissionsService ] }) export class BuildTabComponent implements OnInit { diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/routes-tab/routes-tab/routes-tab.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/routes-tab/routes-tab/routes-tab.component.ts index e0982aa04d..401e1b1c30 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/routes-tab/routes-tab/routes-tab.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/routes-tab/routes-tab/routes-tab.component.ts @@ -5,7 +5,9 @@ import { Subscription } from 'rxjs'; import { first } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService, } from '../../../../../../../../../core/src/shared/components/confirmation-dialog.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-steps.types.ts b/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-steps.types.ts index c85f474a22..5acb4f80d2 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-steps.types.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-steps.types.ts @@ -5,8 +5,8 @@ import { Observable, of } from 'rxjs'; import { filter, first, map, publishReplay, refCount, switchMap } from 'rxjs/operators'; import { SourceType } from '../../../../../cloud-foundry/src/store/types/deploy-application.types'; -import { PermissionConfig } from '../../../../../core/src/core/current-user-permissions.config'; -import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; +import { PermissionConfig } from '../../../../../core/src/core/permissions/current-user-permissions.config'; +import { CurrentUserPermissionsService } from '../../../../../core/src/core/permissions/current-user-permissions.service'; import { CFFeatureFlagTypes } from '../../../cf-api.types'; import { CFAppState } from '../../../cf-app-state'; import { cfEntityCatalog } from '../../../cf-entity-catalog'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts index 2d0902ca11..770e16d1dd 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts @@ -10,17 +10,9 @@ import { getCurrentUserCFEndpointRolesState, } from '../../../../cloud-foundry/src/store/selectors/cf-current-user-role.selectors'; import { ICfRolesState } from '../../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; -import { - CfUser, - CfUserRoleParams, - OrgUserRoleNames, - SpaceUserRoleNames, - UserRoleInOrg, - UserRoleInSpace, -} from '../../../../cloud-foundry/src/store/types/user.types'; import { UserRoleLabels } from '../../../../cloud-foundry/src/store/types/users-roles.types'; -import { PermissionConfig } from '../../../../core/src/core/current-user-permissions.config'; -import { CurrentUserPermissionsService } from '../../../../core/src/core/current-user-permissions.service'; +import { PermissionConfig } from '../../../../core/src/core/permissions/current-user-permissions.config'; +import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; import { getIdFromRoute, pathGet } from '../../../../core/src/core/utils.service'; import { extractActualListEntity, @@ -39,6 +31,14 @@ import { IServiceInstance, IUserProvidedServiceInstance } from '../../cf-api-svc import { CFFeatureFlagTypes, ISpace } from '../../cf-api.types'; import { cfEntityFactory } from '../../cf-entity-factory'; import { CFEntityConfig } from '../../cf-types'; +import { + CfUser, + CfUserRoleParams, + OrgUserRoleNames, + SpaceUserRoleNames, + UserRoleInOrg, + UserRoleInSpace, +} from '../../store/types/cf-user.types'; import { CfCurrentUserPermissions, CfPermissionTypes } from '../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfCell, ActiveRouteCfOrgSpace } from './cf-page.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts index 9a489ffb31..57ddd512a7 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts @@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core'; import { Observable, of as observableOf } from 'rxjs'; import { first, map, startWith } from 'rxjs/operators'; -import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; import { EndpointsService } from '../../../../../core/src/core/endpoints.service'; import { getActionsFromExtensions, @@ -11,6 +10,7 @@ import { StratosActionType, StratosTabType, } from '../../../../../core/src/core/extension/extension-service'; +import { CurrentUserPermissionsService } from '../../../../../core/src/core/permissions/current-user-permissions.service'; import { environment } from '../../../../../core/src/environments/environment.prod'; import { IPageSideNavTab } from '../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { FavoritesConfigMapper } from '../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/quota-definition/quota-definition.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/quota-definition/quota-definition.component.ts index db0d5c75b7..34d2c00086 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/quota-definition/quota-definition.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/quota-definition/quota-definition.component.ts @@ -4,7 +4,7 @@ import { Store } from '@ngrx/store'; import { Observable, of, Subscription } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; -import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../core/src/core/permissions/current-user-permissions.service'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; import { AppState } from '../../../../../store/src/app-state'; import { APIResource } from '../../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-organization.service.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-organization.service.ts index a85683a86f..07848a222f 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-organization.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-organization.service.ts @@ -12,7 +12,6 @@ import { quotaDefinitionEntityType, spaceEntityType, } from '../../../../../cloud-foundry/src/cf-entity-types'; -import { OrgUserRoleNames } from '../../../../../cloud-foundry/src/store/types/user.types'; import { PaginationMonitorFactory } from '../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types'; import { @@ -30,6 +29,7 @@ import { CfUserService } from '../../../shared/data-services/cf-user.service'; import { CloudFoundryUserProvidedServicesService, } from '../../../shared/services/cloud-foundry-user-provided-services.service'; +import { OrgUserRoleNames } from '../../../store/types/cf-user.types'; import { fetchServiceInstancesCount } from '../../service-catalog/services-helper'; import { ActiveRouteCfOrgSpace } from '../cf-page.types'; import { getOrgRolesString } from '../cf.helpers'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space.service.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space.service.ts index 794c014a7b..f3faadd465 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space.service.ts @@ -12,7 +12,6 @@ import { spaceEntityType, spaceQuotaEntityType, } from '../../../../../cloud-foundry/src/cf-entity-types'; -import { SpaceUserRoleNames } from '../../../../../cloud-foundry/src/store/types/user.types'; import { PaginationMonitorFactory } from '../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types'; import { IApp, IOrgQuotaDefinition, IRoute, ISpace, ISpaceQuotaDefinition } from '../../../cf-api.types'; @@ -23,6 +22,7 @@ import { CfUserService } from '../../../shared/data-services/cf-user.service'; import { CloudFoundryUserProvidedServicesService, } from '../../../shared/services/cloud-foundry-user-provided-services.service'; +import { SpaceUserRoleNames } from '../../../store/types/cf-user.types'; import { fetchServiceInstancesCount } from '../../service-catalog/services-helper'; import { ActiveRouteCfOrgSpace } from '../cf-page.types'; import { getSpaceRolesString } from '../cf.helpers'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.ts index d5f5933067..010b22e72c 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.ts @@ -4,7 +4,7 @@ import { Store } from '@ngrx/store'; import { Observable, of, Subscription } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; -import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../core/src/core/permissions/current-user-permissions.service'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; import { AppState } from '../../../../../store/src/app-state'; import { APIResource } from '../../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cf-admin-add-user-warning/cf-admin-add-user-warning.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cf-admin-add-user-warning/cf-admin-add-user-warning.component.ts index 75984014e2..7cb9cae72d 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cf-admin-add-user-warning/cf-admin-add-user-warning.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cf-admin-add-user-warning/cf-admin-add-user-warning.component.ts @@ -3,7 +3,7 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { filter, map, switchMap } from 'rxjs/operators'; -import { GetAllUsersAsAdmin } from '../../../../../../cloud-foundry/src/actions/users.actions'; +import { GetAllCfUsersAsAdmin } from '../../../../../../cloud-foundry/src/actions/users.actions'; import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; @@ -36,7 +36,7 @@ export class CfAdminAddUserWarningComponent { activeRouteCfOrgSpace.orgGuid, activeRouteCfOrgSpace.spaceGuid)), map(fetchUsersAction => { - return !GetAllUsersAsAdmin.is(fetchUsersAction); + return !GetAllCfUsersAsAdmin.is(fetchUsersAction); }) ); } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organization-space-quotas/cloud-foundry-organization-space-quotas.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organization-space-quotas/cloud-foundry-organization-space-quotas.component.ts index c45c051ed2..9a27b50498 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organization-space-quotas/cloud-foundry-organization-space-quotas.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organization-space-quotas/cloud-foundry-organization-space-quotas.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListConfig } from '../../../../../../core/src/shared/components/list/list.component.types'; import { CfSpaceQuotasListConfigService, diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-users/cloud-foundry-space-users.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-users/cloud-foundry-space-users.component.ts index 8c1ff64efc..3b82a9e0e0 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-users/cloud-foundry-space-users.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-users/cloud-foundry-space-users.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { CFAppState } from 'frontend/packages/cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from 'frontend/packages/core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from 'frontend/packages/core/src/core/permissions/current-user-permissions.service'; import { combineLatest, Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-users/cloud-foundry-organization-users.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-users/cloud-foundry-organization-users.component.ts index e845dbdca2..cc902d28b7 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-users/cloud-foundry-organization-users.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-users/cloud-foundry-organization-users.component.ts @@ -3,7 +3,9 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { CFFeatureFlagTypes } from '../../../../../cf-api.types'; import { CFAppState } from '../../../../../cf-app-state'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organizations.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organizations.component.ts index 851f02d6c7..479d1c9618 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organizations.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organizations.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListConfig } from '../../../../../../core/src/shared/components/list/list.component.types'; import { CfOrgCardComponent } from '../../../../shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component'; import { CfOrgsListConfigService } from '../../../../shared/components/list/list-types/cf-orgs/cf-orgs-list-config.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-quotas/cloud-foundry-quotas.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-quotas/cloud-foundry-quotas.component.ts index 97ae3654f9..12b9daccf0 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-quotas/cloud-foundry-quotas.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-quotas/cloud-foundry-quotas.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListConfig } from '../../../../../../core/src/shared/components/list/list.component.types'; import { CfQuotasListConfigService, diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-users/cloud-foundry-users.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-users/cloud-foundry-users.component.ts index f990478288..f184bf4ec8 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-users/cloud-foundry-users.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-users/cloud-foundry-users.component.ts @@ -3,7 +3,7 @@ import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListConfig } from '../../../../../../core/src/shared/components/list/list.component.types'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/user-invites/user-invite.service.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/user-invites/user-invite.service.ts index 4866c7a447..755128bd1b 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/user-invites/user-invite.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/user-invites/user-invite.service.ts @@ -6,7 +6,7 @@ import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../core/src/core/permissions/current-user-permissions.service'; import { environment } from '../../../../../core/src/environments/environment.prod'; import { ConfirmationDialogConfig } from '../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../core/src/shared/components/confirmation-dialog.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/invite-users/invite-users-create/invite-users-create.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/invite-users/invite-users-create/invite-users-create.component.ts index 00b15b39e3..c6c5044e00 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/invite-users/invite-users-create/invite-users-create.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/invite-users/invite-users-create/invite-users-create.component.ts @@ -18,7 +18,7 @@ import { CFAppState } from '../../../../../cf-app-state'; import { cfEntityCatalog } from '../../../../../cf-entity-catalog'; import { cfUserEntityType } from '../../../../../cf-entity-types'; import { CFEntityConfig } from '../../../../../cf-types'; -import { SpaceUserRoleNames } from '../../../../../store/types/user.types'; +import { SpaceUserRoleNames } from '../../../../../store/types/cf-user.types'; import { UserRoleLabels } from '../../../../../store/types/users-roles.types'; import { ActiveRouteCfOrgSpace } from '../../../cf-page.types'; import { UserInviteSendSpaceRoles, UserInviteService } from '../../../user-invites/user-invite.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts index 4a5d0f4b95..56a88ed334 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts @@ -17,7 +17,7 @@ import { createEntityRelationKey, createEntityRelationPaginationKey, } from '../../../../../../cloud-foundry/src/entity-relations/entity-relations.types'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { endpointSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; import { APIResource, EntityInfo } from '../../../../../../store/src/types/api.types'; import { UsersRolesSetChanges } from '../../../../actions/users-roles.actions'; @@ -26,13 +26,13 @@ import { CFAppState } from '../../../../cf-app-state'; import { cfEntityCatalog } from '../../../../cf-entity-catalog'; import { organizationEntityType, spaceEntityType } from '../../../../cf-entity-types'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; -import { createDefaultOrgRoles, createDefaultSpaceRoles } from '../../../../store/reducers/users-roles.reducer'; +import { createDefaultOrgRoles, createDefaultSpaceRoles } from '../../../../store/reducers/cf-users-roles.reducer'; import { - selectUsersRolesCf, - selectUsersRolesPicked, - selectUsersRolesRoles, -} from '../../../../store/selectors/users-roles.selector'; -import { CfUser, IUserPermissionInOrg, UserRoleInOrg, UserRoleInSpace } from '../../../../store/types/user.types'; + selectCfUsersRolesCf, + selectCfUsersRolesPicked, + selectCfUsersRolesRoles, +} from '../../../../store/selectors/cf-users-roles.selector'; +import { CfUser, IUserPermissionInOrg, UserRoleInOrg, UserRoleInSpace } from '../../../../store/types/cf-user.types'; import { CfRoleChange, CfUserRolesSelected } from '../../../../store/types/users-roles.types'; import { CfUserPermissionsChecker } from '../../../../user-permissions/cf-user-permissions-checkers'; import { canUpdateOrgSpaceRoles } from '../../cf.helpers'; @@ -91,15 +91,15 @@ export class CfRolesService { private cfUserService: CfUserService, private userPerms: CurrentUserPermissionsService, ) { - this.existingRoles$ = this.store.select(selectUsersRolesPicked).pipe( - combineLatestOperators(this.store.select(selectUsersRolesCf)), + this.existingRoles$ = this.store.select(selectCfUsersRolesPicked).pipe( + combineLatestOperators(this.store.select(selectCfUsersRolesCf)), filter(([users, cfGuid]) => !!cfGuid), switchMap(([users, cfGuid]) => this.populateRoles(cfGuid, users)), distinctUntilChanged(), publishReplay(1), refCount() ); - this.newRoles$ = this.store.select(selectUsersRolesRoles).pipe( + this.newRoles$ = this.store.select(selectCfUsersRolesRoles).pipe( distinctUntilChanged(), publishReplay(1), refCount() @@ -169,7 +169,7 @@ export class CfRolesService { return this.existingRoles$.pipe( combineLatestOperators( this.newRoles$, - this.store.select(selectUsersRolesPicked), + this.store.select(selectCfUsersRolesPicked), ), first(), map(([existingRoles, newRoles, pickedUsers]) => { diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts index 76fdc3d38b..969da7b695 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts @@ -13,7 +13,7 @@ import { ITableColumn } from '../../../../../../../core/src/shared/components/li import { entityCatalog } from '../../../../../../../store/src/entity-catalog/entity-catalog'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { UsersRolesClearUpdateState } from '../../../../../actions/users-roles.actions'; -import { ChangeUserRole } from '../../../../../actions/users.actions'; +import { ChangeCfUserRole } from '../../../../../actions/users.actions'; import { CFAppState } from '../../../../../cf-app-state'; import { cfEntityFactory } from '../../../../../cf-entity-factory'; import { cfUserEntityType, organizationEntityType, spaceEntityType } from '../../../../../cf-entity-types'; @@ -25,8 +25,8 @@ import { TableCellConfirmRoleAddRemComponent, } from '../../../../../shared/components/list/list-types/cf-confirm-roles/table-cell-confirm-role-add-rem/table-cell-confirm-role-add-rem.component'; import { CfUserService } from '../../../../../shared/data-services/cf-user.service'; -import { selectUsersRoles, selectUsersRolesChangedRoles } from '../../../../../store/selectors/users-roles.selector'; -import { CfUser, OrgUserRoleNames, SpaceUserRoleNames } from '../../../../../store/types/user.types'; +import { selectCfUsersRoles, selectCfUsersRolesChangedRoles } from '../../../../../store/selectors/cf-users-roles.selector'; +import { CfUser, OrgUserRoleNames, SpaceUserRoleNames } from '../../../../../store/types/cf-user.types'; import { CfRoleChangeWithNames, UserRoleLabels } from '../../../../../store/types/users-roles.types'; import { ManageUsersSetUsernamesHelper } from '../manage-users-set-usernames/manage-users-set-usernames.component'; @@ -99,7 +99,7 @@ export class UsersRolesConfirmComponent implements OnInit, AfterContentInit { entityKey: entityCatalog.getEntityKey(schema), schema, monitorState: AppMonitorComponentTypes.UPDATE, - updateKey: ChangeUserRole.generateUpdatingKey(row.role, row.userGuid), + updateKey: ChangeCfUserRole.generateUpdatingKey(row.role, row.userGuid), getId: () => guid }; } @@ -126,7 +126,7 @@ export class UsersRolesConfirmComponent implements OnInit, AfterContentInit { // Kick off an update this.updateChanges.next(new Date().getTime()); // Ensure that any entity we're going to show the state for is clear of any previous or unrelated errors - this.store.select(selectUsersRoles).pipe( + this.store.select(selectCfUsersRoles).pipe( first(), ).subscribe(usersRoles => this.store.dispatch(new UsersRolesClearUpdateState(usersRoles.changedRoles))); } @@ -146,7 +146,7 @@ export class UsersRolesConfirmComponent implements OnInit, AfterContentInit { } private createCfObs() { - this.cfGuid$ = this.store.select(selectUsersRoles).pipe( + this.cfGuid$ = this.store.select(selectCfUsersRoles).pipe( map(mu => mu.cfGuid), filter(cfGuid => !!cfGuid), distinctUntilChanged(), @@ -155,7 +155,7 @@ export class UsersRolesConfirmComponent implements OnInit, AfterContentInit { private createChangesObs() { const changesViaUsername = this.updateChanges.pipe( - switchMap(() => this.store.select(selectUsersRolesChangedRoles)), + switchMap(() => this.store.select(selectCfUsersRolesChangedRoles)), map(changes => changes .map(change => ({ ...change, @@ -168,7 +168,7 @@ export class UsersRolesConfirmComponent implements OnInit, AfterContentInit { const changesViaUserGuid = this.updateChanges.pipe( withLatestFrom(this.cfGuid$), mergeMap(([, cfGuid]) => this.cfUserService.getUsers(cfGuid)), - withLatestFrom(this.store.select(selectUsersRolesChangedRoles)), + withLatestFrom(this.store.select(selectCfUsersRolesChangedRoles)), map(([users, changes]) => changes .map(change => ({ diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts index 5eab2957f5..51c4d54084 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts @@ -43,13 +43,13 @@ import { TableCellSelectOrgComponent, } from '../../../../../shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component'; import { - selectUsersIsRemove, - selectUsersIsSetByUsername, - selectUsersRolesOrgGuid, - selectUsersRolesPicked, - selectUsersRolesRoles, -} from '../../../../../store/selectors/users-roles.selector'; -import { CfUser, OrgUserRoleNames } from '../../../../../store/types/user.types'; + selectCfUsersIsRemove, + selectCfUsersIsSetByUsername, + selectCfUsersRolesOrgGuid, + selectCfUsersRolesPicked, + selectCfUsersRolesRoles, +} from '../../../../../store/selectors/cf-users-roles.selector'; +import { CfUser, OrgUserRoleNames } from '../../../../../store/types/cf-user.types'; import { ActiveRouteCfOrgSpace } from '../../../cf-page.types'; import { CfRolesService } from '../cf-roles.service'; import { SpaceRolesListWrapperComponent } from './space-roles-list-wrapper/space-roles-list-wrapper.component'; @@ -154,7 +154,7 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { this.cfRolesService.loading$.subscribe(loading => this.blocked.next(loading)); } - const orgEntity$ = this.store.select(selectUsersRolesOrgGuid).pipe( + const orgEntity$ = this.store.select(selectCfUsersRolesOrgGuid).pipe( startWith(''), distinctUntilChanged(), filter(orgGuid => !!orgGuid), @@ -197,7 +197,7 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { }); } - const users$: Observable = this.store.select(selectUsersRolesPicked).pipe( + const users$: Observable = this.store.select(selectCfUsersRolesPicked).pipe( filter(users => !!users), distinctUntilChanged(), map(users => users.map(this.mapUser.bind(this))) @@ -211,14 +211,14 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { map(users => users.filter(user => !!user.showWarning).map(user => user.username)) ); - this.valid$ = this.store.select(selectUsersRolesRoles).pipe( + this.valid$ = this.store.select(selectCfUsersRolesRoles).pipe( debounceTime(150), switchMap(newRoles => this.cfRolesService.createRolesDiff(newRoles.orgGuid)), map(changes => !!changes.length) ); - this.isSetByUsername$ = this.store.select(selectUsersIsSetByUsername); - this.isRemove$ = this.store.select(selectUsersIsRemove); + this.isSetByUsername$ = this.store.select(selectCfUsersIsSetByUsername); + this.isRemove$ = this.store.select(selectCfUsersIsRemove); } private mapUser(user: CfUser): CfUserWithWarning { @@ -263,7 +263,7 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { } // When the state is ready (org guid is correct), recreate the space roles table for the selected org - this.store.select(selectUsersRolesRoles).pipe( + this.store.select(selectCfUsersRolesRoles).pipe( // Wait for the store to have the correct org filter(newRoles => newRoles && newRoles.orgGuid === orgGuid), first() @@ -289,7 +289,7 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { } // In order to show the removed roles correctly (as ticks) flip them from remove to add - this.store.select(selectUsersIsRemove).pipe(first()).subscribe(isRemove => { + this.store.select(selectCfUsersIsRemove).pipe(first()).subscribe(isRemove => { if (isRemove) { this.store.dispatch(new UsersRolesFlipSetRoles()); } @@ -305,7 +305,7 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { onNext = () => { return combineLatest([ - this.store.select(selectUsersIsRemove).pipe(first()), + this.store.select(selectCfUsersIsRemove).pipe(first()), this.cfRolesService.createRolesDiff(this.selectedOrgGuid) ]).pipe( map(([isRemove,]) => { diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/space-roles-list-wrapper/space-roles-list-wrapper.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/space-roles-list-wrapper/space-roles-list-wrapper.component.ts index f540626ace..69481c04be 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/space-roles-list-wrapper/space-roles-list-wrapper.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-modify/space-roles-list-wrapper/space-roles-list-wrapper.component.ts @@ -1,7 +1,9 @@ import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; -import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListConfig } from '../../../../../../../../core/src/shared/components/list/list.component.types'; import { CFAppState } from '../../../../../../cf-app-state'; import { diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-select/manage-users-select.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-select/manage-users-select.component.ts index 03f2b5ad32..524836b8ee 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-select/manage-users-select.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-select/manage-users-select.component.ts @@ -13,7 +13,7 @@ import { CfSelectUsersListConfigService, } from '../../../../../shared/components/list/list-types/cf-select-users/cf-select-users-list-config.service'; import { CfUserService } from '../../../../../shared/data-services/cf-user.service'; -import { CfUser } from '../../../../../store/types/user.types'; +import { CfUser } from '../../../../../store/types/cf-user.types'; import { ActiveRouteCfOrgSpace } from '../../../cf-page.types'; import { CfRolesService } from '../cf-roles.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-set-usernames/manage-users-set-usernames.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-set-usernames/manage-users-set-usernames.component.ts index 99944529de..615a571179 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-set-usernames/manage-users-set-usernames.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users-set-usernames/manage-users-set-usernames.component.ts @@ -4,8 +4,10 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs'; import { first, map, publishReplay, refCount, startWith, switchMap, take, tap } from 'rxjs/operators'; -import { PermissionConfig } from '../../../../../../../core/src/core/current-user-permissions.config'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { PermissionConfig } from '../../../../../../../core/src/core/permissions/current-user-permissions.config'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { StackedInputActionConfig, } from '../../../../../../../core/src/shared/components/stacked-input-actions/stacked-input-action/stacked-input-action.component'; @@ -21,7 +23,7 @@ import { } from '../../../../../actions/users-roles.actions'; import { CFFeatureFlagTypes } from '../../../../../cf-api.types'; import { CFAppState } from '../../../../../cf-app-state'; -import { CfUser } from '../../../../../store/types/user.types'; +import { CfUser } from '../../../../../store/types/cf-user.types'; import { CfPermissionTypes } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../../../cf-page.types'; import { waitForCFPermissions } from '../../../cf.helpers'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users.component.ts index df4b52c516..9eb662d103 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/manage-users.component.ts @@ -8,8 +8,8 @@ import { StepOnNextFunction } from '../../../../../../core/src/shared/components import { UsersRolesClear, UsersRolesExecuteChanges, UsersRolesSetUsers } from '../../../../actions/users-roles.actions'; import { CFAppState } from '../../../../cf-app-state'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; -import { selectUsersRoles, selectUsersRolesPicked } from '../../../../store/selectors/users-roles.selector'; -import { CfUser } from '../../../../store/types/user.types'; +import { selectCfUsersRoles, selectCfUsersRolesPicked } from '../../../../store/selectors/cf-users-roles.selector'; +import { CfUser } from '../../../../store/types/cf-user.types'; import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; import { getActiveRouteCfOrgSpaceProvider } from '../../cf.helpers'; import { CfRolesService } from './cf-roles.service'; @@ -55,7 +55,7 @@ export class UsersRolesComponent implements OnDestroy { first() ); } else { - this.initialUsers$ = this.store.select(selectUsersRolesPicked).pipe(first()); + this.initialUsers$ = this.store.select(selectCfUsersRolesPicked).pipe(first()); } this.singleUser$ = this.initialUsers$.pipe( @@ -65,7 +65,7 @@ export class UsersRolesComponent implements OnDestroy { ); // Ensure that when we arrive here directly the store is set up with all it needs - this.store.select(selectUsersRoles).pipe( + this.store.select(selectCfUsersRoles).pipe( combineLatest(this.initialUsers$), first() ).subscribe(([usersRoles, users]) => { diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts index 0ddc4aabcd..7c4a435f3d 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/remove-user/remove-user.component.ts @@ -4,8 +4,8 @@ import { Store } from '@ngrx/store'; import { combineLatest as obsCombineLatest, Observable, of as observableOf } from 'rxjs'; import { combineLatest, filter, first, map, startWith } from 'rxjs/operators'; -import { CurrentUserPermissionsService } from '../../../../../../core/src/core/current-user-permissions.service'; import { LoggerService } from '../../../../../../core/src/core/logger.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { StepOnNextFunction } from '../../../../../../core/src/shared/components/stepper/step/step.component'; import { AppState } from '../../../../../../store/src/app-state'; import { @@ -15,8 +15,8 @@ import { UsersRolesSetUsers, } from '../../../../actions/users-roles.actions'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; -import { selectUsersRoles } from '../../../../store/selectors/users-roles.selector'; -import { CfUser, IUserPermissionInOrg, IUserPermissionInSpace } from '../../../../store/types/user.types'; +import { selectCfUsersRoles } from '../../../../store/selectors/cf-users-roles.selector'; +import { CfUser, IUserPermissionInOrg, IUserPermissionInSpace } from '../../../../store/types/cf-user.types'; import { CfRoleChange } from '../../../../store/types/users-roles.types'; import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; @@ -71,7 +71,7 @@ export class RemoveUserComponent implements OnDestroy { return; } - const cfGuid$ = this.store.select(selectUsersRoles).pipe( + const cfGuid$ = this.store.select(selectCfUsersRoles).pipe( combineLatest(this.singleUser$), first() ); diff --git a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts index 4c3001c6d4..207fbf653e 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts @@ -205,7 +205,7 @@ import { ServicePlanPriceComponent } from './components/service-plan-price/servi import { ServicePlanPublicComponent } from './components/service-plan-public/service-plan-public.component'; import { GitSCMService } from './data-services/scm/scm.service'; import { AppNameUniqueDirective } from './directives/app-name-unique.directive/app-name-unique.directive'; -import { CfUserPermissionDirective } from './directives/user-permission/user-permission.directive'; +import { CfUserPermissionDirective } from './directives/cf-user-permission/cf-user-permission.directive'; import { ApplicationStateService } from './services/application-state.service'; import { CloudFoundryUserProvidedServicesService } from './services/cloud-foundry-user-provided-services.service'; @@ -381,7 +381,8 @@ const cfListCards: Type>[] = [ ApplicationStateService, GitSCMService, CloudFoundryUserProvidedServicesService, - ...cfCurrentUserPermissionsService // TODO: RC bring in via endpoint??? + ...cfCurrentUserPermissionsService // TODO: RC Review: bring in via endpoint, force checkers to supply type (to fetch via endpoint) ] }) export class CloudFoundrySharedModule { } + diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts index d431149d29..8472dd6633 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts @@ -5,22 +5,22 @@ import { combineLatest as combineLatestOp, filter, first, map } from 'rxjs/opera import { UsersRolesSetOrgRole, UsersRolesSetSpaceRole } from '../../../../../cloud-foundry/src/actions/users-roles.actions'; import { CFAppState } from '../../../../../cloud-foundry/src/cf-app-state'; +import { CfUserRolesSelected } from '../../../../../cloud-foundry/src/store/types/users-roles.types'; +import { CurrentUserPermissionsService } from '../../../../../core/src/core/permissions/current-user-permissions.service'; +import { canUpdateOrgSpaceRoles } from '../../../features/cloud-foundry/cf.helpers'; +import { CfRolesService } from '../../../features/cloud-foundry/users/manage-users/cf-roles.service'; +import { + selectCfUsersIsRemove, + selectCfUsersIsSetByUsername, + selectCfUsersRolesPicked, +} from '../../../store/selectors/cf-users-roles.selector'; import { CfUser, IUserPermissionInOrg, IUserPermissionInSpace, OrgUserRoleNames, SpaceUserRoleNames, -} from '../../../../../cloud-foundry/src/store/types/user.types'; -import { CfUserRolesSelected } from '../../../../../cloud-foundry/src/store/types/users-roles.types'; -import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; -import { canUpdateOrgSpaceRoles } from '../../../features/cloud-foundry/cf.helpers'; -import { CfRolesService } from '../../../features/cloud-foundry/users/manage-users/cf-roles.service'; -import { - selectUsersIsRemove, - selectUsersIsSetByUsername, - selectUsersRolesPicked, -} from '../../../store/selectors/users-roles.selector'; +} from '../../../store/types/cf-user.types'; import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; @@ -250,7 +250,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { ngOnInit() { this.isOrgRole = !this.spaceGuid; - const users$ = this.store.select(selectUsersRolesPicked); + const users$ = this.store.select(selectCfUsersRolesPicked); // If setting an org role user must be admin or org manager. // If setting a space role user must be admin, org manager or space manager const canEditRole$ = this.isOrgRole ? @@ -260,7 +260,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { this.cfGuid, this.orgGuid, this.spaceGuid); - const selectUsersIsSetByUsername$ = this.store.select(selectUsersIsSetByUsername); + const selectUsersIsSetByUsername$ = this.store.select(selectCfUsersIsSetByUsername); this.sub = this.cfRolesService.existingRoles$.pipe( combineLatestOp(this.cfRolesService.newRoles$, users$, canEditRole$, selectUsersIsSetByUsername$), @@ -285,8 +285,8 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { }); this.mode$ = combineLatest([ - this.store.select(selectUsersIsSetByUsername), - this.store.select(selectUsersIsRemove) + this.store.select(selectCfUsersIsSetByUsername), + this.store.select(selectCfUsersIsRemove) ]).pipe( map(([isSetByUsername, isRemove]) => { if (!isSetByUsername) { diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-map-routes-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-map-routes-list-config.service.ts index a07393539f..a113574270 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-map-routes-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-map-routes-list-config.service.ts @@ -8,7 +8,9 @@ import { spaceEntityType } from '../../../../../../../cloud-foundry/src/cf-entit import { createEntityRelationPaginationKey, } from '../../../../../../../cloud-foundry/src/entity-relations/entity-relations.types'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { TableCellRadioComponent, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts index f53772ea22..2a658beb99 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts @@ -5,7 +5,9 @@ import { publishReplay, refCount, switchMap } from 'rxjs/operators'; import { GetAppRoutes } from '../../../../../../../cloud-foundry/src/actions/application-service-routes.actions'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { IListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { APIResource } from '../../../../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.spec.ts index 3094755217..59cbb61331 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.spec.ts @@ -4,7 +4,9 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Store } from '@ngrx/store'; import { CoreModule } from '../../../../../../../core/src/core/core.module'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { SharedModule } from '../../../../../../../core/src/shared/shared.module'; import { ApplicationServiceMock } from '../../../../../../test-framework/application-service-helper'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts index 109dc07920..a631fac6ae 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts @@ -4,7 +4,9 @@ import { Store } from '@ngrx/store'; import { take } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { IGlobalListAction, IListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { RouterNav } from '../../../../../../../store/src/actions/router.actions'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts index fb6de7c08c..5f15687925 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts @@ -4,7 +4,9 @@ import { MatDialog } from '@angular/material/dialog'; import { combineLatest as observableCombineLatest, Observable, of as observableOf, of } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; -import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; import { MetaCardMenuItem, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts index bf592133df..68288fa9ec 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts @@ -4,7 +4,9 @@ import { Store } from '@ngrx/store'; import { switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { DataFunctionDefinition, } from '../../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-confirm-roles/table-cell-confirm-role-add-rem/table-cell-confirm-role-add-rem.component.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-confirm-roles/table-cell-confirm-role-add-rem/table-cell-confirm-role-add-rem.component.spec.ts index 0610d25aae..d0ff520581 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-confirm-roles/table-cell-confirm-role-add-rem/table-cell-confirm-role-add-rem.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-confirm-roles/table-cell-confirm-role-add-rem/table-cell-confirm-role-add-rem.component.spec.ts @@ -1,10 +1,10 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { OrgUserRoleNames } from '../../../../../../../../cloud-foundry/src/store/types/user.types'; import { MDAppModule } from '../../../../../../../../core/src/core/md.module'; import { BooleanIndicatorComponent, } from '../../../../../../../../core/src/shared/components/boolean-indicator/boolean-indicator.component'; +import { OrgUserRoleNames } from '../../../../../../store/types/cf-user.types'; import { TableCellConfirmRoleAddRemComponent } from './table-cell-confirm-role-add-rem.component'; describe('TableCellConfirmRoleAddRemComponent', () => { diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-org-users/cf-org-users-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-org-users/cf-org-users-list-config.service.ts index 7d53361cbb..4d125e2cca 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-org-users/cf-org-users-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-org-users/cf-org-users-list-config.service.ts @@ -3,12 +3,14 @@ import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CfUser } from '../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ActiveRouteCfOrgSpace } from '../../../../../features/cloud-foundry/cf-page.types'; import { CloudFoundryOrganizationService, } from '../../../../../features/cloud-foundry/services/cloud-foundry-organization.service'; +import { CfUser } from '../../../../../store/types/cf-user.types'; import { CfUserService } from '../../../../data-services/cf-user.service'; import { CfUserListConfigService } from '../cf-users/cf-user-list-config.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts index b0bcef5edb..c8275787bf 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts @@ -5,8 +5,9 @@ import { map, publishReplay, refCount, switchMap, tap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { organizationEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; -import { createUserRoleInOrg } from '../../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { getFavoriteFromEntity } from '../../../../../../../../core/src/core/user-favorite-helpers'; import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; @@ -36,6 +37,7 @@ import { OrgQuotaHelper } from '../../../../../../features/cloud-foundry/service import { createOrgQuotaDefinition, } from '../../../../../../features/cloud-foundry/services/cloud-foundry-organization.service'; +import { createUserRoleInOrg } from '../../../../../../store/types/cf-user.types'; import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { CfUserService } from '../../../../../data-services/cf-user.service'; import { CF_ENDPOINT_TYPE } from './../../../../../../cf-types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service.ts index 3c7b16cc75..d4e001d8aa 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-quotas/cf-quotas-list-config.service.ts @@ -9,7 +9,9 @@ import { ActiveRouteCfOrgSpace } from '../../../../../../../cloud-foundry/src/fe import { BaseCfListConfig, } from '../../../../../../../cloud-foundry/src/shared/components/list/list-types/base-cf/base-cf-list-config'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogConfig } from '../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { ITableColumn } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-routes/cf-routes-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-routes/cf-routes-list-config.service.ts index 032ff2d46d..9767322990 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-routes/cf-routes-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-routes/cf-routes-list-config.service.ts @@ -5,7 +5,9 @@ import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { map, publishReplay, refCount, startWith, switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { IListConfig, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-select-users/cf-select-users-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-select-users/cf-select-users-list-config.service.ts index a60d8d0c6c..10ee7b1abb 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-select-users/cf-select-users-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-select-users/cf-select-users-list-config.service.ts @@ -3,7 +3,6 @@ import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { distinctUntilChanged, map, publishReplay, refCount, switchMap, tap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CfUser, CfUserMissingRoles } from '../../../../../../../cloud-foundry/src/store/types/user.types'; import { TableRowStateManager, } from '../../../../../../../core/src/shared/components/list/list-table/table-row/table-row-state-manager'; @@ -25,6 +24,7 @@ import { APIResource } from '../../../../../../../store/src/types/api.types'; import { PaginatedAction } from '../../../../../../../store/src/types/pagination.types'; import { ActiveRouteCfOrgSpace } from '../../../../../features/cloud-foundry/cf-page.types'; import { waitForCFPermissions } from '../../../../../features/cloud-foundry/cf.helpers'; +import { CfUser, CfUserMissingRoles } from '../../../../../store/types/cf-user.types'; import { CfUserService } from '../../../../data-services/cf-user.service'; import { CfSelectUsersDataSourceService } from './cf-select-users-data-source.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts index 229c489fae..52b60a12ee 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts @@ -5,7 +5,9 @@ import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListDataSource, } from '../../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts index 054824d011..9f653f851f 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts @@ -5,7 +5,9 @@ import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListDataSource, } from '../../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service.ts index 301fccd563..fd78c9a3fd 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-quotas/cf-space-quotas-list-config.service.ts @@ -3,7 +3,9 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable, Subscription } from 'rxjs'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogConfig } from '../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { ITableColumn } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-routes/cf-space-routes-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-routes/cf-space-routes-list-config.service.ts index 972ec99acf..0090a576fb 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-routes/cf-space-routes-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-routes/cf-space-routes-list-config.service.ts @@ -4,7 +4,9 @@ import { Store } from '@ngrx/store'; import { publishReplay, refCount } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { IListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { APIResource } from '../../../../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-users/cf-space-users-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-users/cf-space-users-list-config.service.ts index fc9a0200fd..0484f50f82 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-users/cf-space-users-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-space-users/cf-space-users-list-config.service.ts @@ -3,13 +3,15 @@ import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CfUser } from '../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ActiveRouteCfOrgSpace } from '../../../../../features/cloud-foundry/cf-page.types'; import { CloudFoundryOrganizationService, } from '../../../../../features/cloud-foundry/services/cloud-foundry-organization.service'; import { CloudFoundrySpaceService } from '../../../../../features/cloud-foundry/services/cloud-foundry-space.service'; +import { CfUser } from '../../../../../store/types/cf-user.types'; import { CfUserService } from '../../../../data-services/cf-user.service'; import { CfUserListConfigService } from '../cf-users/cf-user-list-config.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts index 2b60252659..e87ed733c5 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts @@ -3,7 +3,9 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { IListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { IServiceInstance } from '../../../../../cf-api-svc.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts index b8d4c65e22..d124f0d47e 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts @@ -6,7 +6,9 @@ import { map, switchMap, tap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { spaceEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; import { ISpaceFavMetadata } from '../../../../../../../../cloud-foundry/src/cf-metadata-types'; -import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { getFavoriteFromEntity } from '../../../../../../../../core/src/core/user-favorite-helpers'; import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-data-source.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-data-source.service.ts index a922ee27b8..093fcadccf 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-data-source.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-data-source.service.ts @@ -9,7 +9,9 @@ import { spaceEntityType, } from '../../../../../../../cloud-foundry/src/cf-entity-types'; import { createEntityRelationKey } from '../../../../../../../cloud-foundry/src/entity-relations/entity-relations.types'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ListDataSource, } from '../../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-list-config.service.ts index b9b9aa22a3..a65ce2cf84 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/cf-users-space-roles-list-config.service.ts @@ -3,14 +3,16 @@ import { BehaviorSubject } from 'rxjs'; import { first } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { SpaceUserRoleNames } from '../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ITableColumn } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; import { IListConfig, ListViewTypes } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { ListView } from '../../../../../../../store/src/actions/list.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { ISpace } from '../../../../../cf-api.types'; -import { selectUsersRolesRoles } from '../../../../../store/selectors/users-roles.selector'; +import { selectCfUsersRolesRoles } from '../../../../../store/selectors/cf-users-roles.selector'; +import { SpaceUserRoleNames } from '../../../../../store/types/cf-user.types'; import { CfUsersSpaceRolesDataSourceService } from './cf-users-space-roles-data-source.service'; import { TableCellRoleOrgSpaceComponent } from './table-cell-org-space-role/table-cell-org-space-role.component'; @@ -75,7 +77,7 @@ export class CfUsersSpaceRolesListConfigService implements IListConfig(false); constructor(private store: Store, cfGuid: string, spaceGuid: string, userPerms: CurrentUserPermissionsService) { - this.store.select(selectUsersRolesRoles).pipe( + this.store.select(selectCfUsersRolesRoles).pipe( first() ).subscribe(newRoles => { this.dataSource = new CfUsersSpaceRolesDataSourceService(cfGuid, newRoles.orgGuid, spaceGuid, this.store, userPerms, this); diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts index 7c9d9eacb5..4d11410056 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts @@ -10,7 +10,7 @@ import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { IOrganization } from '../../../../../../cf-api.types'; import { ActiveRouteCfOrgSpace } from '../../../../../../features/cloud-foundry/cf-page.types'; import { CfRolesService } from '../../../../../../features/cloud-foundry/users/manage-users/cf-roles.service'; -import { selectUsersRolesOrgGuid } from '../../../../../../store/selectors/users-roles.selector'; +import { selectCfUsersRolesOrgGuid } from '../../../../../../store/selectors/cf-users-roles.selector'; @Component({ selector: 'app-table-cell-select-org', @@ -43,7 +43,7 @@ export class TableCellSelectOrgComponent extends TableCellCustom orgs && orgs.length === 1 ? orgs[0] : null) ); } - this.orgGuidChangedSub = this.store.select(selectUsersRolesOrgGuid).subscribe(orgGuid => { + this.orgGuidChangedSub = this.store.select(selectCfUsersRolesOrgGuid).subscribe(orgGuid => { this.selectedOrgGuid = orgGuid; }); } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-org-permission-cell/cf-org-permission-cell.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-org-permission-cell/cf-org-permission-cell.component.ts index 3990c51575..76825b3388 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-org-permission-cell/cf-org-permission-cell.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-org-permission-cell/cf-org-permission-cell.component.ts @@ -3,16 +3,13 @@ import { Store } from '@ngrx/store'; import { combineLatest } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { RemoveUserRole } from '../../../../../../../../cloud-foundry/src/actions/users.actions'; +import { RemoveCfUserRole } from '../../../../../../../../cloud-foundry/src/actions/users.actions'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { organizationEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; -import { - CfUser, - IUserPermissionInOrg, - OrgUserRoleNames, -} from '../../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; import { arrayHelper } from '../../../../../../../../core/src/core/helper-classes/array.helper'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { entityCatalog } from '../../../../../../../../store/src/entity-catalog/entity-catalog'; @@ -20,6 +17,7 @@ import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { IOrganization } from '../../../../../../cf-api.types'; import { CF_ENDPOINT_TYPE } from '../../../../../../cf-types'; import { getOrgRoles } from '../../../../../../features/cloud-foundry/cf.helpers'; +import { CfUser, IUserPermissionInOrg, OrgUserRoleNames } from '../../../../../../store/types/cf-user.types'; import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { CfUserService } from '../../../../../data-services/cf-user.service'; import { CfPermissionCell, ICellPermissionList } from '../cf-permission-cell'; @@ -60,7 +58,7 @@ export class CfOrgPermissionCellComponent extends CfPermissionCell, showName: boolean): ICellPermissionList[] { return getOrgRoles(orgPerms.permissions).map(perm => { - const updatingKey = RemoveUserRole.generateUpdatingKey( + const updatingKey = RemoveCfUserRole.generateUpdatingKey( perm.key, row.metadata.guid ); @@ -87,7 +85,7 @@ export class CfOrgPermissionCellComponent extends CfPermissionCell, updateConnectedUser: boolean) { - this.store.dispatch(new RemoveUserRole( + this.store.dispatch(new RemoveCfUserRole( this.cfUserService.activeRouteCfOrgSpace.cfGuid, cellPermission.userGuid, cellPermission.guid, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-permission-cell.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-permission-cell.ts index 766069ffca..554fc97cea 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-permission-cell.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-permission-cell.ts @@ -4,7 +4,6 @@ import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CfUser } from '../../../../../../../cloud-foundry/src/store/types/user.types'; import { UserRoleLabels } from '../../../../../../../cloud-foundry/src/store/types/users-roles.types'; import { AppChip } from '../../../../../../../core/src/shared/components/chips/chips.component'; import { ConfirmationDialogConfig } from '../../../../../../../core/src/shared/components/confirmation-dialog.config'; @@ -13,6 +12,7 @@ import { TableCellCustom } from '../../../../../../../core/src/shared/components import { selectSessionData } from '../../../../../../../store/src/reducers/auth.reducer'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { IUserRole } from '../../../../../features/cloud-foundry/cf.helpers'; +import { CfUser } from '../../../../../store/types/cf-user.types'; import { CfUserService } from '../../../../data-services/cf-user.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts index 1f2d051af9..6aa867410f 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts @@ -3,23 +3,21 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; -import { RemoveUserRole } from '../../../../../../../../cloud-foundry/src/actions/users.actions'; +import { RemoveCfUserRole } from '../../../../../../../../cloud-foundry/src/actions/users.actions'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { organizationEntityType, spaceEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; import { selectCfEntity } from '../../../../../../../../cloud-foundry/src/store/selectors/api.selectors'; -import { - CfUser, - IUserPermissionInSpace, - SpaceUserRoleNames, -} from '../../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; import { arrayHelper } from '../../../../../../../../core/src/core/helper-classes/array.helper'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { entityCatalog } from '../../../../../../../../store/src/entity-catalog/entity-catalog'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { IOrganization, ISpace } from '../../../../../../cf-api.types'; import { CF_ENDPOINT_TYPE } from '../../../../../../cf-types'; import { getSpaceRoles } from '../../../../../../features/cloud-foundry/cf.helpers'; +import { CfUser, IUserPermissionInSpace, SpaceUserRoleNames } from '../../../../../../store/types/cf-user.types'; import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { CfUserService } from '../../../../../data-services/cf-user.service'; import { CfPermissionCell, ICellPermissionList } from '../cf-permission-cell'; @@ -116,7 +114,7 @@ export class CfSpacePermissionCellComponent extends CfPermissionCell, isOrgLevel = true) { return getSpaceRoles(spacePerms.permissions).map(perm => { - const updatingKey = RemoveUserRole.generateUpdatingKey( + const updatingKey = RemoveCfUserRole.generateUpdatingKey( perm.key, row.metadata.guid ); @@ -144,7 +142,7 @@ export class CfSpacePermissionCellComponent extends CfPermissionCell, updateConnectedUser: boolean) { - this.store.dispatch(new RemoveUserRole( + this.store.dispatch(new RemoveCfUserRole( this.cfUserService.activeRouteCfOrgSpace.cfGuid, cellPermission.userGuid, cellPermission.guid, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-data-source.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-data-source.service.ts index 73462af393..5deeae7963 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-data-source.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-data-source.service.ts @@ -3,7 +3,6 @@ import { getRowMetadata } from '@stratos/store'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; import { cfUserEntityType } from '../../../../../../../cloud-foundry/src/cf-entity-types'; -import { CfUser } from '../../../../../../../cloud-foundry/src/store/types/user.types'; import { ListDataSource, } from '../../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; @@ -11,6 +10,7 @@ import { ListConfig } from '../../../../../../../core/src/shared/components/list import { APIResource } from '../../../../../../../store/src/types/api.types'; import { PaginatedAction, PaginationEntityState } from '../../../../../../../store/src/types/pagination.types'; import { cfEntityFactory } from '../../../../../cf-entity-factory'; +import { CfUser } from '../../../../../store/types/cf-user.types'; import { UserListUsersVisible, userListUserVisibleKey } from './cf-user-list-helpers'; function createUserVisibilityFilter(userHasRoles: (user: CfUser) => boolean): diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.spec.ts index 33f477573a..19f56eb01a 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.spec.ts @@ -3,7 +3,9 @@ import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { generateCfBaseTestModules, generateTestCfEndpointServiceProvider, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts index 00d67cac51..23f7f500b9 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts @@ -4,10 +4,11 @@ import { BehaviorSubject, combineLatest, Observable, of as observableOf } from ' import { filter, first, map, switchMap, tap } from 'rxjs/operators'; import { UsersRolesSetUsers } from '../../../../../../../cloud-foundry/src/actions/users-roles.actions'; -import { GetAllUsersAsAdmin } from '../../../../../../../cloud-foundry/src/actions/users.actions'; +import { GetAllCfUsersAsAdmin } from '../../../../../../../cloud-foundry/src/actions/users.actions'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CfUser } from '../../../../../../../cloud-foundry/src/store/types/user.types'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ITableColumn, ITableText } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; import { IListAction, @@ -32,6 +33,7 @@ import { hasSpaceRoleWithinOrg, waitForCFPermissions, } from '../../../../../features/cloud-foundry/cf.helpers'; +import { CfUser } from '../../../../../store/types/cf-user.types'; import { CfUserPermissionsChecker } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { CfUserService } from './../../../../data-services/cf-user.service'; import { CfOrgPermissionCellComponent } from './cf-org-permission-cell/cf-org-permission-cell.component'; @@ -235,7 +237,7 @@ export class CfUserListConfigService extends ListConfig> { this.dataSource = new CfUserDataSourceService(store, action, this, userHasRoles); // Only show the filter (show users with/without roles) if the list of users can actually contain users without roles - if (GetAllUsersAsAdmin.is(action)) { + if (GetAllCfUsersAsAdmin.is(action)) { this.assignMultiConfig(); this.initialiseMultiFilter(action); } else { diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-helpers.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-helpers.ts index 058d2df2d2..e0c964ae23 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users/cf-user-list-helpers.ts @@ -1,4 +1,4 @@ -import { CfUser } from '../../../../../../../cloud-foundry/src/store/types/user.types'; +import { CfUser } from '../../../../../store/types/cf-user.types'; export const userListUserVisibleKey = 'showUsers'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts index 58637e424f..20878f7924 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts @@ -3,7 +3,9 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ServicesService } from '../../../../../features/service-catalog/services.service'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; import { CfServiceInstancesListConfigBase } from '../cf-services/cf-service-instances-list-config.base'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts index 80a69f7fbd..649162074c 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts @@ -4,7 +4,9 @@ import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { serviceInstancesEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; -import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; import { MetaCardMenuItem, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts index d03eb82ab7..f3a4c57132 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts @@ -10,7 +10,9 @@ import { serviceInstancesEntityType, userProvidedServiceInstanceEntityType, } from '../../../../../../../cloud-foundry/src/cf-entity-types'; -import { CurrentUserPermissionsService } from '../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { CardMultiActionComponents, } from '../../../../../../../core/src/shared/components/list/list-cards/card.component.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts index c435c38952..0b2fdcf274 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts @@ -4,7 +4,9 @@ import { BehaviorSubject, of as observableOf } from 'rxjs'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { userProvidedServiceInstanceEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; -import { CurrentUserPermissionsService } from '../../../../../../../../core/src/core/current-user-permissions.service'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; import { MetaCardMenuItem, diff --git a/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-user.service.ts b/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-user.service.ts index e96d52510c..30a0022d4b 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-user.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-user.service.ts @@ -7,15 +7,6 @@ import { CFAppState } from '../../../../cloud-foundry/src/cf-app-state'; import { cfUserEntityType, organizationEntityType, spaceEntityType } from '../../../../cloud-foundry/src/cf-entity-types'; import { createEntityRelationPaginationKey } from '../../../../cloud-foundry/src/entity-relations/entity-relations.types'; import { getCurrentUserCFGlobalStates } from '../../../../cloud-foundry/src/store/selectors/cf-current-user-role.selectors'; -import { - CfUser, - createUserRoleInOrg, - createUserRoleInSpace, - IUserPermissionInOrg, - IUserPermissionInSpace, - UserRoleInOrg, - UserRoleInSpace, -} from '../../../../cloud-foundry/src/store/types/user.types'; import { LocalPaginationHelpers, } from '../../../../core/src/shared/components/list/data-sources-controllers/local-list.helpers'; @@ -48,6 +39,15 @@ import { waitForCFPermissions, } from '../../features/cloud-foundry/cf.helpers'; import { selectCfPaginationState } from '../../store/selectors/pagination.selectors'; +import { + CfUser, + createUserRoleInOrg, + createUserRoleInSpace, + IUserPermissionInOrg, + IUserPermissionInSpace, + UserRoleInOrg, + UserRoleInSpace, +} from '../../store/types/cf-user.types'; @Injectable() export class CfUserService { diff --git a/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts similarity index 100% rename from src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.spec.ts rename to src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts diff --git a/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.ts b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.ts similarity index 94% rename from src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.ts rename to src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.ts index 61e0878519..6ac1e7f27e 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/directives/user-permission/user-permission.directive.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.ts @@ -1,15 +1,14 @@ import { Directive, Input, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable, of as observableOf, Subscription } from 'rxjs'; -import { switchMap, tap } from 'rxjs/operators'; +import { switchMap } from 'rxjs/operators'; -import { CurrentUserPermissionsService } from '../../../../../core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../../../core/src/core/permissions/current-user-permissions.service'; import { AppState } from '../../../../../store/src/app-state'; import { waitForCFPermissions } from '../../../features/cloud-foundry/cf.helpers'; import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; // TODO: RC test -// TODO: RC filename @Directive({ selector: '[appCfUserPermission]' }) @@ -37,7 +36,6 @@ export class CfUserPermissionDirective implements OnDestroy, OnInit { public ngOnInit() { this.canSub = this.waitForEndpointPermissions(this.appCfUserPermissionEndpointGuid).pipe( - tap(console.log), switchMap(() => this.currentUserPermissionsService.can( this.appCfUserPermission, this.appCfUserPermissionEndpointGuid, diff --git a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.reducers.module.ts b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.reducers.module.ts index 6d13912909..71da36d84f 100644 --- a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.reducers.module.ts +++ b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.reducers.module.ts @@ -1,15 +1,17 @@ import { NgModule } from '@angular/core'; import { StoreModule } from '@ngrx/store'; + +import { cfUsersRolesReducer } from './reducers/cf-users-roles.reducer'; import { createAppReducer } from './reducers/create-application.reducer'; -import { deployAppReducer } from './reducers/deploy-app.reducer'; import { createServiceInstanceReducer } from './reducers/create-service-instance.reducer'; -import { UsersRolesReducer } from './reducers/users-roles.reducer'; +import { deployAppReducer } from './reducers/deploy-app.reducer'; + @NgModule({ imports: [ StoreModule.forFeature('createApplication', createAppReducer), StoreModule.forFeature('deployApplication', deployAppReducer), StoreModule.forFeature('createServiceInstance', createServiceInstanceReducer), - StoreModule.forFeature('manageUsersRoles', UsersRolesReducer), + StoreModule.forFeature('manageUsersRoles', cfUsersRolesReducer), ] }) export class CloudFoundryReducersModule { } diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/app.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/app.effects.ts index 60657b138d..76926a21da 100644 --- a/src/frontend/packages/cloud-foundry/src/store/effects/app.effects.ts +++ b/src/frontend/packages/cloud-foundry/src/store/effects/app.effects.ts @@ -7,7 +7,7 @@ import { endpointHasMetrics } from '../../../../core/src/features/endpoints/endp import { EndpointOnlyAppState } from '../../../../store/src/app-state'; import { APISuccessOrFailedAction } from '../../../../store/src/types/request.types'; import { ASSIGN_ROUTE_SUCCESS } from '../../actions/application-service-routes.actions'; -import { UPDATE_SUCCESS, UpdateExistingApplication } from '../../actions/application.actions'; +import { CF_APP_UPDATE_SUCCESS, UpdateExistingApplication } from '../../actions/application.actions'; import { cfEntityCatalog } from '../../cf-entity-catalog'; import { createAppInstancesMetricAction, @@ -29,7 +29,7 @@ export class AppEffects { ); @Effect({ dispatch: false }) clearCellMetrics$ = this.actions$.pipe( - ofType(UPDATE_SUCCESS), + ofType(CF_APP_UPDATE_SUCCESS), map(action => { // User's can scale down instances and previous instance data is kept in store, when the user scales up again this stale data can // be incorrectly shown straight away. In order to work around this fetch the latest metrics again when scaling up diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts index f15fddc33f..764e574ad6 100644 --- a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts +++ b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts @@ -2,13 +2,12 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; -import { map } from 'rxjs/operators'; +import { catchError, map } from 'rxjs/operators'; -import { GET_CURRENT_USER_RELATION, GetUserRelations } from '../../actions/permissions.actions'; +import { GET_CURRENT_CF_USER_RELATION, GetCurrentCfUserRelations } from '../../actions/permissions.actions'; import { CFAppState } from '../../cf-app-state'; import { fetchCfUserRole } from '../../user-permissions/cf-user-roles-fetch'; -// TODO: RC MOVE all GET_CURRENT_USER_RELATION @Injectable() export class PermissionEffects { constructor( @@ -18,10 +17,11 @@ export class PermissionEffects { ) { } @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( - ofType(GET_CURRENT_USER_RELATION), + ofType(GET_CURRENT_CF_USER_RELATION), map(action => { return fetchCfUserRole(this.store, action, this.httpClient).pipe( - map((success) => ({ type: action.actions[1] })) // TODO: RC FIX error handling + map(() => ({ type: action.actions[1] })), + catchError(() => [{ type: action.actions[2] }]) ); }) ); diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/update-app-effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/update-app-effects.ts index a29f72b026..7c080b69e1 100644 --- a/src/frontend/packages/cloud-foundry/src/store/effects/update-app-effects.ts +++ b/src/frontend/packages/cloud-foundry/src/store/effects/update-app-effects.ts @@ -4,7 +4,7 @@ import { mergeMap } from 'rxjs/operators'; import { WrapperRequestActionSuccess } from '../../../../store/src/types/request.types'; import { AppMetadataTypes } from '../../actions/app-metadata.actions'; -import { UPDATE_SUCCESS, UpdateExistingApplication } from '../../actions/application.actions'; +import { CF_APP_UPDATE_SUCCESS, UpdateExistingApplication } from '../../actions/application.actions'; import { cfEntityCatalog } from '../../cf-entity-catalog'; @Injectable() @@ -16,7 +16,7 @@ export class UpdateAppEffects { } @Effect() UpdateAppInStore$ = this.actions$.pipe( - ofType(UPDATE_SUCCESS), + ofType(CF_APP_UPDATE_SUCCESS), mergeMap((action: WrapperRequestActionSuccess) => { const updateAction = action.apiAction as UpdateExistingApplication; const updateEntities = updateAction.updateEntities || [AppMetadataTypes.ENV_VARS, AppMetadataTypes.STATS, AppMetadataTypes.SUMMARY]; diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts index 585a4a7295..8b84913970 100644 --- a/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts +++ b/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts @@ -15,13 +15,13 @@ import { SessionDataEndpoint } from '../../../../store/src/types/auth.types'; import { PaginatedAction } from '../../../../store/src/types/pagination.types'; import { ICFAction, UpdateCfAction } from '../../../../store/src/types/request.types'; import { UsersRolesActions, UsersRolesClearUpdateState, UsersRolesExecuteChanges } from '../../actions/users-roles.actions'; -import { AddUserRole, ChangeUserRole, RemoveUserRole } from '../../actions/users.actions'; +import { AddCfUserRole, ChangeCfUserRole, RemoveCfUserRole } from '../../actions/users.actions'; import { CFAppState } from '../../cf-app-state'; import { organizationEntityType, spaceEntityType } from '../../cf-entity-types'; import { CF_ENDPOINT_TYPE } from '../../cf-types'; import { CfUserService } from '../../shared/data-services/cf-user.service'; -import { selectUsersRoles } from '../selectors/users-roles.selector'; -import { OrgUserRoleNames } from '../types/user.types'; +import { selectCfUsersRoles } from '../selectors/cf-users-roles.selector'; +import { OrgUserRoleNames } from '../types/cf-user.types'; import { CfRoleChange, UsersRolesState } from '../types/users-roles.types'; @@ -43,7 +43,7 @@ export class UsersRolesEffects { guid: change.spaceGuid ? change.spaceGuid : change.orgGuid, endpointType: CF_ENDPOINT_TYPE, entityType: change.spaceGuid ? spaceEntityType : organizationEntityType, - updatingKey: ChangeUserRole.generateUpdatingKey(change.role, change.userGuid), + updatingKey: ChangeCfUserRole.generateUpdatingKey(change.role, change.userGuid), options: null, actions: [], type: '' @@ -57,7 +57,7 @@ export class UsersRolesEffects { @Effect() executeUsersRolesChange$ = this.actions$.pipe( ofType(UsersRolesActions.ExecuteChanges), withLatestFrom( - this.store.select(selectUsersRoles), + this.store.select(selectCfUsersRoles), this.store.select(selectSessionData()) ), mergeMap(([action, usersRoles, sessionData]) => { @@ -196,11 +196,11 @@ export class UsersRolesEffects { change: CfRoleChange, username: string, usernameOrigin: string - ): ChangeUserRole { + ): ChangeCfUserRole { const isSpace = !!change.spaceGuid; const entityGuid = isSpace ? change.spaceGuid : change.orgGuid; return change.add ? - new AddUserRole( + new AddCfUserRole( cfGuid, change.userGuid, entityGuid, @@ -211,7 +211,7 @@ export class UsersRolesEffects { username, usernameOrigin ) : - new RemoveUserRole( + new RemoveCfUserRole( cfGuid, change.userGuid, entityGuid, @@ -224,7 +224,7 @@ export class UsersRolesEffects { ); } - private createActionObs(action: ChangeUserRole): Observable { + private createActionObs(action: ChangeCfUserRole): Observable { return entityCatalog.getEntity(action) .store .getEntityMonitor(action.guid) diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/users-roles.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/cf-users-roles.reducer.ts similarity index 97% rename from src/frontend/packages/cloud-foundry/src/store/reducers/users-roles.reducer.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/cf-users-roles.reducer.ts index bcb4b0173d..01f1eb770c 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/users-roles.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/cf-users-roles.reducer.ts @@ -16,7 +16,7 @@ import { IUserPermissionInOrg, IUserPermissionInSpace, OrgUserRoleNames, -} from '../types/user.types'; +} from '../types/cf-user.types'; import { UsersRolesState } from '../types/users-roles.types'; export function createDefaultOrgRoles(orgGuid: string, orgName: string): IUserPermissionInOrg { @@ -53,7 +53,7 @@ const defaultState: UsersRolesState = { changedRoles: [] }; -export function UsersRolesReducer(state: UsersRolesState = defaultState, action: Action): UsersRolesState { +export function cfUsersRolesReducer(state: UsersRolesState = defaultState, action: Action): UsersRolesState { switch (action.type) { case UsersRolesActions.SetUsers: const setUsersAction = action as UsersRolesSetUsers; diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/users.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/cf-users.reducer.ts similarity index 90% rename from src/frontend/packages/cloud-foundry/src/store/reducers/users.reducer.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/cf-users.reducer.ts index 42376488c6..71079d216e 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/users.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/cf-users.reducer.ts @@ -5,10 +5,10 @@ import { APIResource, NormalizedResponse } from '../../../../store/src/types/api import { APISuccessOrFailedAction } from '../../../../store/src/types/request.types'; import { GET_ORGANIZATION_USERS_SUCCESS, GetAllOrgUsers } from '../../actions/organization.actions'; import { - ADD_ROLE_SUCCESS, - ChangeUserRole, - createDefaultUserRelations, - REMOVE_ROLE_SUCCESS, + ADD_CF_ROLE_SUCCESS, + ChangeCfUserRole, + createDefaultCfUserRelations, + REMOVE_CF_ROLE_SUCCESS, } from '../../actions/users.actions'; import { IOrganization, ISpace } from '../../cf-api.types'; import { cfUserEntityType } from '../../cf-entity-types'; @@ -20,7 +20,7 @@ import { getDefaultCfUserMissingRoles, OrgUserRoleNames, SpaceUserRoleNames, -} from '../types/user.types'; +} from '../types/cf-user.types'; const properties = { org: { @@ -36,12 +36,12 @@ const properties = { } }; -export function userReducer(state: IRequestEntityTypeState>, action: APISuccessOrFailedAction) { +export function cfUserReducer(state: IRequestEntityTypeState>, action: APISuccessOrFailedAction) { switch (action.type) { - case ADD_ROLE_SUCCESS: - case REMOVE_ROLE_SUCCESS: + case ADD_CF_ROLE_SUCCESS: + case REMOVE_CF_ROLE_SUCCESS: // Ensure that a user's roles collections are updated when we call add/remove - const permAction = action.apiAction as ChangeUserRole; + const permAction = action.apiAction as ChangeCfUserRole; if (permAction.username) { return state; } @@ -50,7 +50,7 @@ export function userReducer(state: IRequestEntityTypeState>, ...state, [userGuid]: { ...state[userGuid], - entity: updatePermission(state[userGuid].entity, entityGuid, isSpace, permissionTypeKey, action.type === ADD_ROLE_SUCCESS), + entity: updatePermission(state[userGuid].entity, entityGuid, isSpace, permissionTypeKey, action.type === ADD_CF_ROLE_SUCCESS), } }; case GET_ORGANIZATION_USERS_SUCCESS: @@ -99,18 +99,18 @@ type StateEntities = IRequestEntityTypeState>; export function userSpaceOrgReducer(isSpace: boolean) { return (state: StateEntities, action: APISuccessOrFailedAction) => { switch (action.type) { - case ADD_ROLE_SUCCESS: - case REMOVE_ROLE_SUCCESS: + case ADD_CF_ROLE_SUCCESS: + case REMOVE_CF_ROLE_SUCCESS: // Ensure that an org or space's roles lists are updated when we call add/remove - const permAction = action.apiAction as ChangeUserRole; - const isAdd = action.type === ADD_ROLE_SUCCESS ? true : false; + const permAction = action.apiAction as ChangeCfUserRole; + const isAdd = action.type === ADD_CF_ROLE_SUCCESS ? true : false; return (isSpace && !!permAction.isSpace) || (!isSpace && !permAction.isSpace) ? newEntityState(state, permAction, isAdd) : state; } return state; }; } -function newEntityState(state: StateEntities, action: ChangeUserRole, add: boolean): StateEntities { +function newEntityState(state: StateEntities, action: ChangeCfUserRole, add: boolean): StateEntities { const apiResource: APIResource = state[action.guid]; if (!apiResource) { return state; @@ -165,7 +165,7 @@ function updateUserMissingRoles(users: IRequestEntityTypeState { if (getOrgUsersAction.includeRelations.find(includedRel => includedRel === rel)) { reqRels.push(rel); diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-base-cf-role.reducer.ts similarity index 54% rename from src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-base-cf-role.reducer.ts index e4557f5ef7..64377c46ee 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-base-cf-role.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-base-cf-role.reducer.ts @@ -1,14 +1,13 @@ import { APIResource } from '../../../../../store/src/types/api.types'; import { getDefaultRolesRequestState } from '../../../../../store/src/types/current-user-roles.types'; -import { GetCurrentUserRelationsComplete, UserRelationTypes } from '../../../actions/permissions.actions'; +import { CfUserRelationTypes, GetCurrentCfUserRelationsComplete } from '../../../actions/permissions.actions'; import { ISpace } from '../../../cf-api.types'; import { IAllCfRolesState, ICfRolesState, IOrgsRoleState } from '../../types/cf-current-user-roles.types'; -import { createOrgRoleStateState } from './current-user-roles-org.reducer'; -import { currentUserOrgRolesReducer } from './current-user-roles-orgs.reducer'; -import { currentUserSpaceRolesReducer } from './current-user-roles-spaces.reducer'; +import { createCfOrgRoleStateState } from './current-cf-user-roles-org.reducer'; +import { currentCfUserOrgRolesReducer } from './current-cf-user-roles-orgs.reducer'; +import { currentCfUserSpaceRolesReducer } from './current-cf-user-roles-spaces.reducer'; -// TODO: RC RENAME -export function getDefaultEndpointRoles(): ICfRolesState { +export function getDefaultCfEndpointRoles(): ICfRolesState { return { global: { isAdmin: false, @@ -28,11 +27,11 @@ export function getDefaultEndpointRoles(): ICfRolesState { }; } -export function currentUserBaseCFRolesReducer(state: IAllCfRolesState = {}, action: GetCurrentUserRelationsComplete): IAllCfRolesState { +export function currentUserBaseCFRolesReducer(state: IAllCfRolesState = {}, action: GetCurrentCfUserRelationsComplete): IAllCfRolesState { if (!state[action.endpointGuid]) { state = { ...state, - [action.endpointGuid]: getDefaultEndpointRoles() + [action.endpointGuid]: getDefaultCfEndpointRoles() }; } return { @@ -42,18 +41,18 @@ export function currentUserBaseCFRolesReducer(state: IAllCfRolesState = {}, acti } function currentUserCFRolesReducer( - state: ICfRolesState = getDefaultEndpointRoles(), - action: GetCurrentUserRelationsComplete): ICfRolesState { + state: ICfRolesState = getDefaultCfEndpointRoles(), + action: GetCurrentCfUserRelationsComplete): ICfRolesState { if (isOrgRelation(action.relationType)) { return { ...state, - organizations: currentUserOrgRolesReducer(state.organizations, action) + organizations: currentCfUserOrgRolesReducer(state.organizations, action) }; } if (isSpaceRelation(action.relationType)) { return { ...state, - spaces: currentUserSpaceRolesReducer(state.spaces, action), + spaces: currentCfUserSpaceRolesReducer(state.spaces, action), organizations: assignSpaceToOrg(state.organizations, action.data) }; } @@ -63,7 +62,7 @@ function currentUserCFRolesReducer( function assignSpaceToOrg(organizations: IOrgsRoleState = {}, spaces: APIResource[]): IOrgsRoleState { return spaces.reduce((newOrganizations: IOrgsRoleState, space) => { const orgGuid = space.entity.organization_guid; - const org = newOrganizations[orgGuid] || createOrgRoleStateState(); + const org = newOrganizations[orgGuid] || createCfOrgRoleStateState(); const spaceGuids = org.spaceGuids || []; if (spaceGuids.includes(space.metadata.guid)) { return newOrganizations; @@ -82,15 +81,15 @@ function assignSpaceToOrg(organizations: IOrgsRoleState = {}, spaces: APIResourc } -function isOrgRelation(relationType: UserRelationTypes) { - return relationType === UserRelationTypes.AUDITED_ORGANIZATIONS || - relationType === UserRelationTypes.BILLING_MANAGED_ORGANIZATION || - relationType === UserRelationTypes.MANAGED_ORGANIZATION || - relationType === UserRelationTypes.ORGANIZATIONS; +function isOrgRelation(relationType: CfUserRelationTypes) { + return relationType === CfUserRelationTypes.AUDITED_ORGANIZATIONS || + relationType === CfUserRelationTypes.BILLING_MANAGED_ORGANIZATION || + relationType === CfUserRelationTypes.MANAGED_ORGANIZATION || + relationType === CfUserRelationTypes.ORGANIZATIONS; } -function isSpaceRelation(relationType: UserRelationTypes) { - return relationType === UserRelationTypes.AUDITED_SPACES || - relationType === UserRelationTypes.MANAGED_SPACES || - relationType === UserRelationTypes.SPACES; +function isSpaceRelation(relationType: CfUserRelationTypes) { + return relationType === CfUserRelationTypes.AUDITED_SPACES || + relationType === CfUserRelationTypes.MANAGED_SPACES || + relationType === CfUserRelationTypes.SPACES; } diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-reducer.helpers.ts similarity index 71% rename from src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-reducer.helpers.ts index 8d2608a56c..0cf24c8845 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-reducer.helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-reducer.helpers.ts @@ -1,20 +1,20 @@ import { APIResource } from '../../../../../store/src/types/api.types'; -import { GetCurrentUserRelationsComplete, UserRelationTypes } from '../../../actions/permissions.actions'; +import { CfUserRelationTypes, GetCurrentCfUserRelationsComplete } from '../../../actions/permissions.actions'; -export interface IKeyedByIDObject { +interface IKeyedByIDObject { [id: string]: T; } -export type roleFinalReducer = ( +type roleFinalReducer = ( state: T, - relationType: UserRelationTypes, + relationType: CfUserRelationTypes, userHasRelation: boolean, data?: APIResource ) => T; -export function addNewRoles( +export function addNewCfRoles( state: IKeyedByIDObject, - action: GetCurrentUserRelationsComplete, + action: GetCurrentCfUserRelationsComplete, reducer: roleFinalReducer ) { return action.data.reduce((config, data) => { @@ -29,9 +29,9 @@ export function addNewRoles( }, { newState: { ...state }, addedIds: [] }); } -export function removeOldRoles( +export function removeOldCfRoles( state: IKeyedByIDObject, - action: GetCurrentUserRelationsComplete, + action: GetCurrentCfUserRelationsComplete, newIds: string[], reducer: roleFinalReducer ) { diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-role-session.reducer.ts similarity index 85% rename from src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-role-session.reducer.ts index cf48b55f76..5778477b89 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-role-session.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-role-session.reducer.ts @@ -2,17 +2,17 @@ import { VerifiedSession } from '../../../../../store/src/actions/auth.actions'; import { EndpointActionComplete } from '../../../../../store/src/actions/endpoint.actions'; import { SessionUser } from '../../../../../store/src/types/auth.types'; import { EndpointUser, INewlyConnectedEndpointInfo } from '../../../../../store/src/types/endpoint.types'; +import { CF_ENDPOINT_TYPE } from '../../../cf-types'; import { CfScopeStrings } from '../../../user-permissions/cf-user-permissions-checkers'; import { IAllCfRolesState, ICfRolesState, IGlobalRolesState } from '../../types/cf-current-user-roles.types'; -import { getDefaultEndpointRoles } from './current-user-base-cf-role.reducer'; +import { getDefaultCfEndpointRoles } from './current-cf-user-base-cf-role.reducer'; -// TODO: RC used interface PartialEndpoint { user: EndpointUser | SessionUser; guid: string; } -export function roleInfoFromSessionReducer( +export function cfRoleInfoFromSessionReducer( state: IAllCfRolesState, action: VerifiedSession ): IAllCfRolesState { @@ -20,12 +20,11 @@ export function roleInfoFromSessionReducer( return propagateEndpointsAdminPermissions(state, Object.values(endpoints.cf)); } -export function updateNewlyConnectedEndpoint( +export function updateNewlyConnectedCfEndpoint( state: IAllCfRolesState, action: EndpointActionComplete ): IAllCfRolesState { - // TODO: RC have at start - if (action.endpointType !== 'cf') { + if (action.endpointType !== CF_ENDPOINT_TYPE) { return state; } const endpoint = action.endpoint as INewlyConnectedEndpointInfo; @@ -43,6 +42,9 @@ function propagateEndpointsAdminPermissions( cfState: IAllCfRolesState, endpoints: PartialEndpoint[] ): IAllCfRolesState { + if (!endpoints || !endpoints.length) { + return cfState; + } return Object.values(endpoints).reduce((state, endpoint) => { return { ...state, @@ -51,7 +53,7 @@ function propagateEndpointsAdminPermissions( }, { ...cfState }); } -function propagateEndpointAdminPermissions(state: ICfRolesState = getDefaultEndpointRoles(), endpoint: PartialEndpoint) { +function propagateEndpointAdminPermissions(state: ICfRolesState = getDefaultCfEndpointRoles(), endpoint: PartialEndpoint) { const scopes = endpoint.user ? endpoint.user.scopes : []; const global = getEndpointRoles(scopes, state.global); return { diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-changed.reducers.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-changed.reducers.ts similarity index 90% rename from src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-changed.reducers.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-changed.reducers.ts index 1c32e5b8f8..578f857b0a 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-changed.reducers.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-changed.reducers.ts @@ -1,16 +1,16 @@ import { APISuccessOrFailedAction } from '../../../../../store/src/types/request.types'; -import { ChangeUserRole } from '../../../actions/users.actions'; +import { ChangeCfUserRole } from '../../../actions/users.actions'; import { CfPermissionStrings } from '../../../user-permissions/cf-user-permissions-checkers'; import { IAllCfRolesState, ICfRolesState, IOrgRoleState, ISpaceRoleState } from '../../types/cf-current-user-roles.types'; -import { OrgUserRoleNames, SpaceUserRoleNames } from '../../types/user.types'; -import { defaultUserOrgRoleState } from './current-user-roles-org.reducer'; -import { defaultUserSpaceRoleState } from './current-user-roles-space.reducer'; +import { OrgUserRoleNames, SpaceUserRoleNames } from '../../types/cf-user.types'; +import { defaultCfUserOrgRoleState } from './current-cf-user-roles-org.reducer'; +import { defaultCfUserSpaceRoleState } from './current-cf-user-roles-space.reducer'; -export function updateAfterRoleChange( +export function updateAfterCfRoleChange( state: IAllCfRolesState, isAdd: boolean, action: APISuccessOrFailedAction): IAllCfRolesState { - const changePerm = action.apiAction as ChangeUserRole; + const changePerm = action.apiAction as ChangeCfUserRole; if (!changePerm.updateConnectedUser) { // We haven't changed the user connected to this cf or the connected user is an admin. No need to update the permission roles return state; @@ -45,10 +45,10 @@ export function updateAfterRoleChange( function createEmptyState(isSpace: boolean, orgId?: string): ISpaceRoleState | IOrgRoleState { return isSpace ? { - ...defaultUserSpaceRoleState, + ...defaultCfUserSpaceRoleState, orgId } : { - ...defaultUserOrgRoleState, + ...defaultCfUserOrgRoleState, }; } diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-clear.reducers.ts similarity index 77% rename from src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-clear.reducers.ts index 5cbd0c212f..ade79d48f4 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-clear.reducers.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-clear.reducers.ts @@ -1,23 +1,27 @@ import { EndpointActionComplete } from '../../../../../store/src/actions/endpoint.actions'; import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { APISuccessOrFailedAction } from '../../../../../store/src/types/request.types'; +import { CF_ENDPOINT_TYPE } from '../../../cf-types'; import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; -import { getDefaultEndpointRoles } from './current-user-base-cf-role.reducer'; +import { getDefaultCfEndpointRoles } from './current-cf-user-base-cf-role.reducer'; -export function removeEndpointRoles(state: IAllCfRolesState, action: EndpointActionComplete) { +export function removeEndpointCfRoles(state: IAllCfRolesState, action: EndpointActionComplete) { + if (!state[action.guid]) { + return state; + } const cfState = { ...state }; - if (!cfState[action.guid]) { - return state; - } delete cfState[action.guid]; return { ...cfState, }; } -export function addEndpoint(state: IAllCfRolesState, action: EndpointActionComplete) { +export function addCfEndpoint(state: IAllCfRolesState, action: EndpointActionComplete) { + if (action.endpointType !== CF_ENDPOINT_TYPE) { + return state; + } const endpoint = action.endpoint as EndpointModel; const guid = endpoint.guid; if (state[guid]) { @@ -27,14 +31,14 @@ export function addEndpoint(state: IAllCfRolesState, action: EndpointActionCompl ...state }; - cfState[guid] = getDefaultEndpointRoles(); + cfState[guid] = getDefaultCfEndpointRoles(); return cfState; } -export function removeSpaceRoles(state: IAllCfRolesState, action: APISuccessOrFailedAction) { +export function removeCfSpaceRoles(state: IAllCfRolesState, action: APISuccessOrFailedAction) { const { endpointGuid, guid } = action.apiAction; - const removedOrgOrSpaceState = removeOrgOrSpaceRoles(state, endpointGuid as string, guid, 'spaces'); // TODO: RC HUH - return removeSpaceIdFromOrg(state, endpointGuid as string, guid); + const removedOrgOrSpaceState = removeOrgOrSpaceRoles(state, endpointGuid as string, guid, 'spaces'); + return removeSpaceIdFromOrg(removedOrgOrSpaceState, endpointGuid as string, guid); } function removeSpaceIdFromOrg(state: IAllCfRolesState, endpointGuid: string, spaceGuid: string) { @@ -58,7 +62,7 @@ function removeSpaceIdFromOrg(state: IAllCfRolesState, endpointGuid: string, spa }; } -export function removeOrgRoles(state: IAllCfRolesState, action: APISuccessOrFailedAction) { +export function removeCfOrgRoles(state: IAllCfRolesState, action: APISuccessOrFailedAction) { const { endpointGuid, guid } = action.apiAction; if (!state[endpointGuid as string].organizations[guid]) { return state; diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-org.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-org.reducer.ts new file mode 100644 index 0000000000..ecac70b373 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-org.reducer.ts @@ -0,0 +1,47 @@ +import { CfUserRelationTypes } from '../../../actions/permissions.actions'; +import { IOrgRoleState } from '../../types/cf-current-user-roles.types'; + +export const defaultCfUserOrgRoleState: IOrgRoleState = { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: false, + spaceGuids: [] +}; + +export const createCfOrgRoleStateState = () => ({ + ...defaultCfUserOrgRoleState, + spaceGuids: [ + ...defaultCfUserOrgRoleState.spaceGuids + ] +}); + +export function currentCfUserOrgRoleReducer( + state: IOrgRoleState = createCfOrgRoleStateState(), + relationType: CfUserRelationTypes, + userHasRelation: boolean +) { + switch (relationType) { + case CfUserRelationTypes.AUDITED_ORGANIZATIONS: + return { + ...state, + isAuditor: userHasRelation + }; + case CfUserRelationTypes.BILLING_MANAGED_ORGANIZATION: + return { + ...state, + isBillingManager: userHasRelation + }; + case CfUserRelationTypes.MANAGED_ORGANIZATION: + return { + ...state, + isManager: userHasRelation + }; + case CfUserRelationTypes.ORGANIZATIONS: + return { + ...state, + isUser: userHasRelation + }; + } + return state; +} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-orgs.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-orgs.reducer.ts new file mode 100644 index 0000000000..325d21faa0 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-orgs.reducer.ts @@ -0,0 +1,9 @@ +import { GetCurrentCfUserRelationsComplete } from '../../../actions/permissions.actions'; +import { IOrgsRoleState } from '../../types/cf-current-user-roles.types'; +import { addNewCfRoles, removeOldCfRoles } from './current-cf-user-reducer.helpers'; +import { currentCfUserOrgRoleReducer } from './current-cf-user-roles-org.reducer'; + +export function currentCfUserOrgRolesReducer(state: IOrgsRoleState = {}, action: GetCurrentCfUserRelationsComplete) { + const { newState, addedIds } = addNewCfRoles(state, action, currentCfUserOrgRoleReducer); + return removeOldCfRoles(newState, action, addedIds, currentCfUserOrgRoleReducer); +} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-space.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-space.reducer.ts similarity index 67% rename from src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-space.reducer.ts rename to src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-space.reducer.ts index fda7c35762..944aee675e 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-space.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-space.reducer.ts @@ -1,18 +1,18 @@ import { APIResource } from '../../../../../store/src/types/api.types'; -import { UserRelationTypes } from '../../../actions/permissions.actions'; +import { CfUserRelationTypes } from '../../../actions/permissions.actions'; import { ISpace } from '../../../cf-api.types'; import { ISpaceRoleState } from '../../types/cf-current-user-roles.types'; -export const defaultUserSpaceRoleState: ISpaceRoleState = { +export const defaultCfUserSpaceRoleState: ISpaceRoleState = { orgId: null, isManager: false, isAuditor: false, isDeveloper: false, }; -export function currentUserSpaceRoleReducer( - state: ISpaceRoleState = defaultUserSpaceRoleState, - relationType: UserRelationTypes, +export function currentCfUserSpaceRoleReducer( + state: ISpaceRoleState = defaultCfUserSpaceRoleState, + relationType: CfUserRelationTypes, userHasRelation: boolean, space: APIResource ): ISpaceRoleState { @@ -28,7 +28,7 @@ export function currentUserSpaceRoleReducer( } function addId( - state: ISpaceRoleState = defaultUserSpaceRoleState, + state: ISpaceRoleState = defaultCfUserSpaceRoleState, space: APIResource ) { if (!state.orgId) { @@ -42,21 +42,21 @@ function addId( function applyRoles( state: ISpaceRoleState, - relationType: UserRelationTypes, + relationType: CfUserRelationTypes, userHasRelation: boolean ) { switch (relationType) { - case UserRelationTypes.AUDITED_SPACES: + case CfUserRelationTypes.AUDITED_SPACES: return { ...state, isAuditor: userHasRelation }; - case UserRelationTypes.MANAGED_SPACES: + case CfUserRelationTypes.MANAGED_SPACES: return { ...state, isManager: userHasRelation }; - case UserRelationTypes.SPACES: + case CfUserRelationTypes.SPACES: return { ...state, isDeveloper: userHasRelation diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-spaces.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-spaces.reducer.ts new file mode 100644 index 0000000000..f66284401f --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles-spaces.reducer.ts @@ -0,0 +1,9 @@ +import { GetCurrentCfUserRelationsComplete } from '../../../actions/permissions.actions'; +import { ISpacesRoleState } from '../../types/cf-current-user-roles.types'; +import { addNewCfRoles, removeOldCfRoles } from './current-cf-user-reducer.helpers'; +import { currentCfUserSpaceRoleReducer } from './current-cf-user-roles-space.reducer'; + +export function currentCfUserSpaceRolesReducer(state: ISpacesRoleState = {}, action: GetCurrentCfUserRelationsComplete) { + const { newState, addedIds } = addNewCfRoles(state, action, currentCfUserSpaceRoleReducer); + return removeOldCfRoles(newState, action, addedIds, currentCfUserSpaceRoleReducer); +} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.ts new file mode 100644 index 0000000000..b120d779c8 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.ts @@ -0,0 +1,90 @@ +import { Action } from '@ngrx/store'; + +import { SESSION_VERIFIED, VerifiedSession } from '../../../../../store/src/actions/auth.actions'; +import { + CONNECT_ENDPOINTS_SUCCESS, + DISCONNECT_ENDPOINTS_SUCCESS, + EndpointActionComplete, + REGISTER_ENDPOINTS_SUCCESS, + UNREGISTER_ENDPOINTS_SUCCESS, +} from '../../../../../store/src/actions/endpoint.actions'; +import { EntityUserRolesReducer } from '../../../../../store/src/entity-request-pipeline/entity-request-pipeline.types'; +import { + currentUserRolesRequestStateReducer, + RolesRequestStateStage, +} from '../../../../../store/src/reducers/current-user-roles-reducer/current-user-roles.reducer'; +import { APISuccessOrFailedAction } from '../../../../../store/src/types/request.types'; +import { DELETE_ORGANIZATION_SUCCESS } from '../../../actions/organization.actions'; +import { + GET_CURRENT_CF_USER_RELATION_SUCCESS, + GET_CURRENT_CF_USER_RELATIONS, + GET_CURRENT_CF_USER_RELATIONS_FAILED, + GET_CURRENT_CF_USER_RELATIONS_SUCCESS, + GetCfUserRelations, + GetCurrentCfUserRelationsComplete, +} from '../../../actions/permissions.actions'; +import { DELETE_SPACE_SUCCESS } from '../../../actions/space.actions'; +import { ADD_CF_ROLE_SUCCESS, REMOVE_CF_ROLE_SUCCESS } from '../../../actions/users.actions'; +import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; +import { currentUserBaseCFRolesReducer } from './current-cf-user-base-cf-role.reducer'; +import { cfRoleInfoFromSessionReducer, updateNewlyConnectedCfEndpoint } from './current-cf-user-role-session.reducer'; +import { updateAfterCfRoleChange } from './current-cf-user-roles-changed.reducers'; +import { + addCfEndpoint, + removeCfOrgRoles, + removeCfSpaceRoles, + removeEndpointCfRoles, +} from './current-cf-user-roles-clear.reducers'; + +export const currentCfUserRolesReducer: EntityUserRolesReducer = ( + state: IAllCfRolesState, + action: Action +): IAllCfRolesState => { + switch (action.type) { + case GET_CURRENT_CF_USER_RELATION_SUCCESS: + const gcursAction = action as GetCurrentCfUserRelationsComplete + return currentUserBaseCFRolesReducer(state, gcursAction); + case SESSION_VERIFIED: + return cfRoleInfoFromSessionReducer(state, action as VerifiedSession); + case REGISTER_ENDPOINTS_SUCCESS: + return addCfEndpoint(state, action as EndpointActionComplete); + case CONNECT_ENDPOINTS_SUCCESS: + return updateNewlyConnectedCfEndpoint(state, action as EndpointActionComplete); + case DISCONNECT_ENDPOINTS_SUCCESS: + case UNREGISTER_ENDPOINTS_SUCCESS: + return removeEndpointCfRoles(state, action as EndpointActionComplete); + case DELETE_ORGANIZATION_SUCCESS: + return removeCfOrgRoles(state, action as APISuccessOrFailedAction); + case DELETE_SPACE_SUCCESS: + return removeCfSpaceRoles(state, action as APISuccessOrFailedAction); + case ADD_CF_ROLE_SUCCESS: + return updateAfterCfRoleChange(state, true, action as APISuccessOrFailedAction); + case REMOVE_CF_ROLE_SUCCESS: + return updateAfterCfRoleChange(state, false, action as APISuccessOrFailedAction); + case GET_CURRENT_CF_USER_RELATIONS: + case GET_CURRENT_CF_USER_RELATIONS_SUCCESS: + case GET_CURRENT_CF_USER_RELATIONS_FAILED: + return currentUserCfRolesRequestStateReducer(state, action as GetCfUserRelations); + } + return null; +} + +export function currentUserCfRolesRequestStateReducer(cf: IAllCfRolesState = {}, action: GetCfUserRelations) { + const cfGuid = (action as GetCfUserRelations).cfGuid; + + const type = action.type === GET_CURRENT_CF_USER_RELATIONS ? + RolesRequestStateStage.START : + action.type === GET_CURRENT_CF_USER_RELATIONS_SUCCESS ? RolesRequestStateStage.SUCCESS : + action.type === GET_CURRENT_CF_USER_RELATIONS_FAILED ? RolesRequestStateStage.FAILURE : + RolesRequestStateStage.OTHER + return { + ...cf, + [cfGuid]: { + ...cf[cfGuid], + state: { + ...cf[cfGuid].state, + ...currentUserRolesRequestStateReducer(cf[cfGuid].state, type) + } + } + }; +} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-cf-roles.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-cf-roles.reducer.ts deleted file mode 100644 index a4e80f1682..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-cf-roles.reducer.ts +++ /dev/null @@ -1,2 +0,0 @@ - -// TODO: RC DELETE \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-org.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-org.reducer.ts deleted file mode 100644 index 8f3053d305..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-org.reducer.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { UserRelationTypes } from '../../../actions/permissions.actions'; -import { IOrgRoleState } from '../../types/cf-current-user-roles.types'; - -export const defaultUserOrgRoleState: IOrgRoleState = { - isManager: false, - isAuditor: false, - isBillingManager: false, - isUser: false, - spaceGuids: [] -}; - -export const createOrgRoleStateState = () => ({ - ...defaultUserOrgRoleState, - spaceGuids: [ - ...defaultUserOrgRoleState.spaceGuids - ] -}); - -export function currentUserOrgRoleReducer( - state: IOrgRoleState = createOrgRoleStateState(), - relationType: UserRelationTypes, - userHasRelation: boolean -) { - switch (relationType) { - case UserRelationTypes.AUDITED_ORGANIZATIONS: - return { - ...state, - isAuditor: userHasRelation - }; - case UserRelationTypes.BILLING_MANAGED_ORGANIZATION: - return { - ...state, - isBillingManager: userHasRelation - }; - case UserRelationTypes.MANAGED_ORGANIZATION: - return { - ...state, - isManager: userHasRelation - }; - case UserRelationTypes.ORGANIZATIONS: - return { - ...state, - isUser: userHasRelation - }; - } - return state; -} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-orgs.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-orgs.reducer.ts deleted file mode 100644 index 8961575c0d..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-orgs.reducer.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { GetCurrentUserRelationsComplete } from '../../../actions/permissions.actions'; -import { IOrgsRoleState } from '../../types/cf-current-user-roles.types'; -import { addNewRoles, removeOldRoles } from './current-user-reducer.helpers'; -import { currentUserOrgRoleReducer } from './current-user-roles-org.reducer'; - -export function currentUserOrgRolesReducer(state: IOrgsRoleState = {}, action: GetCurrentUserRelationsComplete) { - const { newState, addedIds } = addNewRoles(state, action, currentUserOrgRoleReducer); - return removeOldRoles(newState, action, addedIds, currentUserOrgRoleReducer); -} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-spaces.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-spaces.reducer.ts deleted file mode 100644 index 6575cd241e..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-spaces.reducer.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { GetCurrentUserRelationsComplete } from '../../../actions/permissions.actions'; -import { ISpacesRoleState } from '../../types/cf-current-user-roles.types'; -import { addNewRoles, removeOldRoles } from './current-user-reducer.helpers'; -import { currentUserSpaceRoleReducer } from './current-user-roles-space.reducer'; - -export function currentUserSpaceRolesReducer(state: ISpacesRoleState = {}, action: GetCurrentUserRelationsComplete) { - const { newState, addedIds } = addNewRoles(state, action, currentUserSpaceRoleReducer); - return removeOldRoles(newState, action, addedIds, currentUserSpaceRoleReducer); -} diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts deleted file mode 100644 index 96760d7a1a..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles.reducer.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Action } from '@ngrx/store'; - -import { SESSION_VERIFIED, VerifiedSession } from '../../../../../store/src/actions/auth.actions'; -import { - CONNECT_ENDPOINTS_SUCCESS, - DISCONNECT_ENDPOINTS_SUCCESS, - EndpointActionComplete, - REGISTER_ENDPOINTS_SUCCESS, - UNREGISTER_ENDPOINTS_SUCCESS, -} from '../../../../../store/src/actions/endpoint.actions'; -import { EntityUserRolesReducer } from '../../../../../store/src/entity-request-pipeline/entity-request-pipeline.types'; -import { - currentUserRolesRequestStateReducer, - RolesRequestStateStage, -} from '../../../../../store/src/reducers/current-user-roles-reducer/current-user-roles.reducer'; -import { APISuccessOrFailedAction } from '../../../../../store/src/types/request.types'; -import { DELETE_ORGANIZATION_SUCCESS } from '../../../actions/organization.actions'; -import { - GET_CURRENT_USER_CF_RELATIONS, - GET_CURRENT_USER_CF_RELATIONS_FAILED, - GET_CURRENT_USER_CF_RELATIONS_SUCCESS, - GET_CURRENT_USER_RELATION_SUCCESS, - GetCurrentUserRelationsComplete, - GetUserCfRelations, -} from '../../../actions/permissions.actions'; -import { DELETE_SPACE_SUCCESS } from '../../../actions/space.actions'; -import { ADD_ROLE_SUCCESS, REMOVE_ROLE_SUCCESS } from '../../../actions/users.actions'; -import { IAllCfRolesState } from '../../types/cf-current-user-roles.types'; -import { currentUserBaseCFRolesReducer } from './current-user-base-cf-role.reducer'; -import { roleInfoFromSessionReducer, updateNewlyConnectedEndpoint } from './current-user-role-session.reducer'; -import { updateAfterRoleChange } from './current-user-roles-changed.reducers'; -import { addEndpoint, removeEndpointRoles, removeOrgRoles, removeSpaceRoles } from './current-user-roles-clear.reducers'; - -// TODO: RC TUESDAY HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// TODO: RC RENAME file -// TODO: RC check each type, abort if not anything to do with cf -export const currentCfUserRolesReducer: EntityUserRolesReducer = ( - state: IAllCfRolesState, - action: Action -): IAllCfRolesState => { - switch (action.type) { - case GET_CURRENT_USER_RELATION_SUCCESS: // TODO: RC CF Only. VS GET_CURRENT_USER_CF_RELATIONS - const gcursAction = action as GetCurrentUserRelationsComplete - return currentUserBaseCFRolesReducer(state, gcursAction); - case SESSION_VERIFIED:// TODO: RC CF Only - return roleInfoFromSessionReducer(state, action as VerifiedSession); - case REGISTER_ENDPOINTS_SUCCESS:// TODO: RC CF Only - return addEndpoint(state, action as EndpointActionComplete); - case CONNECT_ENDPOINTS_SUCCESS:// TODO: RC CF Only - return updateNewlyConnectedEndpoint(state, action as EndpointActionComplete); - case DISCONNECT_ENDPOINTS_SUCCESS:// TODO: RC CF Only - case UNREGISTER_ENDPOINTS_SUCCESS:// TODO: RC CF Only - return removeEndpointRoles(state, action as EndpointActionComplete); - case DELETE_ORGANIZATION_SUCCESS:// TODO: RC CF Only - return removeOrgRoles(state, action as APISuccessOrFailedAction); - case DELETE_SPACE_SUCCESS:// TODO: RC CF Only - return removeSpaceRoles(state, action as APISuccessOrFailedAction); - case ADD_ROLE_SUCCESS:// TODO: RC CF Only - return updateAfterRoleChange(state, true, action as APISuccessOrFailedAction); - case REMOVE_ROLE_SUCCESS:// TODO: RC CF Only - return updateAfterRoleChange(state, false, action as APISuccessOrFailedAction); - case GET_CURRENT_USER_CF_RELATIONS:// TODO: RC CF Only - case GET_CURRENT_USER_CF_RELATIONS_SUCCESS: - case GET_CURRENT_USER_CF_RELATIONS_FAILED: - return currentUserCfRolesRequestStateReducer(state, action as GetUserCfRelations); - } - return null; -} - -export function currentUserCfRolesRequestStateReducer(cf: IAllCfRolesState = {}, action: GetUserCfRelations) { - const cfGuid = (action as GetUserCfRelations).cfGuid; - - const type = action.type === GET_CURRENT_USER_CF_RELATIONS ? - RolesRequestStateStage.START : - action.type === GET_CURRENT_USER_CF_RELATIONS_SUCCESS ? RolesRequestStateStage.SUCCESS : - action.type === GET_CURRENT_USER_CF_RELATIONS_FAILED ? RolesRequestStateStage.FAILURE : - RolesRequestStateStage.OTHER - return { - ...cf, - [cfGuid]: { - ...cf[cfGuid], - state: { - ...cf[cfGuid].state, - ...currentUserRolesRequestStateReducer(cf[cfGuid].state, type) - } - } - }; -} diff --git a/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts b/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts index 2967bdc33a..c3df05ca37 100644 --- a/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts +++ b/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts @@ -1,6 +1,6 @@ import { compose } from '@ngrx/store'; -import { PermissionValues } from '../../../../core/src/core/current-user-permissions.config'; +import { PermissionValues } from '../../../../core/src/core/permissions/current-user-permissions.config'; import { selectCurrentUserGlobalHasScopes, selectCurrentUserRolesState, @@ -62,10 +62,6 @@ export const getCurrentUserCFRolesState = compose( // Specific endpoint roles // ============================ export const getCurrentUserCFEndpointRolesState = (endpointGuid: string) => compose( - (a) => { - console.log('3: ', a) - return a; - }, selectCurrentUserCFEndpointRolesState(endpointGuid), getCurrentUserCFRolesState, ); diff --git a/src/frontend/packages/cloud-foundry/src/store/selectors/users-roles.selector.ts b/src/frontend/packages/cloud-foundry/src/store/selectors/cf-users-roles.selector.ts similarity index 56% rename from src/frontend/packages/cloud-foundry/src/store/selectors/users-roles.selector.ts rename to src/frontend/packages/cloud-foundry/src/store/selectors/cf-users-roles.selector.ts index 2f16a71704..2d5707711f 100644 --- a/src/frontend/packages/cloud-foundry/src/store/selectors/users-roles.selector.ts +++ b/src/frontend/packages/cloud-foundry/src/store/selectors/cf-users-roles.selector.ts @@ -1,51 +1,50 @@ import { compose } from '@ngrx/store'; import { CFAppState } from '../../cf-app-state'; -import { IUserPermissionInOrg } from '../types/user.types'; +import { IUserPermissionInOrg } from '../types/cf-user.types'; import { UsersRolesState } from '../types/users-roles.types'; -// TODO: RC -export const selectUsersRoles = (state: CFAppState): UsersRolesState => state.manageUsersRoles; +export const selectCfUsersRoles = (state: CFAppState): UsersRolesState => state.manageUsersRoles; const selectUsers = (usersRoles: UsersRolesState) => usersRoles.users; -export const selectUsersRolesPicked = compose( +export const selectCfUsersRolesPicked = compose( selectUsers, - selectUsersRoles + selectCfUsersRoles ); const selectNewRoles = (usersRoles: UsersRolesState) => usersRoles.newRoles; -export const selectUsersRolesRoles = compose( +export const selectCfUsersRolesRoles = compose( selectNewRoles, - selectUsersRoles + selectCfUsersRoles ); const selectCfGuid = (usersRoles: UsersRolesState) => usersRoles.cfGuid; -export const selectUsersRolesCf = compose( +export const selectCfUsersRolesCf = compose( selectCfGuid, - selectUsersRoles + selectCfUsersRoles ); const selectChanged = (usersRoles: UsersRolesState) => usersRoles.changedRoles; -export const selectUsersRolesChangedRoles = compose( +export const selectCfUsersRolesChangedRoles = compose( selectChanged, - selectUsersRoles + selectCfUsersRoles ); const selectNewRoleOrgGuid = (newRoles: IUserPermissionInOrg) => newRoles.orgGuid; -export const selectUsersRolesOrgGuid = compose( +export const selectCfUsersRolesOrgGuid = compose( selectNewRoleOrgGuid, selectNewRoles, - selectUsersRoles + selectCfUsersRoles ); const isRemove = (usersRoles: UsersRolesState) => usersRoles.isRemove; -export const selectUsersIsRemove = compose( +export const selectCfUsersIsRemove = compose( isRemove, - selectUsersRoles + selectCfUsersRoles ); const isSetByUsername = (usersRoles: UsersRolesState) => usersRoles.isSetByUsername; -export const selectUsersIsSetByUsername = compose( +export const selectCfUsersIsSetByUsername = compose( isSetByUsername, - selectUsersRoles + selectCfUsersRoles ); diff --git a/src/frontend/packages/cloud-foundry/src/store/types/user.types.ts b/src/frontend/packages/cloud-foundry/src/store/types/cf-user.types.ts similarity index 100% rename from src/frontend/packages/cloud-foundry/src/store/types/user.types.ts rename to src/frontend/packages/cloud-foundry/src/store/types/cf-user.types.ts diff --git a/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts b/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts deleted file mode 100644 index 40701be98b..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/types/current-user-roles.types.ts +++ /dev/null @@ -1 +0,0 @@ -// TODO: RC DELETE ME \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/store/types/users-roles.types.ts b/src/frontend/packages/cloud-foundry/src/store/types/users-roles.types.ts index 5e9b41a9da..e6c7dcb045 100644 --- a/src/frontend/packages/cloud-foundry/src/store/types/users-roles.types.ts +++ b/src/frontend/packages/cloud-foundry/src/store/types/users-roles.types.ts @@ -1,4 +1,4 @@ -import { CfUser, CfUserRoleParams, IUserPermissionInOrg, OrgUserRoleNames, SpaceUserRoleNames } from './user.types'; +import { CfUser, CfUserRoleParams, IUserPermissionInOrg, OrgUserRoleNames, SpaceUserRoleNames } from './cf-user.types'; export interface UsersRolesState { cfGuid: string; diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts index 6331099941..d41440bfb6 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts @@ -2,27 +2,28 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of } from 'rxjs'; import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; -import { - BaseCurrentUserPermissionsChecker, - ICheckCombiner, - IConfigGroup, - ICurrentUserPermissionsChecker, -} from '../../../core/src/core/current-user-permissions.checker'; import { IPermissionConfigs, PermissionConfig, PermissionConfigLink, PermissionTypes, PermissionValues, -} from '../../../core/src/core/current-user-permissions.config'; +} from '../../../core/src/core/permissions/current-user-permissions.config'; import { CurrentUserPermissionsService, CUSTOM_USER_PERMISSION_CHECKERS, -} from '../../../core/src/core/current-user-permissions.service'; +} from '../../../core/src/core/permissions/current-user-permissions.service'; +import { + BaseCurrentUserPermissionsChecker, + IConfigGroup, + ICurrentUserPermissionsChecker, + IPermissionCheckCombiner, +} from '../../../core/src/core/permissions/stratos-user-permissions.checker'; import { GeneralEntityAppState } from '../../../store/src/app-state'; import { connectedEndpointsSelector } from '../../../store/src/selectors/endpoint.selectors'; import { CFFeatureFlagTypes, IFeatureFlag } from '../cf-api.types'; import { cfEntityCatalog } from '../cf-entity-catalog'; +import { CF_ENDPOINT_TYPE } from '../cf-types'; import { getCurrentUserCFEndpointHasScope, getCurrentUserCFEndpointRolesState, @@ -39,13 +40,6 @@ export const cfCurrentUserPermissionsService = [ CurrentUserPermissionsService, ] -// TODO: RC -// type Enum = Record; -// export const cfCurrentUserPermissions2: Enum = { -// a: '1', -// b: '2', -// } -// TODO: RC of type PermissionTypes export enum CfCurrentUserPermissions { APPLICATION_VIEW = 'view.application', APPLICATION_EDIT = 'edit.application', @@ -424,13 +418,13 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker return this.store.select(getCurrentUserCFEndpointRolesState(endpointGuid)); } - public getCheckFromConfig( + public getComplexCheck( configGroup: IConfigGroup, permission: CfPermissionTypes, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string - ): ICheckCombiner { + ): IPermissionCheckCombiner { const checkCombiner = this.getBaseCheckFromConfig(configGroup, permission, endpointGuid, orgOrSpaceGuid, spaceGuid) if (checkCombiner) { checkCombiner.checks = checkCombiner.checks.map(check$ => this.applyAdminCheck(check$, endpointGuid)) @@ -444,12 +438,8 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string - ): ICheckCombiner { + ): IPermissionCheckCombiner { switch (permission) { - // case cfPermissionTypes.ENDPOINT: - // return { - // checks: this.getInternalScopesChecks(configGroup), // TODO: RC not right?? - // }; case CfPermissionTypes.ENDPOINT_SCOPE: return { checks: this.getEndpointScopesChecks(configGroup, endpointGuid), @@ -470,8 +460,8 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker } } - public getFallbackPermission(endpointGuid: string) { - return this.getCfAdminCheck(endpointGuid); + public getFallbackCheck(endpointGuid: string, endpointType: string) { + return endpointType === CF_ENDPOINT_TYPE ? this.getCfAdminCheck(endpointGuid) : null; }; } \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts index bbe95ce980..c066907ffc 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts @@ -18,29 +18,17 @@ import { selectPaginationState } from '../../../store/src/selectors/pagination.s import { EndpointModel } from '../../../store/src/types/endpoint.types'; import { BasePaginatedAction, PaginationEntityState } from '../../../store/src/types/pagination.types'; import { - GET_CURRENT_USER_CF_RELATIONS, - GET_CURRENT_USER_CF_RELATIONS_FAILED, - GET_CURRENT_USER_CF_RELATIONS_SUCCESS, - GetCurrentUserRelationsComplete, - GetUserCfRelations, - GetUserRelations, - UserRelationTypes, + CfUserRelationTypes, + GET_CURRENT_CF_USER_RELATIONS, + GET_CURRENT_CF_USER_RELATIONS_FAILED, + GET_CURRENT_CF_USER_RELATIONS_SUCCESS, + GetCfUserRelations, + GetCurrentCfUserRelations, + GetCurrentCfUserRelationsComplete, } from '../actions/permissions.actions'; import { cfEntityCatalog } from '../cf-entity-catalog'; import { CFResponse } from '../store/types/cf-api.types'; -// TODO: RC -// map(cfEndpoints => -// Object -// .entries(cfEndpoints) -// .filter(([id, endpoint]) => { -// const validId = endpointIds.length === 0 || endpointIds.find(endpointId => endpointId === id); -// const isAdmin = endpoint.user.admin; -// return validId && !isAdmin -// }) -// .map(([, endpoint]) => endpoint) -// ), - export const cfUserRolesFetch: EntityUserRolesFetch = ( endpointIds: string[], store: Store, @@ -56,7 +44,7 @@ export const cfUserRolesFetch: EntityUserRolesFetch = ( const isAllAdmins = cfEndpoints.every(endpoint => !!endpoint.user.admin); // If all endpoints are connected as admin, there's no permissions to fetch. So only update the permission state to initialised if (isAllAdmins) { - cfEndpoints.forEach(endpoint => store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS))) + cfEndpoints.forEach(endpoint => store.dispatch(new GetCfUserRelations(endpoint.guid, GET_CURRENT_CF_USER_RELATIONS_SUCCESS))) } else { // If some endpoints are not connected as admin, go out and fetch the current user's specific roles const flagsAndRoleRequests = dispatchRoleRequests(cfEndpoints, store, logService, httpClient); @@ -92,10 +80,10 @@ function dispatchRoleRequests( if (endpoint.user.admin) { // We don't need permissions for admin users (they can do everything) requests[endpoint.guid] = [of(true)]; - store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_SUCCESS)); + store.dispatch(new GetCfUserRelations(endpoint.guid, GET_CURRENT_CF_USER_RELATIONS_SUCCESS)); } else { // START fetching cf roles for current user - store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS)); + store.dispatch(new GetCfUserRelations(endpoint.guid, GET_CURRENT_CF_USER_RELATIONS)); // Dispatch feature flags fetch actions const ffAction = cfEntityCatalog.featureFlag.actions.getMultiple(endpoint.guid) @@ -109,14 +97,14 @@ function dispatchRoleRequests( combineLatest(requests[endpoint.guid]).pipe( first(), tap(succeeds => { - store.dispatch(new GetUserCfRelations( + store.dispatch(new GetCfUserRelations( endpoint.guid, - succeeds.every(succeeded => !!succeeded) ? GET_CURRENT_USER_CF_RELATIONS_SUCCESS : GET_CURRENT_USER_CF_RELATIONS_FAILED) + succeeds.every(succeeded => !!succeeded) ? GET_CURRENT_CF_USER_RELATIONS_SUCCESS : GET_CURRENT_CF_USER_RELATIONS_FAILED) ); }), catchError(err => { logService.warn('Failed to fetch current user permissions for a cf: ', err); - store.dispatch(new GetUserCfRelations(endpoint.guid, GET_CURRENT_USER_CF_RELATIONS_FAILED)); + store.dispatch(new GetCfUserRelations(endpoint.guid, GET_CURRENT_CF_USER_RELATIONS_FAILED)); return of(err); }) ).subscribe(); @@ -135,8 +123,8 @@ function handleCfRequests(requests: CfsRequestState): Observable[] { } function fetchCfUserRoles(endpoint: IEndpointConnectionInfo, store: Store, httpClient: HttpClient): Observable[] { - return Object.values(UserRelationTypes).map((type: UserRelationTypes) => { - const relAction = new GetUserRelations(endpoint.userGuid, type, endpoint.guid); + return Object.values(CfUserRelationTypes).map((type: CfUserRelationTypes) => { + const relAction = new GetCurrentCfUserRelations(endpoint.userGuid, type, endpoint.guid); return fetchCfUserRole(store, relAction, httpClient); }); } @@ -162,7 +150,7 @@ class PermissionFlattener extends BaseHttpClientFetcher implements P public clearResults = (res: CFResponse) => of(res); } -export function fetchCfUserRole(store: Store, action: GetUserRelations, httpClient: HttpClient): Observable { +export function fetchCfUserRole(store: Store, action: GetCurrentCfUserRelations, httpClient: HttpClient): Observable { const url = `pp/v1/proxy/v2/users/${action.guid}/${action.relationType}`; const params = { headers: { @@ -183,7 +171,7 @@ export function fetchCfUserRole(store: Store, action: GetUserRelations new PermissionFlattener(httpClient, url, params) ).pipe( map(data => { - store.dispatch(new GetCurrentUserRelationsComplete(action.relationType, action.endpointGuid, data.resources)); + store.dispatch(new GetCurrentCfUserRelationsComplete(action.relationType, action.endpointGuid, data.resources)); return true; }), first(), diff --git a/src/frontend/packages/cloud-foundry/test-framework/cloud-foundry-endpoint-service.helper.ts b/src/frontend/packages/cloud-foundry/test-framework/cloud-foundry-endpoint-service.helper.ts index dfb1e5297e..b12a95fdba 100644 --- a/src/frontend/packages/cloud-foundry/test-framework/cloud-foundry-endpoint-service.helper.ts +++ b/src/frontend/packages/cloud-foundry/test-framework/cloud-foundry-endpoint-service.helper.ts @@ -23,7 +23,7 @@ import { import { CfOrgSpaceDataService } from '../src/shared/data-services/cf-org-space-service.service'; import { CfUserService } from '../src/shared/data-services/cf-user.service'; import { CloudFoundryService } from '../src/shared/data-services/cloud-foundry.service'; -import { createUserRoleInOrg } from '../src/store/types/user.types'; +import { createUserRoleInOrg } from '../src/store/types/cf-user.types'; import { CfUserServiceTestProvider } from './user-service-helper'; export const cfEndpointServiceProviderDeps = [ diff --git a/src/frontend/packages/core/src/core/core.module.ts b/src/frontend/packages/core/src/core/core.module.ts index 31a4ba159f..e726c6eed2 100644 --- a/src/frontend/packages/core/src/core/core.module.ts +++ b/src/frontend/packages/core/src/core/core.module.ts @@ -17,7 +17,6 @@ import { ButtonBlurOnClickDirective } from './button-blur-on-click.directive'; import { BytesToHumanSize, MegaBytesToHumanSize } from './byte-formatters.pipe'; import { ClickStopPropagationDirective } from './click-stop-propagation.directive'; import { APP_TITLE, appTitleFactory } from './core.types'; -import { CurrentUserPermissionsService, CUSTOM_USER_PERMISSION_CHECKERS } from './current-user-permissions.service'; import { DisableRouterLinkDirective } from './disable-router-link.directive'; import { DotContentComponent } from './dot-content/dot-content.component'; import { EndpointsService } from './endpoints.service'; @@ -30,6 +29,10 @@ import { MDAppModule } from './md.module'; import { NotSetupGuardService } from './not-setup-guard.service'; import { PageHeaderService } from './page-header-service/page-header.service'; import { PageNotFoundComponentComponent } from './page-not-found-component/page-not-found-component.component'; +import { + CurrentUserPermissionsService, + CUSTOM_USER_PERMISSION_CHECKERS, +} from './permissions/current-user-permissions.service'; import { SafeImgPipe } from './safe-img.pipe'; import { StatefulIconComponent } from './stateful-icon/stateful-icon.component'; import { TruncatePipe } from './truncate.pipe'; diff --git a/src/frontend/packages/core/src/core/current-user-permissions.config.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.config.ts similarity index 74% rename from src/frontend/packages/core/src/core/current-user-permissions.config.ts rename to src/frontend/packages/core/src/core/permissions/current-user-permissions.config.ts index be00d89736..a91481dd62 100644 --- a/src/frontend/packages/core/src/core/current-user-permissions.config.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.config.ts @@ -6,14 +6,11 @@ export interface IPermissionConfigs { export type PermissionTypes = string; export type CurrentUserPermissions = string; export type ScopeStrings = string; - -// export type PermissionValues = StratosPermissionTypes | ScopeStrings | CFFeatureFlagTypes | PermissionStrings; export type PermissionValues = string; export class PermissionConfig { constructor( public type: PermissionTypes, public permission: PermissionValues, - // public permission: PermissionValues = StratosPermissionStrings._GLOBAL_ ) { } } export class PermissionConfigLink { diff --git a/src/frontend/packages/core/src/core/current-user-permissions.service.spec.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts similarity index 96% rename from src/frontend/packages/core/src/core/current-user-permissions.service.spec.ts rename to src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts index 3e4184df98..7d401de85e 100644 --- a/src/frontend/packages/core/src/core/current-user-permissions.service.spec.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts @@ -2,20 +2,20 @@ import { TestBed } from '@angular/core/testing'; import { createBasicStoreModule, createEntityStoreState, TestStoreEntity } from '@stratos/store/testing'; import { first, tap } from 'rxjs/operators'; -import { CFFeatureFlagTypes, IFeatureFlag } from '../../../cloud-foundry/src/cf-api.types'; -import { cfEntityFactory } from '../../../cloud-foundry/src/cf-entity-factory'; -import { generateCFEntities } from '../../../cloud-foundry/src/cf-entity-generator'; -import { featureFlagEntityType } from '../../../cloud-foundry/src/cf-entity-types'; -import { AppState } from '../../../store/src/app-state'; -import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../../store/src/entity-catalog-test.module'; -import { EntityCatalogEntityConfig } from '../../../store/src/entity-catalog/entity-catalog.types'; -import { APIResource } from '../../../store/src/types/api.types'; -import { EndpointModel } from '../../../store/src/types/endpoint.types'; -import { BaseEntityValues } from '../../../store/src/types/entity.types'; -import { PaginationState } from '../../../store/src/types/pagination.types'; -import { AppTestModule } from '../../test-framework/core-test.helper'; -import { endpointEntitySchema } from '../base-entity-schemas'; -import { generateStratosEntities } from '../base-entity-types'; +import { CFFeatureFlagTypes, IFeatureFlag } from '../../../../cloud-foundry/src/cf-api.types'; +import { cfEntityFactory } from '../../../../cloud-foundry/src/cf-entity-factory'; +import { generateCFEntities } from '../../../../cloud-foundry/src/cf-entity-generator'; +import { featureFlagEntityType } from '../../../../cloud-foundry/src/cf-entity-types'; +import { AppState } from '../../../../store/src/app-state'; +import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../../../store/src/entity-catalog-test.module'; +import { EntityCatalogEntityConfig } from '../../../../store/src/entity-catalog/entity-catalog.types'; +import { APIResource } from '../../../../store/src/types/api.types'; +import { EndpointModel } from '../../../../store/src/types/endpoint.types'; +import { BaseEntityValues } from '../../../../store/src/types/entity.types'; +import { PaginationState } from '../../../../store/src/types/pagination.types'; +import { AppTestModule } from '../../../test-framework/core-test.helper'; +import { endpointEntitySchema } from '../../base-entity-schemas'; +import { generateStratosEntities } from '../../base-entity-types'; import { CurrentUserPermissions, PermissionConfig, diff --git a/src/frontend/packages/core/src/core/current-user-permissions.service.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts similarity index 79% rename from src/frontend/packages/core/src/core/current-user-permissions.service.ts rename to src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts index 0674d421cc..4e6a6afb89 100644 --- a/src/frontend/packages/core/src/core/current-user-permissions.service.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts @@ -1,16 +1,14 @@ import { Inject, Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { combineLatest, Observable, of } from 'rxjs'; -import { distinctUntilChanged, map } from 'rxjs/operators'; - -import { InternalAppState } from '../../../store/src/app-state'; -import { - BaseCurrentUserPermissionsChecker, - IConfigGroup, - IConfigGroups, - ICurrentUserPermissionsChecker, - StratosUserPermissionsChecker, -} from './current-user-permissions.checker'; +import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; + +import { InternalAppState } from '../../../../store/src/app-state'; +import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog'; +import { selectEntity } from '../../../../store/src/selectors/api.selectors'; +import { EndpointModel } from '../../../../store/src/types/endpoint.types'; +import { ENDPOINT_TYPE, STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; +import { LoggerService } from '../logger.service'; import { CurrentUserPermissions, PermissionConfig, @@ -18,12 +16,15 @@ import { PermissionConfigType, PermissionTypes, } from './current-user-permissions.config'; -import { LoggerService } from './logger.service'; +import { + BaseCurrentUserPermissionsChecker, + IConfigGroup, + IConfigGroups, + ICurrentUserPermissionsChecker, + IPermissionCheckCombiner, + StratosUserPermissionsChecker, +} from './stratos-user-permissions.checker'; -interface ICheckCombiner { - checks: Observable[]; - combineType?: '&&'; -} export const CUSTOM_USER_PERMISSION_CHECKERS = 'custom_user_perm_checkers' @@ -32,7 +33,7 @@ export class CurrentUserPermissionsService { // private checker: StratosUserPermissionsChecker; private allCheckers: ICurrentUserPermissionsChecker[]; constructor( - store: Store, + private store: Store, @Inject(CUSTOM_USER_PERMISSION_CHECKERS) customCheckers: ICurrentUserPermissionsChecker[], private logger: LoggerService ) { @@ -80,7 +81,13 @@ export class CurrentUserPermissionsService { } else if (actionConfig) { return this.getSimplePermission(actionConfig, endpointGuid, ...args); } else if (endpointGuid) { - return this.getFallbackPermission(endpointGuid); + const key = entityCatalog.getEntityKey(STRATOS_ENDPOINT_TYPE, ENDPOINT_TYPE); + return this.store.select(selectEntity(key, endpointGuid)).pipe( + switchMap(endpoint => endpoint ? + this.getFallbackPermission(endpointGuid, endpoint.cnsi_type) : + of(false) + ) + ); } return null; } @@ -124,39 +131,15 @@ export class CurrentUserPermissionsService { permission: PermissionTypes, endpointGuid: string, ...args: any[] - ): ICheckCombiner { - return this.findChecker( - (checker: ICurrentUserPermissionsChecker) => checker.getCheckFromConfig(configGroup, permission, endpointGuid, ...args), + ): IPermissionCheckCombiner { + return this.findChecker( + (checker: ICurrentUserPermissionsChecker) => checker.getComplexCheck(configGroup, permission, endpointGuid, ...args), 'permissions check', permission, { checks: [of(false)] } ) - - // switch (permission) { - // case PermissionTypes.ENDPOINT: - // return { - // checks: this.checker.getInternalScopesChecks(configGroup), - // }; - // case PermissionTypes.ENDPOINT_SCOPE: - // return { - // checks: this.checker.getEndpointScopesChecks(configGroup, endpointGuid), - // }; - // case PermissionTypes.STRATOS_SCOPE: - // return { - // checks: this.checker.getInternalScopesChecks(configGroup), - // }; - // case PermissionTypes.FEATURE_FLAG: - // return { - // checks: this.checker.getFeatureFlagChecks(configGroup, endpointGuid), - // combineType: '&&' - // }; - // case CHECKER_GROUPS.CF_GROUP: //PermissionTypes.ORGANIZATION || config.type === PermissionTypes.SPACE - // return { - // checks: this.checker.getCfChecks(configGroup, endpointGuid, orgOrSpaceGuid, spaceGuid) - // }; - // } } private getConfig(config: PermissionConfigType, tries = 0): PermissionConfig[] | PermissionConfig { @@ -178,7 +161,7 @@ export class CurrentUserPermissionsService { } private combineChecks( - checkCombiners: ICheckCombiner[], + checkCombiners: IPermissionCheckCombiner[], ) { const reducedChecks = checkCombiners.map(combiner => BaseCurrentUserPermissionsChecker.reduceChecks(combiner.checks, combiner.combineType)); return combineLatest(reducedChecks).pipe( @@ -186,9 +169,9 @@ export class CurrentUserPermissionsService { ); } - private getFallbackPermission(endpointGuid: string): Observable { + private getFallbackPermission(endpointGuid: string, endpointType: string): Observable { return this.findChecker>( - (checker: ICurrentUserPermissionsChecker) => checker.getFallbackPermission(endpointGuid), + (checker: ICurrentUserPermissionsChecker) => checker.getFallbackCheck(endpointGuid, endpointType), 'fallback permission', 'N/A', of(null) diff --git a/src/frontend/packages/core/src/core/current-user-permissions.checker.ts b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts similarity index 78% rename from src/frontend/packages/core/src/core/current-user-permissions.checker.ts rename to src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts index 2a203d4b5c..54956509e5 100644 --- a/src/frontend/packages/core/src/core/current-user-permissions.checker.ts +++ b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts @@ -2,11 +2,11 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { distinctUntilChanged, map } from 'rxjs/operators'; -import { GeneralEntityAppState } from '../../../store/src/app-state'; +import { GeneralEntityAppState } from '../../../../store/src/app-state'; import { getCurrentUserStratosHasScope, getCurrentUserStratosRole, -} from '../../../store/src/selectors/current-user-role.selectors'; +} from '../../../../store/src/selectors/current-user-role.selectors'; import { IPermissionConfigs, PermissionConfig, @@ -22,30 +22,46 @@ export interface IConfigGroups { export type IConfigGroup = PermissionConfig[]; -// TODO: RC name -export interface ICheckCombiner { +export type IPermissionCheckCombineTypes = '||' | '&&'; + +export interface IPermissionCheckCombiner { checks: Observable[]; - combineType?: '&&'; + combineType?: IPermissionCheckCombineTypes; } export interface ICurrentUserPermissionsChecker { - // TODO: RC comments + /** + * For the given permission action find the checker configuration that will determine if the user can or cannot do the action + * If this is not supported by the the checker null is returned. If another checker also lays claim to the same string the check will + * always return denied + */ getPermissionConfig: (action: string) => PermissionConfigType + /** + * Simple checks are used when the permission config contains a single thing to check + */ getSimpleCheck: ( permissionConfig: PermissionConfig, endpointGuid?: string, ...args: any ) => Observable; - getCheckFromConfig: ( + /** + * Used when the permission config contains multiple things to check + */ + getComplexCheck: ( configGroup: IConfigGroup, permission: PermissionTypes, ...args: any[] - ) => ICheckCombiner; - getFallbackPermission: ( - endpointGuid: string + ) => IPermissionCheckCombiner; + /** + * If no checker provides simple + */ + getFallbackCheck: ( + endpointGuid: string, + endpointType: string ) => Observable; } + export abstract class BaseCurrentUserPermissionsChecker { - public static reduceChecks(checks: Observable[], type: '||' | '&&' = '||') { + public static reduceChecks(checks: Observable[], type: IPermissionCheckCombineTypes = '||') { const func = type === '||' ? 'some' : 'every'; if (!checks || !checks.length) { return observableOf(true); @@ -62,9 +78,8 @@ export enum StratosCurrentUserPermissions { PASSWORD_CHANGE = 'change-password', } -// TODO: RC filename export enum StratosPermissionStrings { - _GLOBAL_ = 'global', // TODO: RC + _GLOBAL_ = 'global', STRATOS_ADMIN = 'isAdmin' } @@ -137,11 +152,11 @@ export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChe return this.check(StratosPermissionTypes.STRATOS_SCOPE, permission); } - public getCheckFromConfig( + public getComplexCheck( configGroup: IConfigGroup, permission: PermissionTypes, ...args: any[] - ): ICheckCombiner { + ): IPermissionCheckCombiner { switch (permission) { case StratosPermissionTypes.STRATOS_SCOPE: return { @@ -149,7 +164,7 @@ export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChe }; } } - public getFallbackPermission(endpointGuid: string): Observable { + public getFallbackCheck(endpointGuid: string, endpointType: string): Observable { return null; }; diff --git a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts index 3e7c65a533..7992db8c39 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts @@ -18,7 +18,6 @@ import { delay, first, map, tap } from 'rxjs/operators'; import { RouterNav } from '../../../../../store/src/actions/router.actions'; import { EndpointOnlyAppState } from '../../../../../store/src/app-state'; import { selectDashboardState } from '../../../../../store/src/selectors/dashboard.selectors'; -import { StratosCurrentUserPermissions } from '../../../core/current-user-permissions.checker'; import { CustomizationService, CustomizationsMetadata } from '../../../core/customizations.types'; import { EndpointsService } from '../../../core/endpoints.service'; import { @@ -26,6 +25,7 @@ import { StratosActionMetadata, StratosActionType, } from '../../../core/extension/extension-service'; +import { StratosCurrentUserPermissions } from '../../../core/permissions/stratos-user-permissions.checker'; import { safeUnsubscribe } from '../../../core/utils.service'; import { EndpointListHelper } from '../../../shared/components/list/list-types/endpoint/endpoint-list.helpers'; import { diff --git a/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.ts b/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.ts index 78092a04b6..54194241ee 100644 --- a/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.ts +++ b/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.ts @@ -5,8 +5,8 @@ import { Subscription } from 'rxjs'; import { first, map, take, tap } from 'rxjs/operators'; import { UserProfileInfo, UserProfileInfoUpdates } from '../../../../../store/src/types/user-profile.types'; -import { StratosCurrentUserPermissions } from '../../../core/current-user-permissions.checker'; -import { CurrentUserPermissionsService } from '../../../core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; +import { StratosCurrentUserPermissions } from '../../../core/permissions/stratos-user-permissions.checker'; import { UserProfileService } from '../../../core/user-profile.service'; import { StepOnNextFunction } from '../../../shared/components/stepper/step/step.component'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts index d6d8aeb6f3..5582e7daf7 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts @@ -9,7 +9,7 @@ import { ViewContainerRef, } from '@angular/core'; import { Store } from '@ngrx/store'; -import { CurrentUserPermissionsService } from 'frontend/packages/core/src/core/current-user-permissions.service'; +import { CurrentUserPermissionsService } from 'frontend/packages/core/src/core/permissions/current-user-permissions.service'; import { AppState } from 'frontend/packages/store/src/app-state'; import { Observable, of, ReplaySubject, Subscription } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; @@ -20,7 +20,7 @@ import { } from '../../../../../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types'; -import { StratosCurrentUserPermissions } from '../../../../../../core/current-user-permissions.checker'; +import { StratosCurrentUserPermissions } from '../../../../../../core/permissions/stratos-user-permissions.checker'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; import { coreEndpointListDetailsComponents, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts index f6134fa41d..04c40287d9 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts @@ -14,9 +14,9 @@ import { endpointSchemaKey } from '../../../../../../../store/src/helpers/entity import { selectDeletionInfo, selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors'; import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; import { STRATOS_ENDPOINT_TYPE } from '../../../../../base-entity-schemas'; -import { StratosCurrentUserPermissions } from '../../../../../core/current-user-permissions.checker'; -import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; import { LoggerService } from '../../../../../core/logger.service'; +import { CurrentUserPermissionsService } from '../../../../../core/permissions/current-user-permissions.service'; +import { StratosCurrentUserPermissions } from '../../../../../core/permissions/stratos-user-permissions.checker'; import { ConnectEndpointDialogComponent, } from '../../../../../features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component'; diff --git a/src/frontend/packages/core/src/shared/user-permission.directive.ts b/src/frontend/packages/core/src/shared/user-permission.directive.ts index 13cb71db8c..7b633408fb 100644 --- a/src/frontend/packages/core/src/shared/user-permission.directive.ts +++ b/src/frontend/packages/core/src/shared/user-permission.directive.ts @@ -1,8 +1,8 @@ import { Directive, Input, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { Subscription } from 'rxjs'; -import { PermissionTypes } from '../core/current-user-permissions.config'; -import { CurrentUserPermissionsService } from '../core/current-user-permissions.service'; +import { PermissionTypes } from '../core/permissions/current-user-permissions.config'; +import { CurrentUserPermissionsService } from '../core/permissions/current-user-permissions.service'; @Directive({ selector: '[appUserPermission]' diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts index 66bb0bd211..c6371e3e17 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts @@ -209,15 +209,14 @@ class EntityCatalog { let oneChanged = false; endpoints.forEach(endpoint => { if (endpoint.definition.userRolesReducer) { - // TODO: RC does this churn? - const newState = endpoint.definition.userRolesReducer(state.endpoints[endpoint.type], action); - oneChanged = oneChanged || !!newState; - if (!!newState) { + const endpointState = endpoint.definition.userRolesReducer(state.endpoints[endpoint.type], action); + oneChanged = oneChanged || !!endpointState; + if (!!endpointState) { state = { ...state, endpoints: { ...state.endpoints, - [endpoint.type]: newState + [endpoint.type]: endpointState } } } diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index 34a20a037a..7205f8ff23 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -129,8 +129,14 @@ export interface IStratosEndpointDefinition( entity: any, entityKey: string, favoritesConfigMapper: FavoritesConfigMapper ) => UserFavorite; - readonly userRolesFetch?: EntityUserRolesFetch // TODO: RC Comment - readonly userRolesReducer?: EntityUserRolesReducer // TODO: RC Comment + /** + * Allows the endpoint to fetch user roles, for example when the user loads Stratos or connects an endpoint of this type + */ + readonly userRolesFetch?: EntityUserRolesFetch + /** + * Allows the user roles to be stored, updated and removed in the current user permissions section of the store + */ + readonly userRolesReducer?: EntityUserRolesReducer } export interface StratosEndpointExtensionDefinition extends Omit { } diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.spec.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.spec.ts index 57018352db..7170050ed3 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.spec.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.spec.ts @@ -1,17 +1,21 @@ import { - GetCurrentUserRelationsComplete, - UserRelationTypes, + CfUserRelationTypes, + GetCurrentCfUserRelationsComplete, } from '../../../../cloud-foundry/src/actions/permissions.actions'; import { createOrgRoleStateState, -} from '../../../../cloud-foundry/src/store/reducers/current-user-roles-reducer/current-user-roles-org.reducer'; +} from '../../../../cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-user-roles-org.reducer'; import { ICfRolesState, IOrgRoleState, ISpaceRoleState, RoleEntities, } from '../../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; -import { getDefaultEndpointRoles, ICurrentUserRolesState, getDefaultRolesRequestState } from '../../types/current-user-roles.types'; +import { + getDefaultEndpointRoles, + getDefaultRolesRequestState, + ICurrentUserRolesState, +} from '../../types/current-user-roles.types'; import { currentUserRolesReducer } from './current-user-roles.reducer'; const testOrgGuid = 'org-1'; @@ -19,16 +23,16 @@ const testSpaceGuid = 'space-1'; const generalGuid = 'guid-123'; const testCFEndpointGuid = 'cf-1'; -function getSpaceAction(type: UserRelationTypes, orgGuid: string = testOrgGuid, spaceGuid: string = testSpaceGuid) { - return new GetCurrentUserRelationsComplete( +function getSpaceAction(type: CfUserRelationTypes, orgGuid: string = testOrgGuid, spaceGuid: string = testSpaceGuid) { + return new GetCurrentCfUserRelationsComplete( type, testCFEndpointGuid, [{ metadata: { guid: spaceGuid, created_at: '1', updated_at: '1', url: '1' }, entity: { organization_guid: orgGuid } }] ); } -function getOrgAction(type: UserRelationTypes, orgGuid: string = testOrgGuid) { - return new GetCurrentUserRelationsComplete( +function getOrgAction(type: CfUserRelationTypes, orgGuid: string = testOrgGuid) { + return new GetCurrentCfUserRelationsComplete( type, testCFEndpointGuid, [{ metadata: { guid: orgGuid, created_at: '1', updated_at: '1', url: '1' }, entity: {} }] @@ -82,7 +86,7 @@ describe('currentUserReducer', () => { expect(state).toEqual(expectedState); }); it('should add org manager role to org', () => { - const state = currentUserRolesReducer(undefined, getOrgAction(UserRelationTypes.MANAGED_ORGANIZATION)); + const state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.MANAGED_ORGANIZATION)); const cfPermissions = state.cf[testCFEndpointGuid]; expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { isManager: true, @@ -93,7 +97,7 @@ describe('currentUserReducer', () => { })); }); it('should add org auditor role to org', () => { - const state = currentUserRolesReducer(undefined, getOrgAction(UserRelationTypes.AUDITED_ORGANIZATIONS)); + const state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS)); const cfPermissions = state.cf[testCFEndpointGuid]; expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { isManager: false, @@ -104,7 +108,7 @@ describe('currentUserReducer', () => { })); }); it('should add org billing manager role to org', () => { - const state = currentUserRolesReducer(undefined, getOrgAction(UserRelationTypes.BILLING_MANAGED_ORGANIZATION)); + const state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.BILLING_MANAGED_ORGANIZATION)); const cfPermissions = state.cf[testCFEndpointGuid]; expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { isManager: false, @@ -115,7 +119,7 @@ describe('currentUserReducer', () => { })); }); it('should add org user role to org', () => { - const state = currentUserRolesReducer(undefined, getOrgAction(UserRelationTypes.ORGANIZATIONS)); + const state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); const cfPermissions = state.cf[testCFEndpointGuid]; expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { isManager: false, @@ -127,8 +131,8 @@ describe('currentUserReducer', () => { }); it('should retain other org roles', () => { - let state = currentUserRolesReducer(undefined, getOrgAction(UserRelationTypes.ORGANIZATIONS)); - state = currentUserRolesReducer(state, getOrgAction(UserRelationTypes.AUDITED_ORGANIZATIONS, generalGuid)); + let state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); + state = currentUserRolesReducer(state, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS, generalGuid)); const cfPermissions = state.cf[testCFEndpointGuid]; const toEqual = getState(RoleEntities.ORGS, [{ guid: testOrgGuid, @@ -154,8 +158,8 @@ describe('currentUserReducer', () => { }); it('should retain other space roles', () => { - let state = currentUserRolesReducer(undefined, getSpaceAction(UserRelationTypes.SPACES)); - state = currentUserRolesReducer(state, getSpaceAction(UserRelationTypes.MANAGED_SPACES, generalGuid, generalGuid)); + let state = currentUserRolesReducer(undefined, getSpaceAction(CfUserRelationTypes.SPACES)); + state = currentUserRolesReducer(state, getSpaceAction(CfUserRelationTypes.MANAGED_SPACES, generalGuid, generalGuid)); const cfPermissions = state.cf[testCFEndpointGuid]; const toEqual = getState(RoleEntities.SPACES, [{ guid: testSpaceGuid, @@ -204,10 +208,10 @@ describe('currentUserReducer', () => { }); it('should retain other space and org roles', () => { - let state = currentUserRolesReducer(undefined, getSpaceAction(UserRelationTypes.SPACES)); - state = currentUserRolesReducer(state, getSpaceAction(UserRelationTypes.MANAGED_SPACES, generalGuid, generalGuid)); - state = currentUserRolesReducer(state, getOrgAction(UserRelationTypes.ORGANIZATIONS)); - state = currentUserRolesReducer(state, getOrgAction(UserRelationTypes.AUDITED_ORGANIZATIONS, generalGuid)); + let state = currentUserRolesReducer(undefined, getSpaceAction(CfUserRelationTypes.SPACES)); + state = currentUserRolesReducer(state, getSpaceAction(CfUserRelationTypes.MANAGED_SPACES, generalGuid, generalGuid)); + state = currentUserRolesReducer(state, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); + state = currentUserRolesReducer(state, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS, generalGuid)); const cfPermissions = state.cf[testCFEndpointGuid]; diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts index bbafbbb2a0..c75ebfbc4e 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts @@ -25,8 +25,6 @@ const getDefaultState = () => ({ export function currentUserRolesReducer(state: ICurrentUserRolesState = getDefaultState(), action: Action): ICurrentUserRolesState { const stateAfterStratosChanges = coreCurrentUserRolesReducer(state, action); - // TODO: RC Comment. can cause issues if plugins have same action type names. Should use same method as - // requestData in entity-catalog.module return entityCatalog.getAllCurrentUserReducers(stateAfterStratosChanges, action); } diff --git a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts index a5f6c359d4..d6d9338eba 100644 --- a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts +++ b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts @@ -1,7 +1,7 @@ import { compose } from '@ngrx/store'; -import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; -import { PermissionValues, ScopeStrings } from '../../../core/src/core/current-user-permissions.config'; +import { PermissionValues, ScopeStrings } from '../../../core/src/core/permissions/current-user-permissions.config'; +import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; import { CurrentUserRolesAppState } from '../app-state'; import { ICurrentUserRolesState, IStratosRolesState } from '../types/current-user-roles.types'; @@ -15,9 +15,6 @@ const selectCurrentUserStratosRoles = (role: PermissionValues) => (state: Omit (scopes: ScopeStrings[]) => scopes.includes(scope); const selectCurrentUserStratosScopesState = (state: IStratosRolesState) => state.scopes; @@ -42,17 +39,8 @@ export const getCurrentUserStratosRole = (role: PermissionValues) => compose( // ============================ export const getCurrentUserStratosHasScope = (scope: StratosScopeStrings) => compose( selectCurrentUserGlobalHasScopes(scope), - selectCurrentUserStratosScopesState, // TODO: RC cf stuff shouldn't be + selectCurrentUserStratosScopesState, getCurrentUserStratosRolesState ); // ============================ - -// Top level request state -// ============================ -// export const getCurrentUserRequestState = compose( -// selectCurrentUserRequestState, -// selectCurrentUserRolesState -// ); -// ============================ - diff --git a/src/frontend/packages/store/src/types/auth.types.ts b/src/frontend/packages/store/src/types/auth.types.ts index 9800f2eb91..82dd621ca6 100644 --- a/src/frontend/packages/store/src/types/auth.types.ts +++ b/src/frontend/packages/store/src/types/auth.types.ts @@ -1,4 +1,4 @@ -import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; +import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; export interface SessionDataEndpoint { guid: string; @@ -11,7 +11,7 @@ export interface SessionUser { admin: boolean; guid: string; name: string; - scopes: StratosScopeStrings[]; // TODO: RC check + scopes: StratosScopeStrings[]; // TODO: RC test } export interface PluginConfig { userInvitationsEnabled: 'true' | 'false'; diff --git a/src/frontend/packages/store/src/types/current-user-roles.types.ts b/src/frontend/packages/store/src/types/current-user-roles.types.ts index efdfedda08..f283b3d6d1 100644 --- a/src/frontend/packages/store/src/types/current-user-roles.types.ts +++ b/src/frontend/packages/store/src/types/current-user-roles.types.ts @@ -1,4 +1,4 @@ -import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; +import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; export interface RolesRequestState { initialised: boolean; diff --git a/src/frontend/packages/store/src/types/endpoint.types.ts b/src/frontend/packages/store/src/types/endpoint.types.ts index eb0f6a175b..011bde28dc 100644 --- a/src/frontend/packages/store/src/types/endpoint.types.ts +++ b/src/frontend/packages/store/src/types/endpoint.types.ts @@ -1,5 +1,5 @@ -import { StratosScopeStrings } from '../../../core/src/core/current-user-permissions.checker'; import { EndpointType } from '../../../core/src/core/extension/extension-types'; +import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; import { MetricsAPITargets, MetricsStratosInfo } from '../actions/metrics-api.actions'; import { endpointSchemaKey } from '../helpers/entity-factory'; import { RequestSectionKeys, TRequestTypeKeys } from '../reducers/api-request-reducer/types'; @@ -68,7 +68,7 @@ export interface EndpointUser { guid: string; name: string; admin: boolean; - scopes?: StratosScopeStrings[]; // TODO: RC + scopes?: StratosScopeStrings[]; } export interface EndpointState { diff --git a/src/test-e2e/cloud-foundry/manage-users-by-username-stepper-e2e.spec.ts b/src/test-e2e/cloud-foundry/manage-users-by-username-stepper-e2e.spec.ts index 3cbd402994..f72a3d3422 100644 --- a/src/test-e2e/cloud-foundry/manage-users-by-username-stepper-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/manage-users-by-username-stepper-e2e.spec.ts @@ -1,6 +1,6 @@ import { browser, by, element, promise } from 'protractor'; -import { CfUser } from '../../frontend/packages/cloud-foundry/src/store/types/user.types'; +import { CfUser } from '../../frontend/packages/cloud-foundry/src/store/types/cf-user.types'; import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { e2e } from '../e2e'; import { CFHelpers } from '../helpers/cf-helpers'; diff --git a/src/test-e2e/cloud-foundry/users-removal-e2e.helper.ts b/src/test-e2e/cloud-foundry/users-removal-e2e.helper.ts index 931679b0a4..a449dddd5f 100644 --- a/src/test-e2e/cloud-foundry/users-removal-e2e.helper.ts +++ b/src/test-e2e/cloud-foundry/users-removal-e2e.helper.ts @@ -1,7 +1,7 @@ import { browser, by, element, promise } from 'protractor'; import { protractor } from 'protractor/built/ptor'; -import { CfUser } from '../../frontend/packages/cloud-foundry/src/store/types/user.types'; +import { CfUser } from '../../frontend/packages/cloud-foundry/src/store/types/cf-user.types'; import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { e2e } from '../e2e'; import { CFHelpers } from '../helpers/cf-helpers'; diff --git a/src/test-e2e/helpers/cf-helpers.ts b/src/test-e2e/helpers/cf-helpers.ts index 69b074e4ce..cdf8d3d63b 100644 --- a/src/test-e2e/helpers/cf-helpers.ts +++ b/src/test-e2e/helpers/cf-helpers.ts @@ -10,7 +10,7 @@ import { ISpaceQuotaDefinition, } from '../../frontend/packages/cloud-foundry/src/cf-api.types'; import { CFResponse } from '../../frontend/packages/cloud-foundry/src/store/types/cf-api.types'; -import { CfUser } from '../../frontend/packages/cloud-foundry/src/store/types/user.types'; +import { CfUser } from '../../frontend/packages/cloud-foundry/src/store/types/cf-user.types'; import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { ApplicationPageSummaryTab } from '../application/po/application-page-summary.po'; import { CfTopLevelPage } from '../cloud-foundry/cf-level/cf-top-level-page.po'; From 5f12456167bc7691a57a207bd917ea9e3d0e6562 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 27 May 2020 15:05:16 +0100 Subject: [PATCH 06/82] Minor fixes --- .../cf-services-list-config.service.ts | 2 +- .../cf-org-space-service.service.ts | 2 +- .../store/selectors/cloud-foundry.selector.ts | 5 ++++- .../user-permissions/cf-user-roles-fetch.ts | 2 +- .../store/src/selectors/endpoint.selectors.ts | 19 ++----------------- 5 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-services-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-services-list-config.service.ts index b8c4e53ff4..954c2562d0 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-services-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-services-list-config.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { endpointsCfEntitiesConnectedSelector } from 'frontend/packages/store/src/selectors/endpoint.selectors'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { filter, first, map } from 'rxjs/operators'; @@ -15,6 +14,7 @@ import { ListView } from '../../../../../../../store/src/actions/list.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { ActiveRouteCfOrgSpace } from '../../../../../features/cloud-foundry/cf-page.types'; import { haveMultiConnectedCfs } from '../../../../../features/cloud-foundry/cf.helpers'; +import { endpointsCfEntitiesConnectedSelector } from '../../../../../store/selectors/cloud-foundry.selector'; import { CfOrgSpaceItem, createCfOrgSpaceFilterConfig } from '../../../../data-services/cf-org-space-service.service'; import { CfServiceCardComponent } from './cf-service-card/cf-service-card.component'; import { CfServicesDataSource } from './cf-services-data-source'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-org-space-service.service.ts b/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-org-space-service.service.ts index 75489373b1..8a8951d87c 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-org-space-service.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-org-space-service.service.ts @@ -1,6 +1,5 @@ import { Injectable, OnDestroy } from '@angular/core'; import { Store } from '@ngrx/store'; -import { endpointsCfEntitiesConnectedSelector } from 'frontend/packages/store/src/selectors/endpoint.selectors'; import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; import { distinctUntilChanged, @@ -35,6 +34,7 @@ import { PaginatedAction, PaginationParam } from '../../../../store/src/types/pa import { IOrganization, ISpace } from '../../cf-api.types'; import { cfEntityCatalog } from '../../cf-entity-catalog'; import { cfEntityFactory } from '../../cf-entity-factory'; +import { endpointsCfEntitiesConnectedSelector } from '../../store/selectors/cloud-foundry.selector'; import { QParam, QParamJoiners } from '../q-param'; export function spreadPaginationParams(params: PaginationParam): PaginationParam { diff --git a/src/frontend/packages/cloud-foundry/src/store/selectors/cloud-foundry.selector.ts b/src/frontend/packages/cloud-foundry/src/store/selectors/cloud-foundry.selector.ts index 61e11d3b7c..3df60ec938 100644 --- a/src/frontend/packages/cloud-foundry/src/store/selectors/cloud-foundry.selector.ts +++ b/src/frontend/packages/cloud-foundry/src/store/selectors/cloud-foundry.selector.ts @@ -1 +1,4 @@ -// export const getInfoGuid = compose(getMetadataGuid, getAPIResourceMetadata); +import { connectedEndpointsOfTypesSelector } from '../../../../store/src/selectors/endpoint.selectors'; +import { CF_ENDPOINT_TYPE } from '../../cf-types'; + +export const endpointsCfEntitiesConnectedSelector = connectedEndpointsOfTypesSelector(CF_ENDPOINT_TYPE); diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts index c066907ffc..a38da02657 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts @@ -13,7 +13,6 @@ import { PaginationFlattener, } from '../../../store/src/helpers/paginated-request-helpers'; import { ActionState } from '../../../store/src/reducers/api-request-reducer/types'; -import { endpointsCfEntitiesConnectedSelector } from '../../../store/src/selectors/endpoint.selectors'; import { selectPaginationState } from '../../../store/src/selectors/pagination.selectors'; import { EndpointModel } from '../../../store/src/types/endpoint.types'; import { BasePaginatedAction, PaginationEntityState } from '../../../store/src/types/pagination.types'; @@ -27,6 +26,7 @@ import { GetCurrentCfUserRelationsComplete, } from '../actions/permissions.actions'; import { cfEntityCatalog } from '../cf-entity-catalog'; +import { endpointsCfEntitiesConnectedSelector } from '../store/selectors/cloud-foundry.selector'; import { CFResponse } from '../store/types/cf-api.types'; export const cfUserRolesFetch: EntityUserRolesFetch = ( diff --git a/src/frontend/packages/store/src/selectors/endpoint.selectors.ts b/src/frontend/packages/store/src/selectors/endpoint.selectors.ts index 0400350b59..2846302148 100644 --- a/src/frontend/packages/store/src/selectors/endpoint.selectors.ts +++ b/src/frontend/packages/store/src/selectors/endpoint.selectors.ts @@ -1,4 +1,4 @@ -import { compose, createSelector } from '@ngrx/store'; +import { compose } from '@ngrx/store'; import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; import { InternalAppState, IRequestEntityTypeState } from '../app-state'; @@ -15,7 +15,7 @@ export const endpointStatusSelector = (state: InternalAppState): EndpointState = const endpointEntityKey = EntityCatalogHelpers.buildEntityKey(endpointSchemaKey, STRATOS_ENDPOINT_TYPE); export const endpointEntitiesSelector = selectEntities(endpointEntityKey); -const endpointOfType = (type: string) => +export const endpointOfType = (type: string) => (endpoints: IRequestEntityTypeState): IRequestEntityTypeState => { return Object.values(endpoints || {}).reduce((endpointsOfType, endpoint) => { if (endpoint.cnsi_type === type) { @@ -30,8 +30,6 @@ export const endpointOfTypeSelector = (endpointType: string) => compose( endpointEntitiesSelector, ); -// TODO: Move this #3769 -const cfEndpointEntitiesSelector = endpointOfType('cf'); const getConnectedEndpoints = (endpoints: IRequestEntityTypeState) => Object.values(endpoints || {}).reduce((connected, endpoint) => { @@ -55,19 +53,6 @@ export const connectedEndpointsOfTypesSelector = (endpointType: string) => compo ); -// TODO: Move this #3769 -export const endpointsCFEntitiesSelector = createSelector( - endpointEntitiesSelector, - cfEndpointEntitiesSelector -); - -// const log = (label) => { -// return (val) => console.log(label, val); -// }; - -// TODO: Move this #3769 -export const endpointsCfEntitiesConnectedSelector = connectedEndpointsOfTypesSelector('cf'); - // Single endpoint request information export const endpointsEntityRequestSelector = (guid: string) => selectRequestInfo(endpointEntityKey, guid); // Single endpoint request data From 62248fc648500249743ee842cf17cf8d55253700 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 27 May 2020 16:57:08 +0100 Subject: [PATCH 07/82] Fix unit tests --- .../src/cloud-foundry-test.module.ts | 11 +- .../application-wall.component.spec.ts | 4 +- .../cli-info-cloud-foundry.component.spec.ts | 8 +- ...ndry-organization-spaces.component.spec.ts | 6 +- ...ud-foundry-space-summary.component.spec.ts | 11 +- ...dry-organization-summary.component.spec.ts | 4 +- .../service-tabs-base.component.spec.ts | 6 +- .../services-wall.component.spec.ts | 4 +- .../cf-user-permission.directive.spec.ts | 3 +- .../current-user-permissions.service.spec.ts | 1065 ++++++++++++++++ .../current-cf-user-roles.reducer.spec.ts | 249 ++++ .../current-user-permissions.service.spec.ts | 1111 ++++------------- .../current-user-roles.reducer.spec.ts | 253 +--- .../selectors/current-user-role.selectors.ts | 5 +- .../src/types/current-user-roles.types.ts | 4 +- .../store/src/types/endpoint.types.ts | 4 +- .../store/testing/src/store-test-helper.ts | 6 +- 17 files changed, 1641 insertions(+), 1113 deletions(-) create mode 100644 src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts create mode 100644 src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.spec.ts diff --git a/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts b/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts index ae56fa584e..11769b81a4 100644 --- a/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts +++ b/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts @@ -8,7 +8,11 @@ import { getGitHubAPIURL, GITHUB_API_URL } from '../../core/src/core/github.help import { LoggerService } from '../../core/src/core/logger.service'; import { CATALOGUE_ENTITIES, EntityCatalogFeatureModule } from '../../store/src/entity-catalog.module'; import { entityCatalog, TestEntityCatalog } from '../../store/src/entity-catalog/entity-catalog'; +import { testSCFEndpointGuid } from '../../store/testing/public-api'; +import { BaseCfOrgSpaceRouteMock } from '../test-framework/cloud-foundry-endpoint-service.helper'; import { generateCFEntities } from './cf-entity-generator'; +import { ActiveRouteCfOrgSpace } from './features/cloud-foundry/cf-page.types'; +import { CfUserService } from './shared/data-services/cf-user.service'; import { LongRunningCfOperationsService } from './shared/data-services/long-running-cf-op.service'; import { GitSCMService } from './shared/data-services/scm/scm.service'; import { CloudFoundryStoreModule } from './store/cloud-foundry.store.module'; @@ -39,7 +43,12 @@ import { CloudFoundryStoreModule } from './store/cloud-foundry.store.module'; { provide: GITHUB_API_URL, useFactory: getGitHubAPIURL }, GitSCMService, LoggerService, - LongRunningCfOperationsService + LongRunningCfOperationsService, + CfUserService, + { + provide: ActiveRouteCfOrgSpace, + useFactory: () => new BaseCfOrgSpaceRouteMock(testSCFEndpointGuid) + } ] }) export class CloudFoundryTestingModule { } diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.spec.ts index bc8d31cb10..e92a929b87 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application-wall/application-wall.component.spec.ts @@ -5,6 +5,7 @@ import { TabNavService } from '../../../../../core/tab-nav.service'; import { generateCfBaseTestModules } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; import { CfEndpointsMissingComponent } from '../../../shared/components/cf-endpoints-missing/cf-endpoints-missing.component'; import { CloudFoundryService } from '../../../shared/data-services/cloud-foundry.service'; +import { CfUserPermissionDirective } from '../../../shared/directives/cf-user-permission/cf-user-permission.directive'; import { ApplicationWallComponent } from './application-wall.component'; describe('ApplicationWallComponent', () => { @@ -15,7 +16,8 @@ describe('ApplicationWallComponent', () => { TestBed.configureTestingModule({ declarations: [ ApplicationWallComponent, - CfEndpointsMissingComponent + CfEndpointsMissingComponent, + CfUserPermissionDirective ], imports: generateCfBaseTestModules(), providers: [ diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.spec.ts index 2ab8872fb0..197bf2ee0b 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.spec.ts @@ -7,6 +7,7 @@ import { } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; import { CliCommandComponent } from '../../../shared/components/cli-info/cli-command/cli-command.component'; import { CliInfoComponent } from '../../../shared/components/cli-info/cli-info.component'; +import { CfUserPermissionDirective } from '../../../shared/directives/cf-user-permission/cf-user-permission.directive'; import { ApplicationStateService } from '../../../shared/services/application-state.service'; import { CloudFoundryUserProvidedServicesService, @@ -21,7 +22,12 @@ describe('CliInfoCloudFoundryComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [CliInfoCloudFoundryComponent, CliInfoComponent, CliCommandComponent], + declarations: [ + CliInfoCloudFoundryComponent, + CliInfoComponent, + CliCommandComponent, + CfUserPermissionDirective + ], imports: generateCfBaseTestModules(), providers: [ CloudFoundryEndpointService, diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.spec.ts index b7ab24ec95..47b0e37828 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-organization-spaces.component.spec.ts @@ -8,6 +8,7 @@ import { import { CloudFoundryOrganizationServiceMock, } from '../../../../../../test-framework/cloud-foundry-organization.service.mock'; +import { CfUserPermissionDirective } from '../../../../../shared/directives/cf-user-permission/cf-user-permission.directive'; import { CloudFoundryOrganizationService } from '../../../services/cloud-foundry-organization.service'; import { CloudFoundryOrganizationSpacesComponent } from './cloud-foundry-organization-spaces.component'; @@ -17,7 +18,10 @@ describe('CloudFoundryOrganizationSpacesComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [CloudFoundryOrganizationSpacesComponent], + declarations: [ + CloudFoundryOrganizationSpacesComponent, + CfUserPermissionDirective + ], imports: generateCfBaseTestModules(), providers: [ ...generateTestCfEndpointServiceProvider(), diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-summary/cloud-foundry-space-summary.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-summary/cloud-foundry-space-summary.component.spec.ts index 7153674c1d..e6e27e1e5b 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-summary/cloud-foundry-space-summary.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/tabs/cloud-foundry-space-summary/cloud-foundry-space-summary.component.spec.ts @@ -16,6 +16,9 @@ import { CardCfSpaceDetailsComponent, } from '../../../../../../../shared/components/cards/card-cf-space-details/card-cf-space-details.component'; import { CfUserService } from '../../../../../../../shared/data-services/cf-user.service'; +import { + CfUserPermissionDirective, +} from '../../../../../../../shared/directives/cf-user-permission/cf-user-permission.directive'; import { CloudFoundryUserProvidedServicesService, } from '../../../../../../../shared/services/cloud-foundry-user-provided-services.service'; @@ -30,7 +33,13 @@ describe('CloudFoundrySpaceSummaryComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [CloudFoundrySpaceSummaryComponent, CardCfSpaceDetailsComponent, CardCfRecentAppsComponent, CompactAppCardComponent], + declarations: [ + CloudFoundrySpaceSummaryComponent, + CardCfSpaceDetailsComponent, + CardCfRecentAppsComponent, + CompactAppCardComponent, + CfUserPermissionDirective + ], imports: generateCfBaseTestModules(), providers: [ generateActiveRouteCfOrgSpaceMock(), diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.spec.ts index 86b4a72c57..933c783b42 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.spec.ts @@ -17,6 +17,7 @@ import { import { CompactAppCardComponent, } from '../../../../../shared/components/cards/card-cf-recent-apps/compact-app-card/compact-app-card.component'; +import { CfUserPermissionDirective } from '../../../../../shared/directives/cf-user-permission/cf-user-permission.directive'; import { CloudFoundryOrganizationService } from '../../../services/cloud-foundry-organization.service'; import { CloudFoundryOrganizationSummaryComponent } from './cloud-foundry-organization-summary.component'; @@ -30,7 +31,8 @@ describe('CloudFoundryOrganizationSummaryComponent', () => { CloudFoundryOrganizationSummaryComponent, CardCfOrgUserDetailsComponent, CardCfRecentAppsComponent, - CompactAppCardComponent + CompactAppCardComponent, + CfUserPermissionDirective ], imports: generateCfBaseTestModules(), providers: [ diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.spec.ts index b5a07f34de..e25c5c6f2e 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.spec.ts @@ -2,6 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { TabNavService } from '../../../../../core/tab-nav.service'; import { generateCfBaseTestModules } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; +import { CfUserPermissionDirective } from '../../../shared/directives/cf-user-permission/cf-user-permission.directive'; import { ServicesService } from '../services.service'; import { ServicesServiceMock } from '../services.service.mock'; import { ServiceTabsBaseComponent } from './service-tabs-base.component'; @@ -12,7 +13,10 @@ describe('ServiceTabsBaseComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ServiceTabsBaseComponent], + declarations: [ + ServiceTabsBaseComponent, + CfUserPermissionDirective + ], imports: generateCfBaseTestModules(), providers: [{ provide: ServicesService, useClass: ServicesServiceMock diff --git a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.spec.ts index 4087596081..7d20df5522 100644 --- a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.spec.ts @@ -5,6 +5,7 @@ import { generateCfBaseTestModules } from '../../../../test-framework/cloud-foun import { CfEndpointsMissingComponent } from '../../../shared/components/cf-endpoints-missing/cf-endpoints-missing.component'; import { CfOrgSpaceDataService } from '../../../shared/data-services/cf-org-space-service.service'; import { CloudFoundryService } from '../../../shared/data-services/cloud-foundry.service'; +import { CfUserPermissionDirective } from '../../../shared/directives/cf-user-permission/cf-user-permission.directive'; import { ServicesWallComponent } from './services-wall.component'; describe('ServicesWallComponent', () => { @@ -15,7 +16,8 @@ describe('ServicesWallComponent', () => { TestBed.configureTestingModule({ declarations: [ ServicesWallComponent, - CfEndpointsMissingComponent + CfEndpointsMissingComponent, + CfUserPermissionDirective ], imports: generateCfBaseTestModules(), providers: [ diff --git a/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts index 86d356647a..640d7e1fe6 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts @@ -1,7 +1,8 @@ import { Component, TemplateRef } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BaseTestModules } from '../../test-framework/core-test.helper'; +import { BaseTestModules } from '../../../../../core/test-framework/core-test.helper'; + @Component({ template: `` diff --git a/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts new file mode 100644 index 0000000000..5c9f6bcaaa --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts @@ -0,0 +1,1065 @@ +import { TestBed } from '@angular/core/testing'; +import { createBasicStoreModule, createEntityStoreState, TestStoreEntity } from '@stratos/store/testing'; +import { first, tap } from 'rxjs/operators'; + +import { CFFeatureFlagTypes, IFeatureFlag } from '../../../../cloud-foundry/src/cf-api.types'; +import { cfEntityFactory } from '../../../../cloud-foundry/src/cf-entity-factory'; +import { generateCFEntities } from '../../../../cloud-foundry/src/cf-entity-generator'; +import { featureFlagEntityType } from '../../../../cloud-foundry/src/cf-entity-types'; +import { + CfCurrentUserPermissions, + cfCurrentUserPermissionsService, + CfPermissionTypes, + CfScopeStrings, +} from '../../../../cloud-foundry/src/user-permissions/cf-user-permissions-checkers'; +import { endpointEntitySchema } from '../../../../core/src/base-entity-schemas'; +import { generateStratosEntities } from '../../../../core/src/base-entity-types'; +import { PermissionConfig } from '../../../../core/src/core/permissions/current-user-permissions.config'; +import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; +import { StratosScopeStrings } from '../../../../core/src/core/permissions/stratos-user-permissions.checker'; +import { AppTestModule } from '../../../../core/test-framework/core-test.helper'; +import { AppState } from '../../../../store/src/app-state'; +import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../../../store/src/entity-catalog-test.module'; +import { EntityCatalogEntityConfig } from '../../../../store/src/entity-catalog/entity-catalog.types'; +import { APIResource } from '../../../../store/src/types/api.types'; +import { EndpointModel } from '../../../../store/src/types/endpoint.types'; +import { BaseEntityValues } from '../../../../store/src/types/entity.types'; +import { PaginationState } from '../../../../store/src/types/pagination.types'; + +const ffSchema = cfEntityFactory(featureFlagEntityType); + +describe('CurrentUserPermissionsService with CF checker', () => { + let service: CurrentUserPermissionsService; + + + function createStoreState(): Partial> { + // Data + const endpoints: EndpointModel[] = [ + { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + name: 'SCF', + cnsi_type: 'cf', + api_endpoint: { + Scheme: 'https', + Opaque: '', + User: null, + Host: 'api.10.84.93.10.nip.io:8443', + Path: '', + RawPath: '', + ForceQuery: false, + RawQuery: '', + Fragment: '' + }, + authorization_endpoint: 'https://cf.uaa.10.84.93.10.nip.io:2793', + token_endpoint: 'https://cf.uaa.10.84.93.10.nip.io:2793', + doppler_logging_endpoint: 'wss://doppler.10.84.93.10.nip.io:4443', + skip_ssl_validation: true, + user: { + guid: '670f4618-525e-4784-a56e-a238a0daf63d', + name: 'nathan', + admin: false, + scopes: [ + CfScopeStrings.CF_WRITE_SCOPE, + StratosScopeStrings.STRATOS_CHANGE_PASSWORD, + CfScopeStrings.CF_READ_SCOPE, + ] + }, + metricsAvailable: false, + connectionStatus: 'connected', + system_shared_token: false, + sso_allowed: false + }, + { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + name: 'MainSCF', + cnsi_type: 'cf', + api_endpoint: { + Scheme: 'https', + Opaque: '', + User: null, + Host: 'api.10.84.93.55.nip.io:8443', + Path: '', + RawPath: '', + ForceQuery: false, + RawQuery: '', + Fragment: '' + }, + authorization_endpoint: 'https://cf.uaa.10.84.93.55.nip.io:2793', + token_endpoint: 'https://cf.uaa.10.84.93.55.nip.io:2793', + doppler_logging_endpoint: 'wss://doppler.10.84.93.55.nip.io:4443', + skip_ssl_validation: true, + user: { + guid: '4389dfd6-6048-4149-8b26-5aa6893ac21d', + name: 'admin', + admin: true, + scopes: [ + CfScopeStrings.CF_WRITE_SCOPE, + StratosScopeStrings.STRATOS_CHANGE_PASSWORD, + CfScopeStrings.CF_READ_SCOPE, + CfScopeStrings.CF_ADMIN_GROUP, + CfScopeStrings.CF_READ_ONLY_ADMIN_GROUP, + CfScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP, + StratosScopeStrings.SCIM_READ + ] + }, + metricsAvailable: false, + connectionStatus: 'connected', + system_shared_token: false, + sso_allowed: false + } + ]; + + const featureFlags1: APIResource[] = [ + { + entity: { + name: 'user_org_creation', + enabled: false, + error_message: null, + url: '/v2/config/feature_flags/user_org_creation', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-0', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'private_domain_creation', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/private_domain_creation', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-1' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-1', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'app_bits_upload', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/app_bits_upload', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-2' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-2', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'app_scaling', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/app_scaling', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-3' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-3', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'route_creation', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/route_creation', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-4' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-4', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'service_instance_creation', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/service_instance_creation', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-5' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-5', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'diego_docker', + enabled: false, + error_message: null, + url: '/v2/config/feature_flags/diego_docker', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-6' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-6', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'set_roles_by_username', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/set_roles_by_username', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-7' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-7', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'unset_roles_by_username', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/unset_roles_by_username', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-8' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-8', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'env_var_visibility', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/env_var_visibility', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-10' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-10', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'space_scoped_private_broker_creation', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/space_scoped_private_broker_creation', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-11' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-11', + created_at: '', + updated_at: '', + url: '' + } + }, { + entity: { + name: 'space_developer_env_var_visibility', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/space_developer_env_var_visibility', + cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-12' + }, + metadata: { + guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-12', + created_at: '', + updated_at: '', + url: '' + } + } + ]; + const featureFlags2: APIResource[] = [ + // { + // entity: { + // name: 'user_org_creation', + // enabled: false, + // error_message: null, + // url: '/v2/config/feature_flags/user_org_creation', + // cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + // guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-0' + // }, + // metadata: { + // guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-0', + // created_at: '', + // updated_at: '', + // url: '' + // } + // }, + { + entity: { + name: 'private_domain_creation', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/private_domain_creation', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-1' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-1', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'app_bits_upload', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/app_bits_upload', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-2' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-2', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'app_scaling', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/app_scaling', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-3' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-3', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'route_creation', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/route_creation', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-4' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-4', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'service_instance_creation', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/service_instance_creation', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-5' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-5', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'diego_docker', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/diego_docker', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-6' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-6', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'set_roles_by_username', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/set_roles_by_username', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-7' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-7', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'unset_roles_by_username', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/unset_roles_by_username', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-8' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-8', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'env_var_visibility', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/env_var_visibility', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-10' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-10', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'space_scoped_private_broker_creation', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/space_scoped_private_broker_creation', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-11' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-11', + created_at: '', + updated_at: '', + url: '' + } + }, + { + entity: { + name: 'space_developer_env_var_visibility', + enabled: true, + error_message: null, + url: '/v2/config/feature_flags/space_developer_env_var_visibility', + cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-12' + }, + metadata: { + guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-12', + created_at: '', + updated_at: '', + url: '' + } + } + ]; + + // Pagination + const pagination: PaginationState = { + stratosEndpoint: { + 'endpoint-list': { + currentPage: 1, + totalResults: 2, + pageCount: 1, + ids: { + 1: endpoints.map(endpoint => endpoint.guid) + }, + pageRequests: { + 1: { + busy: false, + error: false, + message: '' + } + }, + params: { + 'results-per-page': 50, + 'order-direction': 'desc', + 'order-direction-field': 'name', + page: 1, + q: [] + }, + clientPagination: { + pageSize: 5, + currentPage: 1, + filter: { + string: '', + items: {} + }, + totalResults: 2 + }, + maxedState: {} + } + }, + cfFeatureFlag: { + 'endpoint-0e934dc8-7ad4-40ff-b85c-53c1b61d2abb': { + pageCount: 1, + currentPage: 1, + totalResults: 13, + ids: { + 1: featureFlags1.map(ff => ff.entity.guid) + }, + pageRequests: { + 1: { + busy: false, + error: false, + message: '' + } + }, + params: {}, + clientPagination: { + pageSize: 9, + currentPage: 1, + filter: { + string: '', + items: {} + }, + totalResults: 13 + }, + maxedState: {} + }, + 'endpoint-c80420ca-204b-4879-bf69-b6b7a202ad87': { + pageCount: 1, + currentPage: 1, + totalResults: 13, + ids: { + 1: featureFlags2.map(ff => ff.entity.guid) + }, + pageRequests: { + 1: { + busy: false, + error: false, + message: '' + } + }, + params: {}, + clientPagination: { + pageSize: 9, + currentPage: 1, + filter: { + string: '', + items: {} + }, + totalResults: 13 + }, + maxedState: {} + } + }, + }; + + // User roles + const initialState: Partial> = { + + }; + + + // Create request and requestData sections + const entityMap = new Map>([ + [ + endpointEntitySchema, + endpoints.map(endpoint => ({ + guid: endpoint.guid, + data: endpoint + })) + ], + [ + ffSchema, + [...featureFlags1, ...featureFlags2].map(featureFlag => ({ + guid: featureFlag.entity.guid, + data: featureFlag + })) + ] + ]); + const requestAndRequestData = createEntityStoreState(entityMap); + + return { + currentUserRoles: { + internal: { + isAdmin: false, + scopes: [ + // CfScopeStrings.CF_ADMIN_GROUP, + // CfScopeStrings.CF_READ_ONLY_ADMIN_GROUP, + // CfScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP, + // CfScopeStrings.CF_WRITE_SCOPE, + // CfScopeStrings.CF_READ_SCOPE, + StratosScopeStrings.STRATOS_CHANGE_PASSWORD, + StratosScopeStrings.SCIM_READ + ], + }, + endpoints: { + cf: { + '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb': { + global: { + isAdmin: false, + isReadOnlyAdmin: false, + isGlobalAuditor: false, + canRead: true, + canWrite: true, + scopes: [ + 'cloud_controller.read', + 'password.write', + 'cloud_controller.write', + 'openid', + 'uaa.user' + ] + }, + spaces: { + '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { + orgId: 'abc', + isManager: true, + isAuditor: false, + isDeveloper: true + } + }, + organizations: { + 'd5e50b05-497f-4b3b-9658-a396a592a8ba': { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'c58e7cfd-c765-400a-a473-313fa572d5c4': { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + } + }, + state: { + initialised: true, + fetching: false, + error: null + } + }, + 'c80420ca-204b-4879-bf69-b6b7a202ad87': { + global: { + isAdmin: false, + isReadOnlyAdmin: false, + isGlobalAuditor: false, + canRead: true, + canWrite: true, + scopes: [ + 'openid', + 'scim.read', + 'cloud_controller.admin', + 'uaa.user', + 'routing.router_groups.read', + 'cloud_controller.read', + 'password.write', + 'cloud_controller.write', + 'doppler.firehose', + 'scim.write' + ] + }, + spaces: { + '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + }, + 'c6450a21-aa1a-4643-9437-035cc818ea72': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + }, + '86577124-4b64-4ca1-9a78-d904c60505c4': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + } + }, + organizations: { + '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'd5246255-867b-4f62-9040-346f113f0b7d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + } + }, + state: { + initialised: true, + fetching: false, + error: null + } + }, + READ_ONLY_ADMIN: { + global: { + isAdmin: false, + isReadOnlyAdmin: true, + isGlobalAuditor: false, + canRead: true, + canWrite: true, + scopes: [ + 'openid', + 'scim.read', + 'cloud_controller.admin', + 'uaa.user', + 'routing.router_groups.read', + 'cloud_controller.read', + 'password.write', + 'cloud_controller.write', + 'doppler.firehose', + 'scim.write' + ] + }, + spaces: { + '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { + orgId: 'abc', + isManager: true, + isAuditor: false, + isDeveloper: true + }, + 'c6450a21-aa1a-4643-9437-035cc818ea72': { + orgId: 'abc', + isManager: true, + isAuditor: false, + isDeveloper: true + }, + '86577124-4b64-4ca1-9a78-d904c60505c4': { + orgId: 'abc', + isManager: true, + isAuditor: false, + isDeveloper: true + } + }, + organizations: { + '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'd5246255-867b-4f62-9040-346f113f0b7d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + } + }, + state: { + initialised: true, + fetching: false, + error: null + } + }, + READ_ONLY_USER: { + global: { + isAdmin: false, + isReadOnlyAdmin: false, + isGlobalAuditor: false, + canRead: true, + canWrite: false, + scopes: [ + 'openid', + 'scim.read', + 'cloud_controller.admin', + 'uaa.user', + 'routing.router_groups.read', + 'cloud_controller.read', + 'password.write', + 'cloud_controller.write', + 'doppler.firehose', + 'scim.write' + ] + }, + spaces: { + '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + }, + 'c6450a21-aa1a-4643-9437-035cc818ea72': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + }, + '86577124-4b64-4ca1-9a78-d904c60505c4': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + } + }, + organizations: { + '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'd5246255-867b-4f62-9040-346f113f0b7d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + } + }, + state: { + initialised: true, + fetching: false, + error: null + } + } + }, + }, + state: { + initialised: true, + fetching: false, + error: null + } + }, + requestData: { + ...initialState.requestData, + ...requestAndRequestData.requestData + }, + pagination: { + ...initialState.pagination, + ...pagination + }, + }; + } + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + ...cfCurrentUserPermissionsService + ], + imports: [ + { + ngModule: EntityCatalogTestModule, + providers: [ + { + provide: TEST_CATALOGUE_ENTITIES, useValue: [ + ...generateStratosEntities(), + generateCFEntities().find(a => a.type === ffSchema.entityType) + ] + } + ] + }, + createBasicStoreModule(createStoreState()), + AppTestModule, + ], + + }); + service = TestBed.get(CurrentUserPermissionsService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should allow create application', done => { + service.can(CfCurrentUserPermissions.APPLICATION_CREATE).pipe( + tap(can => { + expect(can).toBe(true); + done(); + }), + first() + ).subscribe(); + }); + + it('should allow create application for single endpoint with access', done => { + service.can(CfCurrentUserPermissions.APPLICATION_CREATE, '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb').pipe( + tap(can => { + expect(can).toBe(true); + done(); + }), + first() + ).subscribe(); + }); + + it('should allow create application for single endpoint with access and org/space', done => { + service.can( + CfCurrentUserPermissions.APPLICATION_CREATE, + 'c80420ca-204b-4879-bf69-b6b7a202ad87', + '86577124-4b64-4ca1-9a78-d904c60505c4' + ).pipe( + tap(can => { + expect(can).toBe(true); + done(); + }), + first() + ).subscribe(); + }); + + it('should allow if feature flag', done => { + service.can( + [new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.private_domain_creation)] + ).pipe( + tap(can => { + expect(can).toBe(true); + done(); + }), + first() + ).subscribe(); + }); + + it('should allow if feature flag with cf', done => { + service.can( + [new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.private_domain_creation)], + 'c80420ca-204b-4879-bf69-b6b7a202ad87' + ).pipe( + tap(can => { + expect(can).toBe(false); + done(); + }), + first() + ).subscribe(); + }); + + it('should not allow if no feature flag', done => { + service.can( + [new PermissionConfig(CfPermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.user_org_creation)], + 'c80420ca-204b-4879-bf69-b6b7a202ad87' + ).pipe( + tap(can => { + expect(can).toBe(false); + done(); + }), + first() + ).subscribe(); + }); + + + it('should allow if has endpoint scope', done => { + service.can(new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, StratosScopeStrings.SCIM_READ), 'c80420ca-204b-4879-bf69-b6b7a202ad87').pipe( + tap(can => { + expect(can).toBe(true); + done(); + }), + first() + ).subscribe(); + }); + + it('should not allow if has endpoint scope', done => { + service.can(new PermissionConfig(CfPermissionTypes.ENDPOINT_SCOPE, StratosScopeStrings.SCIM_READ), '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb').pipe( + tap(can => { + expect(can).toBe(false); + done(); + }), + first() + ).subscribe(); + }); + + it('should not allow if read only admin', done => { + service.can( + CfCurrentUserPermissions.APPLICATION_CREATE, + 'READ_ONLY_ADMIN', + 'c6450a21-aa1a-4643-9437-035cc818ea72' + ).pipe( + tap(can => { + expect(can).toBe(false); + done(); + }), + first() + ).subscribe(); + }); + + it('should not allow if read only user', done => { + service.can( + CfCurrentUserPermissions.APPLICATION_CREATE, + 'READ_ONLY_USER', + 'c6450a21-aa1a-4643-9437-035cc818ea72' + ).pipe( + tap(can => { + expect(can).toBe(false); + done(); + }), + first() + ).subscribe(); + }); + +}); diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.spec.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.spec.ts new file mode 100644 index 0000000000..eb698f376c --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.spec.ts @@ -0,0 +1,249 @@ +import { CfUserRelationTypes, GetCurrentCfUserRelationsComplete } from '../../../actions/permissions.actions'; +import { + IAllCfRolesState, + ICfRolesState, + IOrgRoleState, + ISpaceRoleState, + RoleEntities, +} from '../../types/cf-current-user-roles.types'; +import { getDefaultCfEndpointRoles } from './current-cf-user-base-cf-role.reducer'; +import { createCfOrgRoleStateState } from './current-cf-user-roles-org.reducer'; +import { currentCfUserRolesReducer } from './current-cf-user-roles.reducer'; + +const testOrgGuid = 'org-1'; +const testSpaceGuid = 'space-1'; +const generalGuid = 'guid-123'; +const testCFEndpointGuid = 'cf-1'; + +function getSpaceAction(type: CfUserRelationTypes, orgGuid: string = testOrgGuid, spaceGuid: string = testSpaceGuid) { + return new GetCurrentCfUserRelationsComplete( + type, + testCFEndpointGuid, + [{ metadata: { guid: spaceGuid, created_at: '1', updated_at: '1', url: '1' }, entity: { organization_guid: orgGuid } }] + ); +} + +function getOrgAction(type: CfUserRelationTypes, orgGuid: string = testOrgGuid) { + return new GetCurrentCfUserRelationsComplete( + type, + testCFEndpointGuid, + [{ metadata: { guid: orgGuid, created_at: '1', updated_at: '1', url: '1' }, entity: {} }] + ); +} + +function getState( + orgOrSpace: RoleEntities, + allRoles: { guid: string, roles: ISpaceRoleState | IOrgRoleState }[] = [], + roles?: ISpaceRoleState | IOrgRoleState +): ICfRolesState { + const baseState = getDefaultCfEndpointRoles(); + if (!allRoles.length) { + let guid = testSpaceGuid; + if (orgOrSpace === RoleEntities.ORGS) { + guid = testOrgGuid; + } + allRoles.push({ guid, roles }); + } + const orgSpaceRoles = { + [orgOrSpace]: {} + }; + if (orgOrSpace === RoleEntities.SPACES) { + orgSpaceRoles.organizations = { + [testOrgGuid]: createCfOrgRoleStateState() + }; + } + allRoles.forEach(role => { + orgSpaceRoles[orgOrSpace][role.guid] = role.roles; + if (orgOrSpace === RoleEntities.SPACES) { + orgSpaceRoles.organizations[testOrgGuid].spaceGuids.push(role.guid); + } + }); + return { + ...baseState, + ...orgSpaceRoles + }; +} + +describe('currentCfUserRolesReducer', () => { + it('set defaults', () => { + const state = currentCfUserRolesReducer(undefined, { type: 'FAKE_ACTION' }); + const expectedState: IAllCfRolesState = null; + expect(state).toEqual(expectedState); + }); + it('should add org manager role to org', () => { + const state = currentCfUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.MANAGED_ORGANIZATION)); + const cfPermissions = state[testCFEndpointGuid]; + expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: false, + spaceGuids: [] + })); + }); + it('should add org auditor role to org', () => { + const state = currentCfUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS)); + const cfPermissions = state[testCFEndpointGuid]; + expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { + isManager: false, + isAuditor: true, + isBillingManager: false, + isUser: false, + spaceGuids: [] + })); + }); + it('should add org billing manager role to org', () => { + const state = currentCfUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.BILLING_MANAGED_ORGANIZATION)); + const cfPermissions = state[testCFEndpointGuid]; + expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { + isManager: false, + isAuditor: false, + isBillingManager: true, + isUser: false, + spaceGuids: [] + })); + }); + it('should add org user role to org', () => { + const state = currentCfUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); + const cfPermissions = state[testCFEndpointGuid]; + expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + })); + }); + + it('should retain other org roles', () => { + let state = currentCfUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); + state = currentCfUserRolesReducer(state, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS, generalGuid)); + const cfPermissions = state[testCFEndpointGuid]; + const toEqual = getState(RoleEntities.ORGS, [{ + guid: testOrgGuid, + roles: { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + }, + { + guid: generalGuid, + roles: { + isManager: false, + isAuditor: true, + isBillingManager: false, + isUser: false, + spaceGuids: [] + } + }]); + expect(cfPermissions).toEqual(toEqual); + }); + + it('should retain other space roles', () => { + let state = currentCfUserRolesReducer(undefined, getSpaceAction(CfUserRelationTypes.SPACES)); + state = currentCfUserRolesReducer(state, getSpaceAction(CfUserRelationTypes.MANAGED_SPACES, generalGuid, generalGuid)); + const cfPermissions = state[testCFEndpointGuid]; + const toEqual = getState(RoleEntities.SPACES, [{ + guid: testSpaceGuid, + roles: { + orgId: testOrgGuid, + isManager: false, + isAuditor: false, + isDeveloper: true + } + }, + { + guid: generalGuid, + roles: { + orgId: generalGuid, + isManager: true, + isAuditor: false, + isDeveloper: false + } + }]); + const orgState = getState(RoleEntities.ORGS, [{ + guid: testOrgGuid, + roles: { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: false, + spaceGuids: [ + testSpaceGuid + ] + } + }, + { + guid: generalGuid, + roles: { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: false, + spaceGuids: [ + generalGuid + ] + } + }]); + toEqual.organizations = orgState.organizations; + expect(cfPermissions).toEqual(toEqual); + }); + + it('should retain other space and org roles', () => { + let state = currentCfUserRolesReducer(undefined, getSpaceAction(CfUserRelationTypes.SPACES)); + state = currentCfUserRolesReducer(state, getSpaceAction(CfUserRelationTypes.MANAGED_SPACES, generalGuid, generalGuid)); + state = currentCfUserRolesReducer(state, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); + state = currentCfUserRolesReducer(state, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS, generalGuid)); + const cfPermissions = state[testCFEndpointGuid]; + + + const spaceState = getState(RoleEntities.SPACES, [{ + guid: testSpaceGuid, + roles: { + orgId: testOrgGuid, + isManager: false, + isAuditor: false, + isDeveloper: true + } + }, + { + guid: generalGuid, + roles: { + orgId: generalGuid, + isManager: true, + isAuditor: false, + isDeveloper: false + } + }]); + + const orgState = getState(RoleEntities.ORGS, [{ + guid: testOrgGuid, + roles: { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [ + testSpaceGuid + ] + } + }, + { + guid: generalGuid, + roles: { + isManager: false, + isAuditor: true, + isBillingManager: false, + isUser: false, + spaceGuids: [ + generalGuid + ] + } + }]); + spaceState.organizations = orgState.organizations; + expect(cfPermissions).toEqual(spaceState); + }); +}); diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts index 7d401de85e..a64bfe18fa 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts @@ -2,30 +2,19 @@ import { TestBed } from '@angular/core/testing'; import { createBasicStoreModule, createEntityStoreState, TestStoreEntity } from '@stratos/store/testing'; import { first, tap } from 'rxjs/operators'; -import { CFFeatureFlagTypes, IFeatureFlag } from '../../../../cloud-foundry/src/cf-api.types'; -import { cfEntityFactory } from '../../../../cloud-foundry/src/cf-entity-factory'; -import { generateCFEntities } from '../../../../cloud-foundry/src/cf-entity-generator'; -import { featureFlagEntityType } from '../../../../cloud-foundry/src/cf-entity-types'; import { AppState } from '../../../../store/src/app-state'; import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../../../store/src/entity-catalog-test.module'; import { EntityCatalogEntityConfig } from '../../../../store/src/entity-catalog/entity-catalog.types'; -import { APIResource } from '../../../../store/src/types/api.types'; import { EndpointModel } from '../../../../store/src/types/endpoint.types'; import { BaseEntityValues } from '../../../../store/src/types/entity.types'; import { PaginationState } from '../../../../store/src/types/pagination.types'; import { AppTestModule } from '../../../test-framework/core-test.helper'; import { endpointEntitySchema } from '../../base-entity-schemas'; import { generateStratosEntities } from '../../base-entity-types'; -import { - CurrentUserPermissions, - PermissionConfig, - PermissionStrings, - PermissionTypes, - ScopeStrings, -} from './current-user-permissions.config'; +import { PermissionConfig } from './current-user-permissions.config'; import { CurrentUserPermissionsService } from './current-user-permissions.service'; +import { StratosPermissionStrings, StratosPermissionTypes, StratosScopeStrings } from './stratos-user-permissions.checker'; -const ffSchema = cfEntityFactory(featureFlagEntityType); describe('CurrentUserPermissionsService', () => { let service: CurrentUserPermissionsService; @@ -58,9 +47,7 @@ describe('CurrentUserPermissionsService', () => { name: 'nathan', admin: false, scopes: [ - ScopeStrings.CF_WRITE_SCOPE, - ScopeStrings.STRATOS_CHANGE_PASSWORD, - ScopeStrings.CF_READ_SCOPE, + StratosScopeStrings.STRATOS_CHANGE_PASSWORD, ] }, metricsAvailable: false, @@ -92,13 +79,8 @@ describe('CurrentUserPermissionsService', () => { name: 'admin', admin: true, scopes: [ - ScopeStrings.CF_WRITE_SCOPE, - ScopeStrings.STRATOS_CHANGE_PASSWORD, - ScopeStrings.CF_READ_SCOPE, - ScopeStrings.CF_ADMIN_GROUP, - ScopeStrings.CF_READ_ONLY_ADMIN_GROUP, - ScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP, - ScopeStrings.SCIM_READ + StratosScopeStrings.STRATOS_CHANGE_PASSWORD, + StratosScopeStrings.SCIM_READ ] }, metricsAvailable: false, @@ -108,383 +90,6 @@ describe('CurrentUserPermissionsService', () => { } ]; - const featureFlags1: APIResource[] = [ - { - entity: { - name: 'user_org_creation', - enabled: false, - error_message: null, - url: '/v2/config/feature_flags/user_org_creation', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-0', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'private_domain_creation', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/private_domain_creation', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-1' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-1', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'app_bits_upload', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/app_bits_upload', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-2' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-2', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'app_scaling', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/app_scaling', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-3' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-3', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'route_creation', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/route_creation', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-4' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-4', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'service_instance_creation', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/service_instance_creation', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-5' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-5', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'diego_docker', - enabled: false, - error_message: null, - url: '/v2/config/feature_flags/diego_docker', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-6' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-6', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'set_roles_by_username', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/set_roles_by_username', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-7' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-7', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'unset_roles_by_username', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/unset_roles_by_username', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-8' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-8', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'env_var_visibility', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/env_var_visibility', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-10' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-10', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'space_scoped_private_broker_creation', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/space_scoped_private_broker_creation', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-11' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-11', - created_at: '', - updated_at: '', - url: '' - } - }, { - entity: { - name: 'space_developer_env_var_visibility', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/space_developer_env_var_visibility', - cfGuid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-12' - }, - metadata: { - guid: '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-12', - created_at: '', - updated_at: '', - url: '' - } - } - ]; - const featureFlags2: APIResource[] = [ - // { - // entity: { - // name: 'user_org_creation', - // enabled: false, - // error_message: null, - // url: '/v2/config/feature_flags/user_org_creation', - // cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - // guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-0' - // }, - // metadata: { - // guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-0', - // created_at: '', - // updated_at: '', - // url: '' - // } - // }, - { - entity: { - name: 'private_domain_creation', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/private_domain_creation', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-1' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-1', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'app_bits_upload', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/app_bits_upload', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-2' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-2', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'app_scaling', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/app_scaling', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-3' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-3', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'route_creation', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/route_creation', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-4' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-4', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'service_instance_creation', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/service_instance_creation', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-5' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-5', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'diego_docker', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/diego_docker', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-6' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-6', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'set_roles_by_username', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/set_roles_by_username', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-7' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-7', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'unset_roles_by_username', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/unset_roles_by_username', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-8' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-8', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'env_var_visibility', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/env_var_visibility', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-10' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-10', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'space_scoped_private_broker_creation', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/space_scoped_private_broker_creation', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-11' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-11', - created_at: '', - updated_at: '', - url: '' - } - }, - { - entity: { - name: 'space_developer_env_var_visibility', - enabled: true, - error_message: null, - url: '/v2/config/feature_flags/space_developer_env_var_visibility', - cfGuid: 'c80420ca-204b-4879-bf69-b6b7a202ad87', - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-12' - }, - metadata: { - guid: 'c80420ca-204b-4879-bf69-b6b7a202ad87-12', - created_at: '', - updated_at: '', - url: '' - } - } - ]; // Pagination const pagination: PaginationState = { @@ -522,60 +127,6 @@ describe('CurrentUserPermissionsService', () => { maxedState: {} } }, - cfFeatureFlag: { - 'endpoint-0e934dc8-7ad4-40ff-b85c-53c1b61d2abb': { - pageCount: 1, - currentPage: 1, - totalResults: 13, - ids: { - 1: featureFlags1.map(ff => ff.entity.guid) - }, - pageRequests: { - 1: { - busy: false, - error: false, - message: '' - } - }, - params: {}, - clientPagination: { - pageSize: 9, - currentPage: 1, - filter: { - string: '', - items: {} - }, - totalResults: 13 - }, - maxedState: {} - }, - 'endpoint-c80420ca-204b-4879-bf69-b6b7a202ad87': { - pageCount: 1, - currentPage: 1, - totalResults: 13, - ids: { - 1: featureFlags2.map(ff => ff.entity.guid) - }, - pageRequests: { - 1: { - busy: false, - error: false, - message: '' - } - }, - params: {}, - clientPagination: { - pageSize: 9, - currentPage: 1, - filter: { - string: '', - items: {} - }, - totalResults: 13 - }, - maxedState: {} - } - }, }; // User roles @@ -593,13 +144,6 @@ describe('CurrentUserPermissionsService', () => { data: endpoint })) ], - [ - ffSchema, - [...featureFlags1, ...featureFlags2].map(featureFlag => ({ - guid: featureFlag.entity.guid, - data: featureFlag - })) - ] ]); const requestAndRequestData = createEntityStoreState(entityMap); @@ -607,291 +151,287 @@ describe('CurrentUserPermissionsService', () => { currentUserRoles: { internal: { isAdmin: false, - scopes: [ - ScopeStrings.CF_ADMIN_GROUP, - ScopeStrings.CF_READ_ONLY_ADMIN_GROUP, - ScopeStrings.CF_ADMIN_GLOBAL_AUDITOR_GROUP, - ScopeStrings.CF_WRITE_SCOPE, - ScopeStrings.CF_READ_SCOPE, - ScopeStrings.STRATOS_CHANGE_PASSWORD, - ScopeStrings.SCIM_READ + StratosScopeStrings.STRATOS_CHANGE_PASSWORD, + StratosScopeStrings.SCIM_READ ], }, - cf: { - '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb': { - global: { - isAdmin: false, - isReadOnlyAdmin: false, - isGlobalAuditor: false, - canRead: true, - canWrite: true, - scopes: [ - 'cloud_controller.read', - 'password.write', - 'cloud_controller.write', - 'openid', - 'uaa.user' - ] - }, - spaces: { - '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { - orgId: 'abc', - isManager: true, - isAuditor: false, - isDeveloper: true - } - }, - organizations: { - 'd5e50b05-497f-4b3b-9658-a396a592a8ba': { - isManager: false, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] + endpoints: { + cf: { + '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb': { + global: { + isAdmin: false, + isReadOnlyAdmin: false, + isGlobalAuditor: false, + canRead: true, + canWrite: true, + scopes: [ + 'cloud_controller.read', + 'password.write', + 'cloud_controller.write', + 'openid', + 'uaa.user' + ] }, - 'c58e7cfd-c765-400a-a473-313fa572d5c4': { - isManager: false, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - } - }, - state: { - initialised: true, - fetching: false, - error: null - } - }, - 'c80420ca-204b-4879-bf69-b6b7a202ad87': { - global: { - isAdmin: false, - isReadOnlyAdmin: false, - isGlobalAuditor: false, - canRead: true, - canWrite: true, - scopes: [ - 'openid', - 'scim.read', - 'cloud_controller.admin', - 'uaa.user', - 'routing.router_groups.read', - 'cloud_controller.read', - 'password.write', - 'cloud_controller.write', - 'doppler.firehose', - 'scim.write' - ] - }, - spaces: { - '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { - isManager: true, - isAuditor: false, - isDeveloper: true, - orgId: 'abc' + spaces: { + '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { + orgId: 'abc', + isManager: true, + isAuditor: false, + isDeveloper: true + } }, - 'c6450a21-aa1a-4643-9437-035cc818ea72': { - isManager: true, - isAuditor: false, - isDeveloper: true, - orgId: 'abc' + organizations: { + 'd5e50b05-497f-4b3b-9658-a396a592a8ba': { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'c58e7cfd-c765-400a-a473-313fa572d5c4': { + isManager: false, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + } }, - '86577124-4b64-4ca1-9a78-d904c60505c4': { - isManager: true, - isAuditor: false, - isDeveloper: true, - orgId: 'abc' + state: { + initialised: true, + fetching: false, + error: null } }, - organizations: { - '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - }, - 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - }, - '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] + 'c80420ca-204b-4879-bf69-b6b7a202ad87': { + global: { + isAdmin: false, + isReadOnlyAdmin: false, + isGlobalAuditor: false, + canRead: true, + canWrite: true, + scopes: [ + 'openid', + 'scim.read', + 'cloud_controller.admin', + 'uaa.user', + 'routing.router_groups.read', + 'cloud_controller.read', + 'password.write', + 'cloud_controller.write', + 'doppler.firehose', + 'scim.write' + ] }, - 'd5246255-867b-4f62-9040-346f113f0b7d': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - } - }, - state: { - initialised: true, - fetching: false, - error: null - } - }, - READ_ONLY_ADMIN: { - global: { - isAdmin: false, - isReadOnlyAdmin: true, - isGlobalAuditor: false, - canRead: true, - canWrite: true, - scopes: [ - 'openid', - 'scim.read', - 'cloud_controller.admin', - 'uaa.user', - 'routing.router_groups.read', - 'cloud_controller.read', - 'password.write', - 'cloud_controller.write', - 'doppler.firehose', - 'scim.write' - ] - }, - spaces: { - '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { - orgId: 'abc', - isManager: true, - isAuditor: false, - isDeveloper: true + spaces: { + '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + }, + 'c6450a21-aa1a-4643-9437-035cc818ea72': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + }, + '86577124-4b64-4ca1-9a78-d904c60505c4': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + } }, - 'c6450a21-aa1a-4643-9437-035cc818ea72': { - orgId: 'abc', - isManager: true, - isAuditor: false, - isDeveloper: true + organizations: { + '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'd5246255-867b-4f62-9040-346f113f0b7d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + } }, - '86577124-4b64-4ca1-9a78-d904c60505c4': { - orgId: 'abc', - isManager: true, - isAuditor: false, - isDeveloper: true + state: { + initialised: true, + fetching: false, + error: null } }, - organizations: { - '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - }, - 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] + READ_ONLY_ADMIN: { + global: { + isAdmin: false, + isReadOnlyAdmin: true, + isGlobalAuditor: false, + canRead: true, + canWrite: true, + scopes: [ + 'openid', + 'scim.read', + 'cloud_controller.admin', + 'uaa.user', + 'routing.router_groups.read', + 'cloud_controller.read', + 'password.write', + 'cloud_controller.write', + 'doppler.firehose', + 'scim.write' + ] }, - '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - }, - 'd5246255-867b-4f62-9040-346f113f0b7d': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - } - }, - state: { - initialised: true, - fetching: false, - error: null - } - }, - READ_ONLY_USER: { - global: { - isAdmin: false, - isReadOnlyAdmin: false, - isGlobalAuditor: false, - canRead: true, - canWrite: false, - scopes: [ - 'openid', - 'scim.read', - 'cloud_controller.admin', - 'uaa.user', - 'routing.router_groups.read', - 'cloud_controller.read', - 'password.write', - 'cloud_controller.write', - 'doppler.firehose', - 'scim.write' - ] - }, - spaces: { - '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { - isManager: true, - isAuditor: false, - isDeveloper: true, - orgId: 'abc' + spaces: { + '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { + orgId: 'abc', + isManager: true, + isAuditor: false, + isDeveloper: true + }, + 'c6450a21-aa1a-4643-9437-035cc818ea72': { + orgId: 'abc', + isManager: true, + isAuditor: false, + isDeveloper: true + }, + '86577124-4b64-4ca1-9a78-d904c60505c4': { + orgId: 'abc', + isManager: true, + isAuditor: false, + isDeveloper: true + } }, - 'c6450a21-aa1a-4643-9437-035cc818ea72': { - isManager: true, - isAuditor: false, - isDeveloper: true, - orgId: 'abc' + organizations: { + '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'd5246255-867b-4f62-9040-346f113f0b7d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + } }, - '86577124-4b64-4ca1-9a78-d904c60505c4': { - isManager: true, - isAuditor: false, - isDeveloper: true, - orgId: 'abc' + state: { + initialised: true, + fetching: false, + error: null } }, - organizations: { - '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] + READ_ONLY_USER: { + global: { + isAdmin: false, + isReadOnlyAdmin: false, + isGlobalAuditor: false, + canRead: true, + canWrite: false, + scopes: [ + 'openid', + 'scim.read', + 'cloud_controller.admin', + 'uaa.user', + 'routing.router_groups.read', + 'cloud_controller.read', + 'password.write', + 'cloud_controller.write', + 'doppler.firehose', + 'scim.write' + ] }, - 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] + spaces: { + '56eb5ecc-7c96-4bb1-bdcc-0c6c3d444dc6': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + }, + 'c6450a21-aa1a-4643-9437-035cc818ea72': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + }, + '86577124-4b64-4ca1-9a78-d904c60505c4': { + isManager: true, + isAuditor: false, + isDeveloper: true, + orgId: 'abc' + } }, - '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] + organizations: { + '367a49c1-b5dc-44e6-a8cf-84b1f56426a7': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'dccfedde-be2c-46a6-99cf-c1320ea8cb6d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + '8a175cad-ff61-436b-8c6f-e5beb13edb5f': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + }, + 'd5246255-867b-4f62-9040-346f113f0b7d': { + isManager: true, + isAuditor: false, + isBillingManager: false, + isUser: true, + spaceGuids: [] + } }, - 'd5246255-867b-4f62-9040-346f113f0b7d': { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] + state: { + initialised: true, + fetching: false, + error: null } - }, - state: { - initialised: true, - fetching: false, - error: null } - } + }, }, state: { initialised: true, @@ -922,7 +462,6 @@ describe('CurrentUserPermissionsService', () => { { provide: TEST_CATALOGUE_ENTITIES, useValue: [ ...generateStratosEntities(), - generateCFEntities().find(a => a.type === ffSchema.entityType) ] } ] @@ -939,80 +478,9 @@ describe('CurrentUserPermissionsService', () => { expect(service).toBeTruthy(); }); - it('should allow create application', done => { - service.can(CurrentUserPermissions.APPLICATION_CREATE).pipe( - tap(can => { - expect(can).toBe(true); - done(); - }), - first() - ).subscribe(); - }); - - it('should allow create application for single endpoint with access', done => { - service.can(CurrentUserPermissions.APPLICATION_CREATE, '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb').pipe( - tap(can => { - expect(can).toBe(true); - done(); - }), - first() - ).subscribe(); - }); - - it('should allow create application for single endpoint with access and org/space', done => { - service.can( - CurrentUserPermissions.APPLICATION_CREATE, - 'c80420ca-204b-4879-bf69-b6b7a202ad87', - '86577124-4b64-4ca1-9a78-d904c60505c4' - ).pipe( - tap(can => { - expect(can).toBe(true); - done(); - }), - first() - ).subscribe(); - }); - - it('should allow if feature flag', done => { - service.can( - [new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.private_domain_creation)] - ).pipe( - tap(can => { - expect(can).toBe(true); - done(); - }), - first() - ).subscribe(); - }); - - it('should allow if feature flag with cf', done => { - service.can( - [new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.private_domain_creation)], - 'c80420ca-204b-4879-bf69-b6b7a202ad87' - ).pipe( - tap(can => { - expect(can).toBe(false); - done(); - }), - first() - ).subscribe(); - }); - - it('should not allow if no feature flag', done => { - service.can( - [new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.user_org_creation)], - 'c80420ca-204b-4879-bf69-b6b7a202ad87' - ).pipe( - tap(can => { - expect(can).toBe(false); - done(); - }), - first() - ).subscribe(); - }); it('should allow if stratos admin', done => { - service.can(new PermissionConfig(PermissionTypes.STRATOS, PermissionStrings.STRATOS_ADMIN)).pipe( + service.can(new PermissionConfig(StratosPermissionTypes.STRATOS, StratosPermissionStrings.STRATOS_ADMIN)).pipe( tap(can => { expect(can).toBe(false); done(); @@ -1022,25 +490,15 @@ describe('CurrentUserPermissionsService', () => { }); it('should allow if has stratos change password scope', done => { - service.can(new PermissionConfig(PermissionTypes.STRATOS_SCOPE, ScopeStrings.STRATOS_CHANGE_PASSWORD)).pipe( - tap(can => { - expect(can).toBe(true); - done(); - }), - first() - ).subscribe(); - - service.can([new PermissionConfig(PermissionTypes.STRATOS_SCOPE, ScopeStrings.STRATOS_CHANGE_PASSWORD)]).pipe( + service.can(new PermissionConfig(StratosPermissionTypes.STRATOS_SCOPE, StratosScopeStrings.STRATOS_CHANGE_PASSWORD)).pipe( tap(can => { expect(can).toBe(true); done(); }), first() ).subscribe(); - }); - it('should allow if has endpoint scope', done => { - service.can(new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.SCIM_READ), 'c80420ca-204b-4879-bf69-b6b7a202ad87').pipe( + service.can([new PermissionConfig(StratosPermissionTypes.STRATOS_SCOPE, StratosScopeStrings.STRATOS_CHANGE_PASSWORD)]).pipe( tap(can => { expect(can).toBe(true); done(); @@ -1049,42 +507,5 @@ describe('CurrentUserPermissionsService', () => { ).subscribe(); }); - it('should not allow if has endpoint scope', done => { - service.can(new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.SCIM_READ), '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb').pipe( - tap(can => { - expect(can).toBe(false); - done(); - }), - first() - ).subscribe(); - }); - - it('should not allow if read only admin', done => { - service.can( - CurrentUserPermissions.APPLICATION_CREATE, - 'READ_ONLY_ADMIN', - 'c6450a21-aa1a-4643-9437-035cc818ea72' - ).pipe( - tap(can => { - expect(can).toBe(false); - done(); - }), - first() - ).subscribe(); - }); - - it('should not allow if read only user', done => { - service.can( - CurrentUserPermissions.APPLICATION_CREATE, - 'READ_ONLY_USER', - 'c6450a21-aa1a-4643-9437-035cc818ea72' - ).pipe( - tap(can => { - expect(can).toBe(false); - done(); - }), - first() - ).subscribe(); - }); }); diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.spec.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.spec.ts index 7170050ed3..083fe4629f 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.spec.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.spec.ts @@ -1,78 +1,7 @@ -import { - CfUserRelationTypes, - GetCurrentCfUserRelationsComplete, -} from '../../../../cloud-foundry/src/actions/permissions.actions'; -import { - createOrgRoleStateState, -} from '../../../../cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-user-roles-org.reducer'; -import { - ICfRolesState, - IOrgRoleState, - ISpaceRoleState, - RoleEntities, -} from '../../../../cloud-foundry/src/store/types/cf-current-user-roles.types'; -import { - getDefaultEndpointRoles, - getDefaultRolesRequestState, - ICurrentUserRolesState, -} from '../../types/current-user-roles.types'; +import { getDefaultRolesRequestState, ICurrentUserRolesState } from '../../types/current-user-roles.types'; import { currentUserRolesReducer } from './current-user-roles.reducer'; -const testOrgGuid = 'org-1'; -const testSpaceGuid = 'space-1'; -const generalGuid = 'guid-123'; -const testCFEndpointGuid = 'cf-1'; - -function getSpaceAction(type: CfUserRelationTypes, orgGuid: string = testOrgGuid, spaceGuid: string = testSpaceGuid) { - return new GetCurrentCfUserRelationsComplete( - type, - testCFEndpointGuid, - [{ metadata: { guid: spaceGuid, created_at: '1', updated_at: '1', url: '1' }, entity: { organization_guid: orgGuid } }] - ); -} - -function getOrgAction(type: CfUserRelationTypes, orgGuid: string = testOrgGuid) { - return new GetCurrentCfUserRelationsComplete( - type, - testCFEndpointGuid, - [{ metadata: { guid: orgGuid, created_at: '1', updated_at: '1', url: '1' }, entity: {} }] - ); -} - -function getState( - orgOrSpace: RoleEntities, - allRoles: { guid: string, roles: ISpaceRoleState | IOrgRoleState }[] = [], - roles?: ISpaceRoleState | IOrgRoleState -): ICfRolesState { - const baseState = getDefaultEndpointRoles(); - if (!allRoles.length) { - let guid = testSpaceGuid; - if (orgOrSpace === RoleEntities.ORGS) { - guid = testOrgGuid; - } - allRoles.push({ guid, roles }); - } - const orgSpaceRoles = { - [orgOrSpace]: {} - }; - if (orgOrSpace === RoleEntities.SPACES) { - orgSpaceRoles.organizations = { - [testOrgGuid]: createOrgRoleStateState() - }; - } - allRoles.forEach(role => { - orgSpaceRoles[orgOrSpace][role.guid] = role.roles; - if (orgOrSpace === RoleEntities.SPACES) { - orgSpaceRoles.organizations[testOrgGuid].spaceGuids.push(role.guid); - } - }); - return { - ...baseState, - ...orgSpaceRoles - }; -} - -describe('currentUserReducer', () => { +describe('currentUserRolesReducer', () => { it('set defaults', () => { const state = currentUserRolesReducer(undefined, { type: 'FAKE_ACTION' }); const expectedState: ICurrentUserRolesState = { @@ -80,185 +9,9 @@ describe('currentUserReducer', () => { isAdmin: false, scopes: [] }, - cf: {}, + endpoints: {}, state: getDefaultRolesRequestState() }; expect(state).toEqual(expectedState); }); - it('should add org manager role to org', () => { - const state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.MANAGED_ORGANIZATION)); - const cfPermissions = state.cf[testCFEndpointGuid]; - expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { - isManager: true, - isAuditor: false, - isBillingManager: false, - isUser: false, - spaceGuids: [] - })); - }); - it('should add org auditor role to org', () => { - const state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS)); - const cfPermissions = state.cf[testCFEndpointGuid]; - expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { - isManager: false, - isAuditor: true, - isBillingManager: false, - isUser: false, - spaceGuids: [] - })); - }); - it('should add org billing manager role to org', () => { - const state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.BILLING_MANAGED_ORGANIZATION)); - const cfPermissions = state.cf[testCFEndpointGuid]; - expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { - isManager: false, - isAuditor: false, - isBillingManager: true, - isUser: false, - spaceGuids: [] - })); - }); - it('should add org user role to org', () => { - const state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); - const cfPermissions = state.cf[testCFEndpointGuid]; - expect(cfPermissions).toEqual(getState(RoleEntities.ORGS, [], { - isManager: false, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - })); - }); - - it('should retain other org roles', () => { - let state = currentUserRolesReducer(undefined, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); - state = currentUserRolesReducer(state, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS, generalGuid)); - const cfPermissions = state.cf[testCFEndpointGuid]; - const toEqual = getState(RoleEntities.ORGS, [{ - guid: testOrgGuid, - roles: { - isManager: false, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [] - }, - }, - { - guid: generalGuid, - roles: { - isManager: false, - isAuditor: true, - isBillingManager: false, - isUser: false, - spaceGuids: [] - } - }]); - expect(cfPermissions).toEqual(toEqual); - }); - - it('should retain other space roles', () => { - let state = currentUserRolesReducer(undefined, getSpaceAction(CfUserRelationTypes.SPACES)); - state = currentUserRolesReducer(state, getSpaceAction(CfUserRelationTypes.MANAGED_SPACES, generalGuid, generalGuid)); - const cfPermissions = state.cf[testCFEndpointGuid]; - const toEqual = getState(RoleEntities.SPACES, [{ - guid: testSpaceGuid, - roles: { - orgId: testOrgGuid, - isManager: false, - isAuditor: false, - isDeveloper: true - } - }, - { - guid: generalGuid, - roles: { - orgId: generalGuid, - isManager: true, - isAuditor: false, - isDeveloper: false - } - }]); - const orgState = getState(RoleEntities.ORGS, [{ - guid: testOrgGuid, - roles: { - isManager: false, - isAuditor: false, - isBillingManager: false, - isUser: false, - spaceGuids: [ - testSpaceGuid - ] - } - }, - { - guid: generalGuid, - roles: { - isManager: false, - isAuditor: false, - isBillingManager: false, - isUser: false, - spaceGuids: [ - generalGuid - ] - } - }]); - toEqual.organizations = orgState.organizations; - expect(cfPermissions).toEqual(toEqual); - }); - - it('should retain other space and org roles', () => { - let state = currentUserRolesReducer(undefined, getSpaceAction(CfUserRelationTypes.SPACES)); - state = currentUserRolesReducer(state, getSpaceAction(CfUserRelationTypes.MANAGED_SPACES, generalGuid, generalGuid)); - state = currentUserRolesReducer(state, getOrgAction(CfUserRelationTypes.ORGANIZATIONS)); - state = currentUserRolesReducer(state, getOrgAction(CfUserRelationTypes.AUDITED_ORGANIZATIONS, generalGuid)); - const cfPermissions = state.cf[testCFEndpointGuid]; - - - const spaceState = getState(RoleEntities.SPACES, [{ - guid: testSpaceGuid, - roles: { - orgId: testOrgGuid, - isManager: false, - isAuditor: false, - isDeveloper: true - } - }, - { - guid: generalGuid, - roles: { - orgId: generalGuid, - isManager: true, - isAuditor: false, - isDeveloper: false - } - }]); - - const orgState = getState(RoleEntities.ORGS, [{ - guid: testOrgGuid, - roles: { - isManager: false, - isAuditor: false, - isBillingManager: false, - isUser: true, - spaceGuids: [ - testSpaceGuid - ] - } - }, - { - guid: generalGuid, - roles: { - isManager: false, - isAuditor: true, - isBillingManager: false, - isUser: false, - spaceGuids: [ - generalGuid - ] - } - }]); - spaceState.organizations = orgState.organizations; - expect(cfPermissions).toEqual(spaceState); - }); }); diff --git a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts index d6d9338eba..166767e168 100644 --- a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts +++ b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts @@ -1,9 +1,10 @@ import { compose } from '@ngrx/store'; -import { PermissionValues, ScopeStrings } from '../../../core/src/core/permissions/current-user-permissions.config'; +import { PermissionValues } from '../../../core/src/core/permissions/current-user-permissions.config'; import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; import { CurrentUserRolesAppState } from '../app-state'; import { ICurrentUserRolesState, IStratosRolesState } from '../types/current-user-roles.types'; +import { UserScopeStrings } from '../types/endpoint.types'; export const selectCurrentUserRolesState = (state: CurrentUserRolesAppState) => state.currentUserRoles; @@ -15,7 +16,7 @@ const selectCurrentUserStratosRoles = (role: PermissionValues) => (state: Omit (scopes: ScopeStrings[]) => scopes.includes(scope); +export const selectCurrentUserGlobalHasScopes = (scope: UserScopeStrings) => (scopes: UserScopeStrings[]) => scopes.includes(scope); const selectCurrentUserStratosScopesState = (state: IStratosRolesState) => state.scopes; diff --git a/src/frontend/packages/store/src/types/current-user-roles.types.ts b/src/frontend/packages/store/src/types/current-user-roles.types.ts index f283b3d6d1..08243b9ed7 100644 --- a/src/frontend/packages/store/src/types/current-user-roles.types.ts +++ b/src/frontend/packages/store/src/types/current-user-roles.types.ts @@ -1,4 +1,4 @@ -import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; +import { UserScopeStrings } from './endpoint.types'; export interface RolesRequestState { initialised: boolean; @@ -16,7 +16,7 @@ export function getDefaultRolesRequestState(): RolesRequestState { export interface IStratosRolesState { isAdmin: boolean; - scopes: StratosScopeStrings[]; + scopes: UserScopeStrings[]; } export interface ICurrentUserRolesState { diff --git a/src/frontend/packages/store/src/types/endpoint.types.ts b/src/frontend/packages/store/src/types/endpoint.types.ts index 011bde28dc..317c1aab7e 100644 --- a/src/frontend/packages/store/src/types/endpoint.types.ts +++ b/src/frontend/packages/store/src/types/endpoint.types.ts @@ -63,12 +63,14 @@ export interface EndpointModel { export const SystemSharedUserGuid = '00000000-1111-2222-3333-444444444444'; +export type UserScopeStrings = string | StratosScopeStrings; + // Metadata for the user connected to an endpoint export interface EndpointUser { guid: string; name: string; admin: boolean; - scopes?: StratosScopeStrings[]; + scopes?: UserScopeStrings[]; } export interface EndpointState { diff --git a/src/frontend/packages/store/testing/src/store-test-helper.ts b/src/frontend/packages/store/testing/src/store-test-helper.ts index 9ad3e9ab30..ddfcd790e2 100644 --- a/src/frontend/packages/store/testing/src/store-test-helper.ts +++ b/src/frontend/packages/store/testing/src/store-test-helper.ts @@ -11,7 +11,7 @@ import { getDefaultRequestState } from '../../src/reducers/api-request-reducer/t import { getDefaultPaginationEntityState } from '../../src/reducers/pagination-reducer/pagination-reducer-reset-pagination'; import { NormalizedResponse } from '../../src/types/api.types'; import { SessionData, SessionDataEndpoint } from '../../src/types/auth.types'; -import { getDefaultEndpointRoles, getDefaultRolesRequestState } from '../../src/types/current-user-roles.types'; +import { getDefaultRolesRequestState } from '../../src/types/current-user-roles.types'; import { EndpointModel } from '../../src/types/endpoint.types'; import { BaseEntityValues } from '../../src/types/entity.types'; import { WrapperRequestActionSuccess } from '../../src/types/request.types'; @@ -202,9 +202,7 @@ function getDefaultInitialTestStratosStoreState() { isAdmin: false, scopes: [] }, - cf: { - [testSCFEndpointGuid]: getDefaultEndpointRoles() - }, + endpoints: {}, state: getDefaultRolesRequestState() } }; From 4814eecd5a827bf7358a08086ddde681ee87fdc9 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 28 May 2020 09:54:43 +0100 Subject: [PATCH 08/82] Tweaks --- .../cloud-foundry/src/features/cloud-foundry/cf.helpers.ts | 2 -- .../cf-user-permission/cf-user-permission.directive.spec.ts | 4 ++-- .../packages/cloud-foundry/src/store/effects/roles.effects.ts | 2 +- .../src/core/permissions/current-user-permissions.service.ts | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts index 770e16d1dd..675a1f4758 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts @@ -288,12 +288,10 @@ export function canUpdateOrgRoles( export function waitForCFPermissions(store: Store, cfGuid: string): Observable { return store.select(getCurrentUserCFEndpointRolesState(cfGuid)).pipe( - tap(a => console.log('Waiting: ', a)), filter(cf => cf && cf.state.initialised), first(), publishReplay(1), refCount(), - tap(a => console.log('Result: ', a)), ); } diff --git a/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts index 640d7e1fe6..f5eb80d06d 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.spec.ts @@ -5,14 +5,14 @@ import { BaseTestModules } from '../../../../../core/test-framework/core-test.he @Component({ - template: `` + template: `` }) class TestUserPermissionComponent { } class MockTemplateRef { } -describe('UserPermissionDirective', () => { +describe('CfUserPermissionDirective', () => { let component: TestUserPermissionComponent; let fixture: ComponentFixture; beforeEach(() => { diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts index 764e574ad6..9181245b63 100644 --- a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts +++ b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts @@ -25,4 +25,4 @@ export class PermissionEffects { ); }) ); -} \ No newline at end of file +} diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts index 4e6a6afb89..5f18666e51 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts @@ -30,7 +30,6 @@ export const CUSTOM_USER_PERMISSION_CHECKERS = 'custom_user_perm_checkers' @Injectable() export class CurrentUserPermissionsService { - // private checker: StratosUserPermissionsChecker; private allCheckers: ICurrentUserPermissionsChecker[]; constructor( private store: Store, From 7a584a8e21ef96e42d73d52fd594ecf9010baaa8 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 28 May 2020 10:20:39 +0100 Subject: [PATCH 09/82] Finish todos --- .../packages/cloud-foundry/src/shared/cf-shared.module.ts | 2 +- .../cf-user-permission/cf-user-permission.directive.ts | 1 - .../success-entity-request.handler.ts | 2 +- src/frontend/packages/store/src/types/auth.types.ts | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts index a8aab7afda..424e0e08c7 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts @@ -381,7 +381,7 @@ const cfListCards: Type>[] = [ ApplicationStateService, GitSCMService, CloudFoundryUserProvidedServicesService, - ...cfCurrentUserPermissionsService // TODO: RC Review: bring in via endpoint, force checkers to supply type (to fetch via endpoint) + ...cfCurrentUserPermissionsService ] }) export class CloudFoundrySharedModule { } diff --git a/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.ts b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.ts index 6ac1e7f27e..283767d5f4 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/directives/cf-user-permission/cf-user-permission.directive.ts @@ -8,7 +8,6 @@ import { AppState } from '../../../../../store/src/app-state'; import { waitForCFPermissions } from '../../../features/cloud-foundry/cf.helpers'; import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; -// TODO: RC test @Directive({ selector: '[appCfUserPermission]' }) diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/success-entity-request.handler.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/success-entity-request.handler.ts index 4c6867b467..7827aa9952 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/success-entity-request.handler.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/success-entity-request.handler.ts @@ -33,7 +33,7 @@ export function successEntityHandler( if (Array.isArray(action.clearPaginationEntityKeys)) { // If clearPaginationEntityKeys is an array then clear the pagination sections regardless of removeEntityOnDelete action.clearPaginationEntityKeys.forEach(key => { - const entityConfig = entityCatalog.getEntity(action.endpointType, key); // TODO: RC test + const entityConfig = entityCatalog.getEntity(action.endpointType, key); actionDispatcher(new ClearPaginationOfType(entityConfig.getSchema())); }); } diff --git a/src/frontend/packages/store/src/types/auth.types.ts b/src/frontend/packages/store/src/types/auth.types.ts index 82dd621ca6..5cf7e40f42 100644 --- a/src/frontend/packages/store/src/types/auth.types.ts +++ b/src/frontend/packages/store/src/types/auth.types.ts @@ -11,7 +11,7 @@ export interface SessionUser { admin: boolean; guid: string; name: string; - scopes: StratosScopeStrings[]; // TODO: RC test + scopes: StratosScopeStrings[]; } export interface PluginConfig { userInvitationsEnabled: 'true' | 'false'; From 4b037b27c114c8dae9be60a356cbb0cc95bccf2c Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Fri, 29 May 2020 14:42:49 +0100 Subject: [PATCH 10/82] Push combine of permission configs into checkers - overcomes some weird change of permission type --- .../cf-user-permissions-checkers.ts | 53 ++++++++++++++----- .../current-user-permissions.service.ts | 46 ++++------------ .../stratos-user-permissions.checker.ts | 42 ++++++++++----- 3 files changed, 80 insertions(+), 61 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts index d41440bfb6..def80a3110 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts @@ -16,6 +16,7 @@ import { import { BaseCurrentUserPermissionsChecker, IConfigGroup, + IConfigGroups, ICurrentUserPermissionsChecker, IPermissionCheckCombiner, } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; @@ -98,6 +99,10 @@ export enum CfPermissionTypes { FEATURE_FLAG = 'feature-flag', } +enum CHECKER_GROUPS { + CF_GROUP = '__CF_TYPE__' +} + // For each set permissions are checked by permission types of ENDPOINT, ENDPOINT_SCOPE, STRATOS_SCOPE, FEATURE_FLAG or a random bag. // Every group result must be true in order for the permission to be true. A group result is true if all or some of it's permissions are // true (see `getCheckFromConfig`). @@ -197,7 +202,6 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker if (type === CfPermissionTypes.ENDPOINT) { return this.store.select(getCurrentUserCFGlobalState(endpointGuid, permission)); } - return this.getCfEndpointState(endpointGuid).pipe( filter(state => !!state), map(state => { @@ -419,22 +423,47 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker } public getComplexCheck( - configGroup: IConfigGroup, - permission: CfPermissionTypes, + permissionConfigs: PermissionConfig[], endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string - ): IPermissionCheckCombiner { - const checkCombiner = this.getBaseCheckFromConfig(configGroup, permission, endpointGuid, orgOrSpaceGuid, spaceGuid) - if (checkCombiner) { - checkCombiner.checks = checkCombiner.checks.map(check$ => this.applyAdminCheck(check$, endpointGuid)) + ): IPermissionCheckCombiner[] { + const groupedChecks = this.groupConfigs(permissionConfigs); + return Object.keys(groupedChecks).map((permission: PermissionTypes) => { + const configGroup = groupedChecks[permission]; + const checkCombiner = this.getBaseCheckFromConfig(configGroup, permission, endpointGuid, orgOrSpaceGuid, spaceGuid) + if (checkCombiner) { + checkCombiner.checks = checkCombiner.checks.map(check$ => this.applyAdminCheck(check$, endpointGuid)) + } + return checkCombiner; + }); + } + + + private groupConfigs(configs: PermissionConfig[]): IConfigGroups { + return configs.reduce((grouped, config) => { + const type = this.getGroupType(config); + return { + ...grouped, + [type]: [ + ...(grouped[type] || []), + config + ] + }; + }, {}); + } + + private getGroupType(config: PermissionConfig) { + if (config.type === CfPermissionTypes.ORGANIZATION || config.type === CfPermissionTypes.SPACE) { + return CHECKER_GROUPS.CF_GROUP; } - return checkCombiner; + return config.type; } + private getBaseCheckFromConfig( configGroup: IConfigGroup, - permission: CfPermissionTypes, + permission: CfPermissionTypes | CHECKER_GROUPS | string, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string @@ -449,11 +478,7 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker checks: this.getFeatureFlagChecks(configGroup, endpointGuid), combineType: '&&' }; - case CfPermissionTypes.ORGANIZATION: - return { - checks: this.getCfChecks(configGroup, endpointGuid, orgOrSpaceGuid, spaceGuid) - }; - case CfPermissionTypes.SPACE: + case CHECKER_GROUPS.CF_GROUP: return { checks: this.getCfChecks(configGroup, endpointGuid, orgOrSpaceGuid, spaceGuid) }; diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts index 5f18666e51..009a965899 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts @@ -14,12 +14,9 @@ import { PermissionConfig, PermissionConfigLink, PermissionConfigType, - PermissionTypes, } from './current-user-permissions.config'; import { BaseCurrentUserPermissionsChecker, - IConfigGroup, - IConfigGroups, ICurrentUserPermissionsChecker, IPermissionCheckCombiner, StratosUserPermissionsChecker, @@ -100,44 +97,23 @@ export class CurrentUserPermissionsService { ) } - private getComplexPermission(actionConfigs: PermissionConfig[], endpointGuid?: string, ...args: any[]) { - const groupedChecks = this.groupConfigs(actionConfigs); - const checks = this.getChecksFromConfigGroups(groupedChecks, endpointGuid, ...args); + private getComplexPermission(permissionConfig: PermissionConfig[], endpointGuid?: string, ...args: any[]) { + const checks = this.getComplexChecks(permissionConfig, endpointGuid, ...args); return this.combineChecks(checks); } - private groupConfigs(configs: PermissionConfig[]): IConfigGroups { - return configs.reduce((grouped, config) => { - const type = config.type; - return { - ...grouped, - [type]: [ - ...(grouped[type] || []), - config - ] - }; - }, {}); - } - - private getChecksFromConfigGroups(groups: IConfigGroups, endpointGuid?: string, ...args: any[]) { - return Object.keys(groups).map((permission: PermissionTypes) => { - return this.getCheckFromConfig(groups[permission], permission, endpointGuid, ...args); - }); - } - - private getCheckFromConfig( - configGroup: IConfigGroup, - permission: PermissionTypes, + private getComplexChecks( + permissionConfig: PermissionConfig[], endpointGuid: string, ...args: any[] - ): IPermissionCheckCombiner { - return this.findChecker( - (checker: ICurrentUserPermissionsChecker) => checker.getComplexCheck(configGroup, permission, endpointGuid, ...args), - 'permissions check', - permission, - { + ): IPermissionCheckCombiner[] { + return this.findChecker( + (checker: ICurrentUserPermissionsChecker) => checker.getComplexCheck(permissionConfig, endpointGuid, ...args), + 'complex permissions check', + 'a group', + [{ checks: [of(false)] - } + }] ) } diff --git a/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts index 54956509e5..ff977c886c 100644 --- a/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts +++ b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts @@ -41,16 +41,16 @@ export interface ICurrentUserPermissionsChecker { getSimpleCheck: ( permissionConfig: PermissionConfig, endpointGuid?: string, - ...args: any + ...args: any[] ) => Observable; /** * Used when the permission config contains multiple things to check */ getComplexCheck: ( - configGroup: IConfigGroup, + permissionConfig: PermissionConfig[], permission: PermissionTypes, ...args: any[] - ) => IPermissionCheckCombiner; + ) => IPermissionCheckCombiner[]; /** * If no checker provides simple */ @@ -153,19 +153,37 @@ export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChe } public getComplexCheck( - configGroup: IConfigGroup, - permission: PermissionTypes, + permissionConfig: PermissionConfig[], ...args: any[] - ): IPermissionCheckCombiner { - switch (permission) { - case StratosPermissionTypes.STRATOS_SCOPE: - return { - checks: this.getInternalScopesChecks(configGroup), - }; - } + ): IPermissionCheckCombiner[] { + const groupedChecks = this.groupConfigs(permissionConfig); + const res = Object.keys(groupedChecks).map((permission: PermissionTypes) => { + const configGroup = groupedChecks[permission]; + switch (permission) { + case StratosPermissionTypes.STRATOS_SCOPE: + return { + checks: this.getInternalScopesChecks(configGroup), + }; + } + }) + // Checker must handle all configs + return res.every(check => !!check) ? res : null; } public getFallbackCheck(endpointGuid: string, endpointType: string): Observable { return null; }; + private groupConfigs(configs: PermissionConfig[]): IConfigGroups { + return configs.reduce((grouped, config) => { + const type = config.type; + return { + ...grouped, + [type]: [ + ...(grouped[type] || []), + config + ] + }; + }, {}); + } + } From 75d0f4f234e1c10b21c9f0ae698c9d229b1e07c1 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 3 Jun 2020 14:25:59 +0100 Subject: [PATCH 11/82] Fix endpoint connect --- .../user-permissions/cf-user-roles-fetch.ts | 33 +++++++++++++------ .../store/src/effects/permissions.effect.ts | 19 ++++++++--- .../entity-request-pipeline.types.ts | 8 ++++- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts index a38da02657..24ae18d80f 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts @@ -6,7 +6,10 @@ import { catchError, first, map, pairwise, share, skipWhile, switchMap, tap } fr import { LoggerService } from '../../../core/src/core/logger.service'; import { AppState } from '../../../store/src/app-state'; import { entityCatalog } from '../../../store/src/entity-catalog/entity-catalog'; -import { EntityUserRolesFetch } from '../../../store/src/entity-request-pipeline/entity-request-pipeline.types'; +import { + EntityUserRolesEndpoint, + EntityUserRolesFetch, +} from '../../../store/src/entity-request-pipeline/entity-request-pipeline.types'; import { BaseHttpClientFetcher, flattenPagination, @@ -14,7 +17,6 @@ import { } from '../../../store/src/helpers/paginated-request-helpers'; import { ActionState } from '../../../store/src/reducers/api-request-reducer/types'; import { selectPaginationState } from '../../../store/src/selectors/pagination.selectors'; -import { EndpointModel } from '../../../store/src/types/endpoint.types'; import { BasePaginatedAction, PaginationEntityState } from '../../../store/src/types/pagination.types'; import { CfUserRelationTypes, @@ -29,18 +31,29 @@ import { cfEntityCatalog } from '../cf-entity-catalog'; import { endpointsCfEntitiesConnectedSelector } from '../store/selectors/cloud-foundry.selector'; import { CFResponse } from '../store/types/cf-api.types'; +const createEndpointArray = (store: Store, endpoints: string[] | EntityUserRolesEndpoint[]): Observable => { + // If there's no endpoints get all from store. Alternatively fetch specific endpoint id's from store + if (!endpoints || !endpoints.length || typeof (endpoints[0]) === 'string') { + const endpointIds = endpoints as string[]; + return store.select(endpointsCfEntitiesConnectedSelector).pipe( + first(), + map(cfEndpoints => endpointIds.length === 0 ? + Object.values(cfEndpoints) : + Object.values(cfEndpoints).filter(cfEndpoint => endpointIds.find(endpointId => endpointId === cfEndpoint.guid)) + ), + ); + } + return of(endpoints as EntityUserRolesEndpoint[]); +} + export const cfUserRolesFetch: EntityUserRolesFetch = ( - endpointIds: string[], + endpoints: string[] | EntityUserRolesEndpoint[], store: Store, logService: LoggerService, httpClient: HttpClient ) => { - return store.select(endpointsCfEntitiesConnectedSelector).pipe( - first(), - map(cfEndpoints => endpointIds.length === 0 ? - Object.values(cfEndpoints) : - Object.values(cfEndpoints).filter(cfEndpoint => endpointIds.find(endpointId => endpointId === cfEndpoint.guid))), - switchMap((cfEndpoints: EndpointModel[]) => { + return createEndpointArray(store, endpoints).pipe( + switchMap((cfEndpoints: EntityUserRolesEndpoint[]) => { const isAllAdmins = cfEndpoints.every(endpoint => !!endpoint.user.admin); // If all endpoints are connected as admin, there's no permissions to fetch. So only update the permission state to initialised if (isAllAdmins) { @@ -68,7 +81,7 @@ interface IEndpointConnectionInfo { } function dispatchRoleRequests( - endpoints: EndpointModel[], + endpoints: EntityUserRolesEndpoint[], store: Store, logService: LoggerService, httpClient: HttpClient diff --git a/src/frontend/packages/store/src/effects/permissions.effect.ts b/src/frontend/packages/store/src/effects/permissions.effect.ts index d3b29a31e8..bb890b00a7 100644 --- a/src/frontend/packages/store/src/effects/permissions.effect.ts +++ b/src/frontend/packages/store/src/effects/permissions.effect.ts @@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { Action, Store } from '@ngrx/store'; -import { combineLatest, of as observableOf, of } from 'rxjs'; +import { combineLatest, EMPTY, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; import { LoggerService } from '../../../core/src/core/logger.service'; @@ -15,6 +15,7 @@ import { } from '../actions/permissions.actions'; import { AppState } from '../app-state'; import { entityCatalog } from '../entity-catalog/entity-catalog'; +import { EntityUserRolesEndpoint } from '../entity-request-pipeline/entity-request-pipeline.types'; const successAction: Action = { type: GET_CURRENT_USER_RELATIONS_SUCCESS }; const failedAction: Action = { type: GET_CURRENT_USER_RELATIONS_FAILED }; @@ -44,7 +45,7 @@ export class PermissionsEffects { }), catchError(err => { this.logService.warn('Failed to fetch current user permissions: ', err); - return observableOf([failedAction]); + return of(failedAction); }) ); @@ -54,11 +55,19 @@ export class PermissionsEffects { switchMap(action => { const endpointType = entityCatalog.getEndpoint(action.endpointType) if (!endpointType.definition.userRolesFetch) { - return of([]); + return EMPTY; } - return endpointType.definition.userRolesFetch([action.guid], this.store, this.logService, this.httpClient).pipe( - map(() => []) + const endpoint: EntityUserRolesEndpoint = { + guid: action.guid, + user: action.endpoint.user + } + return endpointType.definition.userRolesFetch([endpoint], this.store, this.logService, this.httpClient).pipe( + map(succeeded => succeeded ? successAction : failedAction) ); + }), + catchError(err => { + this.logService.warn('Failed to fetch current user permissions after endpoint connected: ', err); + return of(failedAction); }) ); } diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts index 4ce8c8e61f..46e1d685cd 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts @@ -11,6 +11,7 @@ import { } from '../entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { ApiRequestTypes } from '../reducers/api-request-reducer/request-helpers'; import { EntityInfo, NormalizedResponse } from '../types/api.types'; +import { EndpointUser } from '../types/endpoint.types'; import { PaginatedAction, PaginationEntityState } from '../types/pagination.types'; import { EntityRequestAction } from '../types/request.types'; import { JetstreamError } from './entity-request-base-handlers/handle-multi-endpoints.pipe'; @@ -137,8 +138,13 @@ export type EntityFetch = (entity: T) => void; export type EntityFetchHandler = (store: Store, action: EntityRequestAction) => EntityFetch; export type EntitiesFetchHandler = (store: Store, actions: PaginatedAction[]) => () => void; +export interface EntityUserRolesEndpoint { + user?: EndpointUser; + guid?: string; +} + export type EntityUserRolesFetch = ( - endpointIds: string[], + endpoints: string[] | EntityUserRolesEndpoint[], store: Store, logService: LoggerService, httpClient: HttpClient From 74f5d9318e95274ca072ca0c3fd239f41582f776 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 3 Jun 2020 15:58:36 +0100 Subject: [PATCH 12/82] Fix unit test --- .../core/permissions/current-user-permissions.service.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts index a64bfe18fa..e8e69c7782 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts @@ -1,5 +1,5 @@ import { TestBed } from '@angular/core/testing'; -import { createBasicStoreModule, createEntityStoreState, TestStoreEntity } from '@stratos/store/testing'; +import { createBasicStoreModule, createEntityStoreState, TestStoreEntity } from '@stratosui/store/testing'; import { first, tap } from 'rxjs/operators'; import { AppState } from '../../../../store/src/app-state'; From df2a9589a3f4f81d938b2eeb5dbcb6c4f792b7a6 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 3 Jun 2020 16:19:26 +0100 Subject: [PATCH 13/82] Fix e2e test --- .../current-cf-user-roles.reducer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.ts b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.ts index b120d779c8..89a24cc8e5 100644 --- a/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.ts +++ b/src/frontend/packages/cloud-foundry/src/store/reducers/current-cf-user-roles-reducer/current-cf-user-roles.reducer.ts @@ -37,7 +37,7 @@ import { } from './current-cf-user-roles-clear.reducers'; export const currentCfUserRolesReducer: EntityUserRolesReducer = ( - state: IAllCfRolesState, + state: IAllCfRolesState = {}, action: Action ): IAllCfRolesState => { switch (action.type) { From 619e9b3382f1bea6314b50193158dcf541bd1acc Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 4 Jun 2020 13:30:00 +0100 Subject: [PATCH 14/82] Change following review #1 --- .../cf-services-list-config.service.ts | 5 +- .../cf-org-space-service.service.ts | 5 +- .../src/store/cloud-foundry.store.module.ts | 2 - .../src/store/effects/roles.effects.ts | 28 -------- .../src/store/effects/users-roles.effects.ts | 14 ++++ .../store/selectors/cloud-foundry.selector.ts | 4 -- .../cf-user-permissions-checkers.ts | 4 +- .../user-permissions/cf-user-roles-fetch.ts | 5 +- .../current-user-permissions.service.ts | 4 +- .../current-user-permissions.types.ts | 61 ++++++++++++++++ .../stratos-user-permissions.checker.ts | 72 ++----------------- .../current-user-roles.reducer.ts | 4 +- .../src/types/current-user-roles.types.ts | 5 +- 13 files changed, 99 insertions(+), 114 deletions(-) delete mode 100644 src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts delete mode 100644 src/frontend/packages/cloud-foundry/src/store/selectors/cloud-foundry.selector.ts create mode 100644 src/frontend/packages/core/src/core/permissions/current-user-permissions.types.ts diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-services-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-services-list-config.service.ts index 954c2562d0..90fdcad893 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-services-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-services-list-config.service.ts @@ -11,10 +11,11 @@ import { ListViewTypes, } from '../../../../../../../core/src/shared/components/list/list.component.types'; import { ListView } from '../../../../../../../store/src/actions/list.actions'; +import { connectedEndpointsOfTypesSelector } from '../../../../../../../store/src/selectors/endpoint.selectors'; import { APIResource } from '../../../../../../../store/src/types/api.types'; +import { CF_ENDPOINT_TYPE } from '../../../../../cf-types'; import { ActiveRouteCfOrgSpace } from '../../../../../features/cloud-foundry/cf-page.types'; import { haveMultiConnectedCfs } from '../../../../../features/cloud-foundry/cf.helpers'; -import { endpointsCfEntitiesConnectedSelector } from '../../../../../store/selectors/cloud-foundry.selector'; import { CfOrgSpaceItem, createCfOrgSpaceFilterConfig } from '../../../../data-services/cf-org-space-service.service'; import { CfServiceCardComponent } from './cf-service-card/cf-service-card.component'; import { CfServicesDataSource } from './cf-services-data-source'; @@ -38,7 +39,7 @@ export class CfServicesListConfigService implements IListConfig { ) { this.dataSource = new CfServicesDataSource(this.store, activeRouteCfOrgSpace.cfGuid, this); this.cf = { - list$: this.store.select(endpointsCfEntitiesConnectedSelector).pipe( + list$: this.store.select(connectedEndpointsOfTypesSelector(CF_ENDPOINT_TYPE)).pipe( first(), map(endpoints => Object.values(endpoints)) ), diff --git a/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-org-space-service.service.ts b/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-org-space-service.service.ts index 8a8951d87c..e8ce2c3184 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-org-space-service.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-org-space-service.service.ts @@ -27,6 +27,7 @@ import { ResetPagination, SetParams } from '../../../../store/src/actions/pagina import { PaginationMonitorFactory } from '../../../../store/src/monitors/pagination-monitor.factory'; import { getPaginationObservables } from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; import { getCurrentPageRequestInfo } from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.types'; +import { connectedEndpointsOfTypesSelector } from '../../../../store/src/selectors/endpoint.selectors'; import { selectPaginationState } from '../../../../store/src/selectors/pagination.selectors'; import { APIResource } from '../../../../store/src/types/api.types'; import { EndpointModel } from '../../../../store/src/types/endpoint.types'; @@ -34,7 +35,7 @@ import { PaginatedAction, PaginationParam } from '../../../../store/src/types/pa import { IOrganization, ISpace } from '../../cf-api.types'; import { cfEntityCatalog } from '../../cf-entity-catalog'; import { cfEntityFactory } from '../../cf-entity-factory'; -import { endpointsCfEntitiesConnectedSelector } from '../../store/selectors/cloud-foundry.selector'; +import { CF_ENDPOINT_TYPE } from '../../cf-types'; import { QParam, QParamJoiners } from '../q-param'; export function spreadPaginationParams(params: PaginationParam): PaginationParam { @@ -221,7 +222,7 @@ export class CfOrgSpaceDataService implements OnDestroy { } private createCf() { - const list$ = this.store.select(endpointsCfEntitiesConnectedSelector).pipe( + const list$ = this.store.select(connectedEndpointsOfTypesSelector(CF_ENDPOINT_TYPE)).pipe( // Ensure we have endpoints filter(endpoints => endpoints && !!Object.keys(endpoints).length), publishReplay(1), diff --git a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts index 45ddef3acb..d209acc642 100644 --- a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts +++ b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts @@ -10,7 +10,6 @@ import { CreateAppPageEffects } from './effects/create-app-effects'; import { DeployAppEffects } from './effects/deploy-app.effects'; import { GithubEffects } from './effects/github.effects'; import { CfValidateEffects } from './effects/request.effects'; -import { PermissionEffects } from './effects/roles.effects'; import { RouteEffect } from './effects/route.effects'; import { ServiceInstanceEffects } from './effects/service-instance.effects'; import { UpdateAppEffects } from './effects/update-app-effects'; @@ -26,7 +25,6 @@ import { UsersRolesEffects } from './effects/users-roles.effects'; GithubEffects, CloudFoundryEffects, RouteEffect, - PermissionEffects, ServiceInstanceEffects, AppEffects, UpdateAppEffects, diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts deleted file mode 100644 index 9181245b63..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/effects/roles.effects.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; -import { Store } from '@ngrx/store'; -import { catchError, map } from 'rxjs/operators'; - -import { GET_CURRENT_CF_USER_RELATION, GetCurrentCfUserRelations } from '../../actions/permissions.actions'; -import { CFAppState } from '../../cf-app-state'; -import { fetchCfUserRole } from '../../user-permissions/cf-user-roles-fetch'; - -@Injectable() -export class PermissionEffects { - constructor( - private httpClient: HttpClient, - private actions$: Actions, - private store: Store - ) { } - - @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( - ofType(GET_CURRENT_CF_USER_RELATION), - map(action => { - return fetchCfUserRole(this.store, action, this.httpClient).pipe( - map(() => ({ type: action.actions[1] })), - catchError(() => [{ type: action.actions[2] }]) - ); - }) - ); -} diff --git a/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts b/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts index 8b84913970..7ed0d48c09 100644 --- a/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts +++ b/src/frontend/packages/cloud-foundry/src/store/effects/users-roles.effects.ts @@ -1,3 +1,4 @@ +import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; @@ -14,12 +15,14 @@ import { selectSessionData } from '../../../../store/src/reducers/auth.reducer'; import { SessionDataEndpoint } from '../../../../store/src/types/auth.types'; import { PaginatedAction } from '../../../../store/src/types/pagination.types'; import { ICFAction, UpdateCfAction } from '../../../../store/src/types/request.types'; +import { GET_CURRENT_CF_USER_RELATION, GetCurrentCfUserRelations } from '../../actions/permissions.actions'; import { UsersRolesActions, UsersRolesClearUpdateState, UsersRolesExecuteChanges } from '../../actions/users-roles.actions'; import { AddCfUserRole, ChangeCfUserRole, RemoveCfUserRole } from '../../actions/users.actions'; import { CFAppState } from '../../cf-app-state'; import { organizationEntityType, spaceEntityType } from '../../cf-entity-types'; import { CF_ENDPOINT_TYPE } from '../../cf-types'; import { CfUserService } from '../../shared/data-services/cf-user.service'; +import { fetchCfUserRole } from '../../user-permissions/cf-user-roles-fetch'; import { selectCfUsersRoles } from '../selectors/cf-users-roles.selector'; import { OrgUserRoleNames } from '../types/cf-user.types'; import { CfRoleChange, UsersRolesState } from '../types/users-roles.types'; @@ -29,11 +32,22 @@ import { CfRoleChange, UsersRolesState } from '../types/users-roles.types'; export class UsersRolesEffects { constructor( + private httpClient: HttpClient, private actions$: Actions, private store: Store, private cfUserService: CfUserService, ) { } + @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( + ofType(GET_CURRENT_CF_USER_RELATION), + map(action => { + return fetchCfUserRole(this.store, action, this.httpClient).pipe( + map(() => ({ type: action.actions[1] })), + catchError(() => [{ type: action.actions[2] }]) + ); + }) + ); + @Effect() clearEntityUpdates$ = this.actions$.pipe( ofType(UsersRolesActions.ClearUpdateState), mergeMap(action => { diff --git a/src/frontend/packages/cloud-foundry/src/store/selectors/cloud-foundry.selector.ts b/src/frontend/packages/cloud-foundry/src/store/selectors/cloud-foundry.selector.ts deleted file mode 100644 index 3df60ec938..0000000000 --- a/src/frontend/packages/cloud-foundry/src/store/selectors/cloud-foundry.selector.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { connectedEndpointsOfTypesSelector } from '../../../../store/src/selectors/endpoint.selectors'; -import { CF_ENDPOINT_TYPE } from '../../cf-types'; - -export const endpointsCfEntitiesConnectedSelector = connectedEndpointsOfTypesSelector(CF_ENDPOINT_TYPE); diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts index def80a3110..b38816caf9 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts @@ -19,7 +19,7 @@ import { IConfigGroups, ICurrentUserPermissionsChecker, IPermissionCheckCombiner, -} from '../../../core/src/core/permissions/stratos-user-permissions.checker'; +} from '../../../core/src/core/permissions/current-user-permissions.types'; import { GeneralEntityAppState } from '../../../store/src/app-state'; import { connectedEndpointsSelector } from '../../../store/src/selectors/endpoint.selectors'; import { CFFeatureFlagTypes, IFeatureFlag } from '../cf-api.types'; @@ -397,7 +397,7 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker private getAllEndpointGuids() { return this.store.select(connectedEndpointsSelector).pipe( - map(endpoints => Object.values(endpoints).filter(e => e.cnsi_type === 'cf').map(endpoint => endpoint.guid)) + map(endpoints => Object.values(endpoints).filter(e => e.cnsi_type === CF_ENDPOINT_TYPE).map(endpoint => endpoint.guid)) ); } diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts index 24ae18d80f..ec6687ced1 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts @@ -16,6 +16,7 @@ import { PaginationFlattener, } from '../../../store/src/helpers/paginated-request-helpers'; import { ActionState } from '../../../store/src/reducers/api-request-reducer/types'; +import { connectedEndpointsOfTypesSelector } from '../../../store/src/selectors/endpoint.selectors'; import { selectPaginationState } from '../../../store/src/selectors/pagination.selectors'; import { BasePaginatedAction, PaginationEntityState } from '../../../store/src/types/pagination.types'; import { @@ -28,14 +29,14 @@ import { GetCurrentCfUserRelationsComplete, } from '../actions/permissions.actions'; import { cfEntityCatalog } from '../cf-entity-catalog'; -import { endpointsCfEntitiesConnectedSelector } from '../store/selectors/cloud-foundry.selector'; +import { CF_ENDPOINT_TYPE } from '../cf-types'; import { CFResponse } from '../store/types/cf-api.types'; const createEndpointArray = (store: Store, endpoints: string[] | EntityUserRolesEndpoint[]): Observable => { // If there's no endpoints get all from store. Alternatively fetch specific endpoint id's from store if (!endpoints || !endpoints.length || typeof (endpoints[0]) === 'string') { const endpointIds = endpoints as string[]; - return store.select(endpointsCfEntitiesConnectedSelector).pipe( + return store.select(connectedEndpointsOfTypesSelector(CF_ENDPOINT_TYPE)).pipe( first(), map(cfEndpoints => endpointIds.length === 0 ? Object.values(cfEndpoints) : diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts index 009a965899..3d407620cd 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts @@ -19,8 +19,8 @@ import { BaseCurrentUserPermissionsChecker, ICurrentUserPermissionsChecker, IPermissionCheckCombiner, - StratosUserPermissionsChecker, -} from './stratos-user-permissions.checker'; +} from './current-user-permissions.types'; +import { StratosUserPermissionsChecker } from './stratos-user-permissions.checker'; export const CUSTOM_USER_PERMISSION_CHECKERS = 'custom_user_perm_checkers' diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.types.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.types.ts new file mode 100644 index 0000000000..1314130007 --- /dev/null +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.types.ts @@ -0,0 +1,61 @@ +import { combineLatest, Observable, of } from 'rxjs'; +import { distinctUntilChanged, map } from 'rxjs/operators'; + +import { PermissionConfig, PermissionConfigType, PermissionTypes } from './current-user-permissions.config'; + +export interface IConfigGroups { + [permissionType: string]: IConfigGroup; +} + +export type IConfigGroup = PermissionConfig[]; + +export type IPermissionCheckCombineTypes = '||' | '&&'; + +export interface IPermissionCheckCombiner { + checks: Observable[]; + combineType?: IPermissionCheckCombineTypes; +} +export interface ICurrentUserPermissionsChecker { + /** + * For the given permission action find the checker configuration that will determine if the user can or cannot do the action + * If this is not supported by the the checker null is returned. If another checker also lays claim to the same string the check will + * always return denied + */ + getPermissionConfig: (action: string) => PermissionConfigType + /** + * Simple checks are used when the permission config contains a single thing to check + */ + getSimpleCheck: ( + permissionConfig: PermissionConfig, + endpointGuid?: string, + ...args: any[] + ) => Observable; + /** + * Used when the permission config contains multiple things to check + */ + getComplexCheck: ( + permissionConfig: PermissionConfig[], + permission: PermissionTypes, + ...args: any[] + ) => IPermissionCheckCombiner[]; + /** + * If no checker provides simple + */ + getFallbackCheck: ( + endpointGuid: string, + endpointType: string + ) => Observable; +} + +export abstract class BaseCurrentUserPermissionsChecker { + public static reduceChecks(checks: Observable[], type: IPermissionCheckCombineTypes = '||') { + const func = type === '||' ? 'some' : 'every'; + if (!checks || !checks.length) { + return of(true); + } + return combineLatest(checks).pipe( + map(flags => flags[func](flag => flag)), + distinctUntilChanged() + ); + } +} \ No newline at end of file diff --git a/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts index ff977c886c..a0bcb58695 100644 --- a/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts +++ b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts @@ -1,78 +1,20 @@ import { Store } from '@ngrx/store'; -import { combineLatest, Observable, of as observableOf } from 'rxjs'; -import { distinctUntilChanged, map } from 'rxjs/operators'; +import { Observable } from 'rxjs'; import { GeneralEntityAppState } from '../../../../store/src/app-state'; import { getCurrentUserStratosHasScope, getCurrentUserStratosRole, } from '../../../../store/src/selectors/current-user-role.selectors'; +import { IPermissionConfigs, PermissionConfig, PermissionTypes, PermissionValues } from './current-user-permissions.config'; import { - IPermissionConfigs, - PermissionConfig, - PermissionConfigType, - PermissionTypes, - PermissionValues, -} from './current-user-permissions.config'; + BaseCurrentUserPermissionsChecker, + IConfigGroups, + ICurrentUserPermissionsChecker, + IPermissionCheckCombiner, +} from './current-user-permissions.types'; -export interface IConfigGroups { - [permissionType: string]: IConfigGroup; -} - -export type IConfigGroup = PermissionConfig[]; - -export type IPermissionCheckCombineTypes = '||' | '&&'; - -export interface IPermissionCheckCombiner { - checks: Observable[]; - combineType?: IPermissionCheckCombineTypes; -} -export interface ICurrentUserPermissionsChecker { - /** - * For the given permission action find the checker configuration that will determine if the user can or cannot do the action - * If this is not supported by the the checker null is returned. If another checker also lays claim to the same string the check will - * always return denied - */ - getPermissionConfig: (action: string) => PermissionConfigType - /** - * Simple checks are used when the permission config contains a single thing to check - */ - getSimpleCheck: ( - permissionConfig: PermissionConfig, - endpointGuid?: string, - ...args: any[] - ) => Observable; - /** - * Used when the permission config contains multiple things to check - */ - getComplexCheck: ( - permissionConfig: PermissionConfig[], - permission: PermissionTypes, - ...args: any[] - ) => IPermissionCheckCombiner[]; - /** - * If no checker provides simple - */ - getFallbackCheck: ( - endpointGuid: string, - endpointType: string - ) => Observable; -} - -export abstract class BaseCurrentUserPermissionsChecker { - public static reduceChecks(checks: Observable[], type: IPermissionCheckCombineTypes = '||') { - const func = type === '||' ? 'some' : 'every'; - if (!checks || !checks.length) { - return observableOf(true); - } - return combineLatest(checks).pipe( - map(flags => flags[func](flag => flag)), - distinctUntilChanged() - ); - } -} - export enum StratosCurrentUserPermissions { ENDPOINT_REGISTER = 'register.endpoint', PASSWORD_CHANGE = 'change-password', diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts index c75ebfbc4e..ad4ffc58b4 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/current-user-roles.reducer.ts @@ -24,8 +24,8 @@ const getDefaultState = () => ({ }); export function currentUserRolesReducer(state: ICurrentUserRolesState = getDefaultState(), action: Action): ICurrentUserRolesState { - const stateAfterStratosChanges = coreCurrentUserRolesReducer(state, action); - return entityCatalog.getAllCurrentUserReducers(stateAfterStratosChanges, action); + const stateAfterCoreChanges = coreCurrentUserRolesReducer(state, action); + return entityCatalog.getAllCurrentUserReducers(stateAfterCoreChanges, action); } function coreCurrentUserRolesReducer(state: ICurrentUserRolesState, action: Action): ICurrentUserRolesState { diff --git a/src/frontend/packages/store/src/types/current-user-roles.types.ts b/src/frontend/packages/store/src/types/current-user-roles.types.ts index 08243b9ed7..90c41efcb4 100644 --- a/src/frontend/packages/store/src/types/current-user-roles.types.ts +++ b/src/frontend/packages/store/src/types/current-user-roles.types.ts @@ -19,11 +19,10 @@ export interface IStratosRolesState { scopes: UserScopeStrings[]; } -export interface ICurrentUserRolesState { +export interface ICurrentUserRolesState { internal: IStratosRolesState; endpoints: { - // T could be different in each endpoint type, however supplying a type makes it nicer to use when looking at a specific type - [endpointType: string]: T + [endpointType: string]: any } state: RolesRequestState; } From 01d5025a0fd833bf3fe15da725b6e8453b11d47e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2020 14:43:22 +0100 Subject: [PATCH 15/82] Bump github.com/gorilla/websocket from 1.4.1 to 1.4.2 in /src/jetstream (#4199) * Bump github.com/gorilla/websocket from 1.4.1 to 1.4.2 in /src/jetstream Bumps [github.com/gorilla/websocket](https://github.com/gorilla/websocket) from 1.4.1 to 1.4.2. - [Release notes](https://github.com/gorilla/websocket/releases) - [Commits](https://github.com/gorilla/websocket/compare/v1.4.1...v1.4.2) Signed-off-by: dependabot-preview[bot] * Update go.sum Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Neil MacDougall --- src/jetstream/go.mod | 2 +- src/jetstream/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jetstream/go.mod b/src/jetstream/go.mod index aecae07f82..9837788a29 100644 --- a/src/jetstream/go.mod +++ b/src/jetstream/go.mod @@ -47,7 +47,7 @@ require ( github.com/gorilla/context v1.1.1 github.com/gorilla/securecookie v1.1.1 github.com/gorilla/sessions v1.1.3 - github.com/gorilla/websocket v1.4.1 + github.com/gorilla/websocket v1.4.2 github.com/govau/cf-common v0.0.7 github.com/jessevdk/go-flags v1.4.0 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect diff --git a/src/jetstream/go.sum b/src/jetstream/go.sum index 494c818e50..4b5f0a3ca4 100644 --- a/src/jetstream/go.sum +++ b/src/jetstream/go.sum @@ -162,10 +162,10 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.1.3 h1:uXoZdcdA5XdXF3QzuSlheVRUvjl+1rKY7zBXL68L9RU= github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/govau/cf-common v0.0.7 h1:uhp1P6XM6GGzu1+A4C7LELLX/9mCmH6W5DpJZC0kWmo= github.com/govau/cf-common v0.0.7/go.mod h1:5xL/OfE7wxeyHlXb7iei0rAbdQ/5v6dF18BZknPv7NQ= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= From cf3a004aae3015549d0ea63d4b333318e321076b Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 15:08:35 +0100 Subject: [PATCH 16/82] Fix errors in console log during setup screens --- src/frontend/packages/core/src/core/user-profile.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend/packages/core/src/core/user-profile.service.ts b/src/frontend/packages/core/src/core/user-profile.service.ts index 52e766a9b3..f83b16a256 100644 --- a/src/frontend/packages/core/src/core/user-profile.service.ts +++ b/src/frontend/packages/core/src/core/user-profile.service.ts @@ -16,6 +16,7 @@ import { EntityServiceFactory } from '../../../store/src/entity-service-factory. import { ActionState, getDefaultActionState, rootUpdatingKey } from '../../../store/src/reducers/api-request-reducer/types'; import { AuthState } from '../../../store/src/reducers/auth.reducer'; import { selectRequestInfo, selectUpdateInfo } from '../../../store/src/selectors/api.selectors'; +import { SessionData } from '../../../store/src/types/auth.types'; import { UserProfileInfo, UserProfileInfoEmail, UserProfileInfoUpdates } from '../../../store/src/types/user-profile.types'; import { userProfileEntitySchema } from '../base-entity-schemas'; @@ -69,6 +70,7 @@ export class UserProfileService { return this.store.select(s => s.auth).pipe( filter((auth: AuthState) => !!(auth && auth.sessionData)), map((auth: AuthState) => auth.sessionData), + filter((sessionData: SessionData) => !!sessionData.user), first(), map(data => new FetchUserProfileAction(data.user.guid)) ); From 0fca6675e2f8d78b36eda37ee215143e2be28c35 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 15:14:00 +0100 Subject: [PATCH 17/82] Helm: Change default image pull policy to Always --- deploy/kubernetes/console/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/kubernetes/console/values.yaml b/deploy/kubernetes/console/values.yaml index d2d25823db..b4574757a4 100644 --- a/deploy/kubernetes/console/values.yaml +++ b/deploy/kubernetes/console/values.yaml @@ -8,7 +8,7 @@ dockerRegistrySecret: regsecret #noProxy: localhost #ftpProxy: proxy.corp.net #socksProxy: sock-proxy.corp.net -imagePullPolicy: IfNotPresent +imagePullPolicy: Always console: cookieDomain: From 29a1887e9bb2cf3a199176cce1d4729666361673 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 16:41:49 +0100 Subject: [PATCH 18/82] Add copy address and edit to endpoint list view --- .../endpoint-card/endpoint-card.component.ts | 10 +---- .../endpoint/endpoint-list.helpers.ts | 17 +++++++-- .../endpoint/endpoints-list-config.service.ts | 6 +-- ...table-cell-endpoint-address.component.html | 5 +++ ...table-cell-endpoint-address.component.scss | 8 ++++ ...le-cell-endpoint-address.component.spec.ts | 28 ++++++++++++++ .../table-cell-endpoint-address.component.ts | 38 +++++++++++++++++++ .../packages/core/src/shared/shared.module.ts | 4 ++ 8 files changed, 100 insertions(+), 16 deletions(-) create mode 100644 src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.html create mode 100644 src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.scss create mode 100644 src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.spec.ts create mode 100644 src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts index 001218b451..9e91b5e56a 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts @@ -9,7 +9,6 @@ import { ViewContainerRef, } from '@angular/core'; import { Store } from '@ngrx/store'; -import { CurrentUserPermissions } from 'frontend/packages/core/src/core/current-user-permissions.config'; import { CurrentUserPermissionsService } from 'frontend/packages/core/src/core/current-user-permissions.service'; import { AppState } from 'frontend/packages/store/src/app-state'; import { Observable, of, ReplaySubject, Subscription } from 'rxjs'; @@ -107,15 +106,8 @@ export class EndpointCardComponent extends CardCell implements On can: endpointAction.createVisible(this.rowObs) })); - // Add edit - this.cardMenu.push({ - label: 'Edit endpoint', - action: () => this.editEndpoint(), - can: this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER) - }); - this.cardMenu.push(createMetaCardMenuItemSeparator()); - // Add a copy address to clipboard + this.cardMenu.push(createMetaCardMenuItemSeparator()); this.cardMenu.push({ label: 'Copy address to Clipboard', action: () => this.copyToClipboard.copyToClipboard(), diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts index d785fb066b..8770e7b8c5 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts @@ -5,6 +5,7 @@ import { combineLatest, Observable } from 'rxjs'; import { map, pairwise } from 'rxjs/operators'; import { DisconnectEndpoint, UnregisterEndpoint } from '../../../../../../../store/src/actions/endpoint.actions'; +import { RouterNav } from '../../../../../../../store/src/actions/router.actions'; import { ShowSnackBar } from '../../../../../../../store/src/actions/snackBar.actions'; import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions'; import { AppState } from '../../../../../../../store/src/app-state'; @@ -120,6 +121,16 @@ export class EndpointListHelper { label: 'Unregister', description: 'Remove the endpoint', createVisible: () => this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER) + }, + { + action: (item) => { + console.log(item); + const routerLink = `/endpoints/edit/${item.guid}`; + this.store.dispatch(new RouterNav({ path: routerLink })); + }, + label: 'Edit endpoint', + description: 'Edit the endpoint', + createVisible: () => this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER) } ]; } @@ -151,8 +162,8 @@ export class EndpointListHelper { }); } - createEndpointDetails(listDetailsComponent: any, container: ViewContainerRef, componentFactoryResolver: ComponentFactoryResolver): - EndpointDetailsContainerRefs { +createEndpointDetails(listDetailsComponent: any, container: ViewContainerRef, componentFactoryResolver: ComponentFactoryResolver): +EndpointDetailsContainerRefs { const componentFactory = componentFactoryResolver.resolveComponentFactory(listDetailsComponent); const componentRef = container.createComponent(componentFactory); const component = isEndpointListDetailsComponent(componentRef.instance); @@ -168,7 +179,7 @@ export class EndpointListHelper { return refs; } - destroyEndpointDetails(refs: EndpointDetailsContainerRefs) { +destroyEndpointDetails(refs: EndpointDetailsContainerRefs) { if (refs.componentRef && refs.componentRef.destroy) { refs.componentRef.destroy(); } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts index fd8d8c57fc..1848861dae 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts @@ -9,7 +9,6 @@ import { EntityMonitorFactory } from '../../../../../../../store/src/monitors/en import { InternalEventMonitorFactory } from '../../../../../../../store/src/monitors/internal-event-monitor.factory'; import { PaginationMonitorFactory } from '../../../../../../../store/src/monitors/pagination-monitor.factory'; import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; -import { getFullEndpointApiUrl } from '../../../../../features/endpoints/endpoint-helpers'; import { FavoritesConfigMapper } from '../../../favorites-meta-card/favorite-config-mapper'; import { createTableColumnFavorite } from '../../list-table/table-cell-favorite/table-cell-favorite.component'; import { ITableColumn } from '../../list-table/table.types'; @@ -17,6 +16,7 @@ import { IListAction, IListConfig, ListViewTypes } from '../../list.component.ty import { EndpointCardComponent } from './endpoint-card/endpoint-card.component'; import { EndpointListHelper } from './endpoint-list.helpers'; import { EndpointsDataSource } from './endpoints-data-source'; +import { TableCellEndpointAddressComponent } from './table-cell-endpoint-address/table-cell-endpoint-address.component'; import { TableCellEndpointDetailsComponent } from './table-cell-endpoint-details/table-cell-endpoint-details.component'; import { TableCellEndpointNameComponent } from './table-cell-endpoint-name/table-cell-endpoint-name.component'; import { TableCellEndpointStatusComponent } from './table-cell-endpoint-status/table-cell-endpoint-status.component'; @@ -71,9 +71,7 @@ export class EndpointsListConfigService implements IListConfig { { columnId: 'address', headerCell: () => 'Address', - cellDefinition: { - getValue: getFullEndpointApiUrl - }, + cellComponent: TableCellEndpointAddressComponent, sort: { type: 'sort', orderKey: 'address', diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.html new file mode 100644 index 0000000000..f703b669d2 --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.html @@ -0,0 +1,5 @@ +
+
{{ endpoint }}
+ + +
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.scss new file mode 100644 index 0000000000..72910a923e --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.scss @@ -0,0 +1,8 @@ +.endpoint-address-cell { + display: flex; + + &__copy { + width: 24px; + } + +} \ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.spec.ts new file mode 100644 index 0000000000..1222435209 --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.spec.ts @@ -0,0 +1,28 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BaseTestModules } from '../../../../../../../test-framework/core-test.helper'; +import { EndpointListHelper } from '../endpoint-list.helpers'; +import { TableCellEndpointAddressComponent } from './table-cell-endpoint-address.component'; + +describe('TableCellEndpointAddressComponent', () => { + let component: TableCellEndpointAddressComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [], + imports: [...BaseTestModules], + providers: [EndpointListHelper] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TableCellEndpointAddressComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts new file mode 100644 index 0000000000..b01f12007b --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts @@ -0,0 +1,38 @@ +import { Component, Input } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { GetAllEndpoints } from '../../../../../../../../store/src/actions/endpoint.actions'; +import { EntityServiceFactory } from '../../../../../../../../store/src/entity-service-factory.service'; +import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { getFullEndpointApiUrl } from '../../../../../../features/endpoints/endpoint-helpers'; +import { TableCellCustom } from '../../../list.types'; +import { RowWithEndpointId } from '../table-cell-endpoint-name/table-cell-endpoint-name.component'; + +@Component({ + selector: 'app-table-cell-endpoint-address', + templateUrl: './table-cell-endpoint-address.component.html', + styleUrls: ['./table-cell-endpoint-address.component.scss'] +}) +export class TableCellEndpointAddressComponent extends TableCellCustom { + public endpointAddress$: Observable; + + public clipboardValue = ''; + + constructor(private entityServiceFactory: EntityServiceFactory) { + super(); + } + + @Input('row') + set row(row: EndpointModel | RowWithEndpointId) { + /* tslint:disable-next-line:no-string-literal */ + const id = row['endpointId'] || row['guid']; + this.endpointAddress$ = this.entityServiceFactory.create(id, new GetAllEndpoints()).waitForEntity$.pipe( + map(data => data.entity), + map((data: any) => { + this.clipboardValue = getFullEndpointApiUrl(data); + return this.clipboardValue; + }) + ); + } +} diff --git a/src/frontend/packages/core/src/shared/shared.module.ts b/src/frontend/packages/core/src/shared/shared.module.ts index b218f0e621..68ac6be850 100644 --- a/src/frontend/packages/core/src/shared/shared.module.ts +++ b/src/frontend/packages/core/src/shared/shared.module.ts @@ -59,6 +59,9 @@ import { listTableComponents } from './components/list/list-table/table.types'; import { EndpointCardComponent } from './components/list/list-types/endpoint/endpoint-card/endpoint-card.component'; import { EndpointListHelper } from './components/list/list-types/endpoint/endpoint-list.helpers'; import { EndpointsListConfigService } from './components/list/list-types/endpoint/endpoints-list-config.service'; +import { + TableCellEndpointAddressComponent, +} from './components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component'; import { TableCellEndpointNameComponent, } from './components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component'; @@ -220,6 +223,7 @@ import { UserPermissionDirective } from './user-permission.directive'; TableCellSidePanelComponent, CardProgressOverlayComponent, MaxListMessageComponent, + TableCellEndpointAddressComponent, ], exports: [ ApplicationStateIconPipe, From 6930b23b832b42dc7a2f362f064265ca3c9a6bc2 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 17:03:07 +0100 Subject: [PATCH 19/82] Use icon that is less confusing with refresh --- .../shared/components/page-header/page-header.component.html | 2 +- .../components/recent-entities/recent-entities.component.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html index 79b2f5296e..84b796dbea 100644 --- a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html +++ b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html @@ -37,7 +37,7 @@ |
diff --git a/src/frontend/packages/core/src/shared/components/recent-entities/recent-entities.component.html b/src/frontend/packages/core/src/shared/components/recent-entities/recent-entities.component.html index 61b636ae6a..4aa002471d 100644 --- a/src/frontend/packages/core/src/shared/components/recent-entities/recent-entities.component.html +++ b/src/frontend/packages/core/src/shared/components/recent-entities/recent-entities.component.html @@ -56,5 +56,5 @@ - + \ No newline at end of file From 4d21e5a6e936caf7e178d1f6af5a47c3b7a0aa53 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 4 Jun 2020 14:05:47 +0100 Subject: [PATCH 20/82] Change following review #2 - Fix cf package module file name - Make CUSTOM_USER_PERMISSION_CHECKERS optional - Remove need to inject CUSTOM_USER_PERMISSION_CHECKERS in multiple cf modules --- ...undry.module.ts => cloud-foundry-package.module.ts} | 2 ++ .../src/features/applications/applications.module.ts | 2 -- .../src/features/cloud-foundry/cloud-foundry.module.ts | 2 -- .../features/service-catalog/service-catalog.module.ts | 4 ---- .../src/features/services/services.module.ts | 4 ---- .../cloud-foundry/src/shared/cf-shared.module.ts | 4 +--- .../src/store/cloud-foundry.store.module.ts | 4 ---- src/frontend/packages/core/src/app.module.ts | 10 ++++++---- src/frontend/packages/core/src/core/core.module.ts | 9 --------- .../permissions/current-user-permissions.service.ts | 8 +++++--- .../endpoints-page/endpoints-page.component.spec.ts | 3 ++- .../edit-profile-info.component.spec.ts | 3 ++- .../endpoint/endpoints-list-config.service.spec.ts | 3 ++- .../src/shared/components/list/list.component.spec.ts | 4 +++- .../core/src/shared/user-permission.directive.spec.ts | 5 ++--- .../packages/core/test-framework/core-test.helper.ts | 6 +++++- 16 files changed, 30 insertions(+), 43 deletions(-) rename src/frontend/packages/cloud-foundry/src/{cloud-foundry.module.ts => cloud-foundry-package.module.ts} (93%) diff --git a/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts b/src/frontend/packages/cloud-foundry/src/cloud-foundry-package.module.ts similarity index 93% rename from src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts rename to src/frontend/packages/cloud-foundry/src/cloud-foundry-package.module.ts index 1b0d5ebf3f..6e088679f4 100644 --- a/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts +++ b/src/frontend/packages/cloud-foundry/src/cloud-foundry-package.module.ts @@ -16,6 +16,7 @@ import { LongRunningCfOperationsService } from './shared/data-services/long-runn import { ServiceActionHelperService } from './shared/data-services/service-action-helper.service'; import { CloudFoundryUserProvidedServicesService } from './shared/services/cloud-foundry-user-provided-services.service'; import { CloudFoundryStoreModule } from './store/cloud-foundry.store.module'; +import { cfCurrentUserPermissionsService } from './user-permissions/cf-user-permissions-checkers'; @NgModule({ imports: [ @@ -37,6 +38,7 @@ import { CloudFoundryStoreModule } from './store/cloud-foundry.store.module'; // ]) ], providers: [ + ...cfCurrentUserPermissionsService, CfUserService, CloudFoundryService, ServiceActionHelperService, diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/applications.module.ts b/src/frontend/packages/cloud-foundry/src/features/applications/applications.module.ts index 11b02a71f7..ce3afe8842 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/applications.module.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/applications.module.ts @@ -4,7 +4,6 @@ import { NgModule } from '@angular/core'; import { CoreModule } from '../../../../core/src/core/core.module'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { CloudFoundrySharedModule } from '../../shared/cf-shared.module'; -import { cfCurrentUserPermissionsService } from '../../user-permissions/cf-user-permissions-checkers'; import { ApplicationDeleteComponent } from './application-delete/application-delete.component'; import { DeleteAppServiceInstancesComponent, @@ -78,7 +77,6 @@ import { SshApplicationComponent } from './ssh-application/ssh-application.compo ApplicationMonitorService, DatePipe, ApplicationDeploySourceTypes, - ...cfCurrentUserPermissionsService ] }) export class ApplicationsModule { } diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry.module.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry.module.ts index 9bffecd85b..76e9e15ff3 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry.module.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry.module.ts @@ -8,7 +8,6 @@ import { CloudFoundrySharedModule } from '../../shared/cf-shared.module'; import { CFEndpointsListConfigService, } from '../../shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service'; -import { cfCurrentUserPermissionsService } from '../../user-permissions/cf-user-permissions-checkers'; import { AddOrganizationComponent } from './add-organization/add-organization.component'; import { CreateOrganizationStepComponent, @@ -229,7 +228,6 @@ import { RemoveUserComponent } from './users/remove-user/remove-user.component'; CloudFoundryCellService, UserInviteService, UserInviteConfigureService, - ...cfCurrentUserPermissionsService ], entryComponents: [ UserInviteConfigurationDialogComponent diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-catalog.module.ts b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-catalog.module.ts index 93f1c8d797..a959216d92 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-catalog.module.ts +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-catalog.module.ts @@ -4,7 +4,6 @@ import { NgModule } from '@angular/core'; import { CoreModule } from '../../../../core/src/core/core.module'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { CloudFoundrySharedModule } from '../../shared/cf-shared.module'; -import { cfCurrentUserPermissionsService } from '../../user-permissions/cf-user-permissions-checkers'; import { CreateApplicationModule } from '../applications/create-application/create-application.module'; import { ServiceBaseComponent } from './service-base/service-base.component'; import { ServiceCatalogPageComponent } from './service-catalog-page/service-catalog-page.component'; @@ -34,9 +33,6 @@ import { ServiceTabsBaseComponent } from './service-tabs-base/service-tabs-base. ], exports: [ ServiceTabsBaseComponent, - ], - providers: [ - ...cfCurrentUserPermissionsService ] }) export class ServiceCatalogModule { } diff --git a/src/frontend/packages/cloud-foundry/src/features/services/services.module.ts b/src/frontend/packages/cloud-foundry/src/features/services/services.module.ts index ae6a9ca71d..628dced999 100644 --- a/src/frontend/packages/cloud-foundry/src/features/services/services.module.ts +++ b/src/frontend/packages/cloud-foundry/src/features/services/services.module.ts @@ -8,7 +8,6 @@ import { ServiceCatalogModule } from '../../../../cloud-foundry/src/features/ser import { CoreModule } from '../../../../core/src/core/core.module'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { CloudFoundrySharedModule } from '../../shared/cf-shared.module'; -import { cfCurrentUserPermissionsService } from '../../user-permissions/cf-user-permissions-checkers'; import { DetachAppsComponent } from './detach-service-instance/detach-apps/detach-apps.component'; import { DetachServiceInstanceComponent } from './detach-service-instance/detach-service-instance.component'; import { ServicesWallComponent } from './services-wall/services-wall.component'; @@ -28,9 +27,6 @@ import { ServicesRoutingModule } from './services.routing'; ServicesWallComponent, DetachServiceInstanceComponent, DetachAppsComponent - ], - providers: [ - ...cfCurrentUserPermissionsService ] }) export class ServicesModule { } diff --git a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts index 424e0e08c7..7da0831fa8 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts @@ -8,7 +8,6 @@ import { SharedModule } from '../../../core/src/shared/shared.module'; import { ApplicationInstanceChartComponent, } from '../features/applications/application/application-instance-chart/application-instance-chart.component'; -import { cfCurrentUserPermissionsService } from '../user-permissions/cf-user-permissions-checkers'; import { AddServiceInstanceBaseStepComponent, } from './components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component'; @@ -380,8 +379,7 @@ const cfListCards: Type>[] = [ providers: [ ApplicationStateService, GitSCMService, - CloudFoundryUserProvidedServicesService, - ...cfCurrentUserPermissionsService + CloudFoundryUserProvidedServicesService ] }) export class CloudFoundrySharedModule { } diff --git a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts index d209acc642..f2c9b707bd 100644 --- a/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts +++ b/src/frontend/packages/cloud-foundry/src/store/cloud-foundry.store.module.ts @@ -1,7 +1,6 @@ import { NgModule } from '@angular/core'; import { EffectsModule } from '@ngrx/effects'; -import { cfCurrentUserPermissionsService } from '../user-permissions/cf-user-permissions-checkers'; import { CloudFoundryReducersModule } from './cloud-foundry.reducers.module'; import { AppVariablesEffect } from './effects/app-variables.effects'; import { AppEffects } from './effects/app.effects'; @@ -31,9 +30,6 @@ import { UsersRolesEffects } from './effects/users-roles.effects'; CfValidateEffects, UsersRolesEffects ]) - ], - providers: [ - ...cfCurrentUserPermissionsService ] }) export class CloudFoundryStoreModule { } diff --git a/src/frontend/packages/core/src/app.module.ts b/src/frontend/packages/core/src/app.module.ts index 1cb71ceaa0..7ba9fb46a1 100644 --- a/src/frontend/packages/core/src/app.module.ts +++ b/src/frontend/packages/core/src/app.module.ts @@ -1,13 +1,13 @@ -import { NgModule, Injectable } from '@angular/core'; +import { Injectable, NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { Params, RouteReuseStrategy, RouterStateSnapshot } from '@angular/router'; -import { RouterStateSerializer, StoreRouterConnectingModule, DefaultRouterStateSerializer } from '@ngrx/router-store'; +import { DefaultRouterStateSerializer, RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store'; import { Store } from '@ngrx/store'; import { debounceTime, filter, withLatestFrom } from 'rxjs/operators'; import { CfAutoscalerModule } from '../../cf-autoscaler/src/cf-autoscaler.module'; -import { CloudFoundryPackageModule } from '../../cloud-foundry/src/cloud-foundry.module'; +import { CloudFoundryPackageModule } from '../../cloud-foundry/src/cloud-foundry-package.module'; import { SetRecentlyVisitedEntityAction } from '../../store/src/actions/recently-visited.actions'; import { UpdateUserFavoriteMetadataAction, @@ -35,6 +35,7 @@ import { CustomizationService } from './core/customizations.types'; import { DynamicExtensionRoutes } from './core/extension/dynamic-extension-routes'; import { ExtensionService } from './core/extension/extension-service'; import { getGitHubAPIURL, GITHUB_API_URL } from './core/github.helpers'; +import { CurrentUserPermissionsService } from './core/permissions/current-user-permissions.service'; import { UserFavoriteManager } from './core/user-favorite-manager'; import { CustomImportModule } from './custom-import.module'; import { AboutModule } from './features/about/about.module'; @@ -116,7 +117,8 @@ export class CustomRouterStateSerializer SidePanelService, { provide: GITHUB_API_URL, useFactory: getGitHubAPIURL }, { provide: RouterStateSerializer, useClass: CustomRouterStateSerializer }, // Create action for router navigation - { provide: RouteReuseStrategy, useClass: CustomReuseStrategy } + { provide: RouteReuseStrategy, useClass: CustomReuseStrategy }, + CurrentUserPermissionsService ], bootstrap: [AppComponent] }) diff --git a/src/frontend/packages/core/src/core/core.module.ts b/src/frontend/packages/core/src/core/core.module.ts index e726c6eed2..ff8b4eb280 100644 --- a/src/frontend/packages/core/src/core/core.module.ts +++ b/src/frontend/packages/core/src/core/core.module.ts @@ -29,10 +29,6 @@ import { MDAppModule } from './md.module'; import { NotSetupGuardService } from './not-setup-guard.service'; import { PageHeaderService } from './page-header-service/page-header.service'; import { PageNotFoundComponentComponent } from './page-not-found-component/page-not-found-component.component'; -import { - CurrentUserPermissionsService, - CUSTOM_USER_PERMISSION_CHECKERS, -} from './permissions/current-user-permissions.service'; import { SafeImgPipe } from './safe-img.pipe'; import { StatefulIconComponent } from './stateful-icon/stateful-icon.component'; import { TruncatePipe } from './truncate.pipe'; @@ -88,11 +84,6 @@ import { WindowRef } from './window-ref/window-ref.service'; PaginationMonitorFactory, UserProfileService, EntityServiceFactory, - { - provide: CUSTOM_USER_PERMISSION_CHECKERS, - useValue: [] - }, - CurrentUserPermissionsService, { provide: APP_TITLE, useFactory: appTitleFactory, diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts index 3d407620cd..0a7490fb0c 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts @@ -1,4 +1,4 @@ -import { Inject, Injectable } from '@angular/core'; +import { Inject, Injectable, Optional } from '@angular/core'; import { Store } from '@ngrx/store'; import { combineLatest, Observable, of } from 'rxjs'; import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; @@ -30,12 +30,14 @@ export class CurrentUserPermissionsService { private allCheckers: ICurrentUserPermissionsChecker[]; constructor( private store: Store, - @Inject(CUSTOM_USER_PERMISSION_CHECKERS) customCheckers: ICurrentUserPermissionsChecker[], + @Optional() @Inject(CUSTOM_USER_PERMISSION_CHECKERS) customCheckers: ICurrentUserPermissionsChecker[], private logger: LoggerService ) { + // Cannot set default value for parameter as the Optional decorator sets it to null + const nullSafeCustomCheckers = customCheckers || []; this.allCheckers = [ new StratosUserPermissionsChecker(store), - ...customCheckers + ...nullSafeCustomCheckers ] } /** diff --git a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.spec.ts b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.spec.ts index ce469196e9..2906a26a9d 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.spec.ts +++ b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.spec.ts @@ -9,6 +9,7 @@ import { appReducers } from '../../../../../store/src/reducers.module'; import { TabNavService } from '../../../../tab-nav.service'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../shared/shared.module'; import { SidePanelService } from './../../../shared/services/side-panel.service'; import { EndpointsPageComponent } from './endpoints-page.component'; @@ -33,7 +34,7 @@ describe('EndpointsPageComponent', () => { ), NoopAnimationsModule ], - providers: [TabNavService, SidePanelService] + providers: [TabNavService, SidePanelService, CurrentUserPermissionsService] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.spec.ts b/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.spec.ts index 13c1bae7e3..89281e1382 100644 --- a/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.spec.ts +++ b/src/frontend/packages/core/src/features/user-profile/edit-profile-info/edit-profile-info.component.spec.ts @@ -7,6 +7,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { TabNavService } from '../../../../tab-nav.service'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { UserProfileService } from '../../../core/user-profile.service'; import { SharedModule } from '../../../shared/shared.module'; import { EditProfileInfoComponent } from './edit-profile-info.component'; @@ -27,7 +28,7 @@ describe('EditProfileInfoComponent', () => { CoreTestingModule, createBasicStoreModule() ], - providers: [UserProfileService, TabNavService], + providers: [UserProfileService, TabNavService, CurrentUserPermissionsService], }) .compileComponents(); }); diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.spec.ts index d1a7a63121..25c6056137 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.spec.ts @@ -4,6 +4,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../../shared.module'; import { EndpointListHelper } from './endpoint-list.helpers'; import { EndpointsListConfigService } from './endpoints-list-config.service'; @@ -11,7 +12,7 @@ import { EndpointsListConfigService } from './endpoints-list-config.service'; describe('EndpointsListConfigService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [EndpointsListConfigService, EndpointListHelper], + providers: [EndpointsListConfigService, EndpointListHelper, CurrentUserPermissionsService], imports: [ CommonModule, CoreModule, diff --git a/src/frontend/packages/core/src/shared/components/list/list.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list.component.spec.ts index 573d0cbabf..79d01782ed 100644 --- a/src/frontend/packages/core/src/shared/components/list/list.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list.component.spec.ts @@ -14,6 +14,7 @@ import { APIResource } from '../../../../../store/src/types/api.types'; import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../shared.module'; import { EndpointCardComponent } from './list-types/endpoint/endpoint-card/endpoint-card.component'; import { EndpointListHelper } from './list-types/endpoint/endpoint-list.helpers'; @@ -125,7 +126,8 @@ describe('ListComponent', () => { // ApplicationStateService, PaginationMonitorFactory, EntityMonitorFactory, - EndpointListHelper + EndpointListHelper, + CurrentUserPermissionsService ], imports: [ CoreModule, diff --git a/src/frontend/packages/core/src/shared/user-permission.directive.spec.ts b/src/frontend/packages/core/src/shared/user-permission.directive.spec.ts index 6e3ea57118..d1e89790c6 100644 --- a/src/frontend/packages/core/src/shared/user-permission.directive.spec.ts +++ b/src/frontend/packages/core/src/shared/user-permission.directive.spec.ts @@ -1,8 +1,7 @@ -import { Component, TemplateRef } from '@angular/core'; +import { Component } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BaseTestModules, generateBaseTestStoreModules } from '../../test-framework/core-test.helper'; -import { UserPermissionDirective } from './user-permission.directive'; +import { BaseTestModules } from '../../test-framework/core-test.helper'; @Component({ template: `` diff --git a/src/frontend/packages/core/test-framework/core-test.helper.ts b/src/frontend/packages/core/test-framework/core-test.helper.ts index 50ff5a7509..bad6c14d0f 100644 --- a/src/frontend/packages/core/test-framework/core-test.helper.ts +++ b/src/frontend/packages/core/test-framework/core-test.helper.ts @@ -9,6 +9,7 @@ import { EntityCatalogHelper } from '../../store/src/entity-catalog/entity-catal import { EntityCatalogHelpers } from '../../store/src/entity-catalog/entity-catalog.helper'; import { appReducers } from '../../store/src/reducers.module'; import { CoreModule } from '../src/core/core.module'; +import { CurrentUserPermissionsService } from '../src/core/permissions/current-user-permissions.service'; import { ApplicationStateIconComponent, } from '../src/shared/components/application-state/application-state-icon/application-state-icon.component'; @@ -35,7 +36,10 @@ import { CoreTestingModule } from './core-test.modules'; @NgModule({ - imports: [CoreModule] + imports: [CoreModule], + providers: [ + CurrentUserPermissionsService + ] }) export class AppTestModule { constructor( From ac2e441aca3411db9831ad81bee7b4153aa5b0db Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 19:13:44 +0100 Subject: [PATCH 21/82] Add newline at end for codeclimate --- .../table-cell-endpoint-address.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.scss index 72910a923e..8f6f809311 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.scss +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.scss @@ -5,4 +5,4 @@ width: 24px; } -} \ No newline at end of file +} From 1799e8e5c19b48e52992014398b0bafaa92d048e Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 20:14:39 +0100 Subject: [PATCH 22/82] Fix for buildpack filename wrapping on card --- .../cf-buildpack-card.component.html | 2 +- .../meta-card-item/meta-card-item.component.scss | 11 +++++++++++ .../meta-card-item/meta-card-item.component.ts | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-buildpacks/cf-buildpack-card/cf-buildpack-card.component.html b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-buildpacks/cf-buildpack-card/cf-buildpack-card.component.html index 923acf666d..f4a209c775 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-buildpacks/cf-buildpack-card/cf-buildpack-card.component.html +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-buildpacks/cf-buildpack-card/cf-buildpack-card.component.html @@ -27,7 +27,7 @@ Updated {{ row.metadata.updated_at | date: 'medium' }} - + File Name {{ row.entity.filename }} diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.scss b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.scss index 7ad3af708e..c55fb2b8f6 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.scss +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.scss @@ -58,3 +58,14 @@ } } } + +.meta-card-item-multiline { + align-items: flex-start; + display: flex; + justify-content: space-between; + min-height: 30px; + padding: 7px 0 2px 0; + .meta-card-item__value { + white-space: unset; + } +} diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.ts index 3a620e9a56..239b476a02 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.ts @@ -18,6 +18,7 @@ export class MetaCardItemComponent implements OnInit { column: 'meta-card-item-column', 'long-text': 'meta-card-item-long-text', 'long-text-fixed': 'meta-card-item-long-text-fixed', + multiline: 'meta-card-item-multiline', }; itemStyle = 'meta-card-item-row'; @ContentChild(MetaCardKeyComponent, { static: true }) From afb9df25aea9d07fc183331c85820ad5be271ee5 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 20:17:34 +0100 Subject: [PATCH 23/82] Fix code climate issue --- .../meta-card/meta-card-item/meta-card-item.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.scss b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.scss index c55fb2b8f6..2912084f8b 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.scss +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.scss @@ -64,7 +64,7 @@ display: flex; justify-content: space-between; min-height: 30px; - padding: 7px 0 2px 0; + padding: 7px 0 2px; .meta-card-item__value { white-space: unset; } From cfb64d57dda9703e90245bb9ec60fb9a17d18246 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 22:22:16 +0100 Subject: [PATCH 24/82] Update endpoint-list.helpers.ts --- .../components/list/list-types/endpoint/endpoint-list.helpers.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts index 8770e7b8c5..fd4206b216 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts @@ -124,7 +124,6 @@ export class EndpointListHelper { }, { action: (item) => { - console.log(item); const routerLink = `/endpoints/edit/${item.guid}`; this.store.dispatch(new RouterNav({ path: routerLink })); }, From 2ac957e630461f47895f1970757f73ccb6ca6d7d Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 23:08:59 +0100 Subject: [PATCH 25/82] Improve naming --- .../table-cell-endpoint-address.component.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.html index f703b669d2..f12d8357db 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.html +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.html @@ -1,5 +1,5 @@ -
-
{{ endpoint }}
- +
+
{{ address }}
+
From b814838705ae5ab58f0da0d2cb30de7d65f57a9d Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 4 Jun 2020 23:11:30 +0100 Subject: [PATCH 26/82] Tidy up --- .../table-cell-endpoint-address.component.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts index b01f12007b..32956ffa4b 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts @@ -17,8 +17,6 @@ import { RowWithEndpointId } from '../table-cell-endpoint-name/table-cell-endpoi export class TableCellEndpointAddressComponent extends TableCellCustom { public endpointAddress$: Observable; - public clipboardValue = ''; - constructor(private entityServiceFactory: EntityServiceFactory) { super(); } @@ -29,10 +27,7 @@ export class TableCellEndpointAddressComponent extends TableCellCustom data.entity), - map((data: any) => { - this.clipboardValue = getFullEndpointApiUrl(data); - return this.clipboardValue; - }) + map((data: any) => getFullEndpointApiUrl(data)) ); } } From 591898902927e521c3e7381e802e4c19df0be84f Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Fri, 5 Jun 2020 13:39:09 +0100 Subject: [PATCH 27/82] Change following review --- .../list/list-table/table-cell/table-cell.component.ts | 4 ++++ src/frontend/packages/core/src/shared/shared.module.ts | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell/table-cell.component.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell/table-cell.component.ts index beb3046000..2bd2fd27d5 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell/table-cell.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell/table-cell.component.ts @@ -12,6 +12,9 @@ import { import { MultiActionListEntity } from '../../../../../../../store/src/monitors/pagination-monitor'; import { coreEndpointListDetailsComponents } from '../../../../../features/endpoints/endpoint-helpers'; import { IListDataSource } from '../../data-sources-controllers/list-data-source-types'; +import { + TableCellEndpointAddressComponent, +} from '../../list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component'; import { TableCellEndpointDetailsComponent, } from '../../list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component'; @@ -55,6 +58,7 @@ export const listTableCells: Type>[] = [ TableCellSidePanelComponent, TableCellIconComponent, TableCellExpanderComponent, + TableCellEndpointAddressComponent, ...coreEndpointListDetailsComponents ]; diff --git a/src/frontend/packages/core/src/shared/shared.module.ts b/src/frontend/packages/core/src/shared/shared.module.ts index 68ac6be850..b218f0e621 100644 --- a/src/frontend/packages/core/src/shared/shared.module.ts +++ b/src/frontend/packages/core/src/shared/shared.module.ts @@ -59,9 +59,6 @@ import { listTableComponents } from './components/list/list-table/table.types'; import { EndpointCardComponent } from './components/list/list-types/endpoint/endpoint-card/endpoint-card.component'; import { EndpointListHelper } from './components/list/list-types/endpoint/endpoint-list.helpers'; import { EndpointsListConfigService } from './components/list/list-types/endpoint/endpoints-list-config.service'; -import { - TableCellEndpointAddressComponent, -} from './components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component'; import { TableCellEndpointNameComponent, } from './components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component'; @@ -223,7 +220,6 @@ import { UserPermissionDirective } from './user-permission.directive'; TableCellSidePanelComponent, CardProgressOverlayComponent, MaxListMessageComponent, - TableCellEndpointAddressComponent, ], exports: [ ApplicationStateIconPipe, From 531bd0d0af688145f1d9d9afd7c67b7973408c0e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2020 15:45:28 +0100 Subject: [PATCH 28/82] Bump gopkg.in/yaml.v2 from 2.2.8 to 2.3.0 in /src/jetstream (#4336) * Bump gopkg.in/yaml.v2 from 2.2.8 to 2.3.0 in /src/jetstream Bumps [gopkg.in/yaml.v2](https://github.com/go-yaml/yaml) from 2.2.8 to 2.3.0. - [Release notes](https://github.com/go-yaml/yaml/releases) - [Commits](https://github.com/go-yaml/yaml/compare/v2.2.8...v2.3.0) Signed-off-by: dependabot-preview[bot] * CI bump Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Neil MacDougall --- src/jetstream/go.mod | 2 +- src/jetstream/go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/jetstream/go.mod b/src/jetstream/go.mod index 9837788a29..9da9655c41 100644 --- a/src/jetstream/go.mod +++ b/src/jetstream/go.mod @@ -94,7 +94,7 @@ require ( google.golang.org/appengine v1.5.0 // indirect gopkg.in/DATA-DOG/go-sqlmock.v1 v1.0.0-00010101000000-000000000000 gopkg.in/cheggaaa/pb.v1 v1.0.27 // indirect - gopkg.in/yaml.v2 v2.2.8 + gopkg.in/yaml.v2 v2.3.0 ) replace ( diff --git a/src/jetstream/go.sum b/src/jetstream/go.sum index 4b5f0a3ca4..a37e718a67 100644 --- a/src/jetstream/go.sum +++ b/src/jetstream/go.sum @@ -408,7 +408,6 @@ gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -416,6 +415,8 @@ gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= From d1237ccee9e942159582c79ae2f08988c162f711 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2020 15:21:22 +0100 Subject: [PATCH 29/82] [Security] Bump websocket-extensions from 0.1.3 to 0.1.4 (#4356) Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. **This update includes a security fix.** - [Release notes](https://github.com/faye/websocket-extensions-node/releases) - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e6c33bafa9..0d6c170b63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19692,9 +19692,9 @@ } }, "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, "when": { From 3af3d39261a439f9ce4661c505bb73a468d0fdfd Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 9 Jun 2020 15:38:44 +0100 Subject: [PATCH 30/82] Hide deployment info card if not space developer - fixes #4322 --- .../tabs/build-tab/build-tab.component.html | 7 ++--- .../tabs/build-tab/build-tab.component.ts | 27 +++++++++++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html index a1ceaa6f53..de18350435 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html @@ -149,12 +149,12 @@ - + Deployment Info - +
- - None - diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts index 57c88faeb4..6c07dbb615 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts @@ -1,12 +1,15 @@ import { Component, Inject, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { Store } from '@ngrx/store'; -import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; -import { combineLatest, delay, distinct, filter, first, map, mergeMap, startWith, tap } from 'rxjs/operators'; +import { combineLatest as observableCombineLatest, Observable, of as observableOf, of } from 'rxjs'; +import { combineLatest, delay, distinct, filter, first, map, mergeMap, startWith, switchMap, tap } from 'rxjs/operators'; import { AppMetadataTypes } from '../../../../../../../../cloud-foundry/src/actions/app-metadata.actions'; import { UpdateExistingApplication } from '../../../../../../../../cloud-foundry/src/actions/application.actions'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { getFullEndpointApiUrl } from '../../../../../../../../core/src/features/endpoints/endpoint-helpers'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -58,6 +61,7 @@ const appRestageConfirmation = new ConfirmationDialogConfig( export class BuildTabComponent implements OnInit { public isBusyUpdating$: Observable<{ updating: boolean }>; public manageAppPermission = CfCurrentUserPermissions.APPLICATION_MANAGE; + constructor( public applicationService: ApplicationService, private scmService: GitSCMService, @@ -66,7 +70,7 @@ export class BuildTabComponent implements OnInit { private route: ActivatedRoute, private router: Router, private confirmDialog: ConfirmationDialogService, - + private cups: CurrentUserPermissionsService ) { } cardTwoFetching$: Observable; @@ -108,8 +112,17 @@ export class BuildTabComponent implements OnInit { }) ); - this.deploySource$ = this.applicationService.applicationStratProject$.pipe( - combineLatest(this.applicationService.application$) + const canSeeEnvVars$ = this.applicationService.appSpace$.pipe( + switchMap(space => this.cups.can( + CfCurrentUserPermissions.APPLICATION_VIEW_ENV_VARS, + this.applicationService.cfGuid, + space.metadata.guid) + ) + ) + + const deploySource$ = observableCombineLatest( + this.applicationService.applicationStratProject$, + this.applicationService.application$ ).pipe( map(([project, app]) => { if (!!project) { @@ -149,6 +162,10 @@ export class BuildTabComponent implements OnInit { } }), startWith({ type: 'loading' }) + ) + + this.deploySource$ = canSeeEnvVars$.pipe( + switchMap(canSeeEnvVars => canSeeEnvVars ? deploySource$ : of(null)), ); } From c190ec2d5f31e8c2d5b27af31f1ced6367b74f89 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 9 Jun 2020 16:17:48 +0100 Subject: [PATCH 31/82] Only space developers can create/unmap/delete routes in app routes table - fixes #4324 --- .../cf-app-routes-list-config.service.ts | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts index a631fac6ae..b69eb4ab15 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts @@ -1,7 +1,8 @@ import { DatePipe } from '@angular/common'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { take } from 'rxjs/operators'; +import { combineLatest } from 'rxjs'; +import { switchMap, take } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; import { @@ -12,6 +13,7 @@ import { IGlobalListAction, IListConfig } from '../../../../../../../core/src/sh import { RouterNav } from '../../../../../../../store/src/actions/router.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { ApplicationService } from '../../../../../features/applications/application.service'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { CfAppRoutesListConfigServiceBase } from './cf-app-routes-list-config-base'; @@ -23,11 +25,12 @@ export class CfAppRoutesListConfigService extends CfAppRoutesListConfigServiceBa appService: ApplicationService, confirmDialog: ConfirmationDialogService, datePipe: DatePipe, - currentUserPermissionsService: CurrentUserPermissionsService, + private currentUserPermissionsService: CurrentUserPermissionsService, ) { super(store, appService, confirmDialog, datePipe, currentUserPermissionsService, null, true); this.setupList(store, appService); + this.allowSelection = false; // Allow the multi action visibility to determine this } private setupList(store: Store, appService: ApplicationService) { @@ -51,7 +54,18 @@ export class CfAppRoutesListConfigService extends CfAppRoutesListConfigServiceBa }, icon: 'add', label: 'Add', - description: 'Add new route' + description: 'Add new route', + visible$: combineLatest( + appService.appOrg$, + appService.appSpace$ + ).pipe( + switchMap(([org, space]) => this.currentUserPermissionsService.can( + CfCurrentUserPermissions.ROUTE_CREATE, + appService.cfGuid, + org.metadata.guid, + space.metadata.guid + )) + ) }; this.getGlobalActions = () => [listActionAddRoute]; } From d4bb0e9ae4e69942d0a897ebafe9fd17c821235d Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 9 Jun 2020 16:38:20 +0100 Subject: [PATCH 32/82] Only Space Developers should be able to change count, terminate or ssh to instances - fixes #4330 --- .../card-app-instances.component.html | 39 +++++++++++-------- .../card-app-instances.component.ts | 21 ++++++++-- .../cf-app-instances-config.service.ts | 23 +++++++++-- 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.html b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.html index bf67158f11..d2c25acd15 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.html +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.html @@ -5,7 +5,8 @@
- +
@@ -14,23 +15,27 @@
- - - - - - - - - - + + + + + \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts index c3524019b6..548b3d0cca 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts @@ -1,13 +1,15 @@ -import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild, Renderer2 } from '@angular/core'; +import { Component, ElementRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core'; import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar'; -import { Observable, Subscription } from 'rxjs'; -import { first, map } from 'rxjs/operators'; +import { combineLatest, Observable, Subscription } from 'rxjs'; +import { first, map, switchMap } from 'rxjs/operators'; import { AppMetadataTypes } from '../../../../../../cloud-foundry/src/actions/app-metadata.actions'; import { ApplicationService } from '../../../../../../cloud-foundry/src/features/applications/application.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogConfig } from '../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../core/src/shared/components/confirmation-dialog.service'; import { StratosStatus } from '../../../../../../core/src/shared/shared.types'; +import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; const appInstanceScaleToZeroConfirmation = new ConfirmationDialogConfig('Set Instance count to 0', 'Are you sure you want to set the instance count to 0?', 'Confirm', true); @@ -28,14 +30,25 @@ export class CardAppInstancesComponent implements OnInit, OnDestroy { status$: Observable; + public canEditSpace$: Observable; + constructor( public appService: ApplicationService, private renderer: Renderer2, private confirmDialog: ConfirmationDialogService, - private snackBar: MatSnackBar) { + private snackBar: MatSnackBar, + cups: CurrentUserPermissionsService + ) { this.status$ = this.appService.applicationState$.pipe( map(state => state.indicator) ); + this.canEditSpace$ = combineLatest( + appService.appOrg$, + appService.appSpace$ + ).pipe( + switchMap(([org, space]) => cups.can(CfCurrentUserPermissions.SPACE_EDIT, appService.cfGuid, org.metadata.guid, space.metadata.guid)) + ) + } private currentCount = 0; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts index 1559dfec06..bd55fffa79 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts @@ -1,12 +1,15 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; -import { Observable } from 'rxjs'; +import { combineLatest as combineLatestObs, Observable } from 'rxjs'; import { combineLatest, map, switchMap } from 'rxjs/operators'; import { DeleteApplicationInstance } from '../../../../../../../cloud-foundry/src/actions/application.actions'; import { FetchApplicationMetricsAction } from '../../../../../../../cloud-foundry/src/actions/cf-metrics.actions'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { UtilsService } from '../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -27,6 +30,7 @@ import { IMetricMatrixResult, IMetrics } from '../../../../../../../store/src/ty import { IMetricApplication } from '../../../../../../../store/src/types/metric.types'; import { ApplicationService } from '../../../../../features/applications/application.service'; import { CfCellHelper } from '../../../../../features/cloud-foundry/cf-cell.helpers'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ListAppInstance } from './app-instance-types'; import { CfAppInstancesDataSource } from './cf-app-instances-data-source'; import { TableCellCfCellComponent } from './table-cell-cf-cell/table-cell-cf-cell.component'; @@ -158,7 +162,7 @@ export class CfAppInstancesConfigService implements IListConfig }, label: 'Terminate', description: ``, // Description depends on console user permission - + createVisible: () => this.canEditSpace$ }; private listActionSsh: IListAction = { @@ -182,7 +186,8 @@ export class CfAppInstancesConfigService implements IListConfig space.entity.allow_ssh; }) ); - })) + })), + createVisible: () => this.canEditSpace$ }; private singleActions = [ @@ -190,6 +195,8 @@ export class CfAppInstancesConfigService implements IListConfig this.listActionSsh, ]; + private canEditSpace$: Observable; + constructor( private store: Store, private appService: ApplicationService, @@ -197,7 +204,8 @@ export class CfAppInstancesConfigService implements IListConfig private router: Router, private confirmDialog: ConfirmationDialogService, entityServiceFactory: EntityServiceFactory, - paginationMonitorFactory: PaginationMonitorFactory + paginationMonitorFactory: PaginationMonitorFactory, + cups: CurrentUserPermissionsService ) { const cellHelper = new CfCellHelper(store, paginationMonitorFactory); @@ -220,6 +228,13 @@ export class CfAppInstancesConfigService implements IListConfig this.appService.appGuid, this, ); + + this.canEditSpace$ = combineLatestObs( + appService.appOrg$, + appService.appSpace$ + ).pipe( + switchMap(([org, space]) => cups.can(CfCurrentUserPermissions.SPACE_EDIT, appService.cfGuid, org.metadata.guid, space.metadata.guid)) + ) } getGlobalActions = () => null; From 7565ee06408a611647ca5e3c3e1221932ba906b9 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 9 Jun 2020 16:53:24 +0100 Subject: [PATCH 33/82] Permissions: Only Space Developers should be able to create/edit/delete an Autoscaler policy - fixes #4323 --- .../autoscaler-tab-extension.component.html | 4 ++-- .../autoscaler-tab-extension.component.ts | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.html b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.html index 2a20fe1798..c1d419a048 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.html +++ b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.html @@ -1,4 +1,4 @@ - +
\ No newline at end of file diff --git a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts index dfee79bace..1a7fad96d9 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts @@ -3,14 +3,16 @@ import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material/s import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; import { combineLatest, Observable, Subscription } from 'rxjs'; -import { distinctUntilChanged, filter, first, map, pairwise, publishReplay, refCount } from 'rxjs/operators'; +import { distinctUntilChanged, filter, first, map, pairwise, publishReplay, refCount, switchMap } from 'rxjs/operators'; import { applicationEntityType } from '../../../../cloud-foundry/src/cf-entity-types'; import { createEntityRelationPaginationKey } from '../../../../cloud-foundry/src/entity-relations/entity-relations.types'; import { ApplicationMonitorService } from '../../../../cloud-foundry/src/features/applications/application-monitor.service'; import { ApplicationService } from '../../../../cloud-foundry/src/features/applications/application.service'; import { getGuids } from '../../../../cloud-foundry/src/features/applications/application/application-base.component'; +import { CfCurrentUserPermissions } from '../../../../cloud-foundry/src/user-permissions/cf-user-permissions-checkers'; import { StratosTab, StratosTabType } from '../../../../core/src/core/extension/extension-service'; +import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; import { safeUnsubscribe } from '../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../core/src/shared/components/confirmation-dialog.service'; @@ -113,6 +115,8 @@ export class AutoscalerTabExtensionComponent implements OnInit, OnDestroy { 'order-direction': 'desc' }; + public canEditSpace$: Observable; + ngOnDestroy(): void { if (this.appAutoscalerPolicySnackBarRef) { this.appAutoscalerPolicySnackBarRef.dismiss(); @@ -131,6 +135,7 @@ export class AutoscalerTabExtensionComponent implements OnInit, OnDestroy { private appAutoscalerPolicySnackBar: MatSnackBar, private appAutoscalerScalingHistorySnackBar: MatSnackBar, private confirmDialog: ConfirmationDialogService, + private cups: CurrentUserPermissionsService ) { } ngOnInit() { @@ -219,6 +224,18 @@ export class AutoscalerTabExtensionComponent implements OnInit, OnDestroy { publishReplay(1), refCount() ); + + this.canEditSpace$ = combineLatest( + this.applicationService.appOrg$, + this.applicationService.appSpace$ + ).pipe( + switchMap(([org, space]) => this.cups.can( + CfCurrentUserPermissions.SPACE_EDIT, + this.applicationService.cfGuid, + org.metadata.guid, + space.metadata.guid + )) + ) } getAppMetric(metricName: string, trigger: AppScalingTrigger, params: AutoscalerPaginationParams) { From a291040cd65168fffe04a28762bc60f31023d8e5 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 9 Jun 2020 17:53:26 +0100 Subject: [PATCH 34/82] Users with no developer roles could click on add app button - fixes #4361 --- .../src/user-permissions/cf-user-permissions-checkers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts index b38816caf9..5d4e9bc1be 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts @@ -396,7 +396,7 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker } private getAllEndpointGuids() { - return this.store.select(connectedEndpointsSelector).pipe( + return this.store.select(connectedEndpointsSelector()).pipe( map(endpoints => Object.values(endpoints).filter(e => e.cnsi_type === CF_ENDPOINT_TYPE).map(endpoint => endpoint.guid)) ); } From ab2dd37bd267a0ab5af59f992038ca576964d60a Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 11 Jun 2020 12:00:50 +0100 Subject: [PATCH 35/82] Fix tests --- .../autoscaler-tab-extension.component.spec.ts | 6 +++++- src/test-e2e/application/application-view-e2e.spec.ts | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.spec.ts b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.spec.ts index eff100853b..b96d66bdb5 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.spec.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.spec.ts @@ -15,6 +15,9 @@ import { import { RunningInstancesComponent, } from '../../../../cloud-foundry/src/shared/components/running-instances/running-instances.component'; +import { + cfCurrentUserPermissionsService, +} from '../../../../cloud-foundry/src/user-permissions/cf-user-permissions-checkers'; import { ApplicationServiceMock } from '../../../../cloud-foundry/test-framework/application-service-helper'; import { CoreModule } from '../../../../core/src/core/core.module'; import { SharedModule } from '../../../../core/src/shared/shared.module'; @@ -48,7 +51,8 @@ describe('AutoscalerTabExtensionComponent', () => { providers: [ DatePipe, { provide: ApplicationService, useClass: ApplicationServiceMock }, - TabNavService + TabNavService, + ...cfCurrentUserPermissionsService ] }) .compileComponents(); diff --git a/src/test-e2e/application/application-view-e2e.spec.ts b/src/test-e2e/application/application-view-e2e.spec.ts index c2d51b6b78..e7467a6341 100644 --- a/src/test-e2e/application/application-view-e2e.spec.ts +++ b/src/test-e2e/application/application-view-e2e.spec.ts @@ -135,8 +135,7 @@ describe('Application View -', () => { }); it('Deployment Info', () => { - appSummary.cardDeployInfo.waitForTitle('Deployment Info'); - expect(appSummary.cardDeployInfo.getContent()).toBe('None'); + expect(appSummary.cardDeployInfo.isPresent()).toBeFalsy(); }); }); From a5d1de018a9d502a0c52c7c1afeb205ede1b94fd Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 11 Jun 2020 13:58:03 +0100 Subject: [PATCH 36/82] Fail CI build if imagelist generation fails --- deploy/kubernetes/imagelist-gen.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deploy/kubernetes/imagelist-gen.sh b/deploy/kubernetes/imagelist-gen.sh index 293c1a7ba4..77db87f409 100755 --- a/deploy/kubernetes/imagelist-gen.sh +++ b/deploy/kubernetes/imagelist-gen.sh @@ -37,6 +37,10 @@ ls -alR echo "" helm template -f ${__DIRNAME}/imagelist.values.yaml ${CHART_FOLDER} | grep "image:" | grep --extended --only-matching '([^"/[:space:]]+/)?[^"/[:space:]]+/[^:[:space:]]+:[a-zA-Z0-9\._-]+' | sort | uniq | awk -F'/' '{print $2}' > imagelist.txt +if [ $? -ne 0 ]; then + echo -e "${BOLD}${RED}ERROR: Failed to render Helm Chart in order to generate image list" + exit 1 +fi popd > /dev/null printf "${CYAN}" From 8e0bc421171ef7632760ecdb65d323ed68ef197e Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 11 Jun 2020 16:20:01 +0100 Subject: [PATCH 37/82] Org Managers: Disable org role checkboxes in roles stepper if not admin/org manager - fixes #4332 --- .../components/cf-role-checkbox/cf-role-checkbox.component.ts | 3 +-- .../table-cell-org-space-role.component.html | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts index 8472dd6633..f2337914c2 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts @@ -46,6 +46,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { @Input() cfGuid: string; + @Input() orgGuid: string; @Input() spaceGuid: string; @Input() orgName: string; @Input() spaceName: string; @@ -60,7 +61,6 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { sub: Subscription; isOrgRole = false; disabled = false; - orgGuid: string; private static hasExistingRole(role: string, roles: CfUserRolesSelected, userGuid: string, orgGuid: string, spaceGuid: string): boolean { if (roles && roles[userGuid] && roles[userGuid][orgGuid]) { @@ -266,7 +266,6 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { combineLatestOp(this.cfRolesService.newRoles$, users$, canEditRole$, selectUsersIsSetByUsername$), filter(([existingRoles, newRoles, users, canEditRole, isSetByUsername]) => !!users.length && !!newRoles.orgGuid) ).subscribe(([existingRoles, newRoles, users, canEditRole, isSetByUsername]) => { - this.orgGuid = newRoles.orgGuid; const { checked, tooltip } = CfRoleCheckboxComponent.getCheckedState( this.role, users, existingRoles, newRoles, this.orgGuid, this.spaceGuid); this.checked = checked; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-org-space-role/table-cell-org-space-role.component.html b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-org-space-role/table-cell-org-space-role.component.html index 76bda159ca..427d921780 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-org-space-role/table-cell-org-space-role.component.html +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-org-space-role/table-cell-org-space-role.component.html @@ -1,4 +1,5 @@ \ No newline at end of file From 85e27e23196c2e64a2deead541be1cdc90a5a5f7 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 11 Jun 2020 16:45:56 +0100 Subject: [PATCH 38/82] Routes List: Filter by org breaks when user is an org auditor - fixes #4343 --- .../src/features/cloud-foundry/cf.helpers.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts index 675a1f4758..e6e64456f7 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf.helpers.ts @@ -28,9 +28,10 @@ import { APIResource } from '../../../../store/src/types/api.types'; import { EndpointModel } from '../../../../store/src/types/endpoint.types'; import { PaginatedAction, PaginationEntityState } from '../../../../store/src/types/pagination.types'; import { IServiceInstance, IUserProvidedServiceInstance } from '../../cf-api-svc.types'; -import { CFFeatureFlagTypes, ISpace } from '../../cf-api.types'; +import { CFFeatureFlagTypes, IApp, ISpace } from '../../cf-api.types'; import { cfEntityFactory } from '../../cf-entity-factory'; import { CFEntityConfig } from '../../cf-types'; +import { ListCfRoute } from '../../shared/components/list/list-types/cf-routes/cf-routes-data-source-base'; import { CfUser, CfUserRoleParams, @@ -350,12 +351,17 @@ export function fetchTotalResults( ); } +type CfOrgSpaceFilterTypes = IApp | ListCfRoute | IServiceInstance; export const cfOrgSpaceFilter = (entities: APIResource[], paginationState: PaginationEntityState) => { // Filtering is done remotely when maxedResults are hit (see `setMultiFilter`) if (!!paginationState.maxedState.isMaxedMode && !paginationState.maxedState.ignoreMaxed) { return entities; } + const fetchOrgGuid = (e: APIResource): string => { + return e.entity.space ? e.entity.space.entity.organization_guid : null; + } + // Filter by cf/org/space const cfGuid = paginationState.clientPagination.filter.items.cf; const orgGuid = paginationState.clientPagination.filter.items.org; @@ -363,7 +369,7 @@ export const cfOrgSpaceFilter = (entities: APIResource[], paginationState: Pagin return !cfGuid && !orgGuid && !spaceGuid ? entities : entities.filter(e => { e = extractActualListEntity(e); const validCF = !(cfGuid && cfGuid !== e.entity.cfGuid); - const validOrg = !(orgGuid && orgGuid !== e.entity.space.entity.organization_guid); + const validOrg = !(orgGuid && orgGuid !== fetchOrgGuid(e)); const validSpace = !(spaceGuid && spaceGuid !== e.entity.space_guid); return validCF && validOrg && validSpace; }); From 050dd823da67672231ebe199572071054b19f0c0 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Thu, 11 Jun 2020 16:58:19 +0100 Subject: [PATCH 39/82] Rename the e2e cf helper file --- .../application/application-deploy-docker-e2e.spec.ts | 2 +- .../application/application-deploy-e2e.spec.ts | 2 +- src/test-e2e/application/application-e2e-helpers.ts | 2 +- .../application/application-routes-e2e.spec.ts | 2 +- src/test-e2e/application/application-view-e2e.spec.ts | 2 +- .../applications/application-wall-e2e.spec.ts | 2 +- .../cloud-foundry/cf-level/manage-org-e2e.spec.ts | 2 +- .../cloud-foundry/cf-level/manage-quota-e2e.spec.ts | 2 +- src/test-e2e/cloud-foundry/invite-users-e2e.helper.ts | 2 +- .../manage-users-by-username-stepper-e2e.spec.ts | 2 +- .../cloud-foundry/manage-users-stepper-e2e.spec.ts | 2 +- .../cloud-foundry/org-level/cf-org-delete-e2e.spec.ts | 5 +++-- .../org-level/manage-space-quota-e2e.spec.ts | 2 +- .../cloud-foundry/org-level/mange-space-e2e.spec.ts | 4 ++-- .../org-level/org-invite-user-e2e.spec.ts | 2 +- .../cloud-foundry/org-level/org-spaces-e2e.spec.ts | 2 +- .../space-level/cf-space-delete-e2e.spec.ts | 11 ++++++----- .../space-level/cf-space-level-e2e.spec.ts | 2 +- .../space-level/space-invite-user-e2e.spec.ts | 2 +- .../space-level/space-routes-e2e.spec.ts | 2 +- src/test-e2e/cloud-foundry/users-list-e2e.helper.ts | 2 +- .../cloud-foundry/users-removal-e2e.helper.ts | 2 +- .../helpers/{cf-helpers.ts => cf-e2e-helpers.ts} | 0 src/test-e2e/marketplace/services-helper-e2e.ts | 4 ++-- src/test-e2e/po/invite-users-stepper.po.ts | 2 +- 25 files changed, 33 insertions(+), 31 deletions(-) rename src/test-e2e/helpers/{cf-helpers.ts => cf-e2e-helpers.ts} (100%) diff --git a/src/test-e2e/application/application-deploy-docker-e2e.spec.ts b/src/test-e2e/application/application-deploy-docker-e2e.spec.ts index 8215178373..84de49c66c 100644 --- a/src/test-e2e/application/application-deploy-docker-e2e.spec.ts +++ b/src/test-e2e/application/application-deploy-docker-e2e.spec.ts @@ -1,7 +1,7 @@ import { browser } from 'protractor'; import { e2e } from '../e2e'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { CREATE_APP_DEPLOY_TEST_TYPE, createApplicationDeployTests } from './application-deploy-helper'; import { ApplicationE2eHelper } from './application-e2e-helpers'; diff --git a/src/test-e2e/application/application-deploy-e2e.spec.ts b/src/test-e2e/application/application-deploy-e2e.spec.ts index 994fa95c1b..5e07c421b9 100644 --- a/src/test-e2e/application/application-deploy-e2e.spec.ts +++ b/src/test-e2e/application/application-deploy-e2e.spec.ts @@ -1,7 +1,7 @@ import { browser, promise } from 'protractor'; import { e2e } from '../e2e'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { ConfirmDialogComponent } from '../po/confirm-dialog'; import { createApplicationDeployTests } from './application-deploy-helper'; diff --git a/src/test-e2e/application/application-e2e-helpers.ts b/src/test-e2e/application/application-e2e-helpers.ts index 52646ae9b3..b0800c2432 100644 --- a/src/test-e2e/application/application-e2e-helpers.ts +++ b/src/test-e2e/application/application-e2e-helpers.ts @@ -4,7 +4,7 @@ import { IApp, IRoute, ISpace } from '../../frontend/packages/cloud-foundry/src/ import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { e2e, E2ESetup } from '../e2e'; import { E2EConfigCloudFoundry } from '../e2e.types'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { CFRequestHelpers } from '../helpers/cf-request-helpers'; import { E2EHelpers } from '../helpers/e2e-helpers'; diff --git a/src/test-e2e/application/application-routes-e2e.spec.ts b/src/test-e2e/application/application-routes-e2e.spec.ts index 6a0ee1ec60..c90657464e 100644 --- a/src/test-e2e/application/application-routes-e2e.spec.ts +++ b/src/test-e2e/application/application-routes-e2e.spec.ts @@ -3,7 +3,7 @@ import { browser, promise, protractor } from 'protractor'; import { IApp } from '../../frontend/packages/cloud-foundry/src/cf-api.types'; import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { e2e } from '../e2e'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { ConfirmDialogComponent } from '../po/confirm-dialog'; import { ApplicationE2eHelper } from './application-e2e-helpers'; diff --git a/src/test-e2e/application/application-view-e2e.spec.ts b/src/test-e2e/application/application-view-e2e.spec.ts index e7467a6341..8c78955f9c 100644 --- a/src/test-e2e/application/application-view-e2e.spec.ts +++ b/src/test-e2e/application/application-view-e2e.spec.ts @@ -4,7 +4,7 @@ import { IApp } from '../../frontend/packages/cloud-foundry/src/cf-api.types'; import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { ApplicationsPage } from '../applications/applications.po'; import { e2e } from '../e2e'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../helpers/e2e-helpers'; import { ApplicationE2eHelper } from './application-e2e-helpers'; import { ApplicationPageEventsTab } from './po/application-page-events.po'; diff --git a/src/test-e2e/applications/application-wall-e2e.spec.ts b/src/test-e2e/applications/application-wall-e2e.spec.ts index fc8f6d3da0..85fa104fa6 100644 --- a/src/test-e2e/applications/application-wall-e2e.spec.ts +++ b/src/test-e2e/applications/application-wall-e2e.spec.ts @@ -5,7 +5,7 @@ import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { ApplicationE2eHelper } from '../application/application-e2e-helpers'; import { e2e } from '../e2e'; import { E2EConfigCloudFoundry } from '../e2e.types'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../helpers/e2e-helpers'; import { extendE2ETestTime } from '../helpers/extend-test-helpers'; import { FormComponent } from '../po/form.po'; diff --git a/src/test-e2e/cloud-foundry/cf-level/manage-org-e2e.spec.ts b/src/test-e2e/cloud-foundry/cf-level/manage-org-e2e.spec.ts index e6a92dda50..07893a76bb 100644 --- a/src/test-e2e/cloud-foundry/cf-level/manage-org-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/cf-level/manage-org-e2e.spec.ts @@ -1,7 +1,7 @@ import { by, element, promise, protractor } from 'protractor'; import { e2e } from '../../e2e'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; import { CfOrgLevelPage } from '../org-level/cf-org-level-page.po'; import { CfTopLevelPage } from './cf-top-level-page.po'; diff --git a/src/test-e2e/cloud-foundry/cf-level/manage-quota-e2e.spec.ts b/src/test-e2e/cloud-foundry/cf-level/manage-quota-e2e.spec.ts index e70910bfc2..159cfcb4fd 100644 --- a/src/test-e2e/cloud-foundry/cf-level/manage-quota-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/cf-level/manage-quota-e2e.spec.ts @@ -1,7 +1,7 @@ import { by, element, promise, protractor } from 'protractor'; import { e2e } from '../../e2e'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; import { extendE2ETestTime } from '../../helpers/extend-test-helpers'; import { TableComponent } from '../../po/table.po'; diff --git a/src/test-e2e/cloud-foundry/invite-users-e2e.helper.ts b/src/test-e2e/cloud-foundry/invite-users-e2e.helper.ts index 2591e7d680..f8b3ac8198 100644 --- a/src/test-e2e/cloud-foundry/invite-users-e2e.helper.ts +++ b/src/test-e2e/cloud-foundry/invite-users-e2e.helper.ts @@ -2,7 +2,7 @@ import { browser, promise } from 'protractor'; import { e2e } from '../e2e'; import { E2EConfigCloudFoundry } from '../e2e.types'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { extendE2ETestTime } from '../helpers/extend-test-helpers'; import { CFUsersListComponent } from '../po/cf-users-list.po'; diff --git a/src/test-e2e/cloud-foundry/manage-users-by-username-stepper-e2e.spec.ts b/src/test-e2e/cloud-foundry/manage-users-by-username-stepper-e2e.spec.ts index f72a3d3422..637160d806 100644 --- a/src/test-e2e/cloud-foundry/manage-users-by-username-stepper-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/manage-users-by-username-stepper-e2e.spec.ts @@ -3,7 +3,7 @@ import { browser, by, element, promise } from 'protractor'; import { CfUser } from '../../frontend/packages/cloud-foundry/src/store/types/cf-user.types'; import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { e2e } from '../e2e'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../helpers/e2e-helpers'; import { UaaHelpers } from '../helpers/uaa-helpers'; import { CFUsersListComponent } from '../po/cf-users-list.po'; diff --git a/src/test-e2e/cloud-foundry/manage-users-stepper-e2e.spec.ts b/src/test-e2e/cloud-foundry/manage-users-stepper-e2e.spec.ts index 75d391ab0c..bef96542b2 100644 --- a/src/test-e2e/cloud-foundry/manage-users-stepper-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/manage-users-stepper-e2e.spec.ts @@ -1,7 +1,7 @@ import { browser, by, element, protractor } from 'protractor'; import { e2e } from '../e2e'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { E2EHelpers } from '../helpers/e2e-helpers'; import { extendE2ETestTime } from '../helpers/extend-test-helpers'; import { CFUsersListComponent } from '../po/cf-users-list.po'; diff --git a/src/test-e2e/cloud-foundry/org-level/cf-org-delete-e2e.spec.ts b/src/test-e2e/cloud-foundry/org-level/cf-org-delete-e2e.spec.ts index a5dca278a6..7ce53760c4 100644 --- a/src/test-e2e/cloud-foundry/org-level/cf-org-delete-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/org-level/cf-org-delete-e2e.spec.ts @@ -1,10 +1,11 @@ import { by, element, protractor } from 'protractor'; + import { e2e } from '../../e2e'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; -import { CfTopLevelPage } from '../cf-level/cf-top-level-page.po'; import { CFPage } from '../../po/cf-page.po'; import { SideNavMenuItem } from '../../po/side-nav.po'; +import { CfTopLevelPage } from '../cf-level/cf-top-level-page.po'; describe('Delete Organization', () => { let e2eSetup; diff --git a/src/test-e2e/cloud-foundry/org-level/manage-space-quota-e2e.spec.ts b/src/test-e2e/cloud-foundry/org-level/manage-space-quota-e2e.spec.ts index 52bc96cc41..fe7f699afb 100644 --- a/src/test-e2e/cloud-foundry/org-level/manage-space-quota-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/org-level/manage-space-quota-e2e.spec.ts @@ -1,7 +1,7 @@ import { by, element, promise, protractor } from 'protractor'; import { e2e } from '../../e2e'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; import { extendE2ETestTime } from '../../helpers/extend-test-helpers'; import { CfOrgLevelPage } from '../org-level/cf-org-level-page.po'; diff --git a/src/test-e2e/cloud-foundry/org-level/mange-space-e2e.spec.ts b/src/test-e2e/cloud-foundry/org-level/mange-space-e2e.spec.ts index 89fa38c40c..912202fbcd 100644 --- a/src/test-e2e/cloud-foundry/org-level/mange-space-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/org-level/mange-space-e2e.spec.ts @@ -1,12 +1,12 @@ import { by, element, promise, protractor } from 'protractor'; import { e2e } from '../../e2e'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; +import { TableComponent } from '../../po/table.po'; import { CfSpaceLevelPage } from '../space-level/cf-space-level-page.po'; import { CfOrgLevelPage } from './cf-org-level-page.po'; import { SpaceFormPage } from './space-form-page.po'; -import { TableComponent } from '../../po/table.po'; describe('Manage Space', () => { let e2eSetup; diff --git a/src/test-e2e/cloud-foundry/org-level/org-invite-user-e2e.spec.ts b/src/test-e2e/cloud-foundry/org-level/org-invite-user-e2e.spec.ts index 429622a891..1248a60dae 100644 --- a/src/test-e2e/cloud-foundry/org-level/org-invite-user-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/org-level/org-invite-user-e2e.spec.ts @@ -1,5 +1,5 @@ import { E2EConfigCloudFoundry } from '../../e2e.types'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { CFPage } from '../../po/cf-page.po'; import { SideNavMenuItem } from '../../po/side-nav.po'; import { setupInviteUserTests } from '../invite-users-e2e.helper'; diff --git a/src/test-e2e/cloud-foundry/org-level/org-spaces-e2e.spec.ts b/src/test-e2e/cloud-foundry/org-level/org-spaces-e2e.spec.ts index 1ddf2be05e..799c75d439 100644 --- a/src/test-e2e/cloud-foundry/org-level/org-spaces-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/org-level/org-spaces-e2e.spec.ts @@ -4,7 +4,7 @@ import { IOrganization } from '../../../frontend/packages/cloud-foundry/src/cf-a import { APIResource } from '../../../frontend/packages/store/src/types/api.types'; import { e2e } from '../../e2e'; import { E2EConfigCloudFoundry } from '../../e2e.types'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; import { ListComponent } from '../../po/list.po'; import { CfOrgLevelPage } from './cf-org-level-page.po'; diff --git a/src/test-e2e/cloud-foundry/space-level/cf-space-delete-e2e.spec.ts b/src/test-e2e/cloud-foundry/space-level/cf-space-delete-e2e.spec.ts index 73f017292f..c6dc55efbc 100644 --- a/src/test-e2e/cloud-foundry/space-level/cf-space-delete-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/space-level/cf-space-delete-e2e.spec.ts @@ -1,14 +1,15 @@ -import { CfOrgLevelPage } from './../org-level/cf-org-level-page.po'; import { by, element, protractor } from 'protractor'; + import { e2e } from '../../e2e'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; -import { CfTopLevelPage } from '../cf-level/cf-top-level-page.po'; import { CFPage } from '../../po/cf-page.po'; -import { SideNavMenuItem } from '../../po/side-nav.po'; +import { ConfirmDialogComponent } from '../../po/confirm-dialog'; import { ListComponent } from '../../po/list.po'; import { MetaCardTitleType } from '../../po/meta-card.po'; -import { ConfirmDialogComponent } from '../../po/confirm-dialog'; +import { SideNavMenuItem } from '../../po/side-nav.po'; +import { CfTopLevelPage } from '../cf-level/cf-top-level-page.po'; +import { CfOrgLevelPage } from './../org-level/cf-org-level-page.po'; describe('Delete Space', () => { let e2eSetup; diff --git a/src/test-e2e/cloud-foundry/space-level/cf-space-level-e2e.spec.ts b/src/test-e2e/cloud-foundry/space-level/cf-space-level-e2e.spec.ts index f7b6095de0..5cd14c362e 100644 --- a/src/test-e2e/cloud-foundry/space-level/cf-space-level-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/space-level/cf-space-level-e2e.spec.ts @@ -2,7 +2,7 @@ import { by, element, protractor } from 'protractor'; import { e2e } from '../../e2e'; import { E2EConfigCloudFoundry } from '../../e2e.types'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; import { extendE2ETestTime } from '../../helpers/extend-test-helpers'; import { CFPage } from '../../po/cf-page.po'; diff --git a/src/test-e2e/cloud-foundry/space-level/space-invite-user-e2e.spec.ts b/src/test-e2e/cloud-foundry/space-level/space-invite-user-e2e.spec.ts index 158dc0d4c5..240dbc453d 100644 --- a/src/test-e2e/cloud-foundry/space-level/space-invite-user-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/space-level/space-invite-user-e2e.spec.ts @@ -1,7 +1,7 @@ import { promise } from 'protractor'; import { E2EConfigCloudFoundry } from '../../e2e.types'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { setupInviteUserTests } from '../invite-users-e2e.helper'; import { CfSpaceLevelPage } from './cf-space-level-page.po'; diff --git a/src/test-e2e/cloud-foundry/space-level/space-routes-e2e.spec.ts b/src/test-e2e/cloud-foundry/space-level/space-routes-e2e.spec.ts index 386a8bf593..68a726e99a 100644 --- a/src/test-e2e/cloud-foundry/space-level/space-routes-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/space-level/space-routes-e2e.spec.ts @@ -4,7 +4,7 @@ import { ISpace } from '../../../frontend/packages/cloud-foundry/src/cf-api.type import { APIResource } from '../../../frontend/packages/store/src/types/api.types'; import { e2e } from '../../e2e'; import { E2EConfigCloudFoundry } from '../../e2e.types'; -import { CFHelpers } from '../../helpers/cf-helpers'; +import { CFHelpers } from '../../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../../helpers/e2e-helpers'; import { ListComponent } from '../../po/list.po'; import { CfSpaceLevelPage } from './cf-space-level-page.po'; diff --git a/src/test-e2e/cloud-foundry/users-list-e2e.helper.ts b/src/test-e2e/cloud-foundry/users-list-e2e.helper.ts index cb4cf82680..656b0eadb5 100644 --- a/src/test-e2e/cloud-foundry/users-list-e2e.helper.ts +++ b/src/test-e2e/cloud-foundry/users-list-e2e.helper.ts @@ -3,7 +3,7 @@ import { protractor } from 'protractor/built/ptor'; import { e2e, E2ESetup } from '../e2e'; import { E2EConfigCloudFoundry } from '../e2e.types'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../helpers/e2e-helpers'; import { extendE2ETestTime } from '../helpers/extend-test-helpers'; import { CFUsersListComponent, UserRoleChip } from '../po/cf-users-list.po'; diff --git a/src/test-e2e/cloud-foundry/users-removal-e2e.helper.ts b/src/test-e2e/cloud-foundry/users-removal-e2e.helper.ts index a449dddd5f..92208e98ff 100644 --- a/src/test-e2e/cloud-foundry/users-removal-e2e.helper.ts +++ b/src/test-e2e/cloud-foundry/users-removal-e2e.helper.ts @@ -4,7 +4,7 @@ import { protractor } from 'protractor/built/ptor'; import { CfUser } from '../../frontend/packages/cloud-foundry/src/store/types/cf-user.types'; import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { e2e } from '../e2e'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { ConsoleUserType, E2EHelpers } from '../helpers/e2e-helpers'; import { UaaHelpers } from '../helpers/uaa-helpers'; import { CFUsersListComponent } from '../po/cf-users-list.po'; diff --git a/src/test-e2e/helpers/cf-helpers.ts b/src/test-e2e/helpers/cf-e2e-helpers.ts similarity index 100% rename from src/test-e2e/helpers/cf-helpers.ts rename to src/test-e2e/helpers/cf-e2e-helpers.ts diff --git a/src/test-e2e/marketplace/services-helper-e2e.ts b/src/test-e2e/marketplace/services-helper-e2e.ts index 7e358eb5f8..00186196e9 100644 --- a/src/test-e2e/marketplace/services-helper-e2e.ts +++ b/src/test-e2e/marketplace/services-helper-e2e.ts @@ -4,7 +4,7 @@ import { IServiceInstance } from '../../frontend/packages/cloud-foundry/src/cf-a import { CFResponse, createEmptyCfResponse } from '../../frontend/packages/cloud-foundry/src/store/types/cf-api.types'; import { APIResource } from '../../frontend/packages/store/src/types/api.types'; import { e2e, E2ESetup } from '../e2e'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { CFRequestHelpers } from '../helpers/cf-request-helpers'; import { E2EHelpers } from '../helpers/e2e-helpers'; import { ListComponent } from '../po/list.po'; @@ -65,7 +65,7 @@ export class ServicesHelperE2E { deleteServiceInstance = (cfGuid: string, serviceGuid: string, userProvided = false): promise.Promise => { const id = `${cfGuid}:${serviceGuid}`; - const url = userProvided ?`user_provided_service_instances/${serviceGuid}?async=false&recursive=true` : `service_instances/${serviceGuid}?async=false&recursive=true`; + const url = userProvided ? `user_provided_service_instances/${serviceGuid}?async=false&recursive=true` : `service_instances/${serviceGuid}?async=false&recursive=true`; return this.cfRequestHelper.sendCfDelete( cfGuid, url diff --git a/src/test-e2e/po/invite-users-stepper.po.ts b/src/test-e2e/po/invite-users-stepper.po.ts index 5945d300c0..5530ba09de 100644 --- a/src/test-e2e/po/invite-users-stepper.po.ts +++ b/src/test-e2e/po/invite-users-stepper.po.ts @@ -1,6 +1,6 @@ import { by, promise } from 'protractor'; -import { CFHelpers } from '../helpers/cf-helpers'; +import { CFHelpers } from '../helpers/cf-e2e-helpers'; import { E2EHelpers } from '../helpers/e2e-helpers'; import { RadioGroup } from './radio-group.po'; import { SnackBarPo } from './snackbar.po'; From d19213c2f99e6985f02c559855376cceff7c8dab Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 16 Jun 2020 09:59:40 +0100 Subject: [PATCH 40/82] Fix autoscaler tab --- .../autoscaler-tab-extension.component.html | 4 +- .../autoscaler-tab-extension.component.ts | 55 ++++++++++++------- .../src/core/extension/extension-service.ts | 12 +++- .../page-side-nav/page-side-nav.component.ts | 15 +++-- 4 files changed, 57 insertions(+), 29 deletions(-) diff --git a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.html b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.html index c1d419a048..2a20fe1798 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.html +++ b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.html @@ -1,4 +1,4 @@ - +
\ No newline at end of file diff --git a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts index 1a7fad96d9..09be30329a 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts @@ -2,11 +2,19 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar'; import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; -import { combineLatest, Observable, Subscription } from 'rxjs'; +import { combineLatest, Observable, of, Subscription } from 'rxjs'; import { distinctUntilChanged, filter, first, map, pairwise, publishReplay, refCount, switchMap } from 'rxjs/operators'; -import { applicationEntityType } from '../../../../cloud-foundry/src/cf-entity-types'; -import { createEntityRelationPaginationKey } from '../../../../cloud-foundry/src/entity-relations/entity-relations.types'; +import { cfEntityCatalog } from '../../../../cloud-foundry/src/cf-entity-catalog'; +import { + applicationEntityType, + organizationEntityType, + spaceEntityType, +} from '../../../../cloud-foundry/src/cf-entity-types'; +import { + createEntityRelationKey, + createEntityRelationPaginationKey, +} from '../../../../cloud-foundry/src/entity-relations/entity-relations.types'; import { ApplicationMonitorService } from '../../../../cloud-foundry/src/features/applications/application-monitor.service'; import { ApplicationService } from '../../../../cloud-foundry/src/features/applications/application.service'; import { getGuids } from '../../../../cloud-foundry/src/features/applications/application/application-base.component'; @@ -54,9 +62,32 @@ import { appAutoscalerAppMetricEntityType, autoscalerEntityFactory } from '../.. link: 'autoscale', icon: 'meter', iconFont: 'stratos-icons', - hidden: (store: Store, esf: EntityServiceFactory, activatedRoute: ActivatedRoute) => { + hidden: (store: Store, esf: EntityServiceFactory, activatedRoute: ActivatedRoute, cups: CurrentUserPermissionsService) => { const endpointGuid = getGuids('cf')(activatedRoute) || window.location.pathname.split('/')[2]; - return isAutoscalerEnabled(endpointGuid, esf).pipe(map(enabled => !enabled)); + const appGuid = getGuids()(activatedRoute) || window.location.pathname.split('/')[3]; + const appEntService = cfEntityCatalog.application.store.getEntityService(appGuid, endpointGuid, { + includeRelations: [ + createEntityRelationKey(applicationEntityType, spaceEntityType), + createEntityRelationKey(spaceEntityType, organizationEntityType), + ], + populateMissing: true + }) + + const canEditSpace$ = appEntService.waitForEntity$.pipe( + switchMap(app => cups.can( + CfCurrentUserPermissions.APPLICATION_EDIT, + endpointGuid, + app.entity.entity.space.entity.organization_guid, + app.entity.entity.space.metadata.guid + )), + ) + + const autoscalerEnabled = isAutoscalerEnabled(endpointGuid, esf); + + return canEditSpace$.pipe( + switchMap(canEditSpace => canEditSpace ? autoscalerEnabled : of(false)), + map(can => !can) + ) } }) @Component({ @@ -115,8 +146,6 @@ export class AutoscalerTabExtensionComponent implements OnInit, OnDestroy { 'order-direction': 'desc' }; - public canEditSpace$: Observable; - ngOnDestroy(): void { if (this.appAutoscalerPolicySnackBarRef) { this.appAutoscalerPolicySnackBarRef.dismiss(); @@ -224,18 +253,6 @@ export class AutoscalerTabExtensionComponent implements OnInit, OnDestroy { publishReplay(1), refCount() ); - - this.canEditSpace$ = combineLatest( - this.applicationService.appOrg$, - this.applicationService.appSpace$ - ).pipe( - switchMap(([org, space]) => this.cups.can( - CfCurrentUserPermissions.SPACE_EDIT, - this.applicationService.cfGuid, - org.metadata.guid, - space.metadata.guid - )) - ) } getAppMetric(metricName: string, trigger: AppScalingTrigger, params: AutoscalerPaginationParams) { diff --git a/src/frontend/packages/core/src/core/extension/extension-service.ts b/src/frontend/packages/core/src/core/extension/extension-service.ts index 82b7a305ff..c71151f5b7 100644 --- a/src/frontend/packages/core/src/core/extension/extension-service.ts +++ b/src/frontend/packages/core/src/core/extension/extension-service.ts @@ -1,4 +1,4 @@ -import { Injectable, NgModule, ModuleWithProviders } from '@angular/core'; +import { Injectable, ModuleWithProviders, NgModule } from '@angular/core'; import { ActivatedRoute, Route, Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; @@ -6,6 +6,7 @@ import { Observable } from 'rxjs'; import { AppState, GeneralEntityAppState } from '../../../../store/src/app-state'; import { EntityServiceFactory } from '../../../../store/src/entity-service-factory.service'; import { IPageSideNavTab } from '../../features/dashboard/page-side-nav/page-side-nav.component'; +import { CurrentUserPermissionsService } from '../permissions/current-user-permissions.service'; export const extensionsActionRouteKey = 'extensionsActionsKey'; @@ -23,7 +24,12 @@ export interface StratosTabMetadata { link: string; icon?: string; iconFont?: string; - hidden?: (store: Store, esf: EntityServiceFactory, activatedRoute: ActivatedRoute) => Observable; + hidden?: ( + store: Store, + esf: EntityServiceFactory, + activatedRoute: ActivatedRoute, + cups: CurrentUserPermissionsService + ) => Observable; } export interface StratosTabMetadataConfig extends StratosTabMetadata { @@ -97,7 +103,7 @@ function addExtensionTab(tab: StratosTabType, target: any, props: StratosTabMeta }); extensionMetadata.tabs[tab].push({ ...props - }); + }); } function addExtensionAction(action: StratosActionType, target: any, props: StratosActionMetadata) { diff --git a/src/frontend/packages/core/src/features/dashboard/page-side-nav/page-side-nav.component.ts b/src/frontend/packages/core/src/features/dashboard/page-side-nav/page-side-nav.component.ts index a91f4bd200..696435a9bf 100644 --- a/src/frontend/packages/core/src/features/dashboard/page-side-nav/page-side-nav.component.ts +++ b/src/frontend/packages/core/src/features/dashboard/page-side-nav/page-side-nav.component.ts @@ -4,10 +4,11 @@ import { Store } from '@ngrx/store'; import { Observable, of } from 'rxjs'; import { AppState } from '../../../../../store/src/app-state'; +import { EntityServiceFactory } from '../../../../../store/src/entity-service-factory.service'; import { selectIsMobile } from '../../../../../store/src/selectors/dashboard.selectors'; import { TabNavService } from '../../../../tab-nav.service'; -import { EntityServiceFactory } from '../../../../../store/src/entity-service-factory.service'; import { StratosTabMetadata } from '../../../core/extension/extension-service'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { IBreadcrumb } from '../../../shared/components/breadcrumbs/breadcrumbs.types'; export interface IPageSideNavTab extends StratosTabMetadata { @@ -26,10 +27,13 @@ export class PageSideNavComponent implements OnInit { if (!tabs || (this.pTabs && tabs.length === this.pTabs.length)) { return; } - this.pTabs = tabs.map(tab => ({ - ...tab, - hidden$: tab.hidden$ || (tab.hidden ? tab.hidden(this.store, this.esf, this.activatedRoute) : of(false)) - })); + this.pTabs = tabs.map(tab => { + const hidden = (tab.hidden ? tab.hidden(this.store, this.esf, this.activatedRoute, this.cups) : of(false)) + return { + ...tab, + hidden$: tab.hidden$ || hidden + } + }); } get tabs(): IPageSideNavTab[] { return this.pTabs; @@ -45,6 +49,7 @@ export class PageSideNavComponent implements OnInit { private store: Store, private esf: EntityServiceFactory, private activatedRoute: ActivatedRoute, + private cups: CurrentUserPermissionsService ) { this.isMobile$ = this.store.select(selectIsMobile); } From be21060365abbd8eb468b29d61766ee6019b8a70 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 16 Jun 2020 12:27:25 +0100 Subject: [PATCH 41/82] Changes following review --- .../autoscaler-tab-extension.component.ts | 7 +++---- .../card-app-instances.component.html | 2 +- .../card-app-instances.component.ts | 9 +++++---- .../app-instance/cf-app-instances-config.service.ts | 12 +++++++----- .../page-side-nav/page-side-nav.component.ts | 13 ++++++------- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts index 09be30329a..9b3b56c9b2 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-tab-extension/autoscaler-tab-extension.component.ts @@ -73,7 +73,7 @@ import { appAutoscalerAppMetricEntityType, autoscalerEntityFactory } from '../.. populateMissing: true }) - const canEditSpace$ = appEntService.waitForEntity$.pipe( + const canEditApp$ = appEntService.waitForEntity$.pipe( switchMap(app => cups.can( CfCurrentUserPermissions.APPLICATION_EDIT, endpointGuid, @@ -84,7 +84,7 @@ import { appAutoscalerAppMetricEntityType, autoscalerEntityFactory } from '../.. const autoscalerEnabled = isAutoscalerEnabled(endpointGuid, esf); - return canEditSpace$.pipe( + return canEditApp$.pipe( switchMap(canEditSpace => canEditSpace ? autoscalerEnabled : of(false)), map(can => !can) ) @@ -163,8 +163,7 @@ export class AutoscalerTabExtensionComponent implements OnInit, OnDestroy { private paginationMonitorFactory: PaginationMonitorFactory, private appAutoscalerPolicySnackBar: MatSnackBar, private appAutoscalerScalingHistorySnackBar: MatSnackBar, - private confirmDialog: ConfirmationDialogService, - private cups: CurrentUserPermissionsService + private confirmDialog: ConfirmationDialogService ) { } ngOnInit() { diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.html b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.html index d2c25acd15..4c5cd00b6f 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.html +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.html @@ -15,7 +15,7 @@ - + - - - - - - - - + + + + + \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts index c3524019b6..048e57ddac 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts @@ -1,13 +1,15 @@ -import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild, Renderer2 } from '@angular/core'; +import { Component, ElementRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core'; import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar'; -import { Observable, Subscription } from 'rxjs'; -import { first, map } from 'rxjs/operators'; +import { combineLatest, Observable, Subscription } from 'rxjs'; +import { first, map, switchMap } from 'rxjs/operators'; import { AppMetadataTypes } from '../../../../../../cloud-foundry/src/actions/app-metadata.actions'; import { ApplicationService } from '../../../../../../cloud-foundry/src/features/applications/application.service'; +import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogConfig } from '../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../core/src/shared/components/confirmation-dialog.service'; import { StratosStatus } from '../../../../../../core/src/shared/shared.types'; +import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; const appInstanceScaleToZeroConfirmation = new ConfirmationDialogConfig('Set Instance count to 0', 'Are you sure you want to set the instance count to 0?', 'Confirm', true); @@ -28,14 +30,26 @@ export class CardAppInstancesComponent implements OnInit, OnDestroy { status$: Observable; + public canEditApp$: Observable; + constructor( public appService: ApplicationService, private renderer: Renderer2, private confirmDialog: ConfirmationDialogService, - private snackBar: MatSnackBar) { + private snackBar: MatSnackBar, + cups: CurrentUserPermissionsService + ) { this.status$ = this.appService.applicationState$.pipe( map(state => state.indicator) ); + this.canEditApp$ = combineLatest( + appService.appOrg$, + appService.appSpace$ + ).pipe( + switchMap(([org, space]) => + cups.can(CfCurrentUserPermissions.APPLICATION_EDIT, appService.cfGuid, org.metadata.guid, space.metadata.guid) + )) + } private currentCount = 0; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts index 1559dfec06..69b0f82bd8 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts @@ -1,12 +1,15 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; -import { Observable } from 'rxjs'; +import { combineLatest as combineLatestObs, Observable } from 'rxjs'; import { combineLatest, map, switchMap } from 'rxjs/operators'; import { DeleteApplicationInstance } from '../../../../../../../cloud-foundry/src/actions/application.actions'; import { FetchApplicationMetricsAction } from '../../../../../../../cloud-foundry/src/actions/cf-metrics.actions'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; +import { + CurrentUserPermissionsService, +} from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { UtilsService } from '../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -27,6 +30,7 @@ import { IMetricMatrixResult, IMetrics } from '../../../../../../../store/src/ty import { IMetricApplication } from '../../../../../../../store/src/types/metric.types'; import { ApplicationService } from '../../../../../features/applications/application.service'; import { CfCellHelper } from '../../../../../features/cloud-foundry/cf-cell.helpers'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ListAppInstance } from './app-instance-types'; import { CfAppInstancesDataSource } from './cf-app-instances-data-source'; import { TableCellCfCellComponent } from './table-cell-cf-cell/table-cell-cf-cell.component'; @@ -158,7 +162,7 @@ export class CfAppInstancesConfigService implements IListConfig }, label: 'Terminate', description: ``, // Description depends on console user permission - + createVisible: () => this.canEditApp$ }; private listActionSsh: IListAction = { @@ -182,7 +186,8 @@ export class CfAppInstancesConfigService implements IListConfig space.entity.allow_ssh; }) ); - })) + })), + createVisible: () => this.canEditApp$ }; private singleActions = [ @@ -190,6 +195,8 @@ export class CfAppInstancesConfigService implements IListConfig this.listActionSsh, ]; + private canEditApp$: Observable; + constructor( private store: Store, private appService: ApplicationService, @@ -197,7 +204,8 @@ export class CfAppInstancesConfigService implements IListConfig private router: Router, private confirmDialog: ConfirmationDialogService, entityServiceFactory: EntityServiceFactory, - paginationMonitorFactory: PaginationMonitorFactory + paginationMonitorFactory: PaginationMonitorFactory, + cups: CurrentUserPermissionsService ) { const cellHelper = new CfCellHelper(store, paginationMonitorFactory); @@ -220,6 +228,15 @@ export class CfAppInstancesConfigService implements IListConfig this.appService.appGuid, this, ); + + this.canEditApp$ = combineLatestObs( + appService.appOrg$, + appService.appSpace$ + ).pipe( + switchMap(([org, space]) => + cups.can(CfCurrentUserPermissions.APPLICATION_EDIT, appService.cfGuid, org.metadata.guid, space.metadata.guid) + ) + ) } getGlobalActions = () => null; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts index a631fac6ae..b69eb4ab15 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-route/cf-app-routes-list-config.service.ts @@ -1,7 +1,8 @@ import { DatePipe } from '@angular/common'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { take } from 'rxjs/operators'; +import { combineLatest } from 'rxjs'; +import { switchMap, take } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; import { @@ -12,6 +13,7 @@ import { IGlobalListAction, IListConfig } from '../../../../../../../core/src/sh import { RouterNav } from '../../../../../../../store/src/actions/router.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { ApplicationService } from '../../../../../features/applications/application.service'; +import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { CfAppRoutesListConfigServiceBase } from './cf-app-routes-list-config-base'; @@ -23,11 +25,12 @@ export class CfAppRoutesListConfigService extends CfAppRoutesListConfigServiceBa appService: ApplicationService, confirmDialog: ConfirmationDialogService, datePipe: DatePipe, - currentUserPermissionsService: CurrentUserPermissionsService, + private currentUserPermissionsService: CurrentUserPermissionsService, ) { super(store, appService, confirmDialog, datePipe, currentUserPermissionsService, null, true); this.setupList(store, appService); + this.allowSelection = false; // Allow the multi action visibility to determine this } private setupList(store: Store, appService: ApplicationService) { @@ -51,7 +54,18 @@ export class CfAppRoutesListConfigService extends CfAppRoutesListConfigServiceBa }, icon: 'add', label: 'Add', - description: 'Add new route' + description: 'Add new route', + visible$: combineLatest( + appService.appOrg$, + appService.appSpace$ + ).pipe( + switchMap(([org, space]) => this.currentUserPermissionsService.can( + CfCurrentUserPermissions.ROUTE_CREATE, + appService.cfGuid, + org.metadata.guid, + space.metadata.guid + )) + ) }; this.getGlobalActions = () => [listActionAddRoute]; } diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts index b38816caf9..5d4e9bc1be 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts @@ -396,7 +396,7 @@ export class CfUserPermissionsChecker extends BaseCurrentUserPermissionsChecker } private getAllEndpointGuids() { - return this.store.select(connectedEndpointsSelector).pipe( + return this.store.select(connectedEndpointsSelector()).pipe( map(endpoints => Object.values(endpoints).filter(e => e.cnsi_type === CF_ENDPOINT_TYPE).map(endpoint => endpoint.guid)) ); } diff --git a/src/frontend/packages/core/src/core/extension/extension-service.ts b/src/frontend/packages/core/src/core/extension/extension-service.ts index 82b7a305ff..c71151f5b7 100644 --- a/src/frontend/packages/core/src/core/extension/extension-service.ts +++ b/src/frontend/packages/core/src/core/extension/extension-service.ts @@ -1,4 +1,4 @@ -import { Injectable, NgModule, ModuleWithProviders } from '@angular/core'; +import { Injectable, ModuleWithProviders, NgModule } from '@angular/core'; import { ActivatedRoute, Route, Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; @@ -6,6 +6,7 @@ import { Observable } from 'rxjs'; import { AppState, GeneralEntityAppState } from '../../../../store/src/app-state'; import { EntityServiceFactory } from '../../../../store/src/entity-service-factory.service'; import { IPageSideNavTab } from '../../features/dashboard/page-side-nav/page-side-nav.component'; +import { CurrentUserPermissionsService } from '../permissions/current-user-permissions.service'; export const extensionsActionRouteKey = 'extensionsActionsKey'; @@ -23,7 +24,12 @@ export interface StratosTabMetadata { link: string; icon?: string; iconFont?: string; - hidden?: (store: Store, esf: EntityServiceFactory, activatedRoute: ActivatedRoute) => Observable; + hidden?: ( + store: Store, + esf: EntityServiceFactory, + activatedRoute: ActivatedRoute, + cups: CurrentUserPermissionsService + ) => Observable; } export interface StratosTabMetadataConfig extends StratosTabMetadata { @@ -97,7 +103,7 @@ function addExtensionTab(tab: StratosTabType, target: any, props: StratosTabMeta }); extensionMetadata.tabs[tab].push({ ...props - }); + }); } function addExtensionAction(action: StratosActionType, target: any, props: StratosActionMetadata) { diff --git a/src/frontend/packages/core/src/features/dashboard/page-side-nav/page-side-nav.component.ts b/src/frontend/packages/core/src/features/dashboard/page-side-nav/page-side-nav.component.ts index a91f4bd200..b74dbed831 100644 --- a/src/frontend/packages/core/src/features/dashboard/page-side-nav/page-side-nav.component.ts +++ b/src/frontend/packages/core/src/features/dashboard/page-side-nav/page-side-nav.component.ts @@ -4,12 +4,15 @@ import { Store } from '@ngrx/store'; import { Observable, of } from 'rxjs'; import { AppState } from '../../../../../store/src/app-state'; +import { EntityServiceFactory } from '../../../../../store/src/entity-service-factory.service'; import { selectIsMobile } from '../../../../../store/src/selectors/dashboard.selectors'; import { TabNavService } from '../../../../tab-nav.service'; -import { EntityServiceFactory } from '../../../../../store/src/entity-service-factory.service'; import { StratosTabMetadata } from '../../../core/extension/extension-service'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { IBreadcrumb } from '../../../shared/components/breadcrumbs/breadcrumbs.types'; + + export interface IPageSideNavTab extends StratosTabMetadata { hidden$?: Observable; } @@ -28,7 +31,7 @@ export class PageSideNavComponent implements OnInit { } this.pTabs = tabs.map(tab => ({ ...tab, - hidden$: tab.hidden$ || (tab.hidden ? tab.hidden(this.store, this.esf, this.activatedRoute) : of(false)) + hidden$: tab.hidden$ || (tab.hidden ? tab.hidden(this.store, this.esf, this.activatedRoute, this.cups) : of(false)) })); } get tabs(): IPageSideNavTab[] { @@ -45,6 +48,7 @@ export class PageSideNavComponent implements OnInit { private store: Store, private esf: EntityServiceFactory, private activatedRoute: ActivatedRoute, + private cups: CurrentUserPermissionsService ) { this.isMobile$ = this.store.select(selectIsMobile); } diff --git a/src/test-e2e/application/application-view-e2e.spec.ts b/src/test-e2e/application/application-view-e2e.spec.ts index c2d51b6b78..e7467a6341 100644 --- a/src/test-e2e/application/application-view-e2e.spec.ts +++ b/src/test-e2e/application/application-view-e2e.spec.ts @@ -135,8 +135,7 @@ describe('Application View -', () => { }); it('Deployment Info', () => { - appSummary.cardDeployInfo.waitForTitle('Deployment Info'); - expect(appSummary.cardDeployInfo.getContent()).toBe('None'); + expect(appSummary.cardDeployInfo.isPresent()).toBeFalsy(); }); }); From 3058d8a6b22a47f3d0a3ab4aac18cf2441d83dbc Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 17 Jun 2020 11:13:13 +0100 Subject: [PATCH 43/82] Fix service stepper navigation (#4366) * Fix service stepper navigation on create/edit cancel/sumbit - create service stepper from app service tab, marketplace service summary, service wall - edit service stepper from marketplace service instances, service wall instances, space service instances and app service instances lists - fixes #4052, contrinbutes to #4079, #4051 * Fix subscription leak - fixes #4295 - code no-longer needed * Force return location of service stepper, fix table edit of upsi and other improvements * Fix unit tests * Fix e2e tests * Fix e2e tests, add search to marketplace service instances table * Changes following review --- .../service-tabs-base.component.html | 6 +- .../service-tabs-base.component.ts | 33 +++--- .../service-catalog/services.service.ts | 4 +- .../services-wall.component.html | 2 +- .../services-wall/services-wall.component.ts | 6 ++ ...-service-instance-base-step.component.html | 2 +- ...dd-service-instance-base-step.component.ts | 34 +++++- .../add-service-instance/csi-mode.service.ts | 51 ++++++++- .../specify-details-step.component.ts | 18 ++-- ...specify-user-provided-details.component.ts | 26 +++-- .../app-service-binding-card.component.ts | 6 +- ...app-service-binding-list-config.service.ts | 16 ++- .../cf-service-instances-list-config.base.ts | 21 ++-- .../cf-user-service-instances-list-config.ts | 8 +- ...s-service-instances-list-config.service.ts | 8 +- .../service-instances-data-source.ts | 1 + .../service-instances-list-config.service.ts | 16 ++- .../service-instance-card.component.ts | 5 +- ...vice-instances-wall-list-config.service.ts | 8 +- ...rovided-service-instance-card.component.ts | 5 +- .../create-marketplace-service-instance.po.ts | 10 +- .../create-service-instance-e2e.spec.ts | 13 ++- ...reate-service-instance-private-e2e.spec.ts | 10 +- ...-service-instance-space-scoped-e2e.spec.ts | 9 +- .../marketplace/create-service-instance.po.ts | 16 ++- ...ate-service-instances-bind-app-e2e.spec.ts | 7 +- .../create-ups-service-instance.po.ts | 9 ++ .../delete-service-instance-e2e.spec.ts | 13 ++- .../delete-ups-service-instance-e2e.spec.ts | 8 +- .../edit-service-instance-e2e.spec.ts | 5 +- ...place-create-service-instances-e2e.spec.ts | 102 ++++++++---------- .../marketplace/marketplace-instances.po.ts | 11 ++ .../marketplace-summary-e2e.spec.ts | 9 +- .../marketplace/marketplace-summary.po.ts | 1 + .../marketplace/services-wall-e2e.spec.ts | 5 +- src/test-e2e/marketplace/services-wall.po.ts | 10 +- src/test-e2e/po/page.po.ts | 25 +++-- 37 files changed, 366 insertions(+), 173 deletions(-) create mode 100644 src/test-e2e/marketplace/marketplace-instances.po.ts diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.html b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.html index f6b4c53c11..4a7bb72774 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.html @@ -1,11 +1,11 @@
- {{ getServiceLabel() | async }} + {{ serviceLabel$ | async }}
- diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.ts index 817f55a6e2..763af35529 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/service-tabs-base/service-tabs-base.component.ts @@ -6,6 +6,7 @@ import { map, publishReplay, refCount } from 'rxjs/operators'; import { CFAppState } from '../../../../../cloud-foundry/src/cf-app-state'; import { IPageSideNavTab } from '../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; +import { CSI_CANCEL_URL } from '../../../shared/components/add-service-instance/csi-mode.service'; import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; import { getServiceName } from '../services-helper'; import { ServicesService } from '../services.service'; @@ -20,6 +21,9 @@ export class ServiceTabsBaseComponent { toolTipText$: Observable; hasVisiblePlans$: Observable; servicesSubscription: Subscription; + isServiceSpaceScoped$: Observable; + addServiceInstanceLink: string[]; + serviceLabel$: Observable; tabLinks: IPageSideNavTab[] = [ { @@ -59,24 +63,23 @@ export class ServiceTabsBaseComponent { return 'Cannot create service instance (no public or visible plans exist for service)'; } })); - - } - - addServiceInstanceLink = () => [ - '/marketplace', - this.servicesService.cfGuid, - this.servicesService.serviceGuid, - 'create' - ] - - isServiceSpaceScoped = () => this.servicesService.isSpaceScoped$; - - getServiceLabel = (): Observable => { - return this.servicesService.service$.pipe( + this.isServiceSpaceScoped$ = this.servicesService.isSpaceScoped$.pipe( + map(queryParams => ({ + ...queryParams, + [CSI_CANCEL_URL]: `/marketplace/${this.servicesService.cfGuid}/${this.servicesService.serviceGuid}/instances` + })) + ) + this.addServiceInstanceLink = [ + '/marketplace', + this.servicesService.cfGuid, + this.servicesService.serviceGuid, + 'create' + ] + this.serviceLabel$ = this.servicesService.service$.pipe( map(getServiceName), publishReplay(1), refCount() - ); + ) } } diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/services.service.ts b/src/frontend/packages/cloud-foundry/src/features/service-catalog/services.service.ts index a550800a57..05d65754d3 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/services.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/services.service.ts @@ -132,6 +132,7 @@ export class ServicesService { map(o => (o.length === 0 ? null : o[0])) ); this.isSpaceScoped$ = this.serviceBroker$.pipe( + first(), map(o => o ? o.entity.space_guid : null), switchMap(spaceGuid => { if (!spaceGuid) { @@ -151,7 +152,8 @@ export class ServicesService { })), ); } - }) + }), + first() ); this.serviceInstances$ = this.allServiceInstances$.pipe( map(instances => instances.filter(instance => instance.entity.service_guid === this.serviceGuid)) diff --git a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.html b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.html index cf6322f5e7..b47b7c7e12 100644 --- a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.html +++ b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.html @@ -3,7 +3,7 @@

Services

- diff --git a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.ts b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.ts index 96d806b0c5..be3e78240d 100644 --- a/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/services/services-wall/services-wall.component.ts @@ -14,6 +14,7 @@ import { } from '../../../../../cloud-foundry/src/shared/data-services/cf-org-space-service.service'; import { CloudFoundryService } from '../../../../../cloud-foundry/src/shared/data-services/cloud-foundry.service'; import { ListConfig } from '../../../../../core/src/shared/components/list/list.component.types'; +import { CSI_CANCEL_URL } from '../../../shared/components/add-service-instance/csi-mode.service'; import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; @Component({ @@ -35,6 +36,7 @@ export class ServicesWallComponent implements OnDestroy { canCreateServiceInstance: CfCurrentUserPermissions; initCfOrgSpaceService: Subscription; cfIds$: Observable; + location: { [CSI_CANCEL_URL]: string }; constructor( public cloudFoundryService: CloudFoundryService, @@ -57,6 +59,10 @@ export class ServicesWallComponent implements OnDestroy { this.haveConnectedCf$ = cloudFoundryService.connectedCFEndpoints$.pipe( map(endpoints => !!endpoints && endpoints.length > 0) ); + + this.location = { + [CSI_CANCEL_URL]: `/services` + } } ngOnDestroy(): void { diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component.html b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component.html index bdb623280b..20a2ba742b 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component.html +++ b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component.html @@ -1,7 +1,7 @@ Choose Service Type - +

Choose service type to {{ bindApp ? 'bind' : 'create' }}

diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component.ts index 06f9214b75..2daa17cb4a 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component.ts @@ -1,12 +1,14 @@ import { Component } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state'; +import { getIdFromRoute } from '../../../../../../core/src/core/utils.service'; import { BASE_REDIRECT_QUERY } from '../../../../../../core/src/shared/components/stepper/stepper.types'; import { TileConfigManager } from '../../../../../../core/src/shared/components/tile/tile-selector.helpers'; import { ITileConfig, ITileData } from '../../../../../../core/src/shared/components/tile/tile-selector.types'; import { RouterNav } from '../../../../../../store/src/actions/router.actions'; +import { CSI_CANCEL_URL } from '../csi-mode.service'; import { SERVICE_INSTANCE_TYPES } from './add-service-instance.types'; interface ICreateServiceTilesData extends ITileData { @@ -21,6 +23,7 @@ interface ICreateServiceTilesData extends ITileData { export class AddServiceInstanceBaseStepComponent { private tileManager = new TileConfigManager(); public serviceType: string; + public cancelUrl = '/services'; public tileSelectorConfig = [ this.tileManager.getNextTileConfig( @@ -44,16 +47,39 @@ export class AddServiceInstanceBaseStepComponent { this.serviceType = tile ? tile.data.type : null; this.pSelectedTile = tile; if (tile) { - const baseUrl = this.bindApp ? this.router.routerState.snapshot.url : '/services/new'; + const baseUrl = this.createServiceTileUrl(); this.store.dispatch(new RouterNav({ path: `${baseUrl}/${this.serviceType}`, query: { - [BASE_REDIRECT_QUERY]: baseUrl + [BASE_REDIRECT_QUERY]: baseUrl, // 'previous' destination + [CSI_CANCEL_URL]: this.cancelUrl // 'cancel' + 'success' destination } })); } } - constructor(private route: ActivatedRoute, private router: Router, public store: Store) { + + private cfId: string; + private appId: string; + + constructor( + private route: ActivatedRoute, + public store: Store + ) { this.bindApp = !!this.route.snapshot.data.bind; + if (this.bindApp) { + this.cfId = getIdFromRoute(this.route, 'endpointId'); + this.appId = getIdFromRoute(this.route, 'id'); + } + this.cancelUrl = this.createCancelUrl(); + } + + private createServiceTileUrl(): string { + return this.bindApp ? `/applications/${this.cfId}/${this.appId}/bind` : '/services/new' } + + private createCancelUrl(): string { + return this.bindApp ? `/applications/${this.cfId}/${this.appId}/services` : '/services' + } + + } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/csi-mode.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/csi-mode.service.ts index 3c4fa72df5..ad65ce4410 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/csi-mode.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/csi-mode.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { filter, map, pairwise } from 'rxjs/operators'; import { SpaceScopedService } from '../../../../../cloud-foundry/src/features/service-catalog/services.service'; @@ -19,8 +19,23 @@ export const enum CreateServiceFormMode { BindServiceInstance = 'bind-service-instance', } +/** + * Where should the user be taken on cancel (and success). If not supplied will fall back on previous location and then deduced from + * params + */ +export const CSI_CANCEL_URL = 'cancel' + +/** + * Used when `CSI_CANCEL_URL` is not supplied + */ export const CANCEL_SPACE_ID_PARAM = 'space-guid'; +/** + * Used when `CSI_CANCEL_URL` is not supplied + */ export const CANCEL_ORG_ID_PARAM = 'org-guid'; +/** + * Used when `CSI_CANCEL_URL` is not supplied + */ export const CANCEL_USER_PROVIDED = 'up'; interface ViewDetail { @@ -44,12 +59,16 @@ export class CsiModeService { private mode: string; public viewDetail: ViewDetail; + /** + * Where should the user be taken on cancel (and success). Taken from url param, previous location or deduced + */ public cancelUrl: string; // This property is only used when launching the Create Service Instance Wizard from the Marketplace spaceScopedDetails: SpaceScopedService = { isSpaceScoped: false }; constructor( private activatedRoute: ActivatedRoute, + router: Router ) { const serviceId = getIdFromRoute(activatedRoute, 'serviceId'); const serviceInstanceId = getIdFromRoute(activatedRoute, 'serviceInstanceId'); @@ -118,6 +137,7 @@ export class CsiModeService { `/cloud-foundry/${cfId}/organizations/${orgGuid}/spaces/${spaceGuid}/${isUserProvided ? 'user-service-instances' : 'service-instances'}`; } + this.updateCancelUrl(this.activatedRoute, router); } getViewDetail = () => this.viewDetail; @@ -148,4 +168,33 @@ export class CsiModeService { ); } + private updateCancelUrl( + activatedRoute: ActivatedRoute, + router: Router + ) { + // cancelUrl determines where we go on cancel AND success + const cancelUrl = activatedRoute.snapshot.queryParamMap.get(CSI_CANCEL_URL); + if (cancelUrl) { + // Override cancelUrl with what's been passed in (probably came from the service selection pre-step) + this.cancelUrl = cancelUrl; + } else { + // There's some holes with the way cancelUrl in ctor is calculated + // - marketplace/service/instances list --> cancel goes to space service instance list + // - marketplace/service create instance --> cancel goes to marketplace/service/instance regardless of starting tab + // - .. others?? + // For simplicity always go back to the previous location + // - good catch all + // - doesn't work that well for marketplace/service create instance --> success (should go to marketplace/service/instance) + // - if user has refreshed on stepper (previous url was login) use the old cancelUrl best-guess value + const currentNavigation = router.getCurrentNavigation(); + if (currentNavigation && + currentNavigation.previousNavigation && + currentNavigation.previousNavigation.finalUrl && + currentNavigation.previousNavigation.finalUrl.toString() !== '/login' + ) { + this.cancelUrl = currentNavigation.previousNavigation.finalUrl.toString(); + } + } + } + } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/specify-details-step/specify-details-step.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/specify-details-step/specify-details-step.component.ts index 80ed214a56..ae2ed8a868 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/specify-details-step/specify-details-step.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/specify-details-step/specify-details-step.component.ts @@ -31,7 +31,6 @@ import { } from '../../../../../../cloud-foundry/src/actions/create-service-instance.actions'; import { pathGet, safeStringToObj } from '../../../../../../core/src/core/utils.service'; import { StepOnNextResult } from '../../../../../../core/src/shared/components/stepper/step/step.component'; -import { RouterNav } from '../../../../../../store/src/actions/router.actions'; import { getDefaultRequestState, RequestInfoState } from '../../../../../../store/src/reducers/api-request-reducer/types'; import { APIResource, NormalizedResponse } from '../../../../../../store/src/types/api.types'; import { UpdateServiceInstance } from '../../../../actions/service-instances.actions'; @@ -297,7 +296,7 @@ export class SpecifyDetailsStepComponent implements OnDestroy, AfterContentInit this.longRunningOpService.handleLongRunningCreateService(bindApp); // Return to app page instead of falling through to service page if (bindApp) { - return observableOf(this.routeToServices(state.cfGuid, state.bindAppGuid)); + return observableOf(this.routeToServices()); } } else if (request.error) { // The request has errored, report this back @@ -318,7 +317,7 @@ export class SpecifyDetailsStepComponent implements OnDestroy, AfterContentInit } else { // Refetch env vars for app, since they have been changed by CF cfEntityCatalog.appEnvVar.api.getMultiple(state.bindAppGuid, state.cfGuid); - return this.routeToServices(state.cfGuid, state.bindAppGuid); + return this.routeToServices(); } }) ); @@ -356,13 +355,12 @@ export class SpecifyDetailsStepComponent implements OnDestroy, AfterContentInit ); } - routeToServices = (cfGuid: string = null, appGuid: string = null): StepOnNextResult => { - if (this.modeService.isAppServicesMode()) { - this.store.dispatch(new RouterNav({ path: ['/applications', cfGuid, appGuid, 'services'] })); - } else { - this.store.dispatch(new RouterNav({ path: ['/services'] })); - } - return { success: true }; + routeToServices = (): StepOnNextResult => { + return { + success: true, + // We should always go back to where we came from, aka 'cancel' location. + redirect: true, + }; } private setServiceInstanceGuid = (request: { creating: boolean; error: boolean; response: { result: any[]; }; }) => diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/specify-user-provided-details/specify-user-provided-details.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/specify-user-provided-details/specify-user-provided-details.component.ts index a5d2b02b09..258727a9cc 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/specify-user-provided-details/specify-user-provided-details.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/specify-user-provided-details/specify-user-provided-details.component.ts @@ -27,6 +27,7 @@ import { IUserProvidedServiceInstance } from '../../../../cf-api-svc.types'; import { cfEntityCatalog } from '../../../../cf-entity-catalog'; import { AppNameUniqueChecking } from '../../../directives/app-name-unique.directive/app-name-unique.directive'; import { CloudFoundryUserProvidedServicesService } from '../../../services/cloud-foundry-user-provided-services.service'; +import { AppServiceBindingDataSource } from '../../list/list-types/app-sevice-bindings/app-service-binding-data-source'; import { CreateServiceFormMode, CsiModeService } from './../csi-mode.service'; const { proxyAPIVersion, cfAPIVersion } = environment; @@ -38,7 +39,7 @@ const { proxyAPIVersion, cfAPIVersion } = environment; export class SpecifyUserProvidedDetailsComponent implements OnDestroy { constructor( - route: ActivatedRoute, + private route: ActivatedRoute, private upsService: CloudFoundryUserProvidedServicesService, public modeService: CsiModeService, private store: Store, @@ -297,11 +298,24 @@ export class SpecifyUserProvidedDetailsComponent implements OnDestroy { this.serviceInstanceId, updateData ).pipe( - map(er => ({ - success: !er.error, - redirect: !er.error, - message: `Failed to update service instance: ${er.message}` - })) + map(er => { + if (!er.error) { + // Update the application binding list + const appId = this.appId || this.route.snapshot.queryParamMap.get('appId'); + if (appId) { + this.store.dispatch(AppServiceBindingDataSource.createGetAllServiceBindings(appId, this.cfGuid)); + } + return { + success: true, + redirect: true, + }; + } + return { + success: false, + redirect: false, + message: `Failed to update service instance: ${er.message}` + }; + }) ); } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts index 5f15687925..f72b232704 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts @@ -34,6 +34,7 @@ import { import { AppEnvVarsState } from '../../../../../../store/types/app-metadata.types'; import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../../data-services/service-action-helper.service'; +import { CSI_CANCEL_URL } from '../../../../add-service-instance/csi-mode.service'; import { EnvVarViewComponent } from '../../../../env-var-view/env-var-view.component'; @@ -241,7 +242,10 @@ export class AppServiceBindingCardComponent extends CardCell this.serviceActionHelperService.startEditServiceBindingStepper( this.row.entity.service_instance_guid, this.appService.cfGuid, - { appId: this.appService.appGuid }, + { + appId: this.appService.appGuid, + [CSI_CANCEL_URL]: `/applications/${this.appService.cfGuid}/${this.appService.appGuid}/services` + }, this.isUserProvidedServiceInstance ) } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts index 68288fa9ec..2d39cd38df 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service.ts @@ -19,12 +19,12 @@ import { import { ListView } from '../../../../../../../store/src/actions/list.actions'; import { RouterNav } from '../../../../../../../store/src/actions/router.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; -import { GetAppServiceBindings } from '../../../../../actions/application-service-routes.actions'; import { IServiceBinding } from '../../../../../cf-api-svc.types'; import { ApplicationService } from '../../../../../features/applications/application.service'; import { isServiceInstance, isUserProvidedServiceInstance } from '../../../../../features/cloud-foundry/cf.helpers'; import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; +import { CSI_CANCEL_URL } from '../../../add-service-instance/csi-mode.service'; import { BaseCfListConfig } from '../base-cf/base-cf-list-config'; import { TableCellServiceInstanceTagsComponent, @@ -57,17 +57,15 @@ export class AppServiceBindingListConfigService extends BaseCfListConfig> = { action: (item) => { - // FIXME: If the user cancels stepper this leaks #4295 this.serviceActionHelperService.startEditServiceBindingStepper( item.entity.service_instance_guid, this.appService.cfGuid, - { appId: this.appService.appGuid }, + { + appId: this.appService.appGuid, + [CSI_CANCEL_URL]: `/applications/${this.appService.cfGuid}/${this.appService.appGuid}/services` + }, !!isUserProvidedServiceInstance(item.entity.service_instance.entity) - ).subscribe(res => { - if (!res.error) { - this.store.dispatch(new GetAppServiceBindings(this.appService.appGuid, this.appService.cfGuid)); - } - }); + ); }, label: 'Edit', createVisible: () => this.appService.waitForAppEntity$.pipe( @@ -104,7 +102,7 @@ export class AppServiceBindingListConfigService extends BaseCfListConfig 'Service Instances', + headerCell: () => 'Name', cellDefinition: { getValue: (row) => row.entity.service_instance.entity.name }, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts index 52b60a12ee..b1ecf9ef80 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-service-instances-list-config.base.ts @@ -21,9 +21,10 @@ import { import { ListView } from '../../../../../../../store/src/actions/list.actions'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { IServiceInstance } from '../../../../../cf-api-svc.types'; +import { isUserProvidedServiceInstance } from '../../../../../features/cloud-foundry/cf.helpers'; import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; -import { CANCEL_ORG_ID_PARAM, CANCEL_SPACE_ID_PARAM } from '../../../add-service-instance/csi-mode.service'; +import { CANCEL_ORG_ID_PARAM, CANCEL_SPACE_ID_PARAM, CSI_CANCEL_URL } from '../../../add-service-instance/csi-mode.service'; import { TableCellAppCfOrgSpaceHeaderComponent, } from '../app/table-cell-app-cforgspace-header/table-cell-app-cforgspace-header.component'; @@ -61,7 +62,7 @@ export class CfServiceInstancesListConfigBase implements IListConfig>[] = [ { columnId: 'name', - headerCell: () => 'Service Instance', + headerCell: () => 'Name', cellDefinition: { getValue: (row) => `${row.entity.name}` }, @@ -149,10 +150,15 @@ export class CfServiceInstancesListConfigBase implements IListConfig = { action: (item: APIResource) => - this.serviceActionHelperService.startEditServiceBindingStepper(item.metadata.guid, item.entity.cfGuid, { - [CANCEL_SPACE_ID_PARAM]: item.entity.space_guid, - [CANCEL_ORG_ID_PARAM]: item.entity.space.entity.organization_guid - }), + this.serviceActionHelperService.startEditServiceBindingStepper( + item.metadata.guid, + item.entity.cfGuid, + { + [CANCEL_SPACE_ID_PARAM]: item.entity.space_guid, + [CANCEL_ORG_ID_PARAM]: item.entity.space.entity.organization_guid, + [CSI_CANCEL_URL]: this.rootLocation + }, + !!isUserProvidedServiceInstance(item.entity)), label: 'Edit', description: 'Edit Service Instance', createVisible: (row$: Observable>) => @@ -176,7 +182,8 @@ export class CfServiceInstancesListConfigBase implements IListConfig, protected datePipe: DatePipe, protected currentUserPermissionsService: CurrentUserPermissionsService, - private serviceActionHelperService: ServiceActionHelperService + private serviceActionHelperService: ServiceActionHelperService, + private rootLocation: string ) { } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts index 9f653f851f..4a9ee537ec 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-services/cf-user-service-instances-list-config.ts @@ -28,6 +28,7 @@ import { CANCEL_ORG_ID_PARAM, CANCEL_SPACE_ID_PARAM, CANCEL_USER_PROVIDED, + CSI_CANCEL_URL, } from '../../../add-service-instance/csi-mode.service'; import { CfSpacesUserServiceInstancesDataSource, @@ -64,7 +65,7 @@ export class CfUserServiceInstancesListConfigBase implements IListConfig>[] = [ { columnId: 'name', - headerCell: () => 'Service Instance', + headerCell: () => 'Name', cellDefinition: { getValue: (row) => `${row.entity.name}` }, @@ -152,7 +153,8 @@ export class CfUserServiceInstancesListConfigBase implements IListConfig, - cfSpaceService: CloudFoundrySpaceService, + private cfSpaceService: CloudFoundrySpaceService, protected datePipe: DatePipe, protected currentUserPermissionsService: CurrentUserPermissionsService, private serviceActionHelperService: ServiceActionHelperService diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts index e87ed733c5..f747341abe 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts @@ -30,7 +30,13 @@ export class CfSpacesServiceInstancesListConfigService extends CfServiceInstance datePipe: DatePipe, currentUserPermissionsService: CurrentUserPermissionsService, serviceActionHelperService: ServiceActionHelperService) { - super(store, datePipe, currentUserPermissionsService, serviceActionHelperService); + super( + store, + datePipe, + currentUserPermissionsService, + serviceActionHelperService, + `/cloud-foundry/${cfSpaceService.cfGuid}/organizations/${cfSpaceService.orgGuid}/spaces/${cfSpaceService.spaceGuid}/service-instances` + ); this.dataSource = new CfSpacesServiceInstancesDataSource(cfSpaceService.cfGuid, cfSpaceService.spaceGuid, this.store, this); this.serviceInstanceColumns.find(column => column.columnId === 'attachedApps').cellConfig = { breadcrumbs: 'space-services' diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-data-source.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-data-source.ts index b99fead8d1..7c3cc59981 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-data-source.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-data-source.ts @@ -31,6 +31,7 @@ export class ServiceInstancesDataSource extends ListDataSource { paginationKey, isLocal: true, transformEntities: [ + { type: 'filter', field: 'entity.name' }, (entities: APIResource[], paginationState: PaginationEntityState) => { return entities.filter(e => e.entity.service_guid === serviceGuid); } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts index 20878f7924..89c39ee4fa 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts @@ -6,6 +6,7 @@ import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state' import { CurrentUserPermissionsService, } from '../../../../../../../core/src/core/permissions/current-user-permissions.service'; +import { ITableText } from '../../../../../../../core/src/shared/components/list/list-table/table.types'; import { ServicesService } from '../../../../../features/service-catalog/services.service'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; import { CfServiceInstancesListConfigBase } from '../cf-services/cf-service-instances-list-config.base'; @@ -20,13 +21,26 @@ import { ServiceInstancesDataSource } from './service-instances-data-source'; @Injectable() export class ServiceInstancesListConfigService extends CfServiceInstancesListConfigBase { + enableTextFilter = true; + text: ITableText = { + title: null, + filter: 'Search by name', + noEntries: 'There are no service instances', + }; + constructor( store: Store, servicesService: ServicesService, datePipe: DatePipe, currentUserPermissionsService: CurrentUserPermissionsService, serviceActionHelperService: ServiceActionHelperService) { - super(store, datePipe, currentUserPermissionsService, serviceActionHelperService); + super( + store, + datePipe, + currentUserPermissionsService, + serviceActionHelperService, + `/marketplace/${servicesService.cfGuid}/${servicesService.serviceGuid}/instances` + ); // Remove 'Service' column this.serviceInstanceColumns.splice(1, 1); this.dataSource = new ServiceInstancesDataSource(servicesService.cfGuid, servicesService.serviceGuid, store, this); diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts index 649162074c..e9ac71ae99 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts @@ -25,6 +25,7 @@ import { import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../../data-services/service-action-helper.service'; import { CfOrgSpaceLabelService } from '../../../../../services/cf-org-space-label.service'; +import { CSI_CANCEL_URL } from '../../../../add-service-instance/csi-mode.service'; @Component({ selector: 'app-service-instance-card', @@ -130,7 +131,9 @@ export class ServiceInstanceCardComponent extends CardCell this.serviceActionHelperService.startEditServiceBindingStepper( this.serviceInstanceEntity.metadata.guid, this.serviceInstanceEntity.entity.cfGuid, - null + { + [CSI_CANCEL_URL]: '/services' + } ) getServiceName = () => { diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts index f3a4c57132..0f597ef543 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts @@ -70,7 +70,13 @@ export class ServiceInstancesWallListConfigService extends CfServiceInstancesLis currentUserPermissionsService: CurrentUserPermissionsService, serviceActionHelperService: ServiceActionHelperService ) { - super(store, datePipe, currentUserPermissionsService, serviceActionHelperService); + super( + store, + datePipe, + currentUserPermissionsService, + serviceActionHelperService, + `/services` + ); const multiFilterConfigs = [ createCfOrgSpaceFilterConfig('cf', 'Cloud Foundry', this.cfOrgSpaceService.cf), createCfOrgSpaceFilterConfig('org', 'Organization', this.cfOrgSpaceService.org), diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts index 0b2fdcf274..8c2564b26c 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts @@ -19,6 +19,7 @@ import { cfEntityFactory } from '../../../../../../cf-entity-factory'; import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; import { ServiceActionHelperService } from '../../../../../data-services/service-action-helper.service'; import { CfOrgSpaceLabelService } from '../../../../../services/cf-org-space-label.service'; +import { CSI_CANCEL_URL } from '../../../../add-service-instance/csi-mode.service'; @Component({ @@ -120,7 +121,9 @@ export class UserProvidedServiceInstanceCardComponent extends CardCell this.serviceActionHelperService.startEditServiceBindingStepper( this.serviceInstanceEntity.metadata.guid, this.serviceInstanceEntity.entity.cfGuid, - null, + { + [CSI_CANCEL_URL]: '/services' + }, true ) diff --git a/src/test-e2e/marketplace/create-marketplace-service-instance.po.ts b/src/test-e2e/marketplace/create-marketplace-service-instance.po.ts index 993fed4acf..7be967f6d1 100644 --- a/src/test-e2e/marketplace/create-marketplace-service-instance.po.ts +++ b/src/test-e2e/marketplace/create-marketplace-service-instance.po.ts @@ -6,9 +6,17 @@ export class CreateMarketplaceServiceInstance extends Page { public stepper: CreateServiceInstanceStepper; - constructor(url = '/services/new/service?base-previous-redirect=%2Fservices%2Fnew') { + constructor(url = '/services/new/service') { super(url); this.stepper = new CreateServiceInstanceStepper(); } + isActivePage() { + return super.isActivePage(true); + } + + waitForPage() { + return super.waitForPage(undefined, true); + } + } diff --git a/src/test-e2e/marketplace/create-service-instance-e2e.spec.ts b/src/test-e2e/marketplace/create-service-instance-e2e.spec.ts index 8c1d7d7ec3..b326fe3f48 100644 --- a/src/test-e2e/marketplace/create-service-instance-e2e.spec.ts +++ b/src/test-e2e/marketplace/create-service-instance-e2e.spec.ts @@ -29,10 +29,7 @@ describe('Create Service Instance', () => { createServiceInstance.waitForPage(); createMarketplaceServiceInstance = createServiceInstance.selectMarketplace(); servicesHelperE2E = new ServicesHelperE2E(e2eSetup, createMarketplaceServiceInstance); - }); - - it('- should reach create service instance page', () => { - expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + createMarketplaceServiceInstance.waitForPage(); }); describe('Long running tests - ', () => { @@ -40,6 +37,8 @@ describe('Create Service Instance', () => { extendE2ETestTime(timeout); it('- should be able to create a service instance', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + serviceInstanceName = servicesHelperE2E.createServiceInstanceName(); servicesHelperE2E.createService(e2e.secrets.getDefaultCFEndpoint().services.publicService.name, serviceInstanceName); @@ -51,16 +50,17 @@ describe('Create Service Instance', () => { }); it('- should return user to Service summary when cancelled on CFOrgSpace selection', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); // Select CF/Org/Space servicesHelperE2E.setCfOrgSpace(); createMarketplaceServiceInstance.stepper.cancel(); servicesWall.waitForPage(); - }); it('- should return user to Service summary when cancelled on Service selection', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); // Select CF/Org/Space servicesHelperE2E.setCfOrgSpace(); @@ -77,6 +77,7 @@ describe('Create Service Instance', () => { }); it('- should return user to Service summary when cancelled on App binding selection', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); // Select CF/Org/Space servicesHelperE2E.setCfOrgSpace(); @@ -97,6 +98,8 @@ describe('Create Service Instance', () => { }); it('- should return user to Service summary when cancelled on service instance details', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + // Select CF/Org/Space servicesHelperE2E.setCfOrgSpace(); createMarketplaceServiceInstance.stepper.next(); diff --git a/src/test-e2e/marketplace/create-service-instance-private-e2e.spec.ts b/src/test-e2e/marketplace/create-service-instance-private-e2e.spec.ts index 35716683f9..3f81f5b3f0 100644 --- a/src/test-e2e/marketplace/create-service-instance-private-e2e.spec.ts +++ b/src/test-e2e/marketplace/create-service-instance-private-e2e.spec.ts @@ -28,10 +28,7 @@ describe('Create Service Instance of Private Service', () => { createServiceInstance.navigateTo(); createServiceInstance.waitForPage(); createMarketplaceServiceInstance = createServiceInstance.selectMarketplace(); - }); - - it('- should reach create service instance page', () => { - expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + createMarketplaceServiceInstance.waitForPage(); }); describe('Long running tests - ', () => { @@ -39,6 +36,8 @@ describe('Create Service Instance of Private Service', () => { extendE2ETestTime(timeout); it('- should be able to to create a service instance', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + serviceInstanceName = servicesHelperE2E.createServiceInstanceName(); servicesHelperE2E.createService(e2e.secrets.getDefaultCFEndpoint().services.privateService.name, serviceInstanceName, false); @@ -51,6 +50,7 @@ describe('Create Service Instance of Private Service', () => { }); it('- should return user to Service summary when cancelled on CFOrgSpace selection', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); // Select CF/Org/Space servicesHelperE2E.setCfOrgSpace(); @@ -61,6 +61,7 @@ describe('Create Service Instance of Private Service', () => { }); it('- should return user to Service summary when cancelled on Service selection', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); // Select CF/Org/Space servicesHelperE2E.setCfOrgSpace(); @@ -77,6 +78,7 @@ describe('Create Service Instance of Private Service', () => { }); it('- should not show service plan if wrong org/space are selected', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); // Select CF/Org/Space servicesHelperE2E.setCfOrgSpace(e2e.secrets.getDefaultCFEndpoint().services.privateService.invalidOrgName, diff --git a/src/test-e2e/marketplace/create-service-instance-space-scoped-e2e.spec.ts b/src/test-e2e/marketplace/create-service-instance-space-scoped-e2e.spec.ts index 612e48cdb1..42a9a2f6c0 100644 --- a/src/test-e2e/marketplace/create-service-instance-space-scoped-e2e.spec.ts +++ b/src/test-e2e/marketplace/create-service-instance-space-scoped-e2e.spec.ts @@ -27,11 +27,7 @@ describe('Create Service Instance of Space Scoped Service', () => { createServiceInstance.waitForPage(); createMarketplaceServiceInstance = createServiceInstance.selectMarketplace(); servicesHelperE2E = new ServicesHelperE2E(e2eSetup, createMarketplaceServiceInstance); - }); - - - it('- should reach create service instance page', () => { - expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + createMarketplaceServiceInstance.waitForPage(); }); describe('Long running tests - ', () => { @@ -39,6 +35,8 @@ describe('Create Service Instance of Space Scoped Service', () => { extendE2ETestTime(timeout); it('- should be able to to create a service instance', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + serviceInstanceName = servicesHelperE2E.createServiceInstanceName(); servicesHelperE2E.createService(e2e.secrets.getDefaultCFEndpoint().services.spaceScopedService.name, serviceInstanceName); @@ -50,6 +48,7 @@ describe('Create Service Instance of Space Scoped Service', () => { }); it('- should not show service plan if wrong org/space are selected', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); // Select CF/Org/Space servicesHelperE2E.setCfOrgSpace(e2e.secrets.getDefaultCFEndpoint().services.spaceScopedService.invalidOrgName, diff --git a/src/test-e2e/marketplace/create-service-instance.po.ts b/src/test-e2e/marketplace/create-service-instance.po.ts index ee3b61997e..a4cdc26f0d 100644 --- a/src/test-e2e/marketplace/create-service-instance.po.ts +++ b/src/test-e2e/marketplace/create-service-instance.po.ts @@ -1,10 +1,10 @@ - +import { + SERVICE_INSTANCE_TYPES, +} from '../../frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance.types'; import { Page } from '../po/page.po'; import { BaseCreateServiceInstanceStepper } from './base-create-service-instance-stepper.po'; import { CreateMarketplaceServiceInstance } from './create-marketplace-service-instance.po'; -import { - SERVICE_INSTANCE_TYPES -} from '../../frontend/packages/cloud-foundry/src/shared/components/add-service-instance/add-service-instance-base-step/add-service-instance.types'; + export class CreateServiceInstance extends Page { @@ -23,4 +23,12 @@ export class CreateServiceInstance extends Page { super(url); } + isActivePage() { + return super.isActivePage(true); + } + + waitForPage() { + return super.waitForPage(undefined, true); + } + } diff --git a/src/test-e2e/marketplace/create-service-instances-bind-app-e2e.spec.ts b/src/test-e2e/marketplace/create-service-instances-bind-app-e2e.spec.ts index 2608a7a66e..91eb24e945 100644 --- a/src/test-e2e/marketplace/create-service-instances-bind-app-e2e.spec.ts +++ b/src/test-e2e/marketplace/create-service-instances-bind-app-e2e.spec.ts @@ -30,16 +30,15 @@ describe('Create Service Instance with binding', () => { createServiceInstance.waitForPage(); createMarketplaceServiceInstance = createServiceInstance.selectMarketplace(); servicesHelperE2E = new ServicesHelperE2E(e2eSetup, createMarketplaceServiceInstance, servicesHelperE2E); - }); - - it('- should reach create service instance page', () => { - expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + createMarketplaceServiceInstance.waitForPage(); }); describe('Long running tests - ', () => { extendE2ETestTime(100000); it('- should be able to to create a service instance with binding', () => { + expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); + serviceInstanceName = servicesHelperE2E.createServiceInstanceName(); const servicesSecrets = e2e.secrets.getDefaultCFEndpoint().services; diff --git a/src/test-e2e/marketplace/create-ups-service-instance.po.ts b/src/test-e2e/marketplace/create-ups-service-instance.po.ts index 70801bb031..55c68241a7 100644 --- a/src/test-e2e/marketplace/create-ups-service-instance.po.ts +++ b/src/test-e2e/marketplace/create-ups-service-instance.po.ts @@ -10,4 +10,13 @@ export class CreateUserProvidedServiceInstance extends Page { super(url); this.stepper = new CreateServiceInstanceStepper(); } + + isActivePage() { + return super.isActivePage(true); + } + + waitForPage() { + return super.waitForPage(undefined, true); + } + } diff --git a/src/test-e2e/marketplace/delete-service-instance-e2e.spec.ts b/src/test-e2e/marketplace/delete-service-instance-e2e.spec.ts index 98300f1425..aa74438545 100644 --- a/src/test-e2e/marketplace/delete-service-instance-e2e.spec.ts +++ b/src/test-e2e/marketplace/delete-service-instance-e2e.spec.ts @@ -1,16 +1,16 @@ import { e2e } from '../e2e'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { extendE2ETestTime } from '../helpers/extend-test-helpers'; +import { ConfirmDialogComponent } from '../po/confirm-dialog'; +import { ListComponent } from '../po/list.po'; +import { MetaCardTitleType } from '../po/meta-card.po'; import { CreateMarketplaceServiceInstance } from './create-marketplace-service-instance.po'; import { CreateServiceInstance } from './create-service-instance.po'; import { ServicesHelperE2E } from './services-helper-e2e'; import { ServicesWallPage } from './services-wall.po'; -import { ConfirmDialogComponent } from '../po/confirm-dialog'; -import { MetaCardTitleType } from '../po/meta-card.po'; -import { ListComponent } from '../po/list.po'; // Regression test for: -// - Deleting a service instance in the services list will delete the service but the list incorerctly shows no services +// - Deleting a service instance in the services list will delete the service but the list incorrectly shows no services describe('Delete Service Instance', () => { const createServiceInstance = new CreateServiceInstance(); let createMarketplaceServiceInstance: CreateMarketplaceServiceInstance; @@ -41,13 +41,12 @@ describe('Delete Service Instance', () => { createServiceInstance.waitForPage(); createMarketplaceServiceInstance = createServiceInstance.selectMarketplace(); servicesHelperE2E = new ServicesHelperE2E(e2eSetup, createMarketplaceServiceInstance); + createMarketplaceServiceInstance.waitForPage(); }); - it('should go to create service instance view', () => { + it('should be able to create a service instance', () => { expect(createMarketplaceServiceInstance.isActivePage()).toBeTruthy(); - }); - it('should be able to create a service instance', () => { const serviceInstanceName = servicesHelperE2E.createServiceInstanceName(); names.push(serviceInstanceName); servicesHelperE2E.createService(e2e.secrets.getDefaultCFEndpoint().services.publicService.name, serviceInstanceName); diff --git a/src/test-e2e/marketplace/delete-ups-service-instance-e2e.spec.ts b/src/test-e2e/marketplace/delete-ups-service-instance-e2e.spec.ts index eff4c5be7e..112dec4037 100644 --- a/src/test-e2e/marketplace/delete-ups-service-instance-e2e.spec.ts +++ b/src/test-e2e/marketplace/delete-ups-service-instance-e2e.spec.ts @@ -1,13 +1,13 @@ import { e2e } from '../e2e'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { extendE2ETestTime } from '../helpers/extend-test-helpers'; -import { CreateServiceInstance } from './create-service-instance.po'; -import { ServicesHelperE2E } from './services-helper-e2e'; -import { ServicesWallPage } from './services-wall.po'; import { ConfirmDialogComponent } from '../po/confirm-dialog'; -import { MetaCardTitleType } from '../po/meta-card.po'; import { ListComponent } from '../po/list.po'; +import { MetaCardTitleType } from '../po/meta-card.po'; +import { CreateServiceInstance } from './create-service-instance.po'; import { CreateUserProvidedServiceInstance } from './create-ups-service-instance.po'; +import { ServicesHelperE2E } from './services-helper-e2e'; +import { ServicesWallPage } from './services-wall.po'; describe('Delete Service Instance (User Provided Service)', () => { const createServiceInstance = new CreateServiceInstance(); diff --git a/src/test-e2e/marketplace/edit-service-instance-e2e.spec.ts b/src/test-e2e/marketplace/edit-service-instance-e2e.spec.ts index af583a4409..a169e8ab19 100644 --- a/src/test-e2e/marketplace/edit-service-instance-e2e.spec.ts +++ b/src/test-e2e/marketplace/edit-service-instance-e2e.spec.ts @@ -65,7 +65,10 @@ describe('Edit Service Instance', () => { menu.waitUntilNotShown(); return browser.getCurrentUrl().then(url => { - expect(url.endsWith('edit')).toBeTruthy(); + const query = url.indexOf('?'); + const urlWithoutQuery = query >= 0 ? url.substring(0, query) : url; + expect(urlWithoutQuery.endsWith('edit')).toBeTruthy(); + servicesHelperE2E.setServicePlan(true); servicesHelperE2E.createServiceInstance.stepper.next(); diff --git a/src/test-e2e/marketplace/marketplace-create-service-instances-e2e.spec.ts b/src/test-e2e/marketplace/marketplace-create-service-instances-e2e.spec.ts index d520f0da8f..a20621fcfb 100644 --- a/src/test-e2e/marketplace/marketplace-create-service-instances-e2e.spec.ts +++ b/src/test-e2e/marketplace/marketplace-create-service-instances-e2e.spec.ts @@ -4,6 +4,7 @@ import { e2e, E2ESetup } from '../e2e'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { extendE2ETestTime } from '../helpers/extend-test-helpers'; import { CreateMarketplaceServiceInstance } from './create-marketplace-service-instance.po'; +import { MarketplaceInstancesPage } from './marketplace-instances.po'; import { MarketplaceSummaryPage } from './marketplace-summary.po'; import { ServicesHelperE2E } from './services-helper-e2e'; import { ServicesWallPage } from './services-wall.po'; @@ -11,6 +12,7 @@ import { ServicesWallPage } from './services-wall.po'; describe('Service Instance from Marketplace', () => { let setup: E2ESetup; const servicesWall = new ServicesWallPage(); + let servicesInstances: MarketplaceInstancesPage; const timeout = 60000; let serviceInstanceName: string; @@ -29,7 +31,6 @@ describe('Service Instance from Marketplace', () => { beforeAll(() => init(setup, serviceName).then(res => { servicesHelperE2E = res.servicesHelper; marketplaceSummaryPage = res.summaryPage; - })); beforeEach(() => { @@ -37,10 +38,6 @@ describe('Service Instance from Marketplace', () => { marketplaceSummaryPage.waitForPage(); }); - it('- should have an Add Service Instance button', () => { - expect(marketplaceSummaryPage.getAddServiceInstanceButton().isPresent()).toBeTruthy(); - }); - describe('Long running test', () => { extendE2ETestTime(timeout); it('- should be able to create a new service instance', () => { @@ -66,10 +63,6 @@ describe('Service Instance from Marketplace', () => { marketplaceSummaryPage.waitForPage(); }); - it('- should have an Add Service Instance button', () => { - expect(marketplaceSummaryPage.getAddServiceInstanceButton().isPresent()).toBeTruthy(); - }); - describe('Long running test', () => { extendE2ETestTime(timeout); it('- should be able to create a new service instance', () => { @@ -95,11 +88,8 @@ describe('Service Instance from Marketplace', () => { marketplaceSummaryPage.waitForPage(); }); - it('- should have an Add Service Instance button', () => { - expect(marketplaceSummaryPage.getAddServiceInstanceButton().isPresent()).toBeTruthy(); - }); - describe('Long running test', () => { + extendE2ETestTime(timeout); it('- should be able to create a new service instance', () => { serviceInstanceName = servicesHelperE2E.createServiceInstanceName(); @@ -109,48 +99,46 @@ describe('Service Instance from Marketplace', () => { afterAll(() => servicesHelperE2E.cleanUpServiceInstance(serviceInstanceName)); }); -}); - -function createService( - marketplaceSummaryPage: MarketplaceSummaryPage, - servicesHelperE2E: ServicesHelperE2E, - serviceName: string, - servicesWall: ServicesWallPage, - serviceInstanceName: string -) { - const button = marketplaceSummaryPage.header.getIconButton('add'); - expect(button).toBeDefined(); - button.then(bt => bt.click()); - browser.getCurrentUrl().then(url => { - expect(url.endsWith('create?isSpaceScoped=false')).toBeTruthy(); - // Proceed to create a service instance - servicesHelperE2E.createService(serviceName, serviceInstanceName, true); - - servicesWall.waitForPage(); - - servicesHelperE2E.getServiceCardWithTitle(servicesWall.serviceInstancesList, serviceInstanceName); - - }); -} - -function init( - setup: E2ESetup, - serviceName: string, - spaceScoped = false -) { - const defaultCf = e2e.secrets.getDefaultCFEndpoint(); - const endpointGuid = e2e.helper.getEndpointGuid(e2e.info, defaultCf.name); - - const servicesHelperE2E = new ServicesHelperE2E(setup); - return servicesHelperE2E.fetchServices(endpointGuid).then(response => { - serviceName = e2e.secrets.getDefaultCFEndpoint().services.publicService.name; - const service = response.resources.find(e => e.entity.label === serviceName); - const serviceGuid = service.metadata.guid; - servicesHelperE2E.setCreateServiceInstance( - new CreateMarketplaceServiceInstance('/marketplace/' + endpointGuid + '/' + serviceGuid + - '/create?isSpaceScoped=' + (spaceScoped ? 'true' : 'false'))); - const marketplaceSummaryPage = new MarketplaceSummaryPage(endpointGuid, serviceGuid); - return { servicesHelper: servicesHelperE2E, summaryPage: marketplaceSummaryPage }; - }); -} + function createService( + marketplaceSummaryPage: MarketplaceSummaryPage, + servicesHelperE2E: ServicesHelperE2E, + serviceName: string, + servicesWall: ServicesWallPage, + serviceInstanceName: string + ) { + expect(marketplaceSummaryPage.getAddServiceInstanceButton().isPresent()).toBeTruthy(); + marketplaceSummaryPage.getAddServiceInstanceButton().click(); + servicesHelperE2E.createServiceInstance.waitForPage(); + browser.getCurrentUrl().then(url => { + expect(url.indexOf('isSpaceScoped=false') >= 0).toBeTruthy(); + // Proceed to create a service instance + servicesHelperE2E.createService(serviceName, serviceInstanceName, true); + + servicesInstances.waitForPage(); + servicesInstances.list.header.setSearchText(serviceInstanceName); + servicesInstances.list.table.findRow('name', serviceInstanceName, true); + }); + } + + function init( + setup: E2ESetup, + serviceName: string, + ) { + const defaultCf = e2e.secrets.getDefaultCFEndpoint(); + const endpointGuid = e2e.helper.getEndpointGuid(e2e.info, defaultCf.name); + + const servicesHelperE2E = new ServicesHelperE2E(setup); + return servicesHelperE2E.fetchServices(endpointGuid).then(response => { + serviceName = e2e.secrets.getDefaultCFEndpoint().services.publicService.name; + const service = response.resources.find(e => e.entity.label === serviceName); + const serviceGuid = service.metadata.guid; + servicesHelperE2E.setCreateServiceInstance( + new CreateMarketplaceServiceInstance('/marketplace/' + endpointGuid + '/' + serviceGuid + '/create') + ); + servicesInstances = new MarketplaceInstancesPage(endpointGuid, serviceGuid); + const marketplaceSummaryPage = new MarketplaceSummaryPage(endpointGuid, serviceGuid); + return { servicesHelper: servicesHelperE2E, summaryPage: marketplaceSummaryPage }; + }); + } +}); diff --git a/src/test-e2e/marketplace/marketplace-instances.po.ts b/src/test-e2e/marketplace/marketplace-instances.po.ts new file mode 100644 index 0000000000..7dc3791d3e --- /dev/null +++ b/src/test-e2e/marketplace/marketplace-instances.po.ts @@ -0,0 +1,11 @@ +import { ListComponent } from '../po/list.po'; +import { Page } from '../po/page.po'; + +export class MarketplaceInstancesPage extends Page { + public list = new ListComponent(); + + constructor(cfGuid: string, serviceGuid: string) { + super(`/marketplace/${cfGuid}/${serviceGuid}/instances`); + } + +} diff --git a/src/test-e2e/marketplace/marketplace-summary-e2e.spec.ts b/src/test-e2e/marketplace/marketplace-summary-e2e.spec.ts index c48a61a7eb..c3aac96883 100644 --- a/src/test-e2e/marketplace/marketplace-summary-e2e.spec.ts +++ b/src/test-e2e/marketplace/marketplace-summary-e2e.spec.ts @@ -1,7 +1,8 @@ -import { MarketplaceSummaryPage } from './marketplace-summary.po'; -import { ConsoleUserType } from '../helpers/e2e-helpers'; -import { e2e } from '../e2e'; import { browser } from 'protractor'; + +import { e2e } from '../e2e'; +import { ConsoleUserType } from '../helpers/e2e-helpers'; +import { MarketplaceSummaryPage } from './marketplace-summary.po'; import { ServicesHelperE2E } from './services-helper-e2e'; describe('Marketplace Summary', () => { @@ -56,7 +57,7 @@ describe('Marketplace Summary', () => { expect(button).toBeDefined(); button.then(bt => bt.click()); browser.getCurrentUrl().then(url => { - expect(url.endsWith('create?isSpaceScoped=false')).toBeTruthy(); + expect(url.indexOf('create?isSpaceScoped=false') >= 0).toBeTruthy(); }); }); }); diff --git a/src/test-e2e/marketplace/marketplace-summary.po.ts b/src/test-e2e/marketplace/marketplace-summary.po.ts index 1f1ffe0c5f..1fc186e42d 100644 --- a/src/test-e2e/marketplace/marketplace-summary.po.ts +++ b/src/test-e2e/marketplace/marketplace-summary.po.ts @@ -23,4 +23,5 @@ export class MarketplaceSummaryPage extends Page { return element(by.name('add-service-instance')); } + } diff --git a/src/test-e2e/marketplace/services-wall-e2e.spec.ts b/src/test-e2e/marketplace/services-wall-e2e.spec.ts index 1fa6c985d8..398471326f 100644 --- a/src/test-e2e/marketplace/services-wall-e2e.spec.ts +++ b/src/test-e2e/marketplace/services-wall-e2e.spec.ts @@ -128,8 +128,11 @@ describe('Service Instances Wall', () => { expect(editMenuItem.getText()).toEqual('Edit'); expect(editMenuItem.isEnabled()).toBeTruthy(); editMenuItem.click(); + browser.getCurrentUrl().then(url => { - expect(url.endsWith('edit')).toBeTruthy(); + const query = url.indexOf('?'); + const urlWithoutQuery = query >= 0 ? url.substring(0, query) : url; + expect(urlWithoutQuery.endsWith('edit')).toBeTruthy(); }); const createMarketplaceServiceInstance = new CreateMarketplaceServiceInstance(); createMarketplaceServiceInstance.stepper.cancel(); diff --git a/src/test-e2e/marketplace/services-wall.po.ts b/src/test-e2e/marketplace/services-wall.po.ts index 9f1229751a..c61219b05c 100644 --- a/src/test-e2e/marketplace/services-wall.po.ts +++ b/src/test-e2e/marketplace/services-wall.po.ts @@ -1,4 +1,4 @@ -import { ElementArrayFinder, ElementFinder, promise, element, by } from 'protractor'; +import { by, element, ElementArrayFinder, ElementFinder, promise } from 'protractor'; import { ListComponent } from '../po/list.po'; import { MetaCard, MetaCardTitleType } from '../po/meta-card.po'; @@ -43,4 +43,12 @@ export class ServicesWallPage extends Page { applicationsAttached: items[3].value, })); } + + isActivePage() { + return super.isActivePage(true); + } + + waitForPage() { + return super.waitForPage(undefined, true); + } } diff --git a/src/test-e2e/po/page.po.ts b/src/test-e2e/po/page.po.ts index 533bc147cd..c7bc7d919a 100644 --- a/src/test-e2e/po/page.po.ts +++ b/src/test-e2e/po/page.po.ts @@ -43,13 +43,11 @@ export abstract class Page { return browser.get(this.navLink); } - isActivePage(): promise.Promise { - return browser.getCurrentUrl().then(url => url === this.getUrl()); - } - - isActivePageOrChildPage(): promise.Promise { + isActivePage(ignoreQuery = false): promise.Promise { return browser.getCurrentUrl().then(url => { - return url.startsWith(this.getUrl()); + const browserUrl = ignoreQuery ? this.stripQuery(url) : url; + const expectedUrl = ignoreQuery ? this.stripQuery(this.getUrl()) : this.getUrl(); + return browserUrl === expectedUrl; }); } @@ -62,9 +60,15 @@ export abstract class Page { }); } - waitForPage(timeout = 20000) { + waitForPage(timeout = 20000, ignoreQuery = false) { expect(this.navLink.startsWith('/')).toBeTruthy('navLink should start with a /'); - return browser.wait(until.urlIs(this.getUrl()), timeout, `Failed to wait for page with navlink '${this.navLink}'`); + if (ignoreQuery) { + return browser.wait(() => { + return this.isActivePage(true); + }); + } else { + return browser.wait(until.urlIs(this.getUrl()), timeout, `Failed to wait for page with navlink '${this.navLink}'`); + } } waitForPageDataLoaded(timeout = 20000) { @@ -82,4 +86,9 @@ export abstract class Page { browser.wait(until.urlContains(browser.baseUrl + this.navLink + childPath), 20000); } private getUrl = () => browser.baseUrl + this.navLink; + + private stripQuery(url: string): string { + const queryStarts = url.indexOf('?'); + return queryStarts >= 0 ? url.substring(0, queryStarts) : url; + } } From 9349e7b285e36ab1bdc3daedd860e4d4b9f1402a Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Wed, 17 Jun 2020 13:47:03 +0100 Subject: [PATCH 44/82] Move base-entity-* to store package --- .../src/store/autoscaler-entity-factory.ts | 4 ++-- .../src/store/autoscaler-entity-generator.ts | 2 +- .../cloud-foundry/src/cf-entity-factory.ts | 2 +- .../cloud-foundry/src/cf-entity-generator.ts | 2 +- .../src/cloud-foundry-test.module.ts | 2 +- .../space-quota-definition.component.spec.ts | 2 +- .../cloud-foundry-cell-base.component.ts | 2 +- .../data-services/cloud-foundry.service.ts | 2 +- .../services/cf-org-space-label.service.ts | 2 +- .../current-user-permissions.service.spec.ts | 4 ++-- .../test-framework/cf-test-helper.ts | 2 +- src/frontend/packages/core/src/app.module.ts | 4 ++-- .../current-user-permissions.service.spec.ts | 4 ++-- .../current-user-permissions.service.ts | 18 +++++++++--------- .../core/src/core/user-profile.service.ts | 2 +- .../src/features/endpoints/connect.service.ts | 2 +- .../create-endpoint-cf-step-1.component.ts | 2 +- .../error-page/error-page.component.ts | 2 +- .../metrics/services/metrics-service.ts | 2 +- .../app-action-monitor-icon.component.spec.ts | 2 +- .../favorites-meta-card.component.ts | 2 +- ...ell-request-monitor-icon.component.spec.ts | 2 +- .../endpoint/base-endpoints-data-source.ts | 2 +- .../endpoint/endpoint-list.helpers.ts | 2 +- .../core/test-framework/core-test.modules.ts | 2 +- .../store/src/actions/endpoint.actions.ts | 2 +- .../store/src/actions/metrics.actions.ts | 2 +- .../store/src/actions/user-profile.actions.ts | 2 +- .../src/base-entity-schemas.ts | 4 ++-- .../{core => store}/src/base-entity-types.ts | 19 ++++++++----------- .../store/src/effects/endpoint.effects.ts | 2 +- .../store/src/effects/system.effects.ts | 12 ++++++++---- .../src/effects/user-favorites-effect.ts | 4 ++-- .../store/src/effects/user-profile.effects.ts | 2 +- .../entity-catalog-entity.ts | 2 +- .../src/entity-catalog/entity-catalog.spec.ts | 2 +- .../src/entity-catalog/entity-catalog.ts | 6 +++--- .../packages/store/src/entity-service.spec.ts | 2 +- .../recently-visited.reducer.ts | 6 +++--- .../pagination.reducer.spec.ts | 2 +- .../store/src/selectors/endpoint.selectors.ts | 2 +- .../selectors/favorite-groups.selectors.ts | 2 +- .../store/testing/src/store-test-helper.ts | 2 +- 43 files changed, 75 insertions(+), 74 deletions(-) rename src/frontend/packages/{core => store}/src/base-entity-schemas.ts (87%) rename src/frontend/packages/{core => store}/src/base-entity-types.ts (84%) diff --git a/src/frontend/packages/cf-autoscaler/src/store/autoscaler-entity-factory.ts b/src/frontend/packages/cf-autoscaler/src/store/autoscaler-entity-factory.ts index ecdddc9b8c..21df01c5dd 100644 --- a/src/frontend/packages/cf-autoscaler/src/store/autoscaler-entity-factory.ts +++ b/src/frontend/packages/cf-autoscaler/src/store/autoscaler-entity-factory.ts @@ -1,7 +1,7 @@ import { Schema, schema } from 'normalizr'; import { getAPIResourceGuid } from '../../../cloud-foundry/src/store/selectors/api.selectors'; -import { metricEntityType } from '../../../core/src/base-entity-schemas'; +import { metricEntityType } from '../../../store/src/base-entity-schemas'; import { EntitySchema } from '../../../store/src/helpers/entity-schema'; export const appAutoscalerInfoEntityType = 'autoscalerInfo'; @@ -10,7 +10,7 @@ export const appAutoscalerPolicyEntityType = 'autoscalerPolicy'; export const appAutoscalerPolicyTriggerEntityType = 'autoscalerPolicyTrigger'; export const appAutoscalerScalingHistoryEntityType = 'autoscalerScalingHistory'; export const appAutoscalerAppMetricEntityType = 'autoscalerAppMetric'; -export const appAutoscalerCredentialEntityType = 'autoscalerCredential' +export const appAutoscalerCredentialEntityType = 'autoscalerCredential'; export const AUTOSCALER_ENDPOINT_TYPE = 'autoscaler'; diff --git a/src/frontend/packages/cf-autoscaler/src/store/autoscaler-entity-generator.ts b/src/frontend/packages/cf-autoscaler/src/store/autoscaler-entity-generator.ts index 9e946fca20..ec1414cb64 100644 --- a/src/frontend/packages/cf-autoscaler/src/store/autoscaler-entity-generator.ts +++ b/src/frontend/packages/cf-autoscaler/src/store/autoscaler-entity-generator.ts @@ -1,5 +1,5 @@ import { IOrgFavMetadata } from '../../../cloud-foundry/src/cf-metadata-types'; -import { metricEntityType } from '../../../core/src/base-entity-schemas'; +import { metricEntityType } from '../../../store/src/base-entity-schemas'; import { StratosBaseCatalogEntity, StratosCatalogEntity, diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-factory.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-factory.ts index 1112888031..40a49404ee 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-factory.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-factory.ts @@ -1,4 +1,4 @@ -import { metricEntityType } from '../../core/src/base-entity-schemas'; +import { metricEntityType } from '../../store/src/base-entity-schemas'; import { EntitySchema } from '../../store/src/helpers/entity-schema'; import { APIResource } from '../../store/src/types/api.types'; import { diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts index beba13c732..6819e1297f 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts @@ -4,10 +4,10 @@ import { combineLatest, Observable, of } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { EndpointHealthCheck } from '../../core/endpoints-health-checks'; -import { metricEntityType } from '../../core/src/base-entity-schemas'; import { urlValidationExpression } from '../../core/src/core/utils.service'; import { BaseEndpointAuth } from '../../core/src/features/endpoints/endpoint-auth'; import { AppState, GeneralEntityAppState } from '../../store/src/app-state'; +import { metricEntityType } from '../../store/src/base-entity-schemas'; import { StratosBaseCatalogEntity, StratosCatalogEndpointEntity, diff --git a/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts b/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts index 11769b81a4..128aed0b52 100644 --- a/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts +++ b/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts @@ -3,9 +3,9 @@ import { NgModule } from '@angular/core'; import { EffectsModule } from '@ngrx/effects'; import { generateASEntities } from '../../cf-autoscaler/src/store/autoscaler-entity-generator'; -import { generateStratosEntities } from '../../core/src/base-entity-types'; import { getGitHubAPIURL, GITHUB_API_URL } from '../../core/src/core/github.helpers'; import { LoggerService } from '../../core/src/core/logger.service'; +import { generateStratosEntities } from '../../store/src/base-entity-types'; import { CATALOGUE_ENTITIES, EntityCatalogFeatureModule } from '../../store/src/entity-catalog.module'; import { entityCatalog, TestEntityCatalog } from '../../store/src/entity-catalog/entity-catalog'; import { testSCFEndpointGuid } from '../../store/testing/public-api'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.spec.ts index 6ef73eb96f..f4cf1f0ad5 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/space-quota-definition/space-quota-definition.component.spec.ts @@ -3,8 +3,8 @@ import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; import { testSCFEndpoint, testSCFEndpointGuid } from '@stratosui/store/testing'; -import { endpointEntitySchema } from '../../../../../core/src/base-entity-schemas'; import { TabNavService } from '../../../../../core/tab-nav.service'; +import { endpointEntitySchema } from '../../../../../store/src/base-entity-schemas'; import { EntityCatalogHelpers } from '../../../../../store/src/entity-catalog/entity-catalog.helper'; import { EntityCatalogEntityConfig } from '../../../../../store/src/entity-catalog/entity-catalog.types'; import { NormalizedResponse } from '../../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-base/cloud-foundry-cell-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-base/cloud-foundry-cell-base.component.ts index 07a77cddd6..848157a8e1 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-base/cloud-foundry-cell-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-base/cloud-foundry-cell-base.component.ts @@ -2,9 +2,9 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; import { first, map } from 'rxjs/operators'; -import { metricEntityType } from '../../../../../../../../core/src/base-entity-schemas'; import { IPageSideNavTab } from '../../../../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { IHeaderBreadcrumb } from '../../../../../../../../core/src/shared/components/page-header/page-header.types'; +import { metricEntityType } from '../../../../../../../../store/src/base-entity-schemas'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; import { getActiveRouteCfCellProvider } from '../../../../cf.helpers'; import { CloudFoundryEndpointService } from '../../../../services/cloud-foundry-endpoint.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/data-services/cloud-foundry.service.ts b/src/frontend/packages/cloud-foundry/src/shared/data-services/cloud-foundry.service.ts index fe0acd6e1b..45ba64f2e0 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/data-services/cloud-foundry.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/data-services/cloud-foundry.service.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { CFAppState } from '../../../../cloud-foundry/src/cf-app-state'; -import { endpointEntitySchema } from '../../../../core/src/base-entity-schemas'; +import { endpointEntitySchema } from '../../../../store/src/base-entity-schemas'; import { PaginationMonitor } from '../../../../store/src/monitors/pagination-monitor'; import { APIResource, EntityInfo } from '../../../../store/src/types/api.types'; import { endpointListKey, EndpointModel } from '../../../../store/src/types/endpoint.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/services/cf-org-space-label.service.ts b/src/frontend/packages/cloud-foundry/src/shared/services/cf-org-space-label.service.ts index 585f41ed42..de20b2451c 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/services/cf-org-space-label.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/services/cf-org-space-label.service.ts @@ -2,7 +2,7 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable } from 'rxjs'; import { filter, first, map } from 'rxjs/operators'; -import { STRATOS_ENDPOINT_TYPE } from '../../../../core/src/base-entity-schemas'; +import { STRATOS_ENDPOINT_TYPE } from '../../../../store/src/base-entity-schemas'; import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog'; import { endpointSchemaKey } from '../../../../store/src/helpers/entity-factory'; import { selectEntity } from '../../../../store/src/selectors/api.selectors'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts index 99dcb96deb..f807720b7d 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts @@ -12,13 +12,13 @@ import { CfPermissionTypes, CfScopeStrings, } from '../../../../cloud-foundry/src/user-permissions/cf-user-permissions-checkers'; -import { endpointEntitySchema } from '../../../../core/src/base-entity-schemas'; -import { generateStratosEntities } from '../../../../core/src/base-entity-types'; import { PermissionConfig } from '../../../../core/src/core/permissions/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; import { StratosScopeStrings } from '../../../../core/src/core/permissions/stratos-user-permissions.checker'; import { AppTestModule } from '../../../../core/test-framework/core-test.helper'; import { AppState } from '../../../../store/src/app-state'; +import { endpointEntitySchema } from '../../../../store/src/base-entity-schemas'; +import { generateStratosEntities } from '../../../../store/src/base-entity-types'; import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../../../store/src/entity-catalog-test.module'; import { EntityCatalogEntityConfig } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { APIResource } from '../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/test-framework/cf-test-helper.ts b/src/frontend/packages/cloud-foundry/test-framework/cf-test-helper.ts index 0ef667db7e..780d481f28 100644 --- a/src/frontend/packages/cloud-foundry/test-framework/cf-test-helper.ts +++ b/src/frontend/packages/cloud-foundry/test-framework/cf-test-helper.ts @@ -1,7 +1,7 @@ import { BaseTestModules } from '../../core/test-framework/core-test.helper'; +import { generateStratosEntities } from '../../store/src/base-entity-types'; import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../store/src/entity-catalog-test.module'; import { generateCFEntities } from '../src/cf-entity-generator'; -import { generateStratosEntities } from '../../core/src/base-entity-types'; export const CFBaseTestModules = [ ...BaseTestModules, diff --git a/src/frontend/packages/core/src/app.module.ts b/src/frontend/packages/core/src/app.module.ts index 7ba9fb46a1..d5374f3abb 100644 --- a/src/frontend/packages/core/src/app.module.ts +++ b/src/frontend/packages/core/src/app.module.ts @@ -13,6 +13,8 @@ import { UpdateUserFavoriteMetadataAction, } from '../../store/src/actions/user-favourites-actions/update-user-favorite-metadata-action'; import { GeneralEntityAppState, GeneralRequestDataState } from '../../store/src/app-state'; +import { STRATOS_ENDPOINT_TYPE } from '../../store/src/base-entity-schemas'; +import { generateStratosEntities } from '../../store/src/base-entity-types'; import { EntityCatalogModule } from '../../store/src/entity-catalog.module'; import { entityCatalog } from '../../store/src/entity-catalog/entity-catalog'; import { EntityCatalogHelper } from '../../store/src/entity-catalog/entity-catalog-entity/entity-catalog.service'; @@ -28,8 +30,6 @@ import { TabNavService } from '../tab-nav.service'; import { XSRFModule } from '../xsrf.module'; import { AppComponent } from './app.component'; import { RouteModule } from './app.routing'; -import { STRATOS_ENDPOINT_TYPE } from './base-entity-schemas'; -import { generateStratosEntities } from './base-entity-types'; import { CoreModule } from './core/core.module'; import { CustomizationService } from './core/customizations.types'; import { DynamicExtensionRoutes } from './core/extension/dynamic-extension-routes'; diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts index e8e69c7782..0fa151e46d 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts @@ -3,14 +3,14 @@ import { createBasicStoreModule, createEntityStoreState, TestStoreEntity } from import { first, tap } from 'rxjs/operators'; import { AppState } from '../../../../store/src/app-state'; +import { endpointEntitySchema } from '../../../../store/src/base-entity-schemas'; +import { generateStratosEntities } from '../../../../store/src/base-entity-types'; import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../../../store/src/entity-catalog-test.module'; import { EntityCatalogEntityConfig } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { EndpointModel } from '../../../../store/src/types/endpoint.types'; import { BaseEntityValues } from '../../../../store/src/types/entity.types'; import { PaginationState } from '../../../../store/src/types/pagination.types'; import { AppTestModule } from '../../../test-framework/core-test.helper'; -import { endpointEntitySchema } from '../../base-entity-schemas'; -import { generateStratosEntities } from '../../base-entity-types'; import { PermissionConfig } from './current-user-permissions.config'; import { CurrentUserPermissionsService } from './current-user-permissions.service'; import { StratosPermissionStrings, StratosPermissionTypes, StratosScopeStrings } from './stratos-user-permissions.checker'; diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts index 0a7490fb0c..95e8399c3b 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.ts @@ -4,10 +4,10 @@ import { combineLatest, Observable, of } from 'rxjs'; import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; import { InternalAppState } from '../../../../store/src/app-state'; +import { ENDPOINT_TYPE, STRATOS_ENDPOINT_TYPE } from '../../../../store/src/base-entity-schemas'; import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog'; import { selectEntity } from '../../../../store/src/selectors/api.selectors'; import { EndpointModel } from '../../../../store/src/types/endpoint.types'; -import { ENDPOINT_TYPE, STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; import { LoggerService } from '../logger.service'; import { CurrentUserPermissions, @@ -23,7 +23,7 @@ import { import { StratosUserPermissionsChecker } from './stratos-user-permissions.checker'; -export const CUSTOM_USER_PERMISSION_CHECKERS = 'custom_user_perm_checkers' +export const CUSTOM_USER_PERMISSION_CHECKERS = 'custom_user_perm_checkers'; @Injectable() export class CurrentUserPermissionsService { @@ -38,7 +38,7 @@ export class CurrentUserPermissionsService { this.allCheckers = [ new StratosUserPermissionsChecker(store), ...nullSafeCustomCheckers - ] + ]; } /** * @param action The action we're going to check the user's access to. @@ -56,13 +56,13 @@ export class CurrentUserPermissionsService { ): Observable { let actionConfig; if (typeof action === 'string') { - let permConfigType = this.getPermissionConfig(action); + const permConfigType = this.getPermissionConfig(action); if (!permConfigType) { return of(false); // Logging handled in getPermissionConfig } actionConfig = this.getConfig(permConfigType); } else { - actionConfig = this.getConfig(action) + actionConfig = this.getConfig(action); } const obs$ = this.getCanObservable(actionConfig, endpointGuid, ...args); return obs$ ? @@ -96,7 +96,7 @@ export class CurrentUserPermissionsService { 'permissions check', actionConfig.type, of(false) - ) + ); } private getComplexPermission(permissionConfig: PermissionConfig[], endpointGuid?: string, ...args: any[]) { @@ -116,7 +116,7 @@ export class CurrentUserPermissionsService { [{ checks: [of(false)] }] - ) + ); } private getConfig(config: PermissionConfigType, tries = 0): PermissionConfig[] | PermissionConfig { @@ -152,7 +152,7 @@ export class CurrentUserPermissionsService { 'fallback permission', 'N/A', of(null) - ) + ); } private getPermissionConfig(key: CurrentUserPermissions): PermissionConfigType { @@ -161,7 +161,7 @@ export class CurrentUserPermissionsService { 'permissions checker', key, null - ) + ); } /** diff --git a/src/frontend/packages/core/src/core/user-profile.service.ts b/src/frontend/packages/core/src/core/user-profile.service.ts index f83b16a256..936be6ba31 100644 --- a/src/frontend/packages/core/src/core/user-profile.service.ts +++ b/src/frontend/packages/core/src/core/user-profile.service.ts @@ -9,6 +9,7 @@ import { UpdateUserProfileAction, } from '../../../store/src/actions/user-profile.actions'; import { AppState } from '../../../store/src/app-state'; +import { userProfileEntitySchema } from '../../../store/src/base-entity-schemas'; import { userProfilePasswordUpdatingKey } from '../../../store/src/effects/user-profile.effects'; import { entityCatalog } from '../../../store/src/entity-catalog/entity-catalog'; import { EntityService } from '../../../store/src/entity-service'; @@ -18,7 +19,6 @@ import { AuthState } from '../../../store/src/reducers/auth.reducer'; import { selectRequestInfo, selectUpdateInfo } from '../../../store/src/selectors/api.selectors'; import { SessionData } from '../../../store/src/types/auth.types'; import { UserProfileInfo, UserProfileInfoEmail, UserProfileInfoUpdates } from '../../../store/src/types/user-profile.types'; -import { userProfileEntitySchema } from '../base-entity-schemas'; @Injectable() diff --git a/src/frontend/packages/core/src/features/endpoints/connect.service.ts b/src/frontend/packages/core/src/features/endpoints/connect.service.ts index 015ff5b14d..375f591813 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect.service.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect.service.ts @@ -15,6 +15,7 @@ import { import { AuthParams, ConnectEndpoint } from '../../../../store/src/actions/endpoint.actions'; import { GetSystemInfo } from '../../../../store/src/actions/system.actions'; import { EndpointOnlyAppState } from '../../../../store/src/app-state'; +import { STRATOS_ENDPOINT_TYPE } from '../../../../store/src/base-entity-schemas'; import { EndpointsEffect } from '../../../../store/src/effects/endpoint.effects'; import { SystemEffects } from '../../../../store/src/effects/system.effects'; import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog'; @@ -22,7 +23,6 @@ import { endpointSchemaKey } from '../../../../store/src/helpers/entity-factory' import { ActionState } from '../../../../store/src/reducers/api-request-reducer/types'; import { selectEntity, selectRequestInfo, selectUpdateInfo } from '../../../../store/src/selectors/api.selectors'; import { EndpointModel } from '../../../../store/src/types/endpoint.types'; -import { STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; import { EndpointsService } from '../../core/endpoints.service'; import { EndpointType } from '../../core/extension/extension-types'; import { safeUnsubscribe } from '../../core/utils.service'; diff --git a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts index a046dc6b62..a7351064d5 100644 --- a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts @@ -9,6 +9,7 @@ import { filter, map, pairwise, withLatestFrom } from 'rxjs/operators'; import { GetAllEndpoints, RegisterEndpoint } from '../../../../../../store/src/actions/endpoint.actions'; import { ShowSnackBar } from '../../../../../../store/src/actions/snackBar.actions'; import { GeneralEntityAppState } from '../../../../../../store/src/app-state'; +import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../../../../../store/src/base-entity-schemas'; import { EndpointsEffect } from '../../../../../../store/src/effects/endpoint.effects'; import { entityCatalog } from '../../../../../../store/src/entity-catalog/entity-catalog'; import { @@ -17,7 +18,6 @@ import { import { endpointSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; import { getAPIRequestDataState, selectUpdateInfo } from '../../../../../../store/src/selectors/api.selectors'; import { selectPaginationState } from '../../../../../../store/src/selectors/pagination.selectors'; -import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../../../base-entity-schemas'; import { getIdFromRoute } from '../../../../core/utils.service'; import { IStepperStep, StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; import { ConnectEndpointConfig } from '../../connect.service'; diff --git a/src/frontend/packages/core/src/features/error-page/error-page/error-page.component.ts b/src/frontend/packages/core/src/features/error-page/error-page/error-page.component.ts index 9b6ab439b4..7de769a04c 100644 --- a/src/frontend/packages/core/src/features/error-page/error-page/error-page.component.ts +++ b/src/frontend/packages/core/src/features/error-page/error-page/error-page.component.ts @@ -7,13 +7,13 @@ import { first, map, withLatestFrom } from 'rxjs/operators'; import { SendClearEndpointEventsAction } from '../../../../../store/src/actions/internal-events.actions'; import { AppState } from '../../../../../store/src/app-state'; +import { endpointEntitySchema } from '../../../../../store/src/base-entity-schemas'; import { endpointSchemaKey } from '../../../../../store/src/helpers/entity-factory'; import { EntityMonitor } from '../../../../../store/src/monitors/entity-monitor'; import { InternalEventMonitorFactory } from '../../../../../store/src/monitors/internal-event-monitor.factory'; import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { InternalEventState } from '../../../../../store/src/types/internal-events.types'; import { getPreviousRoutingState } from '../../../../../store/src/types/routing.type'; -import { endpointEntitySchema } from '../../../base-entity-schemas'; import { StratosStatus } from '../../../shared/shared.types'; import { eventReturnUrlParam } from '../../event-page/events-page/events-page.component'; diff --git a/src/frontend/packages/core/src/features/metrics/services/metrics-service.ts b/src/frontend/packages/core/src/features/metrics/services/metrics-service.ts index 9e9076acea..6fca8aaefc 100644 --- a/src/frontend/packages/core/src/features/metrics/services/metrics-service.ts +++ b/src/frontend/packages/core/src/features/metrics/services/metrics-service.ts @@ -2,11 +2,11 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map, publishReplay, refCount } from 'rxjs/operators'; +import { endpointEntitySchema } from '../../../../../store/src/base-entity-schemas'; import { PaginationMonitor } from '../../../../../store/src/monitors/pagination-monitor'; import { PaginationMonitorFactory } from '../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types'; import { endpointListKey, EndpointModel } from '../../../../../store/src/types/endpoint.types'; -import { endpointEntitySchema } from '../../../base-entity-schemas'; import { getFullEndpointApiUrl } from '../../endpoints/endpoint-helpers'; export interface MetricsEndpointProvider { diff --git a/src/frontend/packages/core/src/shared/components/app-action-monitor-icon/app-action-monitor-icon.component.spec.ts b/src/frontend/packages/core/src/shared/components/app-action-monitor-icon/app-action-monitor-icon.component.spec.ts index d5e18bd988..06860cf718 100644 --- a/src/frontend/packages/core/src/shared/components/app-action-monitor-icon/app-action-monitor-icon.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/app-action-monitor-icon/app-action-monitor-icon.component.spec.ts @@ -1,7 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { endpointEntitySchema } from '../../../../../store/src/base-entity-schemas'; import { BaseTestModules } from '../../../../test-framework/core-test.helper'; -import { endpointEntitySchema } from '../../../base-entity-schemas'; import { AppActionMonitorIconComponent } from './app-action-monitor-icon.component'; describe('AppActionMonitorIconComponent', () => { diff --git a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts index e95dea1c1a..afecb11450 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts @@ -7,10 +7,10 @@ import { RemoveUserFavoriteAction, } from '../../../../../store/src/actions/user-favourites-actions/remove-user-favorite-action'; import { AppState } from '../../../../../store/src/app-state'; +import { userFavoritesEntitySchema } from '../../../../../store/src/base-entity-schemas'; import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; import { endpointEntitiesSelector } from '../../../../../store/src/selectors/endpoint.selectors'; import { IFavoriteMetadata, UserFavorite } from '../../../../../store/src/types/user-favorites.types'; -import { userFavoritesEntitySchema } from '../../../base-entity-schemas'; import { IFavoriteEntity } from '../../../core/user-favorite-manager'; import { isEndpointConnected } from '../../../features/endpoints/connect.service'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../shared.types'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-request-monitor-icon/table-cell-request-monitor-icon.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-request-monitor-icon/table-cell-request-monitor-icon.component.spec.ts index 04cb6b4ce1..8a69e57ded 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-request-monitor-icon/table-cell-request-monitor-icon.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-request-monitor-icon/table-cell-request-monitor-icon.component.spec.ts @@ -1,7 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { endpointEntitySchema } from '../../../../../../../store/src/base-entity-schemas'; import { BaseTestModules } from '../../../../../../test-framework/core-test.helper'; -import { endpointEntitySchema } from '../../../../../base-entity-schemas'; import { AppMonitorComponentTypes } from '../../../app-action-monitor-icon/app-action-monitor-icon.component'; import { TableCellRequestMonitorIconComponent } from './table-cell-request-monitor-icon.component'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/base-endpoints-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/base-endpoints-data-source.ts index 7f420a1f8c..6eb5dc16f6 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/base-endpoints-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/base-endpoints-data-source.ts @@ -5,13 +5,13 @@ import { map, pairwise, tap, withLatestFrom } from 'rxjs/operators'; import { GetAllEndpoints } from '../../../../../../../store/src/actions/endpoint.actions'; import { CreatePagination } from '../../../../../../../store/src/actions/pagination.actions'; import { AppState } from '../../../../../../../store/src/app-state'; +import { endpointEntitySchema } from '../../../../../../../store/src/base-entity-schemas'; import { endpointSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; import { EntityMonitorFactory } from '../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { InternalEventMonitorFactory } from '../../../../../../../store/src/monitors/internal-event-monitor.factory'; import { PaginationMonitorFactory } from '../../../../../../../store/src/monitors/pagination-monitor.factory'; import { endpointEntitiesSelector } from '../../../../../../../store/src/selectors/endpoint.selectors'; import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; -import { endpointEntitySchema } from '../../../../../base-entity-schemas'; import { DataFunctionDefinition, ListDataSource } from '../../data-sources-controllers/list-data-source'; import { RowsState } from '../../data-sources-controllers/list-data-source-types'; import { TableRowStateManager } from '../../list-table/table-row/table-row-state-manager'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts index b621bc2513..e1e7a7aaf7 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts @@ -9,12 +9,12 @@ import { RouterNav } from '../../../../../../../store/src/actions/router.actions import { ShowSnackBar } from '../../../../../../../store/src/actions/snackBar.actions'; import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions'; import { AppState } from '../../../../../../../store/src/app-state'; +import { STRATOS_ENDPOINT_TYPE } from '../../../../../../../store/src/base-entity-schemas'; import { EndpointsEffect } from '../../../../../../../store/src/effects/endpoint.effects'; import { entityCatalog } from '../../../../../../../store/src/entity-catalog/entity-catalog'; import { endpointSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; import { selectDeletionInfo, selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors'; import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; -import { STRATOS_ENDPOINT_TYPE } from '../../../../../base-entity-schemas'; import { LoggerService } from '../../../../../core/logger.service'; import { CurrentUserPermissionsService } from '../../../../../core/permissions/current-user-permissions.service'; import { StratosCurrentUserPermissions } from '../../../../../core/permissions/stratos-user-permissions.checker'; diff --git a/src/frontend/packages/core/test-framework/core-test.modules.ts b/src/frontend/packages/core/test-framework/core-test.modules.ts index f2e0bc6e7a..f433ecb5e6 100644 --- a/src/frontend/packages/core/test-framework/core-test.modules.ts +++ b/src/frontend/packages/core/test-framework/core-test.modules.ts @@ -1,6 +1,6 @@ import { NgModule } from '@angular/core'; -import { generateStratosEntities } from '../../core/src/base-entity-types'; +import { generateStratosEntities } from '../../store/src/base-entity-types'; import { CATALOGUE_ENTITIES, EntityCatalogFeatureModule } from '../../store/src/entity-catalog.module'; import { entityCatalog, TestEntityCatalog } from '../../store/src/entity-catalog/entity-catalog'; diff --git a/src/frontend/packages/store/src/actions/endpoint.actions.ts b/src/frontend/packages/store/src/actions/endpoint.actions.ts index cd4540b8eb..c72c71dd5c 100644 --- a/src/frontend/packages/store/src/actions/endpoint.actions.ts +++ b/src/frontend/packages/store/src/actions/endpoint.actions.ts @@ -1,7 +1,7 @@ import { Action } from '@ngrx/store'; -import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; import { EndpointType } from '../../../core/src/core/extension/extension-types'; +import { STRATOS_ENDPOINT_TYPE } from '../base-entity-schemas'; import { endpointSchemaKey } from '../helpers/entity-factory'; import { NormalizedResponse } from '../types/api.types'; import { endpointListKey, EndpointModel, INewlyConnectedEndpointInfo } from '../types/endpoint.types'; diff --git a/src/frontend/packages/store/src/actions/metrics.actions.ts b/src/frontend/packages/store/src/actions/metrics.actions.ts index 43b068a14d..df1138601f 100644 --- a/src/frontend/packages/store/src/actions/metrics.actions.ts +++ b/src/frontend/packages/store/src/actions/metrics.actions.ts @@ -1,6 +1,6 @@ -import { metricEntityType } from '../../../core/src/base-entity-schemas'; import { environment } from '../../../core/src/environments/environment'; import { MetricQueryType } from '../../../core/src/shared/services/metrics-range-selector.types'; +import { metricEntityType } from '../base-entity-schemas'; import { EntityRequestAction } from '../types/request.types'; export const METRICS_START = '[Metrics] Fetch Start'; diff --git a/src/frontend/packages/store/src/actions/user-profile.actions.ts b/src/frontend/packages/store/src/actions/user-profile.actions.ts index 00234f772e..73b7b09523 100644 --- a/src/frontend/packages/store/src/actions/user-profile.actions.ts +++ b/src/frontend/packages/store/src/actions/user-profile.actions.ts @@ -1,6 +1,6 @@ import { Action } from '@ngrx/store'; -import { userProfileEntitySchema } from '../../../core/src/base-entity-schemas'; +import { userProfileEntitySchema } from '../base-entity-schemas'; import { EntityRequestAction } from '../types/request.types'; import { UserProfileInfo, UserProfilePasswordUpdate } from '../types/user-profile.types'; diff --git a/src/frontend/packages/core/src/base-entity-schemas.ts b/src/frontend/packages/store/src/base-entity-schemas.ts similarity index 87% rename from src/frontend/packages/core/src/base-entity-schemas.ts rename to src/frontend/packages/store/src/base-entity-schemas.ts index 19da225c8b..f819325d8f 100644 --- a/src/frontend/packages/core/src/base-entity-schemas.ts +++ b/src/frontend/packages/store/src/base-entity-schemas.ts @@ -4,8 +4,8 @@ import { systemInfoSchemaKey, userFavouritesSchemaKey, userProfileSchemaKey, -} from '../../store/src/helpers/entity-factory'; -import { EntitySchema } from '../../store/src/helpers/entity-schema'; +} from './helpers/entity-factory'; +import { EntitySchema } from './helpers/entity-schema'; export const metricEntityType = 'metrics'; diff --git a/src/frontend/packages/core/src/base-entity-types.ts b/src/frontend/packages/store/src/base-entity-types.ts similarity index 84% rename from src/frontend/packages/core/src/base-entity-types.ts rename to src/frontend/packages/store/src/base-entity-types.ts index bdb004deea..ed2a579cb7 100644 --- a/src/frontend/packages/core/src/base-entity-types.ts +++ b/src/frontend/packages/store/src/base-entity-types.ts @@ -1,12 +1,7 @@ +import { BaseEndpointAuth } from '../../core/src/features/endpoints/endpoint-auth'; import { - StratosCatalogEndpointEntity, - StratosCatalogEntity, -} from '../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; -import { - addOrUpdateUserFavoriteMetadataReducer, - deleteUserFavoriteMetadataReducer, -} from '../../store/src/reducers/favorite.reducer'; -import { systemEndpointsReducer } from '../../store/src/reducers/system-endpoints.reducer'; + MetricsEndpointDetailsComponent, +} from '../../core/src/features/metrics/metrics-endpoint-details/metrics-endpoint-details.component'; import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE, @@ -14,10 +9,12 @@ import { userFavoritesEntitySchema, userProfileEntitySchema, } from './base-entity-schemas'; -import { BaseEndpointAuth } from './features/endpoints/endpoint-auth'; import { - MetricsEndpointDetailsComponent, -} from './features/metrics/metrics-endpoint-details/metrics-endpoint-details.component'; + StratosCatalogEndpointEntity, + StratosCatalogEntity, +} from './entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { addOrUpdateUserFavoriteMetadataReducer, deleteUserFavoriteMetadataReducer } from './reducers/favorite.reducer'; +import { systemEndpointsReducer } from './reducers/system-endpoints.reducer'; // // These types are used to represent the base stratos types. diff --git a/src/frontend/packages/store/src/effects/endpoint.effects.ts b/src/frontend/packages/store/src/effects/endpoint.effects.ts index 3ebaf0694a..e11cd4c5d7 100644 --- a/src/frontend/packages/store/src/effects/endpoint.effects.ts +++ b/src/frontend/packages/store/src/effects/endpoint.effects.ts @@ -4,7 +4,6 @@ import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, mergeMap } from 'rxjs/operators'; -import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; import { EndpointType } from '../../../core/src/core/extension/extension-types'; import { BrowserStandardEncoder } from '../../../core/src/helper'; import { @@ -34,6 +33,7 @@ import { ClearPaginationOfEntity } from '../actions/pagination.actions'; import { GET_SYSTEM_INFO_SUCCESS, GetSystemInfo, GetSystemSuccess } from '../actions/system.actions'; import { GetUserFavoritesAction } from '../actions/user-favourites-actions/get-user-favorites-action'; import { DispatchOnlyAppState } from '../app-state'; +import { STRATOS_ENDPOINT_TYPE } from '../base-entity-schemas'; import { entityCatalog } from '../entity-catalog/entity-catalog'; import { endpointSchemaKey } from '../helpers/entity-factory'; import { ApiRequestTypes } from '../reducers/api-request-reducer/request-helpers'; diff --git a/src/frontend/packages/store/src/effects/system.effects.ts b/src/frontend/packages/store/src/effects/system.effects.ts index 962280aebb..b02c7cc365 100644 --- a/src/frontend/packages/store/src/effects/system.effects.ts +++ b/src/frontend/packages/store/src/effects/system.effects.ts @@ -4,12 +4,16 @@ import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, mergeMap } from 'rxjs/operators'; -import { EntityRequestAction } from '../types/request.types'; import { GET_SYSTEM_INFO, GetSystemFailed, GetSystemInfo, GetSystemSuccess } from '../actions/system.actions'; -import { StartRequestAction, WrapperRequestActionFailed, WrapperRequestActionSuccess } from '../types/request.types'; -import { SystemInfo, systemStoreNames } from '../types/system.types'; import { InternalAppState } from '../app-state'; -import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; +import { STRATOS_ENDPOINT_TYPE } from '../base-entity-schemas'; +import { + EntityRequestAction, + StartRequestAction, + WrapperRequestActionFailed, + WrapperRequestActionSuccess, +} from '../types/request.types'; +import { SystemInfo, systemStoreNames } from '../types/system.types'; @Injectable() export class SystemEffects { diff --git a/src/frontend/packages/store/src/effects/user-favorites-effect.ts b/src/frontend/packages/store/src/effects/user-favorites-effect.ts index deebce83a7..27f9ec400b 100644 --- a/src/frontend/packages/store/src/effects/user-favorites-effect.ts +++ b/src/frontend/packages/store/src/effects/user-favorites-effect.ts @@ -4,8 +4,6 @@ import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, first, map, mergeMap, switchMap } from 'rxjs/operators'; -import { userFavoritesEntitySchema } from '../../../core/src/base-entity-schemas'; -import { entityCatalog } from '../entity-catalog/entity-catalog'; import { UserFavoriteManager } from '../../../core/src/core/user-favorite-manager'; import { environment } from '../../../core/src/environments/environment.prod'; import { ClearPaginationOfEntity } from '../actions/pagination.actions'; @@ -28,6 +26,8 @@ import { UpdateUserFavoriteMetadataSuccessAction, } from '../actions/user-favourites-actions/update-user-favorite-metadata-action'; import { DispatchOnlyAppState } from '../app-state'; +import { userFavoritesEntitySchema } from '../base-entity-schemas'; +import { entityCatalog } from '../entity-catalog/entity-catalog'; import { NormalizedResponse } from '../types/api.types'; import { PaginatedAction } from '../types/pagination.types'; import { WrapperRequestActionSuccess } from '../types/request.types'; diff --git a/src/frontend/packages/store/src/effects/user-profile.effects.ts b/src/frontend/packages/store/src/effects/user-profile.effects.ts index 745d4e11cc..bc664985fd 100644 --- a/src/frontend/packages/store/src/effects/user-profile.effects.ts +++ b/src/frontend/packages/store/src/effects/user-profile.effects.ts @@ -4,7 +4,6 @@ import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, mergeMap, switchMap } from 'rxjs/operators'; -import { userProfileEntitySchema } from '../../../core/src/base-entity-schemas'; import { environment } from '../../../core/src/environments/environment'; import { FetchUserProfileAction, @@ -14,6 +13,7 @@ import { UpdateUserPasswordAction, UpdateUserProfileAction, } from '../actions/user-profile.actions'; +import { userProfileEntitySchema } from '../base-entity-schemas'; import { entityCatalog } from '../entity-catalog/entity-catalog'; import { rootUpdatingKey } from '../reducers/api-request-reducer/types'; import { UserProfileInfo } from '../types/user-profile.types'; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts index 3fa2b47b0a..b754067761 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts @@ -1,9 +1,9 @@ import { ActionReducer } from '@ngrx/store'; -import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../../../core/src/base-entity-schemas'; import { KnownKeys, NonOptionalKeys } from '../../../../core/src/core/utils.service'; import { getFullEndpointApiUrl } from '../../../../core/src/features/endpoints/endpoint-helpers'; import { IRequestEntityTypeState } from '../../app-state'; +import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; import { EntitiesFetchHandler, EntitiesInfoHandler, diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts index 7f7a44f245..ce4979a9fc 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts @@ -1,8 +1,8 @@ -import { endpointEntitySchema } from '../../../core/src/base-entity-schemas'; import { BaseEndpointAuth } from '../../../core/src/features/endpoints/endpoint-auth'; import { EndpointListDetailsComponent, } from '../../../core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers'; +import { endpointEntitySchema } from '../base-entity-schemas'; import { EntitySchema } from '../helpers/entity-schema'; import { TestEntityCatalog } from './entity-catalog'; import { StratosCatalogEndpointEntity, StratosCatalogEntity } from './entity-catalog-entity/entity-catalog-entity'; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts index c6371e3e17..40665ba7af 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.ts @@ -1,7 +1,7 @@ import { Action } from '@ngrx/store'; -import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; import { IRequestEntityTypeState } from '../app-state'; +import { STRATOS_ENDPOINT_TYPE } from '../base-entity-schemas'; import { ExtraApiReducers } from '../reducers/api-request-reducers.generator.helpers'; import { ICurrentUserRolesState } from '../types/current-user-roles.types'; import { OrchestratedActionBuilders } from './action-orchestrator/action-orchestrator'; @@ -218,10 +218,10 @@ class EntityCatalog { ...state.endpoints, [endpoint.type]: endpointState } - } + }; } } - }) + }); return oneChanged ? { ...state } : state; diff --git a/src/frontend/packages/store/src/entity-service.spec.ts b/src/frontend/packages/store/src/entity-service.spec.ts index e0e752ada8..8a754fbaae 100644 --- a/src/frontend/packages/store/src/entity-service.spec.ts +++ b/src/frontend/packages/store/src/entity-service.spec.ts @@ -4,12 +4,12 @@ import { inject, TestBed } from '@angular/core/testing'; import { Action, Store } from '@ngrx/store'; import { filter, first, map, pairwise, tap } from 'rxjs/operators'; -import { STRATOS_ENDPOINT_TYPE } from '../../core/src/base-entity-schemas'; import { ENTITY_SERVICE } from '../../core/src/shared/entity.tokens'; import { generateTestEntityServiceProvider } from '../../core/test-framework/entity-service.helper'; import { createEntityStore, TestStoreEntity } from '../testing/src/store-test-helper'; import { APIResponse } from './actions/request.actions'; import { GeneralAppState } from './app-state'; +import { STRATOS_ENDPOINT_TYPE } from './base-entity-schemas'; import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from './entity-catalog-test.module'; import { StratosBaseCatalogEntity } from './entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { EntityCatalogEntityConfig, IStratosEndpointDefinition } from './entity-catalog/entity-catalog.types'; diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/recently-visited.reducer.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/recently-visited.reducer.ts index 2a83934d21..b69b7779aa 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/recently-visited.reducer.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/recently-visited.reducer.ts @@ -8,11 +8,11 @@ import { UNREGISTER_ENDPOINTS_SUCCESS, } from '../../actions/endpoint.actions'; import { AddRecentlyVisitedEntityAction, SetRecentlyVisitedEntityAction } from '../../actions/recently-visited.actions'; -import { IRecentlyVisitedState } from '../../types/recently-visited.types'; -import { addNewHit, cleanRecentsList, getDefaultRecentState } from './recently-visited.reducer.helpers'; +import { STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; import { entityCatalog } from '../../entity-catalog/entity-catalog'; -import { STRATOS_ENDPOINT_TYPE } from '../../../../core/src/base-entity-schemas'; import { endpointSchemaKey } from '../../helpers/entity-factory'; +import { IRecentlyVisitedState } from '../../types/recently-visited.types'; +import { addNewHit, cleanRecentsList, getDefaultRecentState } from './recently-visited.reducer.helpers'; export function recentlyVisitedReducer( state: IRecentlyVisitedState = getDefaultRecentState(), diff --git a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination.reducer.spec.ts b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination.reducer.spec.ts index d3c48a2ad2..95d840e19d 100644 --- a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination.reducer.spec.ts +++ b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination.reducer.spec.ts @@ -1,7 +1,7 @@ import { HttpRequest } from '@angular/common/http'; -import { ENDPOINT_TYPE, endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../../../core/src/base-entity-schemas'; import { RequestTypes } from '../../actions/request.actions'; +import { ENDPOINT_TYPE, endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; import { entityCatalog } from '../../entity-catalog/entity-catalog'; import { EntityCatalogHelpers } from '../../entity-catalog/entity-catalog.helper'; import { EntitySchema } from '../../helpers/entity-schema'; diff --git a/src/frontend/packages/store/src/selectors/endpoint.selectors.ts b/src/frontend/packages/store/src/selectors/endpoint.selectors.ts index 2846302148..59c191d9c9 100644 --- a/src/frontend/packages/store/src/selectors/endpoint.selectors.ts +++ b/src/frontend/packages/store/src/selectors/endpoint.selectors.ts @@ -1,7 +1,7 @@ import { compose } from '@ngrx/store'; -import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; import { InternalAppState, IRequestEntityTypeState } from '../app-state'; +import { STRATOS_ENDPOINT_TYPE } from '../base-entity-schemas'; import { EntityCatalogHelpers } from '../entity-catalog/entity-catalog.helper'; import { endpointSchemaKey } from '../helpers/entity-factory'; import { EndpointModel, EndpointState } from '../types/endpoint.types'; diff --git a/src/frontend/packages/store/src/selectors/favorite-groups.selectors.ts b/src/frontend/packages/store/src/selectors/favorite-groups.selectors.ts index a1b3158b2e..dfb30707a2 100644 --- a/src/frontend/packages/store/src/selectors/favorite-groups.selectors.ts +++ b/src/frontend/packages/store/src/selectors/favorite-groups.selectors.ts @@ -1,8 +1,8 @@ import { compose } from '@ngrx/store'; -import { STRATOS_ENDPOINT_TYPE, userFavoritesEntitySchema } from '../../../core/src/base-entity-schemas'; import { deriveEndpointFavoriteFromFavorite } from '../../../core/src/core/user-favorite-helpers'; import { InternalAppState, IRequestEntityTypeState } from '../app-state'; +import { STRATOS_ENDPOINT_TYPE, userFavoritesEntitySchema } from '../base-entity-schemas'; import { entityCatalog } from '../entity-catalog/entity-catalog'; import { IUserFavoriteGroup, IUserFavoritesGroups, IUserFavoritesGroupsState } from '../types/favorite-groups.types'; import { IFavoriteMetadata, UserFavorite } from '../types/user-favorites.types'; diff --git a/src/frontend/packages/store/testing/src/store-test-helper.ts b/src/frontend/packages/store/testing/src/store-test-helper.ts index 3dac3230b7..44b01d7eb7 100644 --- a/src/frontend/packages/store/testing/src/store-test-helper.ts +++ b/src/frontend/packages/store/testing/src/store-test-helper.ts @@ -2,8 +2,8 @@ import { ModuleWithProviders } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { Store, StoreModule } from '@ngrx/store'; -import { endpointEntitySchema } from '../../../core/src/base-entity-schemas'; import { AppState } from '../../src/app-state'; +import { endpointEntitySchema } from '../../src/base-entity-schemas'; import { entityCatalog } from '../../src/entity-catalog/entity-catalog'; import { EntityCatalogEntityConfig } from '../../src/entity-catalog/entity-catalog.types'; import { appReducers } from '../../src/reducers.module'; From 59ce497a55bc2900341b1dfb634a9cc5cfc84eb3 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Wed, 17 Jun 2020 19:35:34 +0100 Subject: [PATCH 45/82] Add snackbar --- .../card-cf-space-details.component.ts | 7 ++-- .../long-running-cf-op.service.ts | 16 +++---- .../connect-endpoint-dialog.component.ts | 5 ++- .../create-endpoint-cf-step-1.component.ts | 10 +++-- .../endpoints-page.component.ts | 13 +++--- .../endpoint/endpoint-list.helpers.ts | 7 ++-- .../src/shared/services/snackbar.service.ts | 33 +++++++++++++++ .../store/src/actions/snackBar.actions.ts | 28 ------------- .../src/effects/snackBar.effects.spec.ts | 32 -------------- .../store/src/effects/snackBar.effects.ts | 42 ------------------- .../packages/store/src/store.module.ts | 2 - 11 files changed, 66 insertions(+), 129 deletions(-) create mode 100644 src/frontend/packages/core/src/shared/services/snackbar.service.ts delete mode 100644 src/frontend/packages/store/src/actions/snackBar.actions.ts delete mode 100644 src/frontend/packages/store/src/effects/snackBar.effects.spec.ts delete mode 100644 src/frontend/packages/store/src/effects/snackBar.effects.ts diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-cf-space-details/card-cf-space-details.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-cf-space-details/card-cf-space-details.component.ts index 1e20e5ab65..555865d96e 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-cf-space-details/card-cf-space-details.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-cf-space-details/card-cf-space-details.component.ts @@ -8,8 +8,8 @@ import { CloudFoundrySpaceService, } from '../../../../../../cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space.service'; import { safeUnsubscribe } from '../../../../../../core/src/core/utils.service'; +import { SnackBarService } from '../../../../../../core/src/shared/services/snackbar.service'; import { RouterNav } from '../../../../../../store/src/actions/router.actions'; -import { ShowReturnSnackBar } from '../../../../../../store/src/actions/snackBar.actions'; import { AppState } from '../../../../../../store/src/app-state'; @Component({ @@ -24,7 +24,8 @@ export class CardCfSpaceDetailsComponent implements OnDestroy { constructor( public cfSpaceService: CloudFoundrySpaceService, private store: Store, - private router: Router + private router: Router, + private snackBarService: SnackBarService ) { this.allowSshStatus$ = cfSpaceService.allowSsh$.pipe( map(status => status === 'false' ? 'Disabled' : 'Enabled') @@ -34,7 +35,7 @@ export class CardCfSpaceDetailsComponent implements OnDestroy { goToOrgQuota() { this.quotaLinkSub = this.cfSpaceService.quotaLink$.subscribe(quotaLink => { this.store.dispatch(new RouterNav({ path: quotaLink })); - this.store.dispatch(new ShowReturnSnackBar('You were switched to an organization', this.router.url, 'Return to space')); + this.snackBarService.showReturn('You were switched to an organization', this.router.url, 'Return to space'); }); } diff --git a/src/frontend/packages/cloud-foundry/src/shared/data-services/long-running-cf-op.service.ts b/src/frontend/packages/cloud-foundry/src/shared/data-services/long-running-cf-op.service.ts index 443247c3a3..c6633637ec 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/data-services/long-running-cf-op.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/data-services/long-running-cf-op.service.ts @@ -2,14 +2,17 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { LongRunningOperationsService } from '../../../../core/src/shared/services/long-running-op.service'; -import { ShowSnackBar } from '../../../../store/src/actions/snackBar.actions'; +import { SnackBarService } from '../../../../core/src/shared/services/snackbar.service'; import { AppState } from '../../../../store/src/app-state'; import { GetServiceInstance } from '../../actions/service-instances.actions'; @Injectable() export class LongRunningCfOperationsService extends LongRunningOperationsService { - constructor(store: Store) { + constructor( + store: Store, + private snackBarService: SnackBarService + ) { super(store); } @@ -17,21 +20,20 @@ export class LongRunningCfOperationsService extends LongRunningOperationsService const message = `The operation to create the service instance is taking a long time and will continue in the background. Please refresh the service instance list to check it's status ${bindApp ? ` and then bind the application via the Application page.` : '.'}`; - this.store.dispatch(new ShowSnackBar(message, 'Dismiss')); - } + this.snackBarService.show(message, 'Dismiss'); } handleLongRunningUpdateService(serviceInstanceGuid: string, cfGuid: string) { const message = `The operation to update the service instance is taking a long time and will continue in the background. Please refresh the service instance list to check it's status`; - this.store.dispatch(new ShowSnackBar(message, 'Dismiss')); - // Also attempt to fetch the service instance, this will update the `last operation` value to `update` and `in progress` + // Also attempt to fetch the service instance, this will update the `last operation` value to `update` and `in progress` + this.snackBarService.show(message, 'Dismiss'); this.store.dispatch(new GetServiceInstance(serviceInstanceGuid, cfGuid)); } handleLongRunningDeleteService(serviceInstanceGuid: string, cfGuid: string) { const message = `The operation to delete the service instance is taking a long time and will continue in the background. Please refresh the service instance list to check it's status`; - this.store.dispatch(new ShowSnackBar(message, 'Dismiss')); + this.snackBarService.show(message, 'Dismiss'); // Also attempt to fetch the service instance, this will update the `last operation` value to `delete` and `in progress` this.store.dispatch(new GetServiceInstance(serviceInstanceGuid, cfGuid)); } diff --git a/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component.ts b/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component.ts index 3d0f72fa4c..75402fd26f 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component.ts @@ -3,11 +3,11 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { Subscription } from 'rxjs'; -import { ShowSnackBar } from '../../../../../store/src/actions/snackBar.actions'; import { EndpointOnlyAppState } from '../../../../../store/src/app-state'; import { EndpointsService } from '../../../core/endpoints.service'; import { MarkdownPreviewComponent } from '../../../shared/components/markdown-preview/markdown-preview.component'; import { SidePanelService } from '../../../shared/services/side-panel.service'; +import { SnackBarService } from '../../../shared/services/snackbar.service'; import { ConnectEndpointConfig, ConnectEndpointService } from '../connect.service'; @@ -30,11 +30,12 @@ export class ConnectEndpointDialogComponent implements OnDestroy { private store: Store, endpointsService: EndpointsService, private sidePanelService: SidePanelService, + private snackBarService: SnackBarService, ) { this.connectService = new ConnectEndpointService(store, endpointsService, data); this.hasConnected = this.connectService.hasConnected$.subscribe(() => { - this.store.dispatch(new ShowSnackBar(`Connected endpoint '${this.data.name}'`)); + this.snackBarService.show(`Connected endpoint '${this.data.name}'`); this.dialogRef.close(); }); } diff --git a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts index a7351064d5..91491b642b 100644 --- a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts @@ -7,7 +7,6 @@ import { Observable } from 'rxjs'; import { filter, map, pairwise, withLatestFrom } from 'rxjs/operators'; import { GetAllEndpoints, RegisterEndpoint } from '../../../../../../store/src/actions/endpoint.actions'; -import { ShowSnackBar } from '../../../../../../store/src/actions/snackBar.actions'; import { GeneralEntityAppState } from '../../../../../../store/src/app-state'; import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../../../../../store/src/base-entity-schemas'; import { EndpointsEffect } from '../../../../../../store/src/effects/endpoint.effects'; @@ -20,6 +19,7 @@ import { getAPIRequestDataState, selectUpdateInfo } from '../../../../../../stor import { selectPaginationState } from '../../../../../../store/src/selectors/pagination.selectors'; import { getIdFromRoute } from '../../../../core/utils.service'; import { IStepperStep, StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; +import { SnackBarService } from '../../../../shared/services/snackbar.service'; import { ConnectEndpointConfig } from '../../connect.service'; import { getFullEndpointApiUrl, getSSOClientRedirectURI } from '../../endpoint-helpers'; @@ -60,7 +60,11 @@ export class CreateEndpointCfStep1Component implements IStepperStep, AfterConten private endpointEntityKey = entityCatalog.getEntityKey(STRATOS_ENDPOINT_TYPE, endpointSchemaKey); - constructor(private store: Store, activatedRoute: ActivatedRoute, ) { + constructor( + private store: Store, + activatedRoute: ActivatedRoute, + private snackBarService: SnackBarService, + ) { this.existingEndpoints = store.select(selectPaginationState(this.endpointEntityKey, GetAllEndpoints.storeKey)) .pipe( @@ -116,7 +120,7 @@ export class CreateEndpointCfStep1Component implements IStepperStep, AfterConten ssoAllowed: this.ssoAllowedField ? !!this.ssoAllowedField.value : false }; if (!result.error) { - this.store.dispatch(new ShowSnackBar(`Successfully registered '${this.nameField.value}'`)); + this.snackBarService.show(`Successfully registered '${this.nameField.value}'`); } const success = !result.error; return { diff --git a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts index 7992db8c39..9ecf211ded 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts @@ -10,7 +10,6 @@ import { ViewChild, ViewContainerRef, } from '@angular/core'; -import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar'; import { Store } from '@ngrx/store'; import { combineLatest, Subscription } from 'rxjs'; import { delay, first, map, tap } from 'rxjs/operators'; @@ -32,6 +31,7 @@ import { EndpointsListConfigService, } from '../../../shared/components/list/list-types/endpoint/endpoints-list-config.service'; import { ListConfig } from '../../../shared/components/list/list.component.types'; +import { SnackBarService } from '../../../shared/services/snackbar.service'; @Component({ selector: 'app-endpoints-page', @@ -49,7 +49,6 @@ export class EndpointsPageComponent implements AfterViewInit, OnDestroy, OnInit @ViewChild('customNoEndpoints', { read: ViewContainerRef, static: true }) customNoEndpointsContainer; customContentComponentRef: ComponentRef; - private snackBarRef: MatSnackBarRef; private snackBarText = { message: `There are no connected endpoints, connect with your personal credentials to get started.`, action: 'Got it' @@ -62,7 +61,7 @@ export class EndpointsPageComponent implements AfterViewInit, OnDestroy, OnInit public store: Store, private ngZone: NgZone, private resolver: ComponentFactoryResolver, - private snackBar: MatSnackBar, + private snackBarService: SnackBarService, cs: CustomizationService ) { this.customizations = cs.get(); @@ -103,10 +102,10 @@ export class EndpointsPageComponent implements AfterViewInit, OnDestroy, OnInit } private showSnackBar(show: boolean) { - if (!this.snackBarRef && show) { - this.snackBarRef = this.snackBar.open(this.snackBarText.message, this.snackBarText.action, { duration: 20000 }); - } else if (this.snackBarRef && !show) { - this.snackBarRef.dismiss(); + if (show) { + this.snackBarService.show(this.snackBarText.message, this.snackBarText.action, 20000); + } else { + this.snackBarService.hide(); } } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts index e1e7a7aaf7..25f9131be8 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts @@ -6,7 +6,6 @@ import { map, pairwise } from 'rxjs/operators'; import { DisconnectEndpoint, UnregisterEndpoint } from '../../../../../../../store/src/actions/endpoint.actions'; import { RouterNav } from '../../../../../../../store/src/actions/router.actions'; -import { ShowSnackBar } from '../../../../../../../store/src/actions/snackBar.actions'; import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions'; import { AppState } from '../../../../../../../store/src/app-state'; import { STRATOS_ENDPOINT_TYPE } from '../../../../../../../store/src/base-entity-schemas'; @@ -21,6 +20,7 @@ import { StratosCurrentUserPermissions } from '../../../../../core/permissions/s import { ConnectEndpointDialogComponent, } from '../../../../../features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component'; +import { SnackBarService } from '../../../../services/snackbar.service'; import { ConfirmationDialogConfig } from '../../../confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../confirmation-dialog.service'; import { IListAction } from '../../list.component.types'; @@ -50,6 +50,7 @@ export class EndpointListHelper { private currentUserPermissionsService: CurrentUserPermissionsService, private confirmDialog: ConfirmationDialogService, private log: LoggerService, + private snackBarService: SnackBarService, ) { } endpointActions(): IListAction[] { @@ -65,7 +66,7 @@ export class EndpointListHelper { this.confirmDialog.open(confirmation, () => { this.store.dispatch(new DisconnectEndpoint(item.guid, item.cnsi_type)); this.handleUpdateAction(item, EndpointsEffect.disconnectingKey, ([oldVal, newVal]) => { - this.store.dispatch(new ShowSnackBar(`Disconnected endpoint '${item.name}'`)); + this.snackBarService.show(`Disconnected endpoint '${item.name}'`); this.store.dispatch(new GetSystemInfo()); }); }); @@ -114,7 +115,7 @@ export class EndpointListHelper { this.confirmDialog.open(confirmation, () => { this.store.dispatch(new UnregisterEndpoint(item.guid, item.cnsi_type)); this.handleDeleteAction(item, ([oldVal, newVal]) => { - this.store.dispatch(new ShowSnackBar(`Unregistered ${item.name}`)); + this.snackBarService.show(`Unregistered ${item.name}`); }); }); }, diff --git a/src/frontend/packages/core/src/shared/services/snackbar.service.ts b/src/frontend/packages/core/src/shared/services/snackbar.service.ts new file mode 100644 index 0000000000..13ba4eb2c6 --- /dev/null +++ b/src/frontend/packages/core/src/shared/services/snackbar.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar'; + +import { SnackBarReturnComponent } from '../components/snackbar-return/snackbar-return.component'; + +/** + * Servicve for showing snackbars + */ +@Injectable({ + providedIn: 'root', +}) +export class SnackBarService { + + constructor(public snackBar: MatSnackBar) {} + + private snackBars: MatSnackBarRef[] = []; + + public show(message: string, closeMessage?: string, duration: number = 5000) { + this.snackBars.push(this.snackBar.open(message, closeMessage, { + duration: closeMessage ? null :duration + })); + } + + public showReturn(message: string, returnUrl: string, returnLabel: string) { + this.snackBars.push(this.snackBar.openFromComponent(SnackBarReturnComponent, { + data: { message, returnUrl, returnLabel } + })); + } + + public hide() { + this.snackBars.forEach(snackBar => snackBar.dismiss()); + } +} diff --git a/src/frontend/packages/store/src/actions/snackBar.actions.ts b/src/frontend/packages/store/src/actions/snackBar.actions.ts deleted file mode 100644 index bee18d3e57..0000000000 --- a/src/frontend/packages/store/src/actions/snackBar.actions.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Action } from '@ngrx/store'; - -export const SHOW_SNACK_BAR = '[SnackBar] Show'; -export const SHOW_RETURN_SNACK_BAR = '[SnackBar] Show returns'; -export const HIDE_SNACK_BAR = '[SnackBar] Hide'; - -export class ShowSnackBar implements Action { - constructor( - public message: string, - public closeMessage: string = null - ) { - } - type = SHOW_SNACK_BAR; -} - -export class ShowReturnSnackBar implements Action { - constructor( - public message: string, - public returnRouterUrl: string, - public returnLabel: string - ) { - } - type = SHOW_RETURN_SNACK_BAR; -} - -export class HideSnackBar implements Action { - type = HIDE_SNACK_BAR; -} diff --git a/src/frontend/packages/store/src/effects/snackBar.effects.spec.ts b/src/frontend/packages/store/src/effects/snackBar.effects.spec.ts deleted file mode 100644 index 69c2b8924c..0000000000 --- a/src/frontend/packages/store/src/effects/snackBar.effects.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { inject, TestBed } from '@angular/core/testing'; -import { MatDialog } from '@angular/material/dialog'; -import { Store } from '@ngrx/store'; - -import { CoreModule } from '../../../core/src/core/core.module'; -import { EndpointsPageComponent } from '../../../core/src/features/endpoints/endpoints-page/endpoints-page.component'; -import { SharedModule } from '../../../core/src/shared/shared.module'; -import { ShowSnackBar } from './../actions/snackBar.actions'; -import { AppStoreModule } from './../store.module'; - -describe('SnackBarEffect', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - declarations: [EndpointsPageComponent], - imports: [ - CommonModule, - CoreModule, - SharedModule, - AppStoreModule - ] - }) - .compileComponents(); - }); - - it('Should open a dialog', () => { - inject([Store, MatDialog], (store: Store, dialog: MatDialog) => { - store.dispatch(new ShowSnackBar('Test')); - expect(dialog.openDialogs[0]).toBeDefined(); - }); - }); -}); diff --git a/src/frontend/packages/store/src/effects/snackBar.effects.ts b/src/frontend/packages/store/src/effects/snackBar.effects.ts deleted file mode 100644 index 5f6a2540e4..0000000000 --- a/src/frontend/packages/store/src/effects/snackBar.effects.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Injectable } from '@angular/core'; -import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar'; -import { Actions, Effect, ofType } from '@ngrx/effects'; -import { map } from 'rxjs/operators'; - -import { SnackBarReturnComponent } from '../../../core/src/shared/components/snackbar-return/snackbar-return.component'; -import { - HIDE_SNACK_BAR, - HideSnackBar, - SHOW_RETURN_SNACK_BAR, - SHOW_SNACK_BAR, - ShowReturnSnackBar, - ShowSnackBar, -} from '../actions/snackBar.actions'; - - -@Injectable() -export class SnackBarEffects { - constructor( - private actions$: Actions, - public snackBar: MatSnackBar - ) { } - - private snackBars: MatSnackBarRef[] = []; - - @Effect({ dispatch: false }) showSnackBar$ = this.actions$.pipe( - ofType(SHOW_SNACK_BAR), - map(action => this.snackBars.push(this.snackBar.open(action.message, action.closeMessage, { - duration: action.closeMessage ? null : 5000 - })))); - - @Effect({ dispatch: false }) showReturnSnackBar$ = this.actions$.pipe( - ofType(SHOW_RETURN_SNACK_BAR), - map(action => this.snackBars.push(this.snackBar.openFromComponent(SnackBarReturnComponent, { - data: { message: action.message, returnUrl: action.returnRouterUrl, returnLabel: action.returnLabel } - })))); - - @Effect({ dispatch: false }) hideSnackBar$ = this.actions$.pipe( - ofType(HIDE_SNACK_BAR), - map(() => this.snackBars.forEach(snackBar => snackBar.dismiss())) - ); -} diff --git a/src/frontend/packages/store/src/store.module.ts b/src/frontend/packages/store/src/store.module.ts index d66eb95791..794355dc3a 100644 --- a/src/frontend/packages/store/src/store.module.ts +++ b/src/frontend/packages/store/src/store.module.ts @@ -14,7 +14,6 @@ import { PermissionsEffects } from './effects/permissions.effect'; import { RecursiveDeleteEffect } from './effects/recursive-entity-delete.effect'; import { RouterEffect } from './effects/router.effects'; import { SetClientFilterEffect } from './effects/set-client-filter.effect'; -import { SnackBarEffects } from './effects/snackBar.effects'; import { SystemEffects } from './effects/system.effects'; import { UAASetupEffect } from './effects/uaa-setup.effects'; import { UserFavoritesEffect } from './effects/user-favorites-effect'; @@ -41,7 +40,6 @@ import { AppReducersModule } from './reducers.module'; ActionHistoryEffect, RouterEffect, SystemEffects, - SnackBarEffects, SetClientFilterEffect, MetricsEffect, UserProfileEffect, From 5da1c512a84dbf5cc6054db04b336812e58c66b6 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 08:50:09 +0100 Subject: [PATCH 46/82] Remove pathget --- .../store/src/reducers/api-request-reducer/request-helpers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frontend/packages/store/src/reducers/api-request-reducer/request-helpers.ts b/src/frontend/packages/store/src/reducers/api-request-reducer/request-helpers.ts index ae52213fd9..900140b12a 100644 --- a/src/frontend/packages/store/src/reducers/api-request-reducer/request-helpers.ts +++ b/src/frontend/packages/store/src/reducers/api-request-reducer/request-helpers.ts @@ -1,6 +1,5 @@ import { Store } from '@ngrx/store'; -import { pathGet } from '../../../../core/src/core/utils.service'; import { APIResponse } from '../../actions/request.actions'; import { BaseRequestState, GeneralAppState } from '../../app-state'; import { BaseEntityRequestAction } from '../../entity-catalog/action-orchestrator/action-orchestrator'; @@ -82,7 +81,7 @@ export function createRequestStateFromResponse( export type ApiRequestTypes = 'fetch' | 'update' | 'create' | 'delete'; export function getRequestTypeFromMethod(action: EntityRequestAction): ApiRequestTypes { - let method = pathGet('options.method', action); + let method = action.options ? action.options.method : undefined; if (typeof method === 'string') { method = method.toString().toLowerCase(); if (method === 'post') { From bfea4582dc964f195de2c5eef470d04d4d3e3248 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 09:06:23 +0100 Subject: [PATCH 47/82] Remove more store -> core dependencies --- .../packages/store/src/actions/metrics-api.actions.ts | 3 +-- src/frontend/packages/store/src/actions/metrics.actions.ts | 4 +--- src/frontend/packages/store/src/effects/auth.effects.ts | 4 +--- .../packages/store/src/effects/permissions.effect.ts | 6 ++---- .../packages/store/src/effects/user-favorites-effect.ts | 5 ++--- .../packages/store/src/effects/user-profile.effects.ts | 4 +--- .../entity-request-pipeline/pipline-http-client.service.ts | 4 +--- src/frontend/packages/store/src/jetstream.ts | 5 +++++ 8 files changed, 14 insertions(+), 21 deletions(-) create mode 100644 src/frontend/packages/store/src/jetstream.ts diff --git a/src/frontend/packages/store/src/actions/metrics-api.actions.ts b/src/frontend/packages/store/src/actions/metrics-api.actions.ts index 2fe8232094..6b084587a6 100644 --- a/src/frontend/packages/store/src/actions/metrics-api.actions.ts +++ b/src/frontend/packages/store/src/actions/metrics-api.actions.ts @@ -1,12 +1,11 @@ import { Action } from '@ngrx/store'; -import { environment } from '../../../core/src/environments/environment'; +import { proxyAPIVersion } from '../jetstream'; export const METRIC_API_START = '[Metrics] API Start'; export const METRIC_API_SUCCESS = '[Metrics] API Success'; export const METRIC_API_FAILED = '[Metrics] API Failed'; -const { proxyAPIVersion } = environment; export const MetricAPIQueryTypes = { TARGETS: 'targets', diff --git a/src/frontend/packages/store/src/actions/metrics.actions.ts b/src/frontend/packages/store/src/actions/metrics.actions.ts index 43b068a14d..3ea3b265a4 100644 --- a/src/frontend/packages/store/src/actions/metrics.actions.ts +++ b/src/frontend/packages/store/src/actions/metrics.actions.ts @@ -1,14 +1,12 @@ import { metricEntityType } from '../../../core/src/base-entity-schemas'; -import { environment } from '../../../core/src/environments/environment'; import { MetricQueryType } from '../../../core/src/shared/services/metrics-range-selector.types'; +import { proxyAPIVersion } from '../jetstream'; import { EntityRequestAction } from '../types/request.types'; export const METRICS_START = '[Metrics] Fetch Start'; export const METRICS_START_SUCCESS = '[Metrics] Fetch Succeeded'; export const METRICS_START_FAILED = '[Metrics] Fetch Failed'; -const { proxyAPIVersion } = environment; - export interface IMetricQueryConfigParams { window?: string; [key: string]: string | number; diff --git a/src/frontend/packages/store/src/effects/auth.effects.ts b/src/frontend/packages/store/src/effects/auth.effects.ts index 38c8883ba8..8cd9810cc3 100644 --- a/src/frontend/packages/store/src/effects/auth.effects.ts +++ b/src/frontend/packages/store/src/effects/auth.effects.ts @@ -4,7 +4,6 @@ import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, map, mergeMap, switchMap, tap } from 'rxjs/operators'; -import { LoggerService } from '../../../core/src/core/logger.service'; import { BrowserStandardEncoder } from '../../../core/src/helper'; import { InvalidSession, @@ -44,7 +43,6 @@ export class AuthEffect { private http: HttpClient, private actions$: Actions, private store: Store, - private logger: LoggerService ) { } @Effect() loginRequest$ = this.actions$.pipe( @@ -164,7 +162,7 @@ export class AuthEffect { const dashboardData = JSON.parse(storage.getItem(sessionId)); store.dispatch(new HydrateDashboardStateAction(dashboardData)); } catch (e) { - this.logger.warn('Failed to parse user settings from session storage, consider clearing them manually', e); + console.warn('Failed to parse user settings from session storage, consider clearing them manually', e); } } } diff --git a/src/frontend/packages/store/src/effects/permissions.effect.ts b/src/frontend/packages/store/src/effects/permissions.effect.ts index bb890b00a7..37a1d6635c 100644 --- a/src/frontend/packages/store/src/effects/permissions.effect.ts +++ b/src/frontend/packages/store/src/effects/permissions.effect.ts @@ -5,7 +5,6 @@ import { Action, Store } from '@ngrx/store'; import { combineLatest, EMPTY, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; -import { LoggerService } from '../../../core/src/core/logger.service'; import { CONNECT_ENDPOINTS_SUCCESS, EndpointActionComplete } from '../actions/endpoint.actions'; import { GET_CURRENT_USER_RELATIONS, @@ -27,7 +26,6 @@ export class PermissionsEffects { private httpClient: HttpClient, private actions$: Actions, private store: Store, - private logService: LoggerService ) { } @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( @@ -44,7 +42,7 @@ export class PermissionsEffects { ); }), catchError(err => { - this.logService.warn('Failed to fetch current user permissions: ', err); + console.warn('Failed to fetch current user permissions: ', err); return of(failedAction); }) ); @@ -66,7 +64,7 @@ export class PermissionsEffects { ); }), catchError(err => { - this.logService.warn('Failed to fetch current user permissions after endpoint connected: ', err); + console.warn('Failed to fetch current user permissions after endpoint connected: ', err); return of(failedAction); }) ); diff --git a/src/frontend/packages/store/src/effects/user-favorites-effect.ts b/src/frontend/packages/store/src/effects/user-favorites-effect.ts index deebce83a7..d9fb2c53e8 100644 --- a/src/frontend/packages/store/src/effects/user-favorites-effect.ts +++ b/src/frontend/packages/store/src/effects/user-favorites-effect.ts @@ -5,9 +5,7 @@ import { Store } from '@ngrx/store'; import { catchError, first, map, mergeMap, switchMap } from 'rxjs/operators'; import { userFavoritesEntitySchema } from '../../../core/src/base-entity-schemas'; -import { entityCatalog } from '../entity-catalog/entity-catalog'; import { UserFavoriteManager } from '../../../core/src/core/user-favorite-manager'; -import { environment } from '../../../core/src/environments/environment.prod'; import { ClearPaginationOfEntity } from '../actions/pagination.actions'; import { GetUserFavoritesAction, @@ -28,12 +26,13 @@ import { UpdateUserFavoriteMetadataSuccessAction, } from '../actions/user-favourites-actions/update-user-favorite-metadata-action'; import { DispatchOnlyAppState } from '../app-state'; +import { entityCatalog } from '../entity-catalog/entity-catalog'; +import { proxyAPIVersion } from '../jetstream'; import { NormalizedResponse } from '../types/api.types'; import { PaginatedAction } from '../types/pagination.types'; import { WrapperRequestActionSuccess } from '../types/request.types'; import { IFavoriteMetadata, UserFavorite, userFavoritesPaginationKey } from '../types/user-favorites.types'; -const { proxyAPIVersion } = environment; const favoriteUrlPath = `/pp/${proxyAPIVersion}/favorites`; diff --git a/src/frontend/packages/store/src/effects/user-profile.effects.ts b/src/frontend/packages/store/src/effects/user-profile.effects.ts index 745d4e11cc..3f32416407 100644 --- a/src/frontend/packages/store/src/effects/user-profile.effects.ts +++ b/src/frontend/packages/store/src/effects/user-profile.effects.ts @@ -5,7 +5,6 @@ import { Store } from '@ngrx/store'; import { catchError, mergeMap, switchMap } from 'rxjs/operators'; import { userProfileEntitySchema } from '../../../core/src/base-entity-schemas'; -import { environment } from '../../../core/src/environments/environment'; import { FetchUserProfileAction, GET_USERPROFILE, @@ -15,6 +14,7 @@ import { UpdateUserProfileAction, } from '../actions/user-profile.actions'; import { entityCatalog } from '../entity-catalog/entity-catalog'; +import { proxyAPIVersion } from '../jetstream'; import { rootUpdatingKey } from '../reducers/api-request-reducer/types'; import { UserProfileInfo } from '../types/user-profile.types'; import { DispatchOnlyAppState } from './../app-state'; @@ -26,8 +26,6 @@ import { } from './../types/request.types'; -const { proxyAPIVersion } = environment; - export const userProfilePasswordUpdatingKey = 'password'; @Injectable() diff --git a/src/frontend/packages/store/src/entity-request-pipeline/pipline-http-client.service.ts b/src/frontend/packages/store/src/entity-request-pipeline/pipline-http-client.service.ts index 863ac58cef..7690f07da1 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/pipline-http-client.service.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/pipline-http-client.service.ts @@ -4,14 +4,12 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { filter, first, map, mergeMap } from 'rxjs/operators'; -import { environment } from '../../../core/src/environments/environment'; import { InternalAppState } from '../app-state'; import { StratosCatalogEndpointEntity } from '../entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { IStratosEndpointDefinition } from '../entity-catalog/entity-catalog.types'; +import { cfAPIVersion, proxyAPIVersion } from '../jetstream'; import { connectedEndpointsOfTypesSelector, endpointOfTypeSelector } from '../selectors/endpoint.selectors'; -const { proxyAPIVersion, cfAPIVersion } = environment; - @Injectable() export class PipelineHttpClient { diff --git a/src/frontend/packages/store/src/jetstream.ts b/src/frontend/packages/store/src/jetstream.ts new file mode 100644 index 0000000000..dc30c9a4a0 --- /dev/null +++ b/src/frontend/packages/store/src/jetstream.ts @@ -0,0 +1,5 @@ +// API Version to use when making back-end API requests to Jetstraam +export const proxyAPIVersion = 'v1'; + +// CF API Version +export const cfAPIVersion = 'v2'; From 7b885af794bc125f2f37cdbd4981acee5b9a5048 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 09:11:20 +0100 Subject: [PATCH 48/82] Move extension-types to store --- .../auth-forms/credentials-auth-form.component.ts | 5 +++-- .../auth-forms/none-auth-form.component.ts | 3 ++- .../auth-forms/sso-auth-form.component.ts | 3 ++- .../connect-endpoint/connect-endpoint.component.ts | 3 +-- .../core/src/features/endpoints/connect.service.ts | 2 +- .../packages/core/src/features/endpoints/endpoint-auth.ts | 7 ++++--- .../packages/store/src/actions/endpoint.actions.ts | 2 +- .../packages/store/src/effects/endpoint.effects.ts | 2 +- .../store/src/entity-catalog/entity-catalog.types.ts | 2 +- .../src/core/extension => store/src}/extension-types.ts | 0 src/frontend/packages/store/src/types/endpoint.types.ts | 2 +- 11 files changed, 17 insertions(+), 14 deletions(-) rename src/frontend/packages/{core/src/core/extension => store/src}/extension-types.ts (100%) diff --git a/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/credentials-auth-form.component.ts b/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/credentials-auth-form.component.ts index cdf3c405d0..b585c0ab96 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/credentials-auth-form.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/credentials-auth-form.component.ts @@ -1,6 +1,7 @@ -import { FormGroup } from '@angular/forms'; import { Component, Input } from '@angular/core'; -import { IAuthForm } from '../../../../core/extension/extension-types'; +import { FormGroup } from '@angular/forms'; + +import { IAuthForm } from '../../../../../../store/src/extension-types'; @Component({ selector: 'app-credentials-auth-form', diff --git a/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/none-auth-form.component.ts b/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/none-auth-form.component.ts index c76f5a954c..3b6bb325ee 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/none-auth-form.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/none-auth-form.component.ts @@ -1,6 +1,7 @@ import { Component, Input } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { IAuthForm } from '../../../../core/extension/extension-types'; + +import { IAuthForm } from '../../../../../../store/src/extension-types'; @Component({ selector: 'app-none-auth-form', diff --git a/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/sso-auth-form.component.ts b/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/sso-auth-form.component.ts index bdac43f89e..83243a24ec 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/sso-auth-form.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect-endpoint-dialog/auth-forms/sso-auth-form.component.ts @@ -1,6 +1,7 @@ import { Component, Input } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { IAuthForm } from '../../../../core/extension/extension-types'; + +import { IAuthForm } from '../../../../../../store/src/extension-types'; @Component({ selector: 'app-sso-auth-form', diff --git a/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts b/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts index fc355c4928..4bc13f56bb 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts @@ -13,10 +13,9 @@ import { } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Subscription } from 'rxjs'; -import { map } from 'rxjs/operators'; import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; -import { EndpointAuthTypeConfig, IAuthForm, IEndpointAuthComponent } from '../../../core/extension/extension-types'; +import { EndpointAuthTypeConfig, IAuthForm, IEndpointAuthComponent } from '../../../../../store/src/extension-types'; import { safeUnsubscribe } from '../../../core/utils.service'; import { ConnectEndpointConfig, ConnectEndpointData, ConnectEndpointService } from '../connect.service'; import { BaseEndpointAuth } from '../endpoint-auth'; diff --git a/src/frontend/packages/core/src/features/endpoints/connect.service.ts b/src/frontend/packages/core/src/features/endpoints/connect.service.ts index 015ff5b14d..2c3c356ac4 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect.service.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect.service.ts @@ -18,13 +18,13 @@ import { EndpointOnlyAppState } from '../../../../store/src/app-state'; import { EndpointsEffect } from '../../../../store/src/effects/endpoint.effects'; import { SystemEffects } from '../../../../store/src/effects/system.effects'; import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog'; +import { EndpointType } from '../../../../store/src/extension-types'; import { endpointSchemaKey } from '../../../../store/src/helpers/entity-factory'; import { ActionState } from '../../../../store/src/reducers/api-request-reducer/types'; import { selectEntity, selectRequestInfo, selectUpdateInfo } from '../../../../store/src/selectors/api.selectors'; import { EndpointModel } from '../../../../store/src/types/endpoint.types'; import { STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; import { EndpointsService } from '../../core/endpoints.service'; -import { EndpointType } from '../../core/extension/extension-types'; import { safeUnsubscribe } from '../../core/utils.service'; export interface ConnectEndpointConfig { diff --git a/src/frontend/packages/core/src/features/endpoints/endpoint-auth.ts b/src/frontend/packages/core/src/features/endpoints/endpoint-auth.ts index 757b0677e5..9c771119f0 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoint-auth.ts +++ b/src/frontend/packages/core/src/features/endpoints/endpoint-auth.ts @@ -1,9 +1,10 @@ -import { EndpointAuthTypeNames } from './endpoint-helpers'; import { Validators } from '@angular/forms'; -import { EndpointType, EndpointAuthTypeConfig } from '../../core/extension/extension-types'; + +import { EndpointAuthTypeConfig, EndpointType } from '../../../../store/src/extension-types'; import { CredentialsAuthFormComponent } from './connect-endpoint-dialog/auth-forms/credentials-auth-form.component'; -import { SSOAuthFormComponent } from './connect-endpoint-dialog/auth-forms/sso-auth-form.component'; import { NoneAuthFormComponent } from './connect-endpoint-dialog/auth-forms/none-auth-form.component'; +import { SSOAuthFormComponent } from './connect-endpoint-dialog/auth-forms/sso-auth-form.component'; +import { EndpointAuthTypeNames } from './endpoint-helpers'; export abstract class BaseEndpointAuth { static readonly UsernamePassword = { diff --git a/src/frontend/packages/store/src/actions/endpoint.actions.ts b/src/frontend/packages/store/src/actions/endpoint.actions.ts index cd4540b8eb..385d014a96 100644 --- a/src/frontend/packages/store/src/actions/endpoint.actions.ts +++ b/src/frontend/packages/store/src/actions/endpoint.actions.ts @@ -1,7 +1,7 @@ import { Action } from '@ngrx/store'; import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; -import { EndpointType } from '../../../core/src/core/extension/extension-types'; +import { EndpointType } from '../extension-types'; import { endpointSchemaKey } from '../helpers/entity-factory'; import { NormalizedResponse } from '../types/api.types'; import { endpointListKey, EndpointModel, INewlyConnectedEndpointInfo } from '../types/endpoint.types'; diff --git a/src/frontend/packages/store/src/effects/endpoint.effects.ts b/src/frontend/packages/store/src/effects/endpoint.effects.ts index 3ebaf0694a..8e8f228e64 100644 --- a/src/frontend/packages/store/src/effects/endpoint.effects.ts +++ b/src/frontend/packages/store/src/effects/endpoint.effects.ts @@ -5,7 +5,6 @@ import { Store } from '@ngrx/store'; import { catchError, mergeMap } from 'rxjs/operators'; import { STRATOS_ENDPOINT_TYPE } from '../../../core/src/base-entity-schemas'; -import { EndpointType } from '../../../core/src/core/extension/extension-types'; import { BrowserStandardEncoder } from '../../../core/src/helper'; import { CONNECT_ENDPOINTS, @@ -35,6 +34,7 @@ import { GET_SYSTEM_INFO_SUCCESS, GetSystemInfo, GetSystemSuccess } from '../act import { GetUserFavoritesAction } from '../actions/user-favourites-actions/get-user-favorites-action'; import { DispatchOnlyAppState } from '../app-state'; import { entityCatalog } from '../entity-catalog/entity-catalog'; +import { EndpointType } from '../extension-types'; import { endpointSchemaKey } from '../helpers/entity-factory'; import { ApiRequestTypes } from '../reducers/api-request-reducer/request-helpers'; import { NormalizedResponse } from '../types/api.types'; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index 7205f8ff23..a0bba1cf85 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -2,7 +2,6 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { EndpointHealthCheck } from '../../../core/endpoints-health-checks'; -import { EndpointAuthTypeConfig } from '../../../core/src/core/extension/extension-types'; import { FavoritesConfigMapper } from '../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { StratosStatus } from '../../../core/src/shared/shared.types'; import { GeneralEntityAppState } from '../app-state'; @@ -21,6 +20,7 @@ import { import { PaginationPageIteratorConfig, } from '../entity-request-pipeline/pagination-request-base-handlers/pagination-iterator.pipe'; +import { EndpointAuthTypeConfig } from '../extension-types'; import { EntitySchema } from '../helpers/entity-schema'; import { UserFavorite } from '../types/user-favorites.types'; diff --git a/src/frontend/packages/core/src/core/extension/extension-types.ts b/src/frontend/packages/store/src/extension-types.ts similarity index 100% rename from src/frontend/packages/core/src/core/extension/extension-types.ts rename to src/frontend/packages/store/src/extension-types.ts diff --git a/src/frontend/packages/store/src/types/endpoint.types.ts b/src/frontend/packages/store/src/types/endpoint.types.ts index 317c1aab7e..25ccfe3689 100644 --- a/src/frontend/packages/store/src/types/endpoint.types.ts +++ b/src/frontend/packages/store/src/types/endpoint.types.ts @@ -1,6 +1,6 @@ -import { EndpointType } from '../../../core/src/core/extension/extension-types'; import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; import { MetricsAPITargets, MetricsStratosInfo } from '../actions/metrics-api.actions'; +import { EndpointType } from '../extension-types'; import { endpointSchemaKey } from '../helpers/entity-factory'; import { RequestSectionKeys, TRequestTypeKeys } from '../reducers/api-request-reducer/types'; From 19b013d2bee445ab970b8cfc2776e11a422235e8 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 09:17:20 +0100 Subject: [PATCH 49/82] Move favourite mgr and helper from core to store --- .../packages/store/src/selectors/favorite-groups.selectors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/packages/store/src/selectors/favorite-groups.selectors.ts b/src/frontend/packages/store/src/selectors/favorite-groups.selectors.ts index a1b3158b2e..28743830a9 100644 --- a/src/frontend/packages/store/src/selectors/favorite-groups.selectors.ts +++ b/src/frontend/packages/store/src/selectors/favorite-groups.selectors.ts @@ -1,11 +1,11 @@ import { compose } from '@ngrx/store'; import { STRATOS_ENDPOINT_TYPE, userFavoritesEntitySchema } from '../../../core/src/base-entity-schemas'; -import { deriveEndpointFavoriteFromFavorite } from '../../../core/src/core/user-favorite-helpers'; import { InternalAppState, IRequestEntityTypeState } from '../app-state'; import { entityCatalog } from '../entity-catalog/entity-catalog'; import { IUserFavoriteGroup, IUserFavoritesGroups, IUserFavoritesGroupsState } from '../types/favorite-groups.types'; import { IFavoriteMetadata, UserFavorite } from '../types/user-favorites.types'; +import { deriveEndpointFavoriteFromFavorite } from '../user-favorite-helpers'; const favoritesEntityKey = entityCatalog.getEntityKey(STRATOS_ENDPOINT_TYPE, userFavoritesEntitySchema.entityType); From aab424d352e50ad773d58e20a986c43798021f41 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 09:31:30 +0100 Subject: [PATCH 50/82] Move user fav manager and helper to store package --- .../application-tabs-base.component.ts | 2 +- .../cloud-foundry-organization-base.component.ts | 2 +- .../cloud-foundry-space-base.component.ts | 2 +- .../list/list-types/app/card/card-app.component.ts | 2 +- .../cf-orgs/cf-org-card/cf-org-card.component.ts | 2 +- .../cf-spaces/cf-space-card/cf-space-card.component.ts | 2 +- .../meta-card/meta-card-base/meta-card.component.spec.ts | 2 +- .../meta-card/meta-card-base/meta-card.component.ts | 2 +- .../user-favorites-groups.reducer.spec.ts | 2 +- .../user-favorites-groups.reducer.ts | 2 +- .../{core/src/core => store/src}/user-favorite-helpers.ts | 8 ++++---- .../{core/src/core => store/src}/user-favorite-manager.ts | 0 12 files changed, 14 insertions(+), 14 deletions(-) rename src/frontend/packages/{core/src/core => store/src}/user-favorite-helpers.ts (75%) rename src/frontend/packages/{core/src/core => store/src}/user-favorite-manager.ts (100%) diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts index ca2194ba6e..d6e3c44434 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts @@ -15,7 +15,6 @@ import { StratosTabType, } from '../../../../../../core/src/core/extension/extension-service'; import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; -import { getFavoriteFromEntity } from '../../../../../../core/src/core/user-favorite-helpers'; import { safeUnsubscribe } from '../../../../../../core/src/core/utils.service'; import { IPageSideNavTab } from '../../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { @@ -31,6 +30,7 @@ import { ActionState } from '../../../../../../store/src/reducers/api-request-re import { endpointEntitiesSelector } from '../../../../../../store/src/selectors/endpoint.selectors'; import { APIResource } from '../../../../../../store/src/types/api.types'; import { EndpointModel } from '../../../../../../store/src/types/endpoint.types'; +import { getFavoriteFromEntity } from '../../../../../../store/src/user-favorite-helpers'; import { UpdateExistingApplication } from '../../../../actions/application.actions'; import { IApp, IOrganization, ISpace } from '../../../../cf-api.types'; import { CF_ENDPOINT_TYPE } from '../../../../cf-types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-base/cloud-foundry-organization-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-base/cloud-foundry-organization-base.component.ts index 0c83c22d0f..91c27c3f31 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-base/cloud-foundry-organization-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-base/cloud-foundry-organization-base.component.ts @@ -11,7 +11,6 @@ import { StratosActionType, StratosTabType, } from '../../../../../../../core/src/core/extension/extension-service'; -import { getFavoriteFromEntity } from '../../../../../../../core/src/core/user-favorite-helpers'; import { environment } from '../../../../../../../core/src/environments/environment.prod'; import { IPageSideNavTab } from '../../../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { @@ -20,6 +19,7 @@ import { import { IHeaderBreadcrumb } from '../../../../../../../core/src/shared/components/page-header/page-header.types'; import { EntitySchema } from '../../../../../../../store/src/helpers/entity-schema'; import { UserFavorite } from '../../../../../../../store/src/types/user-favorites.types'; +import { getFavoriteFromEntity } from '../../../../../../../store/src/user-favorite-helpers'; import { cfEntityFactory } from '../../../../../cf-entity-factory'; import { CF_ENDPOINT_TYPE } from '../../../../../cf-types'; import { CfUserService } from '../../../../../shared/data-services/cf-user.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts index c8c42c5c5a..7f5e455ecc 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts @@ -13,7 +13,6 @@ import { StratosActionType, StratosTabType, } from '../../../../../../../../core/src/core/extension/extension-service'; -import { getFavoriteFromEntity } from '../../../../../../../../core/src/core/user-favorite-helpers'; import { environment } from '../../../../../../../../core/src/environments/environment.prod'; import { IPageSideNavTab } from '../../../../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -23,6 +22,7 @@ import { import { IHeaderBreadcrumb } from '../../../../../../../../core/src/shared/components/page-header/page-header.types'; import { RouterNav } from '../../../../../../../../store/src/actions/router.actions'; import { UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; +import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; import { CF_ENDPOINT_TYPE } from '../../../../../../cf-types'; import { CfUserService } from '../../../../../../shared/data-services/cf-user.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts index 8236ed5d64..3a450bdde4 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts @@ -6,7 +6,6 @@ import { map, startWith } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { applicationEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; import { IAppFavMetadata } from '../../../../../../../../cloud-foundry/src/cf-metadata-types'; -import { getFavoriteFromEntity } from '../../../../../../../../core/src/core/user-favorite-helpers'; import { FavoritesConfigMapper, } from '../../../../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; @@ -14,6 +13,7 @@ import { CardCell } from '../../../../../../../../core/src/shared/components/lis import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../core/src/shared/shared.types'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; +import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { IApp, ISpace } from '../../../../../../cf-api.types'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; import { CF_ENDPOINT_TYPE } from '../../../../../../cf-types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts index c8275787bf..f146e81e1c 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts @@ -8,7 +8,6 @@ import { organizationEntityType } from '../../../../../../../../cloud-foundry/sr import { CurrentUserPermissionsService, } from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; -import { getFavoriteFromEntity } from '../../../../../../../../core/src/core/user-favorite-helpers'; import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -26,6 +25,7 @@ import { PaginationMonitorFactory } from '../../../../../../../../store/src/moni import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { EndpointUser } from '../../../../../../../../store/src/types/endpoint.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; +import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { IApp, IOrganization } from '../../../../../../cf-api.types'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; import { getStartedAppInstanceCount } from '../../../../../../cf.helpers'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts index d124f0d47e..890fdf2f98 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts @@ -9,7 +9,6 @@ import { ISpaceFavMetadata } from '../../../../../../../../cloud-foundry/src/cf- import { CurrentUserPermissionsService, } from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; -import { getFavoriteFromEntity } from '../../../../../../../../core/src/core/user-favorite-helpers'; import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; @@ -27,6 +26,7 @@ import { PaginationMonitorFactory } from '../../../../../../../../store/src/moni import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { EndpointUser } from '../../../../../../../../store/src/types/endpoint.types'; import { UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; +import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { IApp, ISpace } from '../../../../../../cf-api.types'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; import { CF_ENDPOINT_TYPE } from '../../../../../../cf-types'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts index ed7de6c1dd..d8c56f4960 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts @@ -8,8 +8,8 @@ import { Observable, of } from 'rxjs'; import { EntitySchema } from '../../../../../../../../store/src/helpers/entity-schema'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; +import * as favoriteHelpers from '../../../../../../../../store/src/user-favorite-helpers'; import { CoreTestingModule } from '../../../../../../../test-framework/core-test.modules'; -import * as favoriteHelpers from '../../../../../../core/user-favorite-helpers'; import { UserFavoriteManager } from '../../../../../../core/user-favorite-manager'; import { SharedModule } from '../../../../../shared.module'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../shared.types'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts index 0aec42062f..ced89b65c0 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts @@ -4,7 +4,7 @@ import { first, map, tap } from 'rxjs/operators'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; -import { getFavoriteFromEntity } from '../../../../../../core/user-favorite-helpers'; +import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../shared.types'; import { FavoritesConfigMapper } from '../../../../favorites-meta-card/favorite-config-mapper'; diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/user-favorites-groups.reducer.spec.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/user-favorites-groups.reducer.spec.ts index 0532f4a44d..2d64c4610c 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/user-favorites-groups.reducer.spec.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/user-favorites-groups.reducer.spec.ts @@ -1,4 +1,3 @@ -import { deriveEndpointFavoriteFromFavorite } from '../../../../core/src/core/user-favorite-helpers'; import { GetUserFavoritesAction, GetUserFavoritesFailedAction, @@ -8,6 +7,7 @@ import { RemoveUserFavoriteSuccessAction } from '../../actions/user-favourites-a import { SaveUserFavoriteSuccessAction } from '../../actions/user-favourites-actions/save-user-favorite-action'; import { getDefaultFavoriteGroupsState, IUserFavoritesGroupsState } from '../../types/favorite-groups.types'; import { IEndpointFavMetadata, UserFavorite } from '../../types/user-favorites.types'; +import { deriveEndpointFavoriteFromFavorite } from '../../user-favorite-helpers'; import { userFavoriteGroupsReducer } from './user-favorites-groups.reducer'; const endpointFavorite = () => new UserFavorite( diff --git a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/user-favorites-groups.reducer.ts b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/user-favorites-groups.reducer.ts index 342c061f47..30e33e8c01 100644 --- a/src/frontend/packages/store/src/reducers/current-user-roles-reducer/user-favorites-groups.reducer.ts +++ b/src/frontend/packages/store/src/reducers/current-user-roles-reducer/user-favorites-groups.reducer.ts @@ -1,6 +1,5 @@ import { Action } from '@ngrx/store'; -import { deriveEndpointFavoriteFromFavorite, isEndpointTypeFavorite } from '../../../../core/src/core/user-favorite-helpers'; import { GetUserFavoritesAction, GetUserFavoritesFailedAction, @@ -16,6 +15,7 @@ import { IUserFavoritesGroupsState, } from '../../types/favorite-groups.types'; import { IFavoriteMetadata, UserFavorite } from '../../types/user-favorites.types'; +import { deriveEndpointFavoriteFromFavorite, isEndpointTypeFavorite } from '../../user-favorite-helpers'; export function userFavoriteGroupsReducer( state: IUserFavoritesGroupsState = getDefaultFavoriteGroupsState(), diff --git a/src/frontend/packages/core/src/core/user-favorite-helpers.ts b/src/frontend/packages/store/src/user-favorite-helpers.ts similarity index 75% rename from src/frontend/packages/core/src/core/user-favorite-helpers.ts rename to src/frontend/packages/store/src/user-favorite-helpers.ts index 7a73600412..2033859a4f 100644 --- a/src/frontend/packages/core/src/core/user-favorite-helpers.ts +++ b/src/frontend/packages/store/src/user-favorite-helpers.ts @@ -1,7 +1,7 @@ -import { entityCatalog } from '../../../store/src/entity-catalog/entity-catalog'; -import { IEntityMetadata } from '../../../store/src/entity-catalog/entity-catalog.types'; -import { IFavoriteMetadata, UserFavorite } from '../../../store/src/types/user-favorites.types'; -import { FavoritesConfigMapper } from '../shared/components/favorites-meta-card/favorite-config-mapper'; +import { FavoritesConfigMapper } from '../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; +import { entityCatalog } from './entity-catalog/entity-catalog'; +import { IEntityMetadata } from './entity-catalog/entity-catalog.types'; +import { IFavoriteMetadata, UserFavorite } from './types/user-favorites.types'; export function isEndpointTypeFavorite(favorite: UserFavorite) { return !favorite.entityId; diff --git a/src/frontend/packages/core/src/core/user-favorite-manager.ts b/src/frontend/packages/store/src/user-favorite-manager.ts similarity index 100% rename from src/frontend/packages/core/src/core/user-favorite-manager.ts rename to src/frontend/packages/store/src/user-favorite-manager.ts From f72361ce3ae79ad8f81302998764756b1cf8be81 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 09:35:26 +0100 Subject: [PATCH 51/82] More references --- src/frontend/packages/core/src/app.module.ts | 2 +- .../entity-favorite-star.component.spec.ts | 2 +- .../entity-favorite-star.component.ts | 2 +- .../features/home/home/home-page.component.ts | 4 +-- .../favorites-entity-list.component.ts | 2 +- .../favorites-global-list.component.ts | 2 +- .../favorites-meta-card.component.ts | 2 +- .../meta-card.component.spec.ts | 2 +- .../src/effects/user-favorites-effect.ts | 4 +-- .../store/src/helpers/store-helpers.ts | 2 +- .../store/src/user-favorite-manager.ts | 26 +++++++++---------- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/frontend/packages/core/src/app.module.ts b/src/frontend/packages/core/src/app.module.ts index 7ba9fb46a1..3ff9495574 100644 --- a/src/frontend/packages/core/src/app.module.ts +++ b/src/frontend/packages/core/src/app.module.ts @@ -24,6 +24,7 @@ import { recentlyVisitedSelector } from '../../store/src/selectors/recently-visi import { AppStoreModule } from '../../store/src/store.module'; import { EndpointModel } from '../../store/src/types/endpoint.types'; import { IFavoriteMetadata, UserFavorite } from '../../store/src/types/user-favorites.types'; +import { UserFavoriteManager } from '../../store/src/user-favorite-manager'; import { TabNavService } from '../tab-nav.service'; import { XSRFModule } from '../xsrf.module'; import { AppComponent } from './app.component'; @@ -36,7 +37,6 @@ import { DynamicExtensionRoutes } from './core/extension/dynamic-extension-route import { ExtensionService } from './core/extension/extension-service'; import { getGitHubAPIURL, GITHUB_API_URL } from './core/github.helpers'; import { CurrentUserPermissionsService } from './core/permissions/current-user-permissions.service'; -import { UserFavoriteManager } from './core/user-favorite-manager'; import { CustomImportModule } from './custom-import.module'; import { AboutModule } from './features/about/about.module'; import { DashboardModule } from './features/dashboard/dashboard.module'; diff --git a/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.spec.ts b/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.spec.ts index 5aee8a1959..900bd8ade9 100644 --- a/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.spec.ts +++ b/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.spec.ts @@ -4,11 +4,11 @@ import { BehaviorSubject, of } from 'rxjs'; import { PaginationMonitorFactory } from '../../../../store/src/monitors/pagination-monitor.factory'; import { IFavoriteMetadata, UserFavorite } from '../../../../store/src/types/user-favorites.types'; +import { UserFavoriteManager } from '../../../../store/src/user-favorite-manager'; import { BaseTestModulesNoShared } from '../../../test-framework/core-test.helper'; import { ConfirmationDialogService } from '../../shared/components/confirmation-dialog.service'; import { DialogConfirmComponent } from '../../shared/components/dialog-confirm/dialog-confirm.component'; import { FavoritesConfigMapper } from '../../shared/components/favorites-meta-card/favorite-config-mapper'; -import { UserFavoriteManager } from '../user-favorite-manager'; import { EntityFavoriteStarComponent } from './entity-favorite-star.component'; describe('EntityFavoriteStarComponent', () => { diff --git a/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.ts b/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.ts index 6487ce3708..1aed1b41b0 100644 --- a/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.ts +++ b/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.ts @@ -3,11 +3,11 @@ import { Observable } from 'rxjs'; import { first, tap } from 'rxjs/operators'; import { IFavoriteMetadata, UserFavorite } from '../../../../store/src/types/user-favorites.types'; +import { UserFavoriteManager } from '../../../../store/src/user-favorite-manager'; import { ConfirmationDialogConfig } from '../../shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../shared/components/confirmation-dialog.service'; import { FavoritesConfigMapper } from '../../shared/components/favorites-meta-card/favorite-config-mapper'; import { EndpointsService } from '../endpoints.service'; -import { UserFavoriteManager } from '../user-favorite-manager'; @Component({ selector: 'app-entity-favorite-star', diff --git a/src/frontend/packages/core/src/features/home/home/home-page.component.ts b/src/frontend/packages/core/src/features/home/home/home-page.component.ts index 1c3a977d31..6700b83fa3 100644 --- a/src/frontend/packages/core/src/features/home/home/home-page.component.ts +++ b/src/frontend/packages/core/src/features/home/home/home-page.component.ts @@ -5,12 +5,12 @@ import { first, map } from 'rxjs/operators'; import { RouterNav } from '../../../../../store/src/actions/router.actions'; import { AppState, IRequestEntityTypeState } from '../../../../../store/src/app-state'; +import { EntityCatalogHelpers } from '../../../../../store/src/entity-catalog/entity-catalog.helper'; import { IUserFavoritesGroups } from '../../../../../store/src/types/favorite-groups.types'; import { UserFavorite } from '../../../../../store/src/types/user-favorites.types'; +import { UserFavoriteManager } from '../../../../../store/src/user-favorite-manager'; import { EndpointsService } from '../../../core/endpoints.service'; import { LoggerService } from '../../../core/logger.service'; -import { UserFavoriteManager } from '../../../core/user-favorite-manager'; -import { EntityCatalogHelpers } from '../../../../../store/src/entity-catalog/entity-catalog.helper'; @Component({ selector: 'app-home-page', diff --git a/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts b/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts index d0ea51b21d..31171980d5 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { combineLatest, Observable, ReplaySubject, Subject } from 'rxjs'; import { distinctUntilChanged, map, scan, startWith } from 'rxjs/operators'; -import { IFavoriteEntity } from '../../../core/user-favorite-manager'; +import { IFavoriteEntity } from '../../../../../store/src/user-favorite-manager'; import { FavoritesConfigMapper, IFavoriteTypes } from '../favorites-meta-card/favorite-config-mapper'; diff --git a/src/frontend/packages/core/src/shared/components/favorites-global-list/favorites-global-list.component.ts b/src/frontend/packages/core/src/shared/components/favorites-global-list/favorites-global-list.component.ts index ffd96652f0..aff1a3bb08 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-global-list/favorites-global-list.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-global-list/favorites-global-list.component.ts @@ -10,7 +10,7 @@ import { IFavoritesInfo, IGroupedFavorites, UserFavoriteManager, -} from '../../../core/user-favorite-manager'; +} from '../../../../../store/src/user-favorite-manager'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts index e95dea1c1a..803edbda7a 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts @@ -10,8 +10,8 @@ import { AppState } from '../../../../../store/src/app-state'; import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; import { endpointEntitiesSelector } from '../../../../../store/src/selectors/endpoint.selectors'; import { IFavoriteMetadata, UserFavorite } from '../../../../../store/src/types/user-favorites.types'; +import { IFavoriteEntity } from '../../../../../store/src/user-favorite-manager'; import { userFavoritesEntitySchema } from '../../../base-entity-schemas'; -import { IFavoriteEntity } from '../../../core/user-favorite-manager'; import { isEndpointConnected } from '../../../features/endpoints/connect.service'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../shared.types'; import { ConfirmationDialogConfig } from '../confirmation-dialog.config'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts index d8c56f4960..8800a8a802 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts @@ -9,8 +9,8 @@ import { EntitySchema } from '../../../../../../../../store/src/helpers/entity-s import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import * as favoriteHelpers from '../../../../../../../../store/src/user-favorite-helpers'; +import { UserFavoriteManager } from '../../../../../../../../store/src/user-favorite-manager'; import { CoreTestingModule } from '../../../../../../../test-framework/core-test.modules'; -import { UserFavoriteManager } from '../../../../../../core/user-favorite-manager'; import { SharedModule } from '../../../../../shared.module'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../shared.types'; import { FavoritesConfigMapper } from '../../../../favorites-meta-card/favorite-config-mapper'; diff --git a/src/frontend/packages/store/src/effects/user-favorites-effect.ts b/src/frontend/packages/store/src/effects/user-favorites-effect.ts index deebce83a7..18e3f25fa8 100644 --- a/src/frontend/packages/store/src/effects/user-favorites-effect.ts +++ b/src/frontend/packages/store/src/effects/user-favorites-effect.ts @@ -5,8 +5,6 @@ import { Store } from '@ngrx/store'; import { catchError, first, map, mergeMap, switchMap } from 'rxjs/operators'; import { userFavoritesEntitySchema } from '../../../core/src/base-entity-schemas'; -import { entityCatalog } from '../entity-catalog/entity-catalog'; -import { UserFavoriteManager } from '../../../core/src/core/user-favorite-manager'; import { environment } from '../../../core/src/environments/environment.prod'; import { ClearPaginationOfEntity } from '../actions/pagination.actions'; import { @@ -28,10 +26,12 @@ import { UpdateUserFavoriteMetadataSuccessAction, } from '../actions/user-favourites-actions/update-user-favorite-metadata-action'; import { DispatchOnlyAppState } from '../app-state'; +import { entityCatalog } from '../entity-catalog/entity-catalog'; import { NormalizedResponse } from '../types/api.types'; import { PaginatedAction } from '../types/pagination.types'; import { WrapperRequestActionSuccess } from '../types/request.types'; import { IFavoriteMetadata, UserFavorite, userFavoritesPaginationKey } from '../types/user-favorites.types'; +import { UserFavoriteManager } from '../user-favorite-manager'; const { proxyAPIVersion } = environment; const favoriteUrlPath = `/pp/${proxyAPIVersion}/favorites`; diff --git a/src/frontend/packages/store/src/helpers/store-helpers.ts b/src/frontend/packages/store/src/helpers/store-helpers.ts index 15f69e72db..597e43ecf9 100644 --- a/src/frontend/packages/store/src/helpers/store-helpers.ts +++ b/src/frontend/packages/store/src/helpers/store-helpers.ts @@ -2,11 +2,11 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import { IFavoritesInfo } from '../../../core/src/core/user-favorite-manager'; import { AppState } from '../app-state'; import { MultiActionListEntity } from '../monitors/pagination-monitor'; import { errorFetchingFavoritesSelector, fetchingFavoritesSelector } from '../selectors/favorite-groups.selectors'; import { APIResource } from '../types/api.types'; +import { IFavoritesInfo } from '../user-favorite-manager'; export function getDashboardStateSessionId(username?: string) { diff --git a/src/frontend/packages/store/src/user-favorite-manager.ts b/src/frontend/packages/store/src/user-favorite-manager.ts index 45e4fded8a..102c371206 100644 --- a/src/frontend/packages/store/src/user-favorite-manager.ts +++ b/src/frontend/packages/store/src/user-favorite-manager.ts @@ -3,24 +3,24 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of } from 'rxjs'; import { filter, map, switchMap, tap } from 'rxjs/operators'; -import { ToggleUserFavoriteAction } from '../../../store/src/actions/user-favourites-actions/toggle-user-favorite-action'; -import { GeneralEntityAppState, IRequestEntityTypeState } from '../../../store/src/app-state'; -import { entityCatalog } from '../../../store/src/entity-catalog/entity-catalog'; -import { endpointEntitiesSelector } from '../../../store/src/selectors/endpoint.selectors'; +import { LoggerService } from '../../core/src/core/logger.service'; +import { + FavoritesConfigMapper, + TFavoriteMapperFunction, +} from '../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; +import { ToggleUserFavoriteAction } from './actions/user-favourites-actions/toggle-user-favorite-action'; +import { GeneralEntityAppState, IRequestEntityTypeState } from './app-state'; +import { entityCatalog } from './entity-catalog/entity-catalog'; +import { endpointEntitiesSelector } from './selectors/endpoint.selectors'; import { errorFetchingFavoritesSelector, favoriteEntitiesSelector, favoriteGroupsSelector, fetchingFavoritesSelector, -} from '../../../store/src/selectors/favorite-groups.selectors'; -import { isFavorite } from '../../../store/src/selectors/favorite.selectors'; -import { IUserFavoritesGroups } from '../../../store/src/types/favorite-groups.types'; -import { IEndpointFavMetadata, IFavoriteMetadata, UserFavorite } from '../../../store/src/types/user-favorites.types'; -import { - FavoritesConfigMapper, - TFavoriteMapperFunction, -} from '../shared/components/favorites-meta-card/favorite-config-mapper'; -import { LoggerService } from './logger.service'; +} from './selectors/favorite-groups.selectors'; +import { isFavorite } from './selectors/favorite.selectors'; +import { IUserFavoritesGroups } from './types/favorite-groups.types'; +import { IEndpointFavMetadata, IFavoriteMetadata, UserFavorite } from './types/user-favorites.types'; export interface IFavoriteEntity { type: string; From 4d1e8aaec74f843320295e8ee8281d0dd82efd0f Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 11:20:10 +0100 Subject: [PATCH 52/82] Fix logger service removal --- src/frontend/packages/store/src/effects/permissions.effect.ts | 2 +- .../entity-request-pipeline/entity-request-pipeline.types.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/frontend/packages/store/src/effects/permissions.effect.ts b/src/frontend/packages/store/src/effects/permissions.effect.ts index 37a1d6635c..f5bd82e35c 100644 --- a/src/frontend/packages/store/src/effects/permissions.effect.ts +++ b/src/frontend/packages/store/src/effects/permissions.effect.ts @@ -33,7 +33,7 @@ export class PermissionsEffects { switchMap(action => { const allRequestsCompleted = entityCatalog.getAllBaseEndpointTypes().reduce((res, endpointType) => { if (endpointType.definition.userRolesFetch) { - res.push(endpointType.definition.userRolesFetch([], this.store, this.logService, this.httpClient)); + res.push(endpointType.definition.userRolesFetch([], this.store, this.httpClient)); } return res; }, []); diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts index 46e1d685cd..74975aad4f 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts @@ -2,7 +2,6 @@ import { HttpClient, HttpRequest } from '@angular/common/http'; import { Action, Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { LoggerService } from '../../../core/src/core/logger.service'; import { JetStreamErrorResponse } from '../../../core/src/jetstream.helpers'; import { AppState, GeneralEntityAppState, InternalAppState } from '../app-state'; import { @@ -146,7 +145,6 @@ export interface EntityUserRolesEndpoint { export type EntityUserRolesFetch = ( endpoints: string[] | EntityUserRolesEndpoint[], store: Store, - logService: LoggerService, httpClient: HttpClient ) => Observable; From 77eed6c144260606cc4e94c7844759460b0a3fba Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 11:25:47 +0100 Subject: [PATCH 53/82] Fix build --- .../src/user-permissions/cf-user-roles-fetch.ts | 7 ++----- .../packages/store/src/effects/permissions.effect.ts | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts index ec6687ced1..06340d5496 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-roles-fetch.ts @@ -3,7 +3,6 @@ import { Action, Store } from '@ngrx/store'; import { combineLatest, Observable, of } from 'rxjs'; import { catchError, first, map, pairwise, share, skipWhile, switchMap, tap } from 'rxjs/operators'; -import { LoggerService } from '../../../core/src/core/logger.service'; import { AppState } from '../../../store/src/app-state'; import { entityCatalog } from '../../../store/src/entity-catalog/entity-catalog'; import { @@ -50,7 +49,6 @@ const createEndpointArray = (store: Store, endpoints: string[] | Entit export const cfUserRolesFetch: EntityUserRolesFetch = ( endpoints: string[] | EntityUserRolesEndpoint[], store: Store, - logService: LoggerService, httpClient: HttpClient ) => { return createEndpointArray(store, endpoints).pipe( @@ -61,7 +59,7 @@ export const cfUserRolesFetch: EntityUserRolesFetch = ( cfEndpoints.forEach(endpoint => store.dispatch(new GetCfUserRelations(endpoint.guid, GET_CURRENT_CF_USER_RELATIONS_SUCCESS))) } else { // If some endpoints are not connected as admin, go out and fetch the current user's specific roles - const flagsAndRoleRequests = dispatchRoleRequests(cfEndpoints, store, logService, httpClient); + const flagsAndRoleRequests = dispatchRoleRequests(cfEndpoints, store, httpClient); const allRequestsCompleted = handleCfRequests(flagsAndRoleRequests); return combineLatest(allRequestsCompleted).pipe( map(succeeds => succeeds.every(succeeded => !!succeeded)), @@ -84,7 +82,6 @@ interface IEndpointConnectionInfo { function dispatchRoleRequests( endpoints: EntityUserRolesEndpoint[], store: Store, - logService: LoggerService, httpClient: HttpClient ): CfsRequestState { const requests: CfsRequestState = {}; @@ -117,7 +114,7 @@ function dispatchRoleRequests( ); }), catchError(err => { - logService.warn('Failed to fetch current user permissions for a cf: ', err); + console.warn('Failed to fetch current user permissions for a cf: ', err); store.dispatch(new GetCfUserRelations(endpoint.guid, GET_CURRENT_CF_USER_RELATIONS_FAILED)); return of(err); }) diff --git a/src/frontend/packages/store/src/effects/permissions.effect.ts b/src/frontend/packages/store/src/effects/permissions.effect.ts index f5bd82e35c..b9569d4b2e 100644 --- a/src/frontend/packages/store/src/effects/permissions.effect.ts +++ b/src/frontend/packages/store/src/effects/permissions.effect.ts @@ -59,7 +59,7 @@ export class PermissionsEffects { guid: action.guid, user: action.endpoint.user } - return endpointType.definition.userRolesFetch([endpoint], this.store, this.logService, this.httpClient).pipe( + return endpointType.definition.userRolesFetch([endpoint], this.store, this.httpClient).pipe( map(succeeded => succeeded ? successAction : failedAction) ); }), From 2291273b309a737244ae1259a0c73e73dd6d868b Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 13:39:17 +0100 Subject: [PATCH 54/82] Address PR feedback --- .../packages/core/src/environments/environment.prod.ts | 5 +++-- src/frontend/packages/core/src/environments/environment.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/frontend/packages/core/src/environments/environment.prod.ts b/src/frontend/packages/core/src/environments/environment.prod.ts index 651a68d984..da8e7d8dbd 100644 --- a/src/frontend/packages/core/src/environments/environment.prod.ts +++ b/src/frontend/packages/core/src/environments/environment.prod.ts @@ -1,10 +1,11 @@ +import { cfAPIVersion, proxyAPIVersion } from '../../../store/src/jetstream'; import { LogLevel } from './../../../store/src/actions/log.actions'; export const environment = { production: true, logLevel: LogLevel.WARN, - proxyAPIVersion: 'v1', - cfAPIVersion: 'v2', + proxyAPIVersion, + cfAPIVersion, logToConsole: true, logEnableConsoleActions: false, showObsDebug: false, diff --git a/src/frontend/packages/core/src/environments/environment.ts b/src/frontend/packages/core/src/environments/environment.ts index bb1db6f839..e10f7527a5 100644 --- a/src/frontend/packages/core/src/environments/environment.ts +++ b/src/frontend/packages/core/src/environments/environment.ts @@ -1,4 +1,5 @@ import { LogLevel } from '../../../store/src/actions/log.actions'; +import { cfAPIVersion, proxyAPIVersion } from '../../../store/src/jetstream'; // The file contents for the current environment will overwrite these during build. // The build system defaults to the dev environment which uses `environment.ts`, but if you do @@ -7,8 +8,8 @@ import { LogLevel } from '../../../store/src/actions/log.actions'; export const environment = { production: false, - proxyAPIVersion: 'v1', - cfAPIVersion: 'v2', + proxyAPIVersion, + cfAPIVersion, logLevel: LogLevel.DEBUG, logToConsole: true, logEnableConsoleActions: false, From c30340cd9259bdb8f6148f63daa387ced6e5905b Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 13:45:36 +0100 Subject: [PATCH 55/82] Fix LoggerService after code moves --- .../packages/store/src/types/user-favorites.types.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/frontend/packages/store/src/types/user-favorites.types.ts b/src/frontend/packages/store/src/types/user-favorites.types.ts index 6dbd7c28fc..b9a52c3ffa 100644 --- a/src/frontend/packages/store/src/types/user-favorites.types.ts +++ b/src/frontend/packages/store/src/types/user-favorites.types.ts @@ -1,5 +1,4 @@ import { IEntityMetadata } from '../entity-catalog/entity-catalog.types'; -import { LoggerService } from '../../../core/src/core/logger.service'; export const userFavoritesPaginationKey = 'userFavorites'; @@ -76,10 +75,10 @@ export class UserFavorite implement .join(favoriteGuidSeparator); } - static getEntityGuidFromFavoriteGuid(favoriteGuid: string, logger: LoggerService): string { + static getEntityGuidFromFavoriteGuid(favoriteGuid: string): string { const parts = favoriteGuid.split(favoriteGuidSeparator); if (parts.length < 3) { - logger.error('Failed to determine entity guid from favorite guid: ', parts); + console.error('Failed to determine entity guid from favorite guid: ', parts); return null; } else if (parts.length === 3) { return favoriteGuid.split(favoriteGuidSeparator)[0]; From a7cb5d7384f308e4c4daf70fb98d1f96a23057f2 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 13:47:04 +0100 Subject: [PATCH 56/82] Fix logger service ref --- src/frontend/packages/store/src/user-favorite-manager.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/frontend/packages/store/src/user-favorite-manager.ts b/src/frontend/packages/store/src/user-favorite-manager.ts index 102c371206..b67f56c0e3 100644 --- a/src/frontend/packages/store/src/user-favorite-manager.ts +++ b/src/frontend/packages/store/src/user-favorite-manager.ts @@ -3,7 +3,6 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of } from 'rxjs'; import { filter, map, switchMap, tap } from 'rxjs/operators'; -import { LoggerService } from '../../core/src/core/logger.service'; import { FavoritesConfigMapper, TFavoriteMapperFunction, @@ -58,7 +57,6 @@ export interface IHydrationResults, - private logger: LoggerService, private favoritesConfigMapper: FavoritesConfigMapper ) { } @@ -124,7 +122,7 @@ export class UserFavoriteManager { if (!endpointFav) { return this.store.select(endpointEntitiesSelector).pipe( map(endpoints => { - const endpointGuid = UserFavorite.getEntityGuidFromFavoriteGuid(endpointFavoriteGuid, this.logger); + const endpointGuid = UserFavorite.getEntityGuidFromFavoriteGuid(endpointFavoriteGuid); const endpointEntity = endpoints[endpointGuid]; return this.favoritesConfigMapper.getFavoriteEndpointFromEntity(endpointEntity); }), From 22566f455ae4b7053b6d94f30d1145681167c10c Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 14:11:31 +0100 Subject: [PATCH 57/82] Fix build issues --- src/frontend/packages/store/src/actions/metrics.actions.ts | 1 + src/frontend/packages/store/src/effects/user-favorites-effect.ts | 1 + src/frontend/packages/store/src/types/base-metric.types.ts | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/packages/store/src/actions/metrics.actions.ts b/src/frontend/packages/store/src/actions/metrics.actions.ts index 7f5b7c613e..ae1bf4b3a9 100644 --- a/src/frontend/packages/store/src/actions/metrics.actions.ts +++ b/src/frontend/packages/store/src/actions/metrics.actions.ts @@ -1,4 +1,5 @@ import { MetricQueryType } from '../../../core/src/shared/services/metrics-range-selector.types'; +import { metricEntityType } from '../base-entity-schemas'; import { proxyAPIVersion } from '../jetstream'; import { EntityRequestAction } from '../types/request.types'; diff --git a/src/frontend/packages/store/src/effects/user-favorites-effect.ts b/src/frontend/packages/store/src/effects/user-favorites-effect.ts index bca2ed50a8..be235e1b03 100644 --- a/src/frontend/packages/store/src/effects/user-favorites-effect.ts +++ b/src/frontend/packages/store/src/effects/user-favorites-effect.ts @@ -24,6 +24,7 @@ import { UpdateUserFavoriteMetadataSuccessAction, } from '../actions/user-favourites-actions/update-user-favorite-metadata-action'; import { DispatchOnlyAppState } from '../app-state'; +import { userFavoritesEntitySchema } from '../base-entity-schemas'; import { entityCatalog } from '../entity-catalog/entity-catalog'; import { proxyAPIVersion } from '../jetstream'; import { NormalizedResponse } from '../types/api.types'; diff --git a/src/frontend/packages/store/src/types/base-metric.types.ts b/src/frontend/packages/store/src/types/base-metric.types.ts index a281dbb974..0ad9c00358 100644 --- a/src/frontend/packages/store/src/types/base-metric.types.ts +++ b/src/frontend/packages/store/src/types/base-metric.types.ts @@ -1,5 +1,4 @@ import { MetricQueryConfig } from '../actions/metrics.actions'; -import { MetricQueryType } from '../../../core/src/shared/services/metrics-range-selector.types'; export enum MetricResultTypes { MATRIX = 'matrix', From 35a75688a8efd26635d078121800fc07f281bc22 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 15:46:35 +0100 Subject: [PATCH 58/82] Fix health check import --- .../cloud-foundry/src/cf-entity-generator.ts | 2 +- .../packages/core/endpoints-health-checks.ts | 13 +------------ .../packages/core/src/core/endpoints.service.ts | 3 ++- .../src/entity-catalog/entity-catalog.types.ts | 13 ++++++++++++- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts index 6819e1297f..a3dac1cd20 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts @@ -3,7 +3,6 @@ import * as moment from 'moment'; import { combineLatest, Observable, of } from 'rxjs'; import { first, map } from 'rxjs/operators'; -import { EndpointHealthCheck } from '../../core/endpoints-health-checks'; import { urlValidationExpression } from '../../core/src/core/utils.service'; import { BaseEndpointAuth } from '../../core/src/features/endpoints/endpoint-auth'; import { AppState, GeneralEntityAppState } from '../../store/src/app-state'; @@ -14,6 +13,7 @@ import { StratosCatalogEntity, } from '../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { + EndpointHealthCheck, IStratosEntityDefinition, StratosEndpointExtensionDefinition, } from '../../store/src/entity-catalog/entity-catalog.types'; diff --git a/src/frontend/packages/core/endpoints-health-checks.ts b/src/frontend/packages/core/endpoints-health-checks.ts index 2c7624fd76..11e46ae3fc 100644 --- a/src/frontend/packages/core/endpoints-health-checks.ts +++ b/src/frontend/packages/core/endpoints-health-checks.ts @@ -1,20 +1,9 @@ import { Injectable } from '@angular/core'; import { entityCatalog } from '../store/src/entity-catalog/entity-catalog'; +import { EndpointHealthCheck } from '../store/src/entity-catalog/entity-catalog.types'; import { EndpointModel } from '../store/src/types/endpoint.types'; - -export class EndpointHealthCheck { - /** - * @param check To show an error, the check should either call a WrapperRequestActionFailed - * or kick off a chain that eventually calls a WrapperRequestActionFailed - */ - constructor( - public endpointType: string, - public check: (endpoint: EndpointModel) => void - ) { } -} - @Injectable({ providedIn: 'root' }) diff --git a/src/frontend/packages/core/src/core/endpoints.service.ts b/src/frontend/packages/core/src/core/endpoints.service.ts index 842330f087..1d82326027 100644 --- a/src/frontend/packages/core/src/core/endpoints.service.ts +++ b/src/frontend/packages/core/src/core/endpoints.service.ts @@ -7,10 +7,11 @@ import { first, map, skipWhile, withLatestFrom } from 'rxjs/operators'; import { RouterNav } from '../../../store/src/actions/router.actions'; import { EndpointOnlyAppState, IRequestEntityTypeState } from '../../../store/src/app-state'; import { entityCatalog } from '../../../store/src/entity-catalog/entity-catalog'; +import { EndpointHealthCheck } from '../../../store/src/entity-catalog/entity-catalog.types'; import { AuthState } from '../../../store/src/reducers/auth.reducer'; import { endpointEntitiesSelector, endpointStatusSelector } from '../../../store/src/selectors/endpoint.selectors'; import { EndpointModel, EndpointState } from '../../../store/src/types/endpoint.types'; -import { EndpointHealthCheck, EndpointHealthChecks } from '../../endpoints-health-checks'; +import { EndpointHealthChecks } from '../../endpoints-health-checks'; import { endpointHasMetricsByAvailable } from '../features/endpoints/endpoint-helpers'; import { UserService } from './user.service'; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index a0bba1cf85..f2a65e1200 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -1,7 +1,6 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { EndpointHealthCheck } from '../../../core/endpoints-health-checks'; import { FavoritesConfigMapper } from '../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { StratosStatus } from '../../../core/src/shared/shared.types'; import { GeneralEntityAppState } from '../app-state'; @@ -22,6 +21,7 @@ import { } from '../entity-request-pipeline/pagination-request-base-handlers/pagination-iterator.pipe'; import { EndpointAuthTypeConfig } from '../extension-types'; import { EntitySchema } from '../helpers/entity-schema'; +import { EndpointModel } from '../types/endpoint.types'; import { UserFavorite } from '../types/user-favorites.types'; export interface EntityCatalogEntityConfig { @@ -95,6 +95,17 @@ export interface IStratosBaseEntityDefinition void + ) { } +} + /** * Static information describing a stratos endpoint. * From a671bd1b8ab18e6a649ab99257c7ea4e60981037 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 15:48:01 +0100 Subject: [PATCH 59/82] Move sortStringify (only used once) --- src/frontend/packages/core/src/core/utils.service.ts | 7 ------- .../pagination-reducer/pagination-reducer.helper.ts | 9 ++++++++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/frontend/packages/core/src/core/utils.service.ts b/src/frontend/packages/core/src/core/utils.service.ts index 415a8f89c6..e41d005035 100644 --- a/src/frontend/packages/core/src/core/utils.service.ts +++ b/src/frontend/packages/core/src/core/utils.service.ts @@ -319,13 +319,6 @@ export const safeUnsubscribe = (...subs: Subscription[]) => { export const truthyIncludingZero = (obj: any): boolean => !!obj || obj === 0; export const truthyIncludingZeroString = (obj: any): string => truthyIncludingZero(obj) ? obj.toString() : null; -export const sortStringify = (obj: { [key: string]: string | string[] | number }): string => { - const keys = Object.keys(obj).sort(); - return keys.reduce((res, key) => { - return res += `${key}-${obj[key]},`; - }, ''); -}; - /** * Real basic, shallow check */ diff --git a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer.helper.ts b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer.helper.ts index 56a5e0bef4..427a184b21 100644 --- a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer.helper.ts +++ b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer.helper.ts @@ -12,7 +12,6 @@ import { tap, } from 'rxjs/operators'; -import { sortStringify } from '../../../../core/src/core/utils.service'; import { SetInitialParams } from '../../actions/pagination.actions'; import { AppState, GeneralEntityAppState } from '../../app-state'; import { entityCatalog } from '../../entity-catalog/entity-catalog'; @@ -152,6 +151,14 @@ function paginationParamsString(params: PaginationParam): string { return sortStringify(clone); } + +function sortStringify(obj: { [key: string]: string | string[] | number }): string { + const keys = Object.keys(obj).sort(); + return keys.reduce((res, key) => { + return res += `${key}-${obj[key]},`; + }, ''); +} + function shouldFetchNonLocalList(pagination: PaginationEntityState): boolean { return !hasError(pagination) && !hasValidOrGettingPage(pagination); } From 85f3da879bd82cb356485d7764044cf6cdc58072 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 15:49:06 +0100 Subject: [PATCH 60/82] NonOptionalKeys - only used once --- src/frontend/packages/core/src/core/utils.service.ts | 7 ------- .../entity-catalog-entity/entity-catalog-entity.ts | 8 +++++++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/frontend/packages/core/src/core/utils.service.ts b/src/frontend/packages/core/src/core/utils.service.ts index e41d005035..7abec899ce 100644 --- a/src/frontend/packages/core/src/core/utils.service.ts +++ b/src/frontend/packages/core/src/core/utils.service.ts @@ -17,13 +17,6 @@ export type OptionalKeys = Exclude<{ : never }[keyof T], undefined> - -export type NonOptionalKeys = Exclude<{ - [K in keyof T]: T extends Record - ? K - : never -}[keyof T], undefined> - export type NeverKeys = Exclude<{ [K in keyof T]: T[K] extends never ? K diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts index b754067761..b6c3609f55 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts @@ -1,6 +1,6 @@ import { ActionReducer } from '@ngrx/store'; -import { KnownKeys, NonOptionalKeys } from '../../../../core/src/core/utils.service'; +import { KnownKeys } from '../../../../core/src/core/utils.service'; import { getFullEndpointApiUrl } from '../../../../core/src/features/endpoints/endpoint-helpers'; import { IRequestEntityTypeState } from '../../app-state'; import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; @@ -38,6 +38,12 @@ import { ActionBuilderConfigMapper } from './action-builder-config.mapper'; import { ActionDispatchers, EntityCatalogEntityStoreHelpers } from './entity-catalog-entity-store-helpers'; import { EntityCatalogEntityStore } from './entity-catalog-entity.types'; +type NonOptionalKeys = Exclude<{ + [K in keyof T]: T extends Record + ? K + : never +}[keyof T], undefined> + export type KnownActionBuilders = Pick>>>; export interface EntityCatalogBuilders< From 3c9aea9def05ddf2d9258d86378cb5d46c372bf1 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 15:50:32 +0100 Subject: [PATCH 61/82] Move KnownKeys --- .../packages/core/src/core/utils.service.ts | 11 ----------- .../entity-catalog-entity.ts | 3 +-- .../entity-catalog-entity.types.ts | 17 +++++++++++------ 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/frontend/packages/core/src/core/utils.service.ts b/src/frontend/packages/core/src/core/utils.service.ts index 7abec899ce..37de7d5cab 100644 --- a/src/frontend/packages/core/src/core/utils.service.ts +++ b/src/frontend/packages/core/src/core/utils.service.ts @@ -23,17 +23,6 @@ export type NeverKeys = Exclude<{ : never }[keyof T], undefined> - -/** - * Remove keys such as typed indexes (i.e. [key: string]) - * For magic see - * - https://github.com/Microsoft/TypeScript/issues/25987#issuecomment-441224690 - * - https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-414808995 - */ -export type KnownKeys = { - [K in keyof T]: string extends K ? never : number extends K ? never : K -} extends { [_ in keyof T]: infer U } ? ({} extends U ? never : U) : never; - /** * Pick all properties who's function has the specified return type U */ diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts index b6c3609f55..0bf0715cbc 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts @@ -1,6 +1,5 @@ import { ActionReducer } from '@ngrx/store'; -import { KnownKeys } from '../../../../core/src/core/utils.service'; import { getFullEndpointApiUrl } from '../../../../core/src/features/endpoints/endpoint-helpers'; import { IRequestEntityTypeState } from '../../app-state'; import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; @@ -36,7 +35,7 @@ import { } from '../entity-catalog.types'; import { ActionBuilderConfigMapper } from './action-builder-config.mapper'; import { ActionDispatchers, EntityCatalogEntityStoreHelpers } from './entity-catalog-entity-store-helpers'; -import { EntityCatalogEntityStore } from './entity-catalog-entity.types'; +import { EntityCatalogEntityStore, KnownKeys } from './entity-catalog-entity.types'; type NonOptionalKeys = Exclude<{ [K in keyof T]: T extends Record diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts index 0280477e6f..93a0b5e40b 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts @@ -1,9 +1,4 @@ -import { - FilteredByNotReturnType, - FilteredByReturnType, - KnownKeys, - NeverKeys, -} from '../../../../core/src/core/utils.service'; +import { FilteredByNotReturnType, FilteredByReturnType, NeverKeys } from '../../../../core/src/core/utils.service'; import { EntityService } from '../../entity-service'; import { EntityMonitor } from '../../monitors/entity-monitor'; import { PaginationMonitor } from '../../monitors/pagination-monitor'; @@ -11,6 +6,16 @@ import { PaginationObservables } from '../../reducers/pagination-reducer/paginat import { PaginatedAction } from '../../types/pagination.types'; import { OrchestratedActionBuilders, OrchestratedActionCoreBuilders } from '../action-orchestrator/action-orchestrator'; +/** + * Remove keys such as typed indexes (i.e. [key: string]) + * For magic see + * - https://github.com/Microsoft/TypeScript/issues/25987#issuecomment-441224690 + * - https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-414808995 + */ +export type KnownKeys = { + [K in keyof T]: string extends K ? never : number extends K ? never : K +} extends { [_ in keyof T]: infer U } ? ({} extends U ? never : U) : never; + /** * Core entity and entities access (entity/entities monitors and services) */ From 3a1520db43eed560c8d17088c76096f473dcb06c Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 16:00:15 +0100 Subject: [PATCH 62/82] Move BrowserStandardEncoder --- .../endpoints/backup-restore/backup-endpoints.service.ts | 2 +- .../backup-restore/restore-endpoints.service.ts | 2 +- .../{core/src/helper.ts => store/src/browser-encoder.ts} | 9 --------- src/frontend/packages/store/src/effects/auth.effects.ts | 2 +- .../packages/store/src/effects/endpoint.effects.ts | 2 +- 5 files changed, 4 insertions(+), 13 deletions(-) rename src/frontend/packages/{core/src/helper.ts => store/src/browser-encoder.ts} (72%) diff --git a/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints.service.ts b/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints.service.ts index 5251a66479..2aee2629c1 100644 --- a/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints.service.ts +++ b/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints.service.ts @@ -5,9 +5,9 @@ import { BehaviorSubject, Observable } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { GeneralEntityAppState } from '../../../../../store/src/app-state'; +import { BrowserStandardEncoder } from '../../../../../store/src/browser-encoder'; import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; -import { BrowserStandardEncoder } from '../../../helper'; import { BackupEndpointConfigUI, BackupEndpointConnectionTypes, diff --git a/src/frontend/packages/core/src/features/endpoints/backup-restore/restore-endpoints.service.ts b/src/frontend/packages/core/src/features/endpoints/backup-restore/restore-endpoints.service.ts index 8fa35048c1..38dee43257 100644 --- a/src/frontend/packages/core/src/features/endpoints/backup-restore/restore-endpoints.service.ts +++ b/src/frontend/packages/core/src/features/endpoints/backup-restore/restore-endpoints.service.ts @@ -5,10 +5,10 @@ import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { filter, map, switchMap } from 'rxjs/operators'; import { GeneralEntityAppState } from '../../../../../store/src/app-state'; +import { BrowserStandardEncoder } from '../../../../../store/src/browser-encoder'; import { selectSessionData } from '../../../../../store/src/reducers/auth.reducer'; import { SessionData } from '../../../../../store/src/types/auth.types'; import { LoggerService } from '../../../core/logger.service'; -import { BrowserStandardEncoder } from '../../../helper'; interface BackupContent { payload: string; diff --git a/src/frontend/packages/core/src/helper.ts b/src/frontend/packages/store/src/browser-encoder.ts similarity index 72% rename from src/frontend/packages/core/src/helper.ts rename to src/frontend/packages/store/src/browser-encoder.ts index 88cbff36f5..ffdc0584ed 100644 --- a/src/frontend/packages/core/src/helper.ts +++ b/src/frontend/packages/store/src/browser-encoder.ts @@ -1,14 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; -export function getPath(object: { [key: string]: any }, path: string[]) { - try { - return path.reduce((o, i) => o[i], object); - } catch (err) { - return null; - } -} - - export class BrowserStandardEncoder implements HttpParameterCodec { encodeKey(key: string): string { return encodeURIComponent(key); diff --git a/src/frontend/packages/store/src/effects/auth.effects.ts b/src/frontend/packages/store/src/effects/auth.effects.ts index 8cd9810cc3..086c791cea 100644 --- a/src/frontend/packages/store/src/effects/auth.effects.ts +++ b/src/frontend/packages/store/src/effects/auth.effects.ts @@ -4,7 +4,6 @@ import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, map, mergeMap, switchMap, tap } from 'rxjs/operators'; -import { BrowserStandardEncoder } from '../../../core/src/helper'; import { InvalidSession, LOGIN, @@ -28,6 +27,7 @@ import { HydrateDashboardStateAction } from '../actions/dashboard-actions'; import { GET_ENDPOINTS_SUCCESS, GetAllEndpointsSuccess } from '../actions/endpoint.actions'; import { GetSystemInfo } from '../actions/system.actions'; import { DispatchOnlyAppState } from '../app-state'; +import { BrowserStandardEncoder } from '../browser-encoder'; import { getDashboardStateSessionId } from '../helpers/store-helpers'; import { SessionData } from '../types/auth.types'; diff --git a/src/frontend/packages/store/src/effects/endpoint.effects.ts b/src/frontend/packages/store/src/effects/endpoint.effects.ts index 35ac3594a3..0a7f25fcae 100644 --- a/src/frontend/packages/store/src/effects/endpoint.effects.ts +++ b/src/frontend/packages/store/src/effects/endpoint.effects.ts @@ -4,7 +4,6 @@ import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, mergeMap } from 'rxjs/operators'; -import { BrowserStandardEncoder } from '../../../core/src/helper'; import { CONNECT_ENDPOINTS, CONNECT_ENDPOINTS_FAILED, @@ -33,6 +32,7 @@ import { GET_SYSTEM_INFO_SUCCESS, GetSystemInfo, GetSystemSuccess } from '../act import { GetUserFavoritesAction } from '../actions/user-favourites-actions/get-user-favorites-action'; import { DispatchOnlyAppState } from '../app-state'; import { STRATOS_ENDPOINT_TYPE } from '../base-entity-schemas'; +import { BrowserStandardEncoder } from '../browser-encoder'; import { entityCatalog } from '../entity-catalog/entity-catalog'; import { EndpointType } from '../extension-types'; import { endpointSchemaKey } from '../helpers/entity-factory'; From 1bffe920d0fc14b7cc15dc67f4cd47ce44ec8581 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 19:36:46 +0100 Subject: [PATCH 63/82] Remove last environment link --- src/frontend/packages/core/src/app.module.ts | 15 ++++++++ .../packages/store/src/reducers.module.ts | 37 +++++++------------ 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/frontend/packages/core/src/app.module.ts b/src/frontend/packages/core/src/app.module.ts index ca4a5daacb..6bd23e2f0a 100644 --- a/src/frontend/packages/core/src/app.module.ts +++ b/src/frontend/packages/core/src/app.module.ts @@ -4,6 +4,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { Params, RouteReuseStrategy, RouterStateSnapshot } from '@angular/router'; import { DefaultRouterStateSerializer, RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store'; import { Store } from '@ngrx/store'; +import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { debounceTime, filter, withLatestFrom } from 'rxjs/operators'; import { CfAutoscalerModule } from '../../cf-autoscaler/src/cf-autoscaler.module'; @@ -38,6 +39,7 @@ import { ExtensionService } from './core/extension/extension-service'; import { getGitHubAPIURL, GITHUB_API_URL } from './core/github.helpers'; import { CurrentUserPermissionsService } from './core/permissions/current-user-permissions.service'; import { CustomImportModule } from './custom-import.module'; +import { environment } from './environments/environment'; import { AboutModule } from './features/about/about.module'; import { DashboardModule } from './features/dashboard/dashboard.module'; import { HomeModule } from './features/home/home.module'; @@ -80,6 +82,18 @@ export class CustomRouterStateSerializer } } +const storeDebugImports = environment.production ? [] : [ + StoreDevtoolsModule.instrument({ + maxAge: 100, + logOnly: !environment.production + }) +]; + +@NgModule({ + imports: storeDebugImports +}) +class AppStoreDebugModule {} + /** * `HttpXsrfTokenExtractor` which retrieves the token from a cookie. */ @@ -94,6 +108,7 @@ export class CustomRouterStateSerializer RouteModule, CloudFoundryPackageModule, AppStoreModule, + AppStoreDebugModule, BrowserModule, SharedModule, BrowserAnimationsModule, diff --git a/src/frontend/packages/store/src/reducers.module.ts b/src/frontend/packages/store/src/reducers.module.ts index 23054fd7fb..d5268b68bf 100644 --- a/src/frontend/packages/store/src/reducers.module.ts +++ b/src/frontend/packages/store/src/reducers.module.ts @@ -1,10 +1,7 @@ import { NgModule } from '@angular/core'; import { ActionReducer, ActionReducerMap, StoreModule } from '@ngrx/store'; -import { StoreDevtoolsModule } from '@ngrx/store-devtools'; - import { localStorageSync } from 'ngrx-store-localstorage'; -import { environment } from '../../core/src/environments/environment'; import { getDashboardStateSessionId } from './helpers/store-helpers'; import { actionHistoryReducer } from './reducers/action-history-reducer'; import { requestReducer } from './reducers/api-request-reducers.generator'; @@ -71,29 +68,21 @@ export function localStorageSyncReducer(reducer: ActionReducer): ActionRedu })(reducer); } -const metaReducers = [localStorageSyncReducer]; -const storeModule = StoreModule.forRoot( - appReducers, - { - metaReducers, - runtimeChecks: { - strictStateImmutability: true, - strictActionImmutability: false - } - } -); -const imports = environment.production ? [ - storeModule -] : [ - storeModule, - StoreDevtoolsModule.instrument({ - maxAge: 100, - logOnly: !environment.production - }) - ]; +const metaReducers = [localStorageSyncReducer]; @NgModule({ - imports + imports: [ + StoreModule.forRoot( + appReducers, + { + metaReducers, + runtimeChecks: { + strictStateImmutability: true, + strictActionImmutability: false + } + } + ) + ] }) export class AppReducersModule { } From ffedabd6422e75cf8c109170973288ae48371ea4 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 19:42:24 +0100 Subject: [PATCH 64/82] Move favourite config mapper --- .../cloud-foundry/src/cf-favorites-helpers.ts | 2 +- .../application-tabs-base.component.ts | 4 +--- .../cloud-foundry-tabs-base.component.ts | 2 +- ...oud-foundry-organization-base.component.ts | 4 +--- .../cloud-foundry-space-base.component.ts | 4 +--- .../list-types/app/card/card-app.component.ts | 4 +--- .../cf-org-card/cf-org-card.component.ts | 4 +--- .../cf-space-card/cf-space-card.component.ts | 4 +--- src/frontend/packages/core/src/app.module.ts | 2 +- .../entity-favorite-star.component.spec.ts | 2 +- .../entity-favorite-star.component.ts | 2 +- .../favorites-entity-list.component.ts | 2 +- .../favorites-meta-card.component.ts | 2 +- .../meta-card.component.spec.ts | 2 +- .../meta-card-base/meta-card.component.ts | 2 +- .../table-cell-favorite.component.ts | 2 +- .../endpoint-card/endpoint-card.component.ts | 2 +- .../endpoint/endpoints-list-config.service.ts | 2 +- .../page-header/page-header.component.ts | 2 +- .../entity-catalog/entity-catalog.types.ts | 2 +- .../src}/favorite-config-mapper.ts | 23 ++++++++----------- .../store/src/user-favorite-helpers.ts | 2 +- .../store/src/user-favorite-manager.ts | 5 +--- 23 files changed, 31 insertions(+), 51 deletions(-) rename src/frontend/packages/{core/src/shared/components/favorites-meta-card => store/src}/favorite-config-mapper.ts (86%) diff --git a/src/frontend/packages/cloud-foundry/src/cf-favorites-helpers.ts b/src/frontend/packages/cloud-foundry/src/cf-favorites-helpers.ts index ec23f4125f..8f19d39a21 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-favorites-helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-favorites-helpers.ts @@ -1,5 +1,5 @@ -import { FavoritesConfigMapper } from '../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { IEntityMetadata } from '../../store/src/entity-catalog/entity-catalog.types'; +import { FavoritesConfigMapper } from '../../store/src/favorite-config-mapper'; import { UserFavorite } from '../../store/src/types/user-favorites.types'; import { CfAPIResource } from './store/types/cf-api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts index d6e3c44434..7974416cac 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts @@ -17,14 +17,12 @@ import { import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { safeUnsubscribe } from '../../../../../../core/src/core/utils.service'; import { IPageSideNavTab } from '../../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; -import { - FavoritesConfigMapper, -} from '../../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { IHeaderBreadcrumb } from '../../../../../../core/src/shared/components/page-header/page-header.types'; import { ENTITY_SERVICE } from '../../../../../../core/src/shared/entity.tokens'; import { RouterNav } from '../../../../../../store/src/actions/router.actions'; import { entityCatalog } from '../../../../../../store/src/entity-catalog/entity-catalog'; import { EntityService } from '../../../../../../store/src/entity-service'; +import { FavoritesConfigMapper } from '../../../../../../store/src/favorite-config-mapper'; import { EntitySchema } from '../../../../../../store/src/helpers/entity-schema'; import { ActionState } from '../../../../../../store/src/reducers/api-request-reducer/types'; import { endpointEntitiesSelector } from '../../../../../../store/src/selectors/endpoint.selectors'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts index 57ddd512a7..c086f9cd86 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cloud-foundry-tabs-base/cloud-foundry-tabs-base.component.ts @@ -13,7 +13,7 @@ import { import { CurrentUserPermissionsService } from '../../../../../core/src/core/permissions/current-user-permissions.service'; import { environment } from '../../../../../core/src/environments/environment.prod'; import { IPageSideNavTab } from '../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; -import { FavoritesConfigMapper } from '../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; +import { FavoritesConfigMapper } from '../../../../../store/src/favorite-config-mapper'; import { UserFavoriteEndpoint } from '../../../../../store/src/types/user-favorites.types'; import { CfCurrentUserPermissions } from '../../../user-permissions/cf-user-permissions-checkers'; import { CloudFoundryEndpointService } from '../services/cloud-foundry-endpoint.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-base/cloud-foundry-organization-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-base/cloud-foundry-organization-base.component.ts index 91c27c3f31..f9a24ac961 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-base/cloud-foundry-organization-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-base/cloud-foundry-organization-base.component.ts @@ -13,10 +13,8 @@ import { } from '../../../../../../../core/src/core/extension/extension-service'; import { environment } from '../../../../../../../core/src/environments/environment.prod'; import { IPageSideNavTab } from '../../../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; -import { - FavoritesConfigMapper, -} from '../../../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { IHeaderBreadcrumb } from '../../../../../../../core/src/shared/components/page-header/page-header.types'; +import { FavoritesConfigMapper } from '../../../../../../../store/src/favorite-config-mapper'; import { EntitySchema } from '../../../../../../../store/src/helpers/entity-schema'; import { UserFavorite } from '../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../store/src/user-favorite-helpers'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts index 7f5e455ecc..5ae190a43b 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts @@ -16,11 +16,9 @@ import { import { environment } from '../../../../../../../../core/src/environments/environment.prod'; import { IPageSideNavTab } from '../../../../../../../../core/src/features/dashboard/page-side-nav/page-side-nav.component'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; -import { - FavoritesConfigMapper, -} from '../../../../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { IHeaderBreadcrumb } from '../../../../../../../../core/src/shared/components/page-header/page-header.types'; import { RouterNav } from '../../../../../../../../store/src/actions/router.actions'; +import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts index 3a450bdde4..4fdef71b47 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts @@ -6,11 +6,9 @@ import { map, startWith } from 'rxjs/operators'; import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-state'; import { applicationEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; import { IAppFavMetadata } from '../../../../../../../../cloud-foundry/src/cf-metadata-types'; -import { - FavoritesConfigMapper, -} from '../../../../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../core/src/shared/shared.types'; +import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts index f146e81e1c..2e7f605c23 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts @@ -11,15 +11,13 @@ import { import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; -import { - FavoritesConfigMapper, -} from '../../../../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { MetaCardMenuItem, } from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../core/src/shared/shared.types'; import { RouterNav } from '../../../../../../../../store/src/actions/router.actions'; +import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { PaginationMonitorFactory } from '../../../../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts index 890fdf2f98..189604d778 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts @@ -12,15 +12,13 @@ import { import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; -import { - FavoritesConfigMapper, -} from '../../../../../../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { MetaCardMenuItem, } from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../core/src/shared/shared.types'; import { RouterNav } from '../../../../../../../../store/src/actions/router.actions'; +import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { PaginationMonitorFactory } from '../../../../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/core/src/app.module.ts b/src/frontend/packages/core/src/app.module.ts index 6bd23e2f0a..5143286c99 100644 --- a/src/frontend/packages/core/src/app.module.ts +++ b/src/frontend/packages/core/src/app.module.ts @@ -20,6 +20,7 @@ import { EntityCatalogModule } from '../../store/src/entity-catalog.module'; import { entityCatalog } from '../../store/src/entity-catalog/entity-catalog'; import { EntityCatalogHelper } from '../../store/src/entity-catalog/entity-catalog-entity/entity-catalog.service'; import { EntityCatalogHelpers } from '../../store/src/entity-catalog/entity-catalog.helper'; +import { FavoritesConfigMapper } from '../../store/src/favorite-config-mapper'; import { endpointSchemaKey } from '../../store/src/helpers/entity-factory'; import { getAPIRequestDataState, selectEntity } from '../../store/src/selectors/api.selectors'; import { internalEventStateSelector } from '../../store/src/selectors/internal-events.selectors'; @@ -48,7 +49,6 @@ import { NoEndpointsNonAdminComponent } from './features/no-endpoints-non-admin/ import { SetupModule } from './features/setup/setup.module'; import { LoggedInService } from './logged-in.service'; import { CustomReuseStrategy } from './route-reuse-stragegy'; -import { FavoritesConfigMapper } from './shared/components/favorites-meta-card/favorite-config-mapper'; import { endpointEventKey, GlobalEventData, GlobalEventService } from './shared/global-events.service'; import { SidePanelService } from './shared/services/side-panel.service'; import { SharedModule } from './shared/shared.module'; diff --git a/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.spec.ts b/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.spec.ts index 900bd8ade9..067a4e1f69 100644 --- a/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.spec.ts +++ b/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.spec.ts @@ -2,13 +2,13 @@ import { OverlayContainer } from '@angular/cdk/overlay'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { BehaviorSubject, of } from 'rxjs'; +import { FavoritesConfigMapper } from '../../../../store/src/favorite-config-mapper'; import { PaginationMonitorFactory } from '../../../../store/src/monitors/pagination-monitor.factory'; import { IFavoriteMetadata, UserFavorite } from '../../../../store/src/types/user-favorites.types'; import { UserFavoriteManager } from '../../../../store/src/user-favorite-manager'; import { BaseTestModulesNoShared } from '../../../test-framework/core-test.helper'; import { ConfirmationDialogService } from '../../shared/components/confirmation-dialog.service'; import { DialogConfirmComponent } from '../../shared/components/dialog-confirm/dialog-confirm.component'; -import { FavoritesConfigMapper } from '../../shared/components/favorites-meta-card/favorite-config-mapper'; import { EntityFavoriteStarComponent } from './entity-favorite-star.component'; describe('EntityFavoriteStarComponent', () => { diff --git a/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.ts b/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.ts index 1aed1b41b0..c345e7d523 100644 --- a/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.ts +++ b/src/frontend/packages/core/src/core/entity-favorite-star/entity-favorite-star.component.ts @@ -2,11 +2,11 @@ import { Component, Input } from '@angular/core'; import { Observable } from 'rxjs'; import { first, tap } from 'rxjs/operators'; +import { FavoritesConfigMapper } from '../../../../store/src/favorite-config-mapper'; import { IFavoriteMetadata, UserFavorite } from '../../../../store/src/types/user-favorites.types'; import { UserFavoriteManager } from '../../../../store/src/user-favorite-manager'; import { ConfirmationDialogConfig } from '../../shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../shared/components/confirmation-dialog.service'; -import { FavoritesConfigMapper } from '../../shared/components/favorites-meta-card/favorite-config-mapper'; import { EndpointsService } from '../endpoints.service'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts b/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts index 31171980d5..aeeca51973 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts @@ -2,8 +2,8 @@ import { Component, Input, OnInit } from '@angular/core'; import { combineLatest, Observable, ReplaySubject, Subject } from 'rxjs'; import { distinctUntilChanged, map, scan, startWith } from 'rxjs/operators'; +import { FavoritesConfigMapper, IFavoriteTypes } from '../../../../../store/src/favorite-config-mapper'; import { IFavoriteEntity } from '../../../../../store/src/user-favorite-manager'; -import { FavoritesConfigMapper, IFavoriteTypes } from '../favorites-meta-card/favorite-config-mapper'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts index a559cedad0..db9713e8aa 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts @@ -9,6 +9,7 @@ import { import { AppState } from '../../../../../store/src/app-state'; import { userFavoritesEntitySchema } from '../../../../../store/src/base-entity-schemas'; import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; +import { IFavoritesMetaCardConfig } from '../../../../../store/src/favorite-config-mapper'; import { endpointEntitiesSelector } from '../../../../../store/src/selectors/endpoint.selectors'; import { IFavoriteMetadata, UserFavorite } from '../../../../../store/src/types/user-favorites.types'; import { IFavoriteEntity } from '../../../../../store/src/user-favorite-manager'; @@ -17,7 +18,6 @@ import { ComponentEntityMonitorConfig, StratosStatus } from '../../shared.types' import { ConfirmationDialogConfig } from '../confirmation-dialog.config'; import { ConfirmationDialogService } from '../confirmation-dialog.service'; import { MetaCardMenuItem } from '../list/list-cards/meta-card/meta-card-base/meta-card.component'; -import { IFavoritesMetaCardConfig } from './favorite-config-mapper'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts index 8800a8a802..4a35630e03 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts @@ -5,6 +5,7 @@ import { StoreModule } from '@ngrx/store'; import { createBasicStoreModule } from '@stratosui/store/testing'; import { Observable, of } from 'rxjs'; +import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntitySchema } from '../../../../../../../../store/src/helpers/entity-schema'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; @@ -13,7 +14,6 @@ import { UserFavoriteManager } from '../../../../../../../../store/src/user-favo import { CoreTestingModule } from '../../../../../../../test-framework/core-test.modules'; import { SharedModule } from '../../../../../shared.module'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../shared.types'; -import { FavoritesConfigMapper } from '../../../../favorites-meta-card/favorite-config-mapper'; import { MetaCardComponent } from './meta-card.component'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts index ced89b65c0..2a180f646f 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts @@ -2,12 +2,12 @@ import { Component, ContentChild, ContentChildren, Input, OnDestroy, QueryList } import { combineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import { first, map, tap } from 'rxjs/operators'; +import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../shared.types'; -import { FavoritesConfigMapper } from '../../../../favorites-meta-card/favorite-config-mapper'; import { MetaCardItemComponent } from '../meta-card-item/meta-card-item.component'; import { MetaCardTitleComponent } from '../meta-card-title/meta-card-title.component'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-favorite/table-cell-favorite.component.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-favorite/table-cell-favorite.component.ts index 93f89e58de..cb239478f9 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-favorite/table-cell-favorite.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-favorite/table-cell-favorite.component.ts @@ -1,9 +1,9 @@ import { Component, Input } from '@angular/core'; +import { FavoritesConfigMapper } from '../../../../../../../store/src/favorite-config-mapper'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../store/src/types/user-favorites.types'; import { TableCellCustom } from '../../list.types'; import { ITableColumn } from '../table.types'; -import { FavoritesConfigMapper } from '../../../favorites-meta-card/favorite-config-mapper'; export interface TableCellFavoriteComponentConfig { createUserFavorite: (entity: T) => UserFavorite; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts index 581680cd4f..e975236944 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts @@ -18,6 +18,7 @@ import { entityCatalog } from '../../../../../../../../store/src/entity-catalog/ import { StratosCatalogEndpointEntity, } from '../../../../../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; @@ -26,7 +27,6 @@ import { getFullEndpointApiUrl, } from '../../../../../../features/endpoints/endpoint-helpers'; import { StratosStatus } from '../../../../../shared.types'; -import { FavoritesConfigMapper } from '../../../../favorites-meta-card/favorite-config-mapper'; import { createMetaCardMenuItemSeparator, MetaCardMenuItem, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts index 1848861dae..0f091dbd85 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts @@ -5,11 +5,11 @@ import { filter } from 'rxjs/operators'; import { ListView } from '../../../../../../../store/src/actions/list.actions'; import { AppState } from '../../../../../../../store/src/app-state'; import { entityCatalog } from '../../../../../../../store/src/entity-catalog/entity-catalog'; +import { FavoritesConfigMapper } from '../../../../../../../store/src/favorite-config-mapper'; import { EntityMonitorFactory } from '../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { InternalEventMonitorFactory } from '../../../../../../../store/src/monitors/internal-event-monitor.factory'; import { PaginationMonitorFactory } from '../../../../../../../store/src/monitors/pagination-monitor.factory'; import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; -import { FavoritesConfigMapper } from '../../../favorites-meta-card/favorite-config-mapper'; import { createTableColumnFavorite } from '../../list-table/table-cell-favorite/table-cell-favorite.component'; import { ITableColumn } from '../../list-table/table.types'; import { IListAction, IListConfig, ListViewTypes } from '../../list.component.types'; diff --git a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts index ce65f784ba..a032a1d887 100644 --- a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts +++ b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts @@ -10,6 +10,7 @@ import { ToggleSideNav } from '../../../../../store/src/actions/dashboard-action import { AddRecentlyVisitedEntityAction } from '../../../../../store/src/actions/recently-visited.actions'; import { AppState } from '../../../../../store/src/app-state'; import { EntityCatalogHelpers } from '../../../../../store/src/entity-catalog/entity-catalog.helper'; +import { FavoritesConfigMapper } from '../../../../../store/src/favorite-config-mapper'; import { selectIsMobile } from '../../../../../store/src/selectors/dashboard.selectors'; import { InternalEventSeverity } from '../../../../../store/src/types/internal-events.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../store/src/types/user-favorites.types'; @@ -18,7 +19,6 @@ import { UserProfileService } from '../../../core/user-profile.service'; import { IPageSideNavTab } from '../../../features/dashboard/page-side-nav/page-side-nav.component'; import { GlobalEventService, IGlobalEvent } from '../../global-events.service'; import { StratosStatus } from '../../shared.types'; -import { FavoritesConfigMapper } from '../favorites-meta-card/favorite-config-mapper'; import { selectDashboardState } from './../../../../../store/src/selectors/dashboard.selectors'; import { UserProfileInfo } from './../../../../../store/src/types/user-profile.types'; import { BREADCRUMB_URL_PARAM, IHeaderBreadcrumb, IHeaderBreadcrumbLink } from './page-header.types'; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index f2a65e1200..33b6fea18f 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -1,7 +1,6 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { FavoritesConfigMapper } from '../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { StratosStatus } from '../../../core/src/shared/shared.types'; import { GeneralEntityAppState } from '../app-state'; import { @@ -20,6 +19,7 @@ import { PaginationPageIteratorConfig, } from '../entity-request-pipeline/pagination-request-base-handlers/pagination-iterator.pipe'; import { EndpointAuthTypeConfig } from '../extension-types'; +import { FavoritesConfigMapper } from '../favorite-config-mapper'; import { EntitySchema } from '../helpers/entity-schema'; import { EndpointModel } from '../types/endpoint.types'; import { UserFavorite } from '../types/user-favorites.types'; diff --git a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorite-config-mapper.ts b/src/frontend/packages/store/src/favorite-config-mapper.ts similarity index 86% rename from src/frontend/packages/core/src/shared/components/favorites-meta-card/favorite-config-mapper.ts rename to src/frontend/packages/store/src/favorite-config-mapper.ts index 94e4d2bbd6..7a5faf9b60 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorite-config-mapper.ts +++ b/src/frontend/packages/store/src/favorite-config-mapper.ts @@ -1,21 +1,16 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; import { - StratosBaseCatalogEntity, -} from '../../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; -import { EntityCatalogHelpers } from '../../../../../store/src/entity-catalog/entity-catalog.helper'; -import { IEntityMetadata, IStratosEntityDefinition } from '../../../../../store/src/entity-catalog/entity-catalog.types'; -import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; -import { EntityRequestAction } from '../../../../../store/src/types/request.types'; -import { - IFavoriteMetadata, - IFavoriteTypeInfo, - UserFavorite, - UserFavoriteEndpoint, -} from '../../../../../store/src/types/user-favorites.types'; -import { MetaCardMenuItem } from '../list/list-cards/meta-card/meta-card-base/meta-card.component'; + MetaCardMenuItem, +} from '../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; +import { entityCatalog } from './entity-catalog/entity-catalog'; +import { StratosBaseCatalogEntity } from './entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { EntityCatalogHelpers } from './entity-catalog/entity-catalog.helper'; +import { IEntityMetadata, IStratosEntityDefinition } from './entity-catalog/entity-catalog.types'; +import { EndpointModel } from './types/endpoint.types'; +import { EntityRequestAction } from './types/request.types'; +import { IFavoriteMetadata, IFavoriteTypeInfo, UserFavorite, UserFavoriteEndpoint } from './types/user-favorites.types'; export interface IFavoriteTypes { diff --git a/src/frontend/packages/store/src/user-favorite-helpers.ts b/src/frontend/packages/store/src/user-favorite-helpers.ts index 2033859a4f..84f81be582 100644 --- a/src/frontend/packages/store/src/user-favorite-helpers.ts +++ b/src/frontend/packages/store/src/user-favorite-helpers.ts @@ -1,6 +1,6 @@ -import { FavoritesConfigMapper } from '../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { entityCatalog } from './entity-catalog/entity-catalog'; import { IEntityMetadata } from './entity-catalog/entity-catalog.types'; +import { FavoritesConfigMapper } from './favorite-config-mapper'; import { IFavoriteMetadata, UserFavorite } from './types/user-favorites.types'; export function isEndpointTypeFavorite(favorite: UserFavorite) { diff --git a/src/frontend/packages/store/src/user-favorite-manager.ts b/src/frontend/packages/store/src/user-favorite-manager.ts index b67f56c0e3..d6420bf804 100644 --- a/src/frontend/packages/store/src/user-favorite-manager.ts +++ b/src/frontend/packages/store/src/user-favorite-manager.ts @@ -3,13 +3,10 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of } from 'rxjs'; import { filter, map, switchMap, tap } from 'rxjs/operators'; -import { - FavoritesConfigMapper, - TFavoriteMapperFunction, -} from '../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { ToggleUserFavoriteAction } from './actions/user-favourites-actions/toggle-user-favorite-action'; import { GeneralEntityAppState, IRequestEntityTypeState } from './app-state'; import { entityCatalog } from './entity-catalog/entity-catalog'; +import { FavoritesConfigMapper, TFavoriteMapperFunction } from './favorite-config-mapper'; import { endpointEntitiesSelector } from './selectors/endpoint.selectors'; import { errorFetchingFavoritesSelector, From 74a6ca32d6a93a4e05c7eb0d57584b2b1a590bd1 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 19:45:10 +0100 Subject: [PATCH 65/82] Remove dependency on StratosScopeStrings --- .../store/src/selectors/current-user-role.selectors.ts | 3 +-- src/frontend/packages/store/src/types/auth.types.ts | 4 +--- src/frontend/packages/store/src/types/endpoint.types.ts | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts index 166767e168..6e274d7fa8 100644 --- a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts +++ b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts @@ -1,7 +1,6 @@ import { compose } from '@ngrx/store'; import { PermissionValues } from '../../../core/src/core/permissions/current-user-permissions.config'; -import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; import { CurrentUserRolesAppState } from '../app-state'; import { ICurrentUserRolesState, IStratosRolesState } from '../types/current-user-roles.types'; import { UserScopeStrings } from '../types/endpoint.types'; @@ -38,7 +37,7 @@ export const getCurrentUserStratosRole = (role: PermissionValues) => compose( // Top level stratos endpoint scopes // ============================ -export const getCurrentUserStratosHasScope = (scope: StratosScopeStrings) => compose( +export const getCurrentUserStratosHasScope = (scope: UserScopeStrings) => compose( selectCurrentUserGlobalHasScopes(scope), selectCurrentUserStratosScopesState, getCurrentUserStratosRolesState diff --git a/src/frontend/packages/store/src/types/auth.types.ts b/src/frontend/packages/store/src/types/auth.types.ts index 5cf7e40f42..7795c7e242 100644 --- a/src/frontend/packages/store/src/types/auth.types.ts +++ b/src/frontend/packages/store/src/types/auth.types.ts @@ -1,5 +1,3 @@ -import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; - export interface SessionDataEndpoint { guid: string; name: string; @@ -11,7 +9,7 @@ export interface SessionUser { admin: boolean; guid: string; name: string; - scopes: StratosScopeStrings[]; + scopes: []; } export interface PluginConfig { userInvitationsEnabled: 'true' | 'false'; diff --git a/src/frontend/packages/store/src/types/endpoint.types.ts b/src/frontend/packages/store/src/types/endpoint.types.ts index 25ccfe3689..779b7cabbd 100644 --- a/src/frontend/packages/store/src/types/endpoint.types.ts +++ b/src/frontend/packages/store/src/types/endpoint.types.ts @@ -1,4 +1,3 @@ -import { StratosScopeStrings } from '../../../core/src/core/permissions/stratos-user-permissions.checker'; import { MetricsAPITargets, MetricsStratosInfo } from '../actions/metrics-api.actions'; import { EndpointType } from '../extension-types'; import { endpointSchemaKey } from '../helpers/entity-factory'; @@ -63,7 +62,7 @@ export interface EndpointModel { export const SystemSharedUserGuid = '00000000-1111-2222-3333-444444444444'; -export type UserScopeStrings = string | StratosScopeStrings; +export type UserScopeStrings = string; // Metadata for the user connected to an endpoint export interface EndpointUser { From d4d20ae2c0c96525810b59a5f9e613376b9a5c90 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 19:47:33 +0100 Subject: [PATCH 66/82] Move BaseEndpointAuth --- .../cloud-foundry/src/cf-entity-generator.ts | 2 +- .../connect-endpoint.component.ts | 2 +- .../packages/store/src/base-entity-types.ts | 2 +- .../endpoints => store/src}/endpoint-auth.ts | 16 +++++++++++----- .../src/entity-catalog/entity-catalog.spec.ts | 2 +- 5 files changed, 15 insertions(+), 9 deletions(-) rename src/frontend/packages/{core/src/features/endpoints => store/src}/endpoint-auth.ts (59%) diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts index a3dac1cd20..a0eae51b11 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts @@ -4,9 +4,9 @@ import { combineLatest, Observable, of } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { urlValidationExpression } from '../../core/src/core/utils.service'; -import { BaseEndpointAuth } from '../../core/src/features/endpoints/endpoint-auth'; import { AppState, GeneralEntityAppState } from '../../store/src/app-state'; import { metricEntityType } from '../../store/src/base-entity-schemas'; +import { BaseEndpointAuth } from '../../store/src/endpoint-auth'; import { StratosBaseCatalogEntity, StratosCatalogEndpointEntity, diff --git a/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts b/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts index 4bc13f56bb..78c10d099a 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts @@ -14,11 +14,11 @@ import { import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Subscription } from 'rxjs'; +import { BaseEndpointAuth } from '../../../../../store/src/endpoint-auth'; import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; import { EndpointAuthTypeConfig, IAuthForm, IEndpointAuthComponent } from '../../../../../store/src/extension-types'; import { safeUnsubscribe } from '../../../core/utils.service'; import { ConnectEndpointConfig, ConnectEndpointData, ConnectEndpointService } from '../connect.service'; -import { BaseEndpointAuth } from '../endpoint-auth'; @Component({ selector: 'app-connect-endpoint', diff --git a/src/frontend/packages/store/src/base-entity-types.ts b/src/frontend/packages/store/src/base-entity-types.ts index ed2a579cb7..e9cf682103 100644 --- a/src/frontend/packages/store/src/base-entity-types.ts +++ b/src/frontend/packages/store/src/base-entity-types.ts @@ -1,4 +1,3 @@ -import { BaseEndpointAuth } from '../../core/src/features/endpoints/endpoint-auth'; import { MetricsEndpointDetailsComponent, } from '../../core/src/features/metrics/metrics-endpoint-details/metrics-endpoint-details.component'; @@ -9,6 +8,7 @@ import { userFavoritesEntitySchema, userProfileEntitySchema, } from './base-entity-schemas'; +import { BaseEndpointAuth } from './endpoint-auth'; import { StratosCatalogEndpointEntity, StratosCatalogEntity, diff --git a/src/frontend/packages/core/src/features/endpoints/endpoint-auth.ts b/src/frontend/packages/store/src/endpoint-auth.ts similarity index 59% rename from src/frontend/packages/core/src/features/endpoints/endpoint-auth.ts rename to src/frontend/packages/store/src/endpoint-auth.ts index 9c771119f0..5cad621ff1 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoint-auth.ts +++ b/src/frontend/packages/store/src/endpoint-auth.ts @@ -1,10 +1,16 @@ import { Validators } from '@angular/forms'; -import { EndpointAuthTypeConfig, EndpointType } from '../../../../store/src/extension-types'; -import { CredentialsAuthFormComponent } from './connect-endpoint-dialog/auth-forms/credentials-auth-form.component'; -import { NoneAuthFormComponent } from './connect-endpoint-dialog/auth-forms/none-auth-form.component'; -import { SSOAuthFormComponent } from './connect-endpoint-dialog/auth-forms/sso-auth-form.component'; -import { EndpointAuthTypeNames } from './endpoint-helpers'; +import { + CredentialsAuthFormComponent, +} from '../../core/src/features/endpoints/connect-endpoint-dialog/auth-forms/credentials-auth-form.component'; +import { + NoneAuthFormComponent, +} from '../../core/src/features/endpoints/connect-endpoint-dialog/auth-forms/none-auth-form.component'; +import { + SSOAuthFormComponent, +} from '../../core/src/features/endpoints/connect-endpoint-dialog/auth-forms/sso-auth-form.component'; +import { EndpointAuthTypeNames } from '../../core/src/features/endpoints/endpoint-helpers'; +import { EndpointAuthTypeConfig, EndpointType } from './extension-types'; export abstract class BaseEndpointAuth { static readonly UsernamePassword = { diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts index ce4979a9fc..38bd2aec54 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts @@ -1,8 +1,8 @@ -import { BaseEndpointAuth } from '../../../core/src/features/endpoints/endpoint-auth'; import { EndpointListDetailsComponent, } from '../../../core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers'; import { endpointEntitySchema } from '../base-entity-schemas'; +import { BaseEndpointAuth } from '../endpoint-auth'; import { EntitySchema } from '../helpers/entity-schema'; import { TestEntityCatalog } from './entity-catalog'; import { StratosCatalogEndpointEntity, StratosCatalogEntity } from './entity-catalog-entity/entity-catalog-entity'; From 2b682bea04fbebc7e8a173bb324f5713a06cbfe3 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 19:52:41 +0100 Subject: [PATCH 67/82] Move StratosTheme --- src/frontend/packages/core/src/core/theme.service.ts | 9 ++------- .../packages/store/src/actions/dashboard-actions.ts | 2 +- src/frontend/packages/store/src/types/theme.types.ts | 5 +++++ 3 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 src/frontend/packages/store/src/types/theme.types.ts diff --git a/src/frontend/packages/core/src/core/theme.service.ts b/src/frontend/packages/core/src/core/theme.service.ts index 2d8efab76a..5ca3a378fb 100644 --- a/src/frontend/packages/core/src/core/theme.service.ts +++ b/src/frontend/packages/core/src/core/theme.service.ts @@ -2,19 +2,14 @@ import { OverlayContainer } from '@angular/cdk/overlay'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { first, map, filter } from 'rxjs/operators'; +import { filter, first, map } from 'rxjs/operators'; import { SetThemeAction } from '../../../store/src/actions/dashboard-actions'; import { DashboardOnlyAppState } from '../../../store/src/app-state'; import { selectDashboardState } from '../../../store/src/selectors/dashboard.selectors'; +import { StratosTheme } from '../../../store/src/types/theme.types'; import { StyleService } from './style.service'; -export interface StratosTheme { - key: string; - label: string; - styleName: string; -} - const lightTheme: StratosTheme = { key: 'default', label: 'Light', diff --git a/src/frontend/packages/store/src/actions/dashboard-actions.ts b/src/frontend/packages/store/src/actions/dashboard-actions.ts index 946b291c16..a2bc55101a 100644 --- a/src/frontend/packages/store/src/actions/dashboard-actions.ts +++ b/src/frontend/packages/store/src/actions/dashboard-actions.ts @@ -1,7 +1,7 @@ import { Action } from '@ngrx/store'; -import { StratosTheme } from '../../../core/src/core/theme.service'; import { DashboardState } from '../reducers/dashboard-reducer'; +import { StratosTheme } from '../types/theme.types'; export const OPEN_SIDE_NAV = '[Dashboard] Open side nav'; export const CLOSE_SIDE_NAV = '[Dashboard] Close side nav'; diff --git a/src/frontend/packages/store/src/types/theme.types.ts b/src/frontend/packages/store/src/types/theme.types.ts new file mode 100644 index 0000000000..a31d01e5c3 --- /dev/null +++ b/src/frontend/packages/store/src/types/theme.types.ts @@ -0,0 +1,5 @@ +export interface StratosTheme { + key: string; + label: string; + styleName: string; +} \ No newline at end of file From bd51864e71a50afb3a94686a4e94ca6f6e67e2d0 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 19:58:02 +0100 Subject: [PATCH 68/82] Move ThemeService --- src/frontend/packages/core/src/app.component.ts | 6 +++--- .../packages/core/src/features/setup/setup.module.ts | 2 +- .../profile-info/profile-info.component.ts | 2 +- .../packages/store/src/effects/dashboard.effects.ts | 2 +- .../{core/src/core => store/src}/theme.service.ts | 10 +++++----- 5 files changed, 11 insertions(+), 11 deletions(-) rename src/frontend/packages/{core/src/core => store/src}/theme.service.ts (92%) diff --git a/src/frontend/packages/core/src/app.component.ts b/src/frontend/packages/core/src/app.component.ts index 542077cb5e..7e7be0556e 100644 --- a/src/frontend/packages/core/src/app.component.ts +++ b/src/frontend/packages/core/src/app.component.ts @@ -1,13 +1,13 @@ -import { AfterContentInit, Component, HostBinding, OnDestroy, OnInit, Inject } from '@angular/core'; +import { DOCUMENT } from '@angular/common'; +import { AfterContentInit, Component, HostBinding, Inject, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { create } from 'rxjs-spy'; import { AuthOnlyAppState } from '../../store/src/app-state'; -import { ThemeService } from './core/theme.service'; +import { ThemeService } from '../../store/src/theme.service'; import { environment } from './environments/environment'; import { LoggedInService } from './logged-in.service'; -import { DOCUMENT } from '@angular/common'; @Component({ selector: 'app-root', diff --git a/src/frontend/packages/core/src/features/setup/setup.module.ts b/src/frontend/packages/core/src/features/setup/setup.module.ts index cd9593967a..c730116607 100644 --- a/src/frontend/packages/core/src/features/setup/setup.module.ts +++ b/src/frontend/packages/core/src/features/setup/setup.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; +import { ThemeService } from '../../../../store/src/theme.service'; import { CoreModule } from '../../core/core.module'; -import { ThemeService } from '../../core/theme.service'; import { SharedModule } from '../../shared/shared.module'; import { DomainMismatchComponent } from './domain-mismatch/domain-mismatch.component'; import { LocalAccountWizardComponent } from './local-account-wizard/local-account-wizard.component'; diff --git a/src/frontend/packages/core/src/features/user-profile/profile-info/profile-info.component.ts b/src/frontend/packages/core/src/features/user-profile/profile-info/profile-info.component.ts index d5984a3886..915ecd6aea 100644 --- a/src/frontend/packages/core/src/features/user-profile/profile-info/profile-info.component.ts +++ b/src/frontend/packages/core/src/features/user-profile/profile-info/profile-info.component.ts @@ -6,8 +6,8 @@ import { map } from 'rxjs/operators'; import { SetPollingEnabledAction, SetSessionTimeoutAction } from '../../../../../store/src/actions/dashboard-actions'; import { DashboardOnlyAppState } from '../../../../../store/src/app-state'; import { selectDashboardState } from '../../../../../store/src/selectors/dashboard.selectors'; +import { ThemeService } from '../../../../../store/src/theme.service'; import { UserProfileInfo } from '../../../../../store/src/types/user-profile.types'; -import { ThemeService } from '../../../core/theme.service'; import { UserProfileService } from '../../../core/user-profile.service'; import { UserService } from '../../../core/user.service'; import { SetGravatarEnabledAction } from './../../../../../store/src/actions/dashboard-actions'; diff --git a/src/frontend/packages/store/src/effects/dashboard.effects.ts b/src/frontend/packages/store/src/effects/dashboard.effects.ts index 2d34737508..3e70adb94b 100644 --- a/src/frontend/packages/store/src/effects/dashboard.effects.ts +++ b/src/frontend/packages/store/src/effects/dashboard.effects.ts @@ -2,8 +2,8 @@ import { Injectable } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { map } from 'rxjs/operators'; -import { ThemeService } from '../../../core/src/core/theme.service'; import { HYDRATE_DASHBOARD_STATE, HydrateDashboardStateAction } from '../actions/dashboard-actions'; +import { ThemeService } from '../theme.service'; @Injectable() diff --git a/src/frontend/packages/core/src/core/theme.service.ts b/src/frontend/packages/store/src/theme.service.ts similarity index 92% rename from src/frontend/packages/core/src/core/theme.service.ts rename to src/frontend/packages/store/src/theme.service.ts index 5ca3a378fb..82cfbf0a26 100644 --- a/src/frontend/packages/core/src/core/theme.service.ts +++ b/src/frontend/packages/store/src/theme.service.ts @@ -4,11 +4,11 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { filter, first, map } from 'rxjs/operators'; -import { SetThemeAction } from '../../../store/src/actions/dashboard-actions'; -import { DashboardOnlyAppState } from '../../../store/src/app-state'; -import { selectDashboardState } from '../../../store/src/selectors/dashboard.selectors'; -import { StratosTheme } from '../../../store/src/types/theme.types'; -import { StyleService } from './style.service'; +import { StyleService } from '../../core/src/core/style.service'; +import { SetThemeAction } from './actions/dashboard-actions'; +import { DashboardOnlyAppState } from './app-state'; +import { selectDashboardState } from './selectors/dashboard.selectors'; +import { StratosTheme } from './types/theme.types'; const lightTheme: StratosTheme = { key: 'default', From d4bcc8c177d0d11c8189c7ffa23d5eb787048cdc Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 19:59:32 +0100 Subject: [PATCH 69/82] Move types from utils.service that are only used once in store --- .../packages/core/src/core/utils.service.ts | 17 ------------- .../entity-catalog-entity.types.ts | 25 ++++++++++++++++--- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/frontend/packages/core/src/core/utils.service.ts b/src/frontend/packages/core/src/core/utils.service.ts index 37de7d5cab..74255c5e57 100644 --- a/src/frontend/packages/core/src/core/utils.service.ts +++ b/src/frontend/packages/core/src/core/utils.service.ts @@ -17,25 +17,8 @@ export type OptionalKeys = Exclude<{ : never }[keyof T], undefined> -export type NeverKeys = Exclude<{ - [K in keyof T]: T[K] extends never - ? K - : never -}[keyof T], undefined> -/** - * Pick all properties who's function has the specified return type U - */ -export type FilteredByReturnType any }, U> = { - [P in keyof T]: ReturnType extends U ? T[P] : never -}; -/** - * Pick all properties who's function do not have the specified return type U - */ -export type FilteredByNotReturnType any }, U> = { - [P in keyof T]: ReturnType extends U ? never : T[P] -}; // Note - Adding }[keyof T] to [P in keyof T] types should filter out properties of type `never`, however this fails with generics! export type FilteredByValueType any }, U> = { diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts index 93a0b5e40b..3d2c458d9d 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts @@ -1,4 +1,3 @@ -import { FilteredByNotReturnType, FilteredByReturnType, NeverKeys } from '../../../../core/src/core/utils.service'; import { EntityService } from '../../entity-service'; import { EntityMonitor } from '../../monitors/entity-monitor'; import { PaginationMonitor } from '../../monitors/pagination-monitor'; @@ -12,10 +11,30 @@ import { OrchestratedActionBuilders, OrchestratedActionCoreBuilders } from '../a * - https://github.com/Microsoft/TypeScript/issues/25987#issuecomment-441224690 * - https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-414808995 */ -export type KnownKeys = { +type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { [_ in keyof T]: infer U } ? ({} extends U ? never : U) : never; +type NeverKeys = Exclude<{ + [K in keyof T]: T[K] extends never + ? K + : never +}[keyof T], undefined> + +/** + * Pick all properties who's function has the specified return type U + */ +type FilteredByReturnType any }, U> = { + [P in keyof T]: ReturnType extends U ? T[P] : never +}; + +/** + * Pick all properties who's function do not have the specified return type U + */ +type FilteredByNotReturnType any }, U> = { + [P in keyof T]: ReturnType extends U ? never : T[P] +}; + /** * Core entity and entities access (entity/entities monitors and services) */ @@ -110,7 +129,7 @@ export type CustomEntityCatalogEntityStore Date: Thu, 18 Jun 2020 20:06:29 +0100 Subject: [PATCH 70/82] Move PermissionValues --- .../store/selectors/cf-current-user-role.selectors.ts | 2 +- .../src/user-permissions/cf-user-permissions-checkers.ts | 2 +- .../core/permissions/current-user-permissions.config.ts | 3 ++- .../core/permissions/stratos-user-permissions.checker.ts | 3 ++- .../core/src/features/endpoints/endpoint-helpers.ts | 6 ------ src/frontend/packages/store/src/endpoint-auth.ts | 7 ++++++- .../entity-catalog-entity/entity-catalog-entity.ts | 8 +------- .../entity-catalog-entity/entity-catalog-entity.types.ts | 9 ++++++++- .../store/src/selectors/current-user-role.selectors.ts | 2 +- 9 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts b/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts index c3df05ca37..ee2fd00471 100644 --- a/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts +++ b/src/frontend/packages/cloud-foundry/src/store/selectors/cf-current-user-role.selectors.ts @@ -1,7 +1,7 @@ import { compose } from '@ngrx/store'; -import { PermissionValues } from '../../../../core/src/core/permissions/current-user-permissions.config'; import { + PermissionValues, selectCurrentUserGlobalHasScopes, selectCurrentUserRolesState, } from '../../../../store/src/selectors/current-user-role.selectors'; diff --git a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts index 5d4e9bc1be..1aead1cd0f 100644 --- a/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts +++ b/src/frontend/packages/cloud-foundry/src/user-permissions/cf-user-permissions-checkers.ts @@ -7,7 +7,6 @@ import { PermissionConfig, PermissionConfigLink, PermissionTypes, - PermissionValues, } from '../../../core/src/core/permissions/current-user-permissions.config'; import { CurrentUserPermissionsService, @@ -21,6 +20,7 @@ import { IPermissionCheckCombiner, } from '../../../core/src/core/permissions/current-user-permissions.types'; import { GeneralEntityAppState } from '../../../store/src/app-state'; +import { PermissionValues } from '../../../store/src/selectors/current-user-role.selectors'; import { connectedEndpointsSelector } from '../../../store/src/selectors/endpoint.selectors'; import { CFFeatureFlagTypes, IFeatureFlag } from '../cf-api.types'; import { cfEntityCatalog } from '../cf-entity-catalog'; diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.config.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.config.ts index a91481dd62..9e08107255 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.config.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.config.ts @@ -1,3 +1,5 @@ +import { PermissionValues } from '../../../../store/src/selectors/current-user-role.selectors'; + export type PermissionConfigType = PermissionConfig[] | PermissionConfig | PermissionConfigLink; export interface IPermissionConfigs { [permissionString: string]: PermissionConfigType; @@ -6,7 +8,6 @@ export interface IPermissionConfigs { export type PermissionTypes = string; export type CurrentUserPermissions = string; export type ScopeStrings = string; -export type PermissionValues = string; export class PermissionConfig { constructor( public type: PermissionTypes, diff --git a/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts index a0bcb58695..db4c382b26 100644 --- a/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts +++ b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts @@ -5,8 +5,9 @@ import { GeneralEntityAppState } from '../../../../store/src/app-state'; import { getCurrentUserStratosHasScope, getCurrentUserStratosRole, + PermissionValues, } from '../../../../store/src/selectors/current-user-role.selectors'; -import { IPermissionConfigs, PermissionConfig, PermissionTypes, PermissionValues } from './current-user-permissions.config'; +import { IPermissionConfigs, PermissionConfig, PermissionTypes } from './current-user-permissions.config'; import { BaseCurrentUserPermissionsChecker, IConfigGroups, diff --git a/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts b/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts index 39d567fe8b..2f0187bb62 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts +++ b/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts @@ -27,12 +27,6 @@ export interface EndpointIcon { font: string; } -export enum EndpointAuthTypeNames { - CREDS = 'creds', - SSO = 'sso', - NONE = 'none' -} - // Any initial endpointTypes listDetailsComponent should be added here export const coreEndpointListDetailsComponents: Type[] = []; diff --git a/src/frontend/packages/store/src/endpoint-auth.ts b/src/frontend/packages/store/src/endpoint-auth.ts index 5cad621ff1..c5f857da8b 100644 --- a/src/frontend/packages/store/src/endpoint-auth.ts +++ b/src/frontend/packages/store/src/endpoint-auth.ts @@ -9,9 +9,14 @@ import { import { SSOAuthFormComponent, } from '../../core/src/features/endpoints/connect-endpoint-dialog/auth-forms/sso-auth-form.component'; -import { EndpointAuthTypeNames } from '../../core/src/features/endpoints/endpoint-helpers'; import { EndpointAuthTypeConfig, EndpointType } from './extension-types'; +export enum EndpointAuthTypeNames { + CREDS = 'creds', + SSO = 'sso', + NONE = 'none' +} + export abstract class BaseEndpointAuth { static readonly UsernamePassword = { name: 'Username and Password', diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts index 0bf0715cbc..3f48831325 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts @@ -35,13 +35,7 @@ import { } from '../entity-catalog.types'; import { ActionBuilderConfigMapper } from './action-builder-config.mapper'; import { ActionDispatchers, EntityCatalogEntityStoreHelpers } from './entity-catalog-entity-store-helpers'; -import { EntityCatalogEntityStore, KnownKeys } from './entity-catalog-entity.types'; - -type NonOptionalKeys = Exclude<{ - [K in keyof T]: T extends Record - ? K - : never -}[keyof T], undefined> +import { EntityCatalogEntityStore, KnownKeys, NonOptionalKeys } from './entity-catalog-entity.types'; export type KnownActionBuilders = Pick>>>; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts index 3d2c458d9d..02f63c8e61 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts @@ -5,13 +5,20 @@ import { PaginationObservables } from '../../reducers/pagination-reducer/paginat import { PaginatedAction } from '../../types/pagination.types'; import { OrchestratedActionBuilders, OrchestratedActionCoreBuilders } from '../action-orchestrator/action-orchestrator'; +export type NonOptionalKeys = Exclude<{ + [K in keyof T]: T extends Record + ? K + : never +}[keyof T], undefined> + + /** * Remove keys such as typed indexes (i.e. [key: string]) * For magic see * - https://github.com/Microsoft/TypeScript/issues/25987#issuecomment-441224690 * - https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-414808995 */ -type KnownKeys = { +export type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { [_ in keyof T]: infer U } ? ({} extends U ? never : U) : never; diff --git a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts index 6e274d7fa8..b26832638a 100644 --- a/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts +++ b/src/frontend/packages/store/src/selectors/current-user-role.selectors.ts @@ -1,10 +1,10 @@ import { compose } from '@ngrx/store'; -import { PermissionValues } from '../../../core/src/core/permissions/current-user-permissions.config'; import { CurrentUserRolesAppState } from '../app-state'; import { ICurrentUserRolesState, IStratosRolesState } from '../types/current-user-roles.types'; import { UserScopeStrings } from '../types/endpoint.types'; +export type PermissionValues = string; export const selectCurrentUserRolesState = (state: CurrentUserRolesAppState) => state.currentUserRoles; From 6393755ddf7bd66d2f5edc5853155789779adf07 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 20:12:44 +0100 Subject: [PATCH 71/82] Move http and jetstream helpers --- .../src/store/autoscaler.effects.ts | 2 +- .../cloud-foundry/src/cf-error-helpers.ts | 3 +- .../packages/core/src/jetstream.helpers.ts | 46 +---------------- .../store/src/effects/uaa-setup.effects.ts | 2 +- .../handle-multi-endpoints.pipe.spec.ts | 2 +- .../handle-multi-endpoints.pipe.ts | 4 +- .../entity-request-pipeline.ts | 2 +- .../entity-request-pipeline.types.ts | 2 +- src/frontend/packages/store/src/jetstream.ts | 49 +++++++++++++++++++ 9 files changed, 59 insertions(+), 53 deletions(-) diff --git a/src/frontend/packages/cf-autoscaler/src/store/autoscaler.effects.ts b/src/frontend/packages/cf-autoscaler/src/store/autoscaler.effects.ts index e85527a5cd..98c2e1e7c1 100644 --- a/src/frontend/packages/cf-autoscaler/src/store/autoscaler.effects.ts +++ b/src/frontend/packages/cf-autoscaler/src/store/autoscaler.effects.ts @@ -7,9 +7,9 @@ import { catchError, mergeMap, withLatestFrom } from 'rxjs/operators'; import { PaginationResponse } from '../../../cloud-foundry/src/store/types/cf-api.types'; import { environment } from '../../../core/src/environments/environment'; -import { isHttpErrorResponse } from '../../../core/src/jetstream.helpers'; import { AppState } from '../../../store/src/app-state'; import { entityCatalog } from '../../../store/src/entity-catalog/entity-catalog'; +import { isHttpErrorResponse } from '../../../store/src/jetstream'; import { ApiRequestTypes } from '../../../store/src/reducers/api-request-reducer/request-helpers'; import { resultPerPageParam, diff --git a/src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts b/src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts index 73c4b0c0d4..81e86196ad 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts @@ -1,4 +1,5 @@ -import { JetStreamErrorResponse, jetStreamErrorResponseToSafeString } from '../../core/src/jetstream.helpers'; +import { jetStreamErrorResponseToSafeString } from '../../core/src/jetstream.helpers'; +import { JetStreamErrorResponse } from '../../store/src/jetstream'; export interface CfErrorObject { code: number; diff --git a/src/frontend/packages/core/src/jetstream.helpers.ts b/src/frontend/packages/core/src/jetstream.helpers.ts index 1a29978099..e6f191b74f 100644 --- a/src/frontend/packages/core/src/jetstream.helpers.ts +++ b/src/frontend/packages/core/src/jetstream.helpers.ts @@ -1,39 +1,7 @@ import { HttpErrorResponse } from '@angular/common/http'; -/** - * Actual error response from stratos - */ -export interface JetStreamErrorResponse { - error: { - status: string; - statusCode: number; - }; - /** - * Actual response from proxied endpoint - */ - errorResponse: T; -} +import { isHttpErrorResponse, JetStreamErrorResponse } from '../../store/src/jetstream'; -export function isJetstreamError(err: any): JetStreamErrorResponse { - return !!( - err && - err.error && - err.error.status && - err.error.statusCode && - 'errorResponse' in err - ) ? err as JetStreamErrorResponse : null; -} - -// TODO It would be nice if the BE could return a unique para for us to check for. #3827 -// There is always a chance that this will return a false positive (more so with extensions). -export function hasJetStreamError(pages: Partial[]): JetStreamErrorResponse { - if (!pages || !pages.length) { - return null; - } - return pages.find(page => { - return isJetstreamError(page); - }) as JetStreamErrorResponse; -} export function jetStreamErrorResponseToSafeString(response: JetStreamErrorResponse): string { return response.error && response.error.status && response.error.statusCode ? @@ -41,18 +9,6 @@ export function jetStreamErrorResponseToSafeString(response: JetStreamErrorRespo null; } -export function isHttpErrorResponse(obj: any): HttpErrorResponse { - const props = Object.keys(obj); - return ( - props.indexOf('error') >= 0 && - props.indexOf('headers') >= 0 && - props.indexOf('ok') >= 0 && - props.indexOf('status') >= 0 && - props.indexOf('statusText') >= 0 && - props.indexOf('url') >= 0 - ) ? obj as HttpErrorResponse : null; -} - /** * Attempt to create a sensible string explaining the error object returned from a failed http request * @param err The raw error from a http request diff --git a/src/frontend/packages/store/src/effects/uaa-setup.effects.ts b/src/frontend/packages/store/src/effects/uaa-setup.effects.ts index 9e193e4380..ea7092d69b 100644 --- a/src/frontend/packages/store/src/effects/uaa-setup.effects.ts +++ b/src/frontend/packages/store/src/effects/uaa-setup.effects.ts @@ -3,7 +3,7 @@ import { Injectable } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { catchError, map, switchMap } from 'rxjs/operators'; -import { isHttpErrorResponse } from '../../../core/src/jetstream.helpers'; +import { isHttpErrorResponse } from '../jetstream'; import { SETUP_GET_SCOPES, SETUP_SAVE_CONFIG, diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/handle-multi-endpoints.pipe.spec.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/handle-multi-endpoints.pipe.spec.ts index 59e448d735..d82d9e77ed 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/handle-multi-endpoints.pipe.spec.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/handle-multi-endpoints.pipe.spec.ts @@ -1,6 +1,6 @@ import { of } from 'rxjs'; -import { JetStreamErrorResponse } from '../../../../core/src/jetstream.helpers'; +import { JetStreamErrorResponse } from '../../jetstream'; import { JetstreamResponse } from '../entity-request-pipeline.types'; import { handleJetstreamResponsePipeFactory, JetstreamError } from './handle-multi-endpoints.pipe'; diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/handle-multi-endpoints.pipe.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/handle-multi-endpoints.pipe.ts index 8ae7a743b1..5be8e90170 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/handle-multi-endpoints.pipe.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-base-handlers/handle-multi-endpoints.pipe.ts @@ -1,8 +1,8 @@ -import { hasJetStreamError, JetStreamErrorResponse } from '../../../../core/src/jetstream.helpers'; +import { NonJetstreamRequestHandler } from '../../entity-catalog/entity-catalog.types'; +import { hasJetStreamError, JetStreamErrorResponse } from '../../jetstream'; import { PagedJetstreamResponse } from '../entity-request-pipeline.types'; import { PaginationPageIteratorConfig } from '../pagination-request-base-handlers/pagination-iterator.pipe'; import { stratosEndpointGuidKey } from '../pipeline.types'; -import { NonJetstreamRequestHandler } from '../../entity-catalog/entity-catalog.types'; /** * Generic container for information about an errored request to a specific endpoint diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.ts index 2fbc4f3eda..661461c77f 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.ts @@ -2,11 +2,11 @@ import { Action, Store } from '@ngrx/store'; import { of } from 'rxjs'; import { catchError, map, tap } from 'rxjs/operators'; -import { isHttpErrorResponse } from '../../../core/src/jetstream.helpers'; import { AppState, InternalAppState } from '../app-state'; import { RecursiveDelete } from '../effects/recursive-entity-delete.effect'; import { entityCatalog } from '../entity-catalog/entity-catalog'; import { StratosBaseCatalogEntity } from '../entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { isHttpErrorResponse } from '../jetstream'; import { ApiRequestTypes, getRequestTypeFromMethod } from '../reducers/api-request-reducer/request-helpers'; import { PaginatedAction } from '../types/pagination.types'; import { EntityRequestAction } from '../types/request.types'; diff --git a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts index 74975aad4f..d32a05be26 100644 --- a/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts +++ b/src/frontend/packages/store/src/entity-request-pipeline/entity-request-pipeline.types.ts @@ -2,12 +2,12 @@ import { HttpClient, HttpRequest } from '@angular/common/http'; import { Action, Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { JetStreamErrorResponse } from '../../../core/src/jetstream.helpers'; import { AppState, GeneralEntityAppState, InternalAppState } from '../app-state'; import { StratosBaseCatalogEntity, StratosCatalogEndpointEntity, } from '../entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { JetStreamErrorResponse } from '../jetstream'; import { ApiRequestTypes } from '../reducers/api-request-reducer/request-helpers'; import { EntityInfo, NormalizedResponse } from '../types/api.types'; import { EndpointUser } from '../types/endpoint.types'; diff --git a/src/frontend/packages/store/src/jetstream.ts b/src/frontend/packages/store/src/jetstream.ts index dc30c9a4a0..c41746d425 100644 --- a/src/frontend/packages/store/src/jetstream.ts +++ b/src/frontend/packages/store/src/jetstream.ts @@ -1,5 +1,54 @@ +import { HttpErrorResponse } from '@angular/common/http'; + // API Version to use when making back-end API requests to Jetstraam export const proxyAPIVersion = 'v1'; // CF API Version export const cfAPIVersion = 'v2'; + +/** + * Actual error response from stratos + */ +export interface JetStreamErrorResponse { + error: { + status: string; + statusCode: number; + }; + /** + * Actual response from proxied endpoint + */ + errorResponse: T; +} + +export function isHttpErrorResponse(obj: any): HttpErrorResponse { + const props = Object.keys(obj); + return ( + props.indexOf('error') >= 0 && + props.indexOf('headers') >= 0 && + props.indexOf('ok') >= 0 && + props.indexOf('status') >= 0 && + props.indexOf('statusText') >= 0 && + props.indexOf('url') >= 0 + ) ? obj as HttpErrorResponse : null; +} + +// TODO It would be nice if the BE could return a unique para for us to check for. #3827 +// There is always a chance that this will return a false positive (more so with extensions). +export function hasJetStreamError(pages: Partial[]): JetStreamErrorResponse { + if (!pages || !pages.length) { + return null; + } + return pages.find(page => { + return isJetstreamError(page); + }) as JetStreamErrorResponse; +} + +function isJetstreamError(err: any): JetStreamErrorResponse { + return !!( + err && + err.error && + err.error.status && + err.error.statusCode && + 'errorResponse' in err + ) ? err as JetStreamErrorResponse : null; +} From ed65a6fc98d217b39695cdc5b79d45d1f943552b Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 20:28:19 +0100 Subject: [PATCH 72/82] Move StyleService --- .../packages/{core/src/core => store/src}/style.service.ts | 0 src/frontend/packages/store/src/theme.service.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/frontend/packages/{core/src/core => store/src}/style.service.ts (100%) diff --git a/src/frontend/packages/core/src/core/style.service.ts b/src/frontend/packages/store/src/style.service.ts similarity index 100% rename from src/frontend/packages/core/src/core/style.service.ts rename to src/frontend/packages/store/src/style.service.ts diff --git a/src/frontend/packages/store/src/theme.service.ts b/src/frontend/packages/store/src/theme.service.ts index 82cfbf0a26..0e140476b6 100644 --- a/src/frontend/packages/store/src/theme.service.ts +++ b/src/frontend/packages/store/src/theme.service.ts @@ -4,10 +4,10 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { filter, first, map } from 'rxjs/operators'; -import { StyleService } from '../../core/src/core/style.service'; import { SetThemeAction } from './actions/dashboard-actions'; import { DashboardOnlyAppState } from './app-state'; import { selectDashboardState } from './selectors/dashboard.selectors'; +import { StyleService } from './style.service'; import { StratosTheme } from './types/theme.types'; const lightTheme: StratosTheme = { From 2e2f90367003e93a3ba1a28c61042f2eff3cdfef Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 20:33:10 +0100 Subject: [PATCH 73/82] Move MetricQueryType --- .../cf-app-autoscaler-events-config.service.ts | 3 ++- .../app-autoscaler-metric-chart-list-config.service.ts | 3 ++- .../cloud-foundry/src/actions/cf-metrics.actions.ts | 2 +- .../application-instance-chart.component.ts | 3 +-- .../src/features/cloud-foundry/cf-cell.helpers.ts | 2 +- .../cloud-foundry-cell-charts.component.ts | 3 +-- .../cloud-foundry-cell-summary.component.spec.ts | 2 +- .../cloud-foundry-cell/cloud-foundry-cell.service.ts | 3 +-- .../app-instance/cf-app-instances-config.service.ts | 3 +-- .../list/list-types/cf-cell-apps/cf-cell-apps-source.ts | 3 +-- .../metrics-parent-range-selector.component.ts | 4 ++-- .../metrics-range-selector.component.ts | 3 ++- .../services/metrics-range-selector-manager.service.ts | 5 +++-- .../src/shared/services/metrics-range-selector.service.ts | 3 ++- .../src/shared/services/metrics-range-selector.types.ts | 8 ++++---- .../packages/store/src/actions/metrics.actions.ts | 2 +- src/frontend/packages/store/src/types/metric.types.ts | 5 +++++ 17 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-event/cf-app-autoscaler-events-config.service.ts b/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-event/cf-app-autoscaler-events-config.service.ts index 98d5b15a48..8732d20bfb 100644 --- a/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-event/cf-app-autoscaler-events-config.service.ts +++ b/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-event/cf-app-autoscaler-events-config.service.ts @@ -8,8 +8,9 @@ import { ApplicationService } from '../../../../../cloud-foundry/src/features/ap import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; import { IListConfig, ListConfig, ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; import { MetricsRangeSelectorService } from '../../../../../core/src/shared/services/metrics-range-selector.service'; -import { ITimeRange, MetricQueryType } from '../../../../../core/src/shared/services/metrics-range-selector.types'; +import { ITimeRange } from '../../../../../core/src/shared/services/metrics-range-selector.types'; import { APIResource } from '../../../../../store/src/types/api.types'; +import { MetricQueryType } from '../../../../../store/src/types/metric.types'; import { AppAutoscalerEvent } from '../../../store/app-autoscaler.types'; import { CfAppAutoscalerEventsDataSource } from './cf-app-autoscaler-events-data-source'; import { diff --git a/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-list-config.service.ts b/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-list-config.service.ts index 05e19cc82a..a5c3fd8aef 100644 --- a/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-list-config.service.ts +++ b/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-list-config.service.ts @@ -10,9 +10,10 @@ import { import { ITableColumn } from '../../../../../core/src/shared/components/list/list-table/table.types'; import { ListViewTypes } from '../../../../../core/src/shared/components/list/list.component.types'; import { MetricsRangeSelectorService } from '../../../../../core/src/shared/services/metrics-range-selector.service'; -import { ITimeRange, MetricQueryType } from '../../../../../core/src/shared/services/metrics-range-selector.types'; +import { ITimeRange } from '../../../../../core/src/shared/services/metrics-range-selector.types'; import { ListView } from '../../../../../store/src/actions/list.actions'; import { APIResource } from '../../../../../store/src/types/api.types'; +import { MetricQueryType } from '../../../../../store/src/types/metric.types'; import { AutoscalerConstants } from '../../../core/autoscaler-helpers/autoscaler-util'; import { AppScalingTrigger } from '../../../store/app-autoscaler.types'; import { diff --git a/src/frontend/packages/cloud-foundry/src/actions/cf-metrics.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/cf-metrics.actions.ts index 4422c703f6..e57065e7f0 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/cf-metrics.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/cf-metrics.actions.ts @@ -1,5 +1,5 @@ -import { MetricQueryType } from '../../../core/src/shared/services/metrics-range-selector.types'; import { MetricQueryConfig, MetricsAction, MetricsChartAction } from '../../../store/src/actions/metrics.actions'; +import { MetricQueryType } from '../../../store/src/types/metric.types'; import { PaginatedAction } from '../../../store/src/types/pagination.types'; import { CF_ENDPOINT_TYPE } from '../cf-types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.ts index 5401a177bc..ae6d1e1eeb 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.ts @@ -3,10 +3,9 @@ import { Component, Input, OnInit } from '@angular/core'; import { MetricsConfig } from '../../../../../../core/src/shared/components/metrics-chart/metrics-chart.component'; import { MetricsLineChartConfig } from '../../../../../../core/src/shared/components/metrics-chart/metrics-chart.types'; import { MetricsChartHelpers } from '../../../../../../core/src/shared/components/metrics-chart/metrics.component.helpers'; -import { MetricQueryType } from '../../../../../../core/src/shared/services/metrics-range-selector.types'; import { MetricQueryConfig } from '../../../../../../store/src/actions/metrics.actions'; import { IMetricMatrixResult } from '../../../../../../store/src/types/base-metric.types'; -import { IMetricApplication } from '../../../../../../store/src/types/metric.types'; +import { IMetricApplication, MetricQueryType } from '../../../../../../store/src/types/metric.types'; import { FetchApplicationMetricsAction } from '../../../../actions/cf-metrics.actions'; @Component({ diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf-cell.helpers.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf-cell.helpers.ts index c0673a5c49..375a28581a 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf-cell.helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cf-cell.helpers.ts @@ -3,12 +3,12 @@ import { Observable, of } from 'rxjs'; import { filter, first, map, publishReplay, refCount, switchMap } from 'rxjs/operators'; import { endpointHasMetricsByAvailable } from '../../../../core/src/features/endpoints/endpoint-helpers'; -import { MetricQueryType } from '../../../../core/src/shared/services/metrics-range-selector.types'; import { MetricQueryConfig } from '../../../../store/src/actions/metrics.actions'; import { AppState } from '../../../../store/src/app-state'; import { PaginationMonitorFactory } from '../../../../store/src/monitors/pagination-monitor.factory'; import { getPaginationObservables } from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; import { IMetrics } from '../../../../store/src/types/base-metric.types'; +import { MetricQueryType } from '../../../../store/src/types/metric.types'; import { FetchCFCellMetricsPaginatedAction } from '../../actions/cf-metrics.actions'; import { CFEntityConfig } from '../../cf-types'; import { CellMetrics } from './tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-charts/cloud-foundry-cell-charts.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-charts/cloud-foundry-cell-charts.component.ts index 081ec14430..e43d9ca244 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-charts/cloud-foundry-cell-charts.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-charts/cloud-foundry-cell-charts.component.ts @@ -4,9 +4,8 @@ import { MetricsConfig } from '../../../../../../../../core/src/shared/component import { MetricsLineChartConfig, } from '../../../../../../../../core/src/shared/components/metrics-chart/metrics-chart.types'; -import { MetricQueryType } from '../../../../../../../../core/src/shared/services/metrics-range-selector.types'; import { IMetricMatrixResult } from '../../../../../../../../store/src/types/base-metric.types'; -import { IMetricCell } from '../../../../../../../../store/src/types/metric.types'; +import { IMetricCell, MetricQueryType } from '../../../../../../../../store/src/types/metric.types'; import { CloudFoundryCellService } from '../cloud-foundry-cell.service'; @Component({ diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.spec.ts index e8c160cbcf..669e75977b 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.spec.ts @@ -10,8 +10,8 @@ import { import { MetricsChartHelpers, } from '../../../../../../../../core/src/shared/components/metrics-chart/metrics.component.helpers'; -import { MetricQueryType } from '../../../../../../../../core/src/shared/services/metrics-range-selector.types'; import { MetricQueryConfig } from '../../../../../../../../store/src/actions/metrics.actions'; +import { MetricQueryType } from '../../../../../../../../store/src/types/metric.types'; import { generateCfBaseTestModules } from '../../../../../../../test-framework/cloud-foundry-endpoint-service.helper'; import { FetchCFCellMetricsAction } from '../../../../../../actions/cf-metrics.actions'; import { ActiveRouteCfCell } from '../../../../cf-page.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell.service.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell.service.ts index fb6c1e76ec..708a438723 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell.service.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell.service.ts @@ -8,13 +8,12 @@ import { MetricsLineChartConfig } from '../../../../../../../core/src/shared/com import { MetricsChartHelpers, } from '../../../../../../../core/src/shared/components/metrics-chart/metrics.component.helpers'; -import { MetricQueryType } from '../../../../../../../core/src/shared/services/metrics-range-selector.types'; import { MetricQueryConfig } from '../../../../../../../store/src/actions/metrics.actions'; import { AppState } from '../../../../../../../store/src/app-state'; import { EntityServiceFactory } from '../../../../../../../store/src/entity-service-factory.service'; import { PaginationMonitorFactory } from '../../../../../../../store/src/monitors/pagination-monitor.factory'; import { IMetricMatrixResult, IMetrics, IMetricVectorResult } from '../../../../../../../store/src/types/base-metric.types'; -import { IMetricCell } from '../../../../../../../store/src/types/metric.types'; +import { IMetricCell, MetricQueryType } from '../../../../../../../store/src/types/metric.types'; import { FetchCFCellMetricsAction } from '../../../../../actions/cf-metrics.actions'; import { CfCellHelper } from '../../../cf-cell.helpers'; import { ActiveRouteCfCell } from '../../../cf-page.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts index 69b0f82bd8..2753ce8909 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-instance/cf-app-instances-config.service.ts @@ -22,12 +22,11 @@ import { IListConfig, ListViewTypes, } from '../../../../../../../core/src/shared/components/list/list.component.types'; -import { MetricQueryType } from '../../../../../../../core/src/shared/services/metrics-range-selector.types'; import { MetricQueryConfig } from '../../../../../../../store/src/actions/metrics.actions'; import { EntityServiceFactory } from '../../../../../../../store/src/entity-service-factory.service'; import { PaginationMonitorFactory } from '../../../../../../../store/src/monitors/pagination-monitor.factory'; import { IMetricMatrixResult, IMetrics } from '../../../../../../../store/src/types/base-metric.types'; -import { IMetricApplication } from '../../../../../../../store/src/types/metric.types'; +import { IMetricApplication, MetricQueryType } from '../../../../../../../store/src/types/metric.types'; import { ApplicationService } from '../../../../../features/applications/application.service'; import { CfCellHelper } from '../../../../../features/cloud-foundry/cf-cell.helpers'; import { CfCurrentUserPermissions } from '../../../../../user-permissions/cf-user-permissions-checkers'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-cell-apps/cf-cell-apps-source.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-cell-apps/cf-cell-apps-source.ts index 6e834f3121..2d12d50d6f 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-cell-apps/cf-cell-apps-source.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-cell-apps/cf-cell-apps-source.ts @@ -13,12 +13,11 @@ import { ListDataSource, } from '../../../../../../../core/src/shared/components/list/data-sources-controllers/list-data-source'; import { IListConfig } from '../../../../../../../core/src/shared/components/list/list.component.types'; -import { MetricQueryType } from '../../../../../../../core/src/shared/services/metrics-range-selector.types'; import { MetricQueryConfig } from '../../../../../../../store/src/actions/metrics.actions'; import { EntityServiceFactory } from '../../../../../../../store/src/entity-service-factory.service'; import { APIResource } from '../../../../../../../store/src/types/api.types'; import { IMetrics, IMetricVectorResult } from '../../../../../../../store/src/types/base-metric.types'; -import { IMetricApplication } from '../../../../../../../store/src/types/metric.types'; +import { IMetricApplication, MetricQueryType } from '../../../../../../../store/src/types/metric.types'; import { FetchCFMetricsPaginatedAction } from '../../../../../actions/cf-metrics.actions'; import { IApp } from '../../../../../cf-api.types'; import { cfEntityFactory } from '../../../../../cf-entity-factory'; diff --git a/src/frontend/packages/core/src/shared/components/metrics-parent-range-selector/metrics-parent-range-selector.component.ts b/src/frontend/packages/core/src/shared/components/metrics-parent-range-selector/metrics-parent-range-selector.component.ts index 9c5dec430a..016031c362 100644 --- a/src/frontend/packages/core/src/shared/components/metrics-parent-range-selector/metrics-parent-range-selector.component.ts +++ b/src/frontend/packages/core/src/shared/components/metrics-parent-range-selector/metrics-parent-range-selector.component.ts @@ -1,10 +1,10 @@ import { AfterContentInit, Component, ContentChildren, OnDestroy, QueryList } from '@angular/core'; import { Subscription } from 'rxjs'; -import { IMetrics } from '../../../../../store/src/types/base-metric.types'; import { EntityMonitorFactory } from '../../../../../store/src/monitors/entity-monitor.factory.service'; +import { IMetrics } from '../../../../../store/src/types/base-metric.types'; +import { MetricQueryType } from '../../../../../store/src/types/metric.types'; import { MetricsRangeSelectorManagerService } from '../../services/metrics-range-selector-manager.service'; -import { MetricQueryType } from '../../services/metrics-range-selector.types'; import { MetricsChartComponent } from '../metrics-chart/metrics-chart.component'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/metrics-range-selector/metrics-range-selector.component.ts b/src/frontend/packages/core/src/shared/components/metrics-range-selector/metrics-range-selector.component.ts index d485087726..1fab0c74fc 100644 --- a/src/frontend/packages/core/src/shared/components/metrics-range-selector/metrics-range-selector.component.ts +++ b/src/frontend/packages/core/src/shared/components/metrics-range-selector/metrics-range-selector.component.ts @@ -6,8 +6,9 @@ import { MetricsAction } from '../../../../../store/src/actions/metrics.actions' import { EntityMonitor } from '../../../../../store/src/monitors/entity-monitor'; import { EntityMonitorFactory } from '../../../../../store/src/monitors/entity-monitor.factory.service'; import { IMetrics } from '../../../../../store/src/types/base-metric.types'; +import { MetricQueryType } from '../../../../../store/src/types/metric.types'; import { MetricsRangeSelectorManagerService } from '../../services/metrics-range-selector-manager.service'; -import { ITimeRange, MetricQueryType } from '../../services/metrics-range-selector.types'; +import { ITimeRange } from '../../services/metrics-range-selector.types'; @Component({ selector: 'app-metrics-range-selector', diff --git a/src/frontend/packages/core/src/shared/services/metrics-range-selector-manager.service.ts b/src/frontend/packages/core/src/shared/services/metrics-range-selector-manager.service.ts index c424ef13e6..bb8ef4dc09 100644 --- a/src/frontend/packages/core/src/shared/services/metrics-range-selector-manager.service.ts +++ b/src/frontend/packages/core/src/shared/services/metrics-range-selector-manager.service.ts @@ -4,10 +4,11 @@ import { Subject, Subscription } from 'rxjs'; import { debounceTime, takeWhile, tap } from 'rxjs/operators'; import { MetricsAction } from '../../../../store/src/actions/metrics.actions'; -import { IMetrics } from '../../../../store/src/types/base-metric.types'; import { EntityMonitor } from '../../../../store/src/monitors/entity-monitor'; +import { IMetrics } from '../../../../store/src/types/base-metric.types'; +import { MetricQueryType } from '../../../../store/src/types/metric.types'; import { MetricsRangeSelectorService } from './metrics-range-selector.service'; -import { ITimeRange, MetricQueryType } from './metrics-range-selector.types'; +import { ITimeRange } from './metrics-range-selector.types'; @Injectable() export class MetricsRangeSelectorManagerService { diff --git a/src/frontend/packages/core/src/shared/services/metrics-range-selector.service.ts b/src/frontend/packages/core/src/shared/services/metrics-range-selector.service.ts index ee5b4e64c0..9789997fe0 100644 --- a/src/frontend/packages/core/src/shared/services/metrics-range-selector.service.ts +++ b/src/frontend/packages/core/src/shared/services/metrics-range-selector.service.ts @@ -3,7 +3,8 @@ import * as moment from 'moment'; import { MetricQueryConfig, MetricsAction } from '../../../../store/src/actions/metrics.actions'; import { IMetrics } from '../../../../store/src/types/base-metric.types'; -import { ITimeRange, MetricQueryType, StoreMetricTimeRange } from './metrics-range-selector.types'; +import { MetricQueryType } from '../../../../store/src/types/metric.types'; +import { ITimeRange, StoreMetricTimeRange } from './metrics-range-selector.types'; @Injectable() export class MetricsRangeSelectorService { diff --git a/src/frontend/packages/core/src/shared/services/metrics-range-selector.types.ts b/src/frontend/packages/core/src/shared/services/metrics-range-selector.types.ts index bb39cc6bca..872a42e0c8 100644 --- a/src/frontend/packages/core/src/shared/services/metrics-range-selector.types.ts +++ b/src/frontend/packages/core/src/shared/services/metrics-range-selector.types.ts @@ -1,4 +1,7 @@ import * as moment from 'moment'; + +import { MetricQueryType } from '../../../../store/src/types/metric.types'; + export type momentTuple = [moment.DurationInputArg1, moment.unitOfTime.DurationConstructor]; export interface ITimeRange { value?: string; @@ -13,7 +16,4 @@ export interface StoreMetricTimeRange { step?: number; } -export enum MetricQueryType { - QUERY = 'query', - RANGE_QUERY = 'query_range', -} + diff --git a/src/frontend/packages/store/src/actions/metrics.actions.ts b/src/frontend/packages/store/src/actions/metrics.actions.ts index ae1bf4b3a9..1cbcc786f3 100644 --- a/src/frontend/packages/store/src/actions/metrics.actions.ts +++ b/src/frontend/packages/store/src/actions/metrics.actions.ts @@ -1,6 +1,6 @@ -import { MetricQueryType } from '../../../core/src/shared/services/metrics-range-selector.types'; import { metricEntityType } from '../base-entity-schemas'; import { proxyAPIVersion } from '../jetstream'; +import { MetricQueryType } from '../types/metric.types'; import { EntityRequestAction } from '../types/request.types'; export const METRICS_START = '[Metrics] Fetch Start'; diff --git a/src/frontend/packages/store/src/types/metric.types.ts b/src/frontend/packages/store/src/types/metric.types.ts index 3041f3f369..5bf57f1802 100644 --- a/src/frontend/packages/store/src/types/metric.types.ts +++ b/src/frontend/packages/store/src/types/metric.types.ts @@ -22,3 +22,8 @@ export interface IMetricCell { job: string; origin: string; } + +export enum MetricQueryType { + QUERY = 'query', + RANGE_QUERY = 'query_range' +} From d74fcf14e44e5b31ae385653dfef78ef9c4ea3ca Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 21:37:52 +0100 Subject: [PATCH 74/82] Move getFullEndpointApiUrl --- .../tabs/build-tab/build-tab.component.ts | 2 +- .../cli-info-application/cli-info-application.component.ts | 6 +++--- .../cli-info-cloud-foundry.component.ts | 2 +- .../create-endpoint-cf-step-1.component.ts | 3 ++- .../edit-endpoint-step/edit-endpoint-step.component.ts | 3 ++- .../core/src/features/endpoints/endpoint-helpers.ts | 4 ---- .../packages/core/src/features/metrics/metrics.helpers.ts | 3 ++- .../core/src/features/metrics/services/metrics-service.ts | 2 +- .../endpoint/endpoint-card/endpoint-card.component.ts | 6 ++---- src/frontend/packages/store/src/endpoint-utils.ts | 6 ++++++ .../entity-catalog-entity/entity-catalog-entity.ts | 2 +- 11 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 src/frontend/packages/store/src/endpoint-utils.ts diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts index 6c07dbb615..c2b6aa3ca6 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts @@ -10,11 +10,11 @@ import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-sta import { CurrentUserPermissionsService, } from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; -import { getFullEndpointApiUrl } from '../../../../../../../../core/src/features/endpoints/endpoint-helpers'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; import { ENTITY_SERVICE } from '../../../../../../../../core/src/shared/entity.tokens'; import { ResetPagination } from '../../../../../../../../store/src/actions/pagination.actions'; +import { getFullEndpointApiUrl } from '../../../../../../../../store/src/endpoint-utils'; import { EntityService } from '../../../../../../../../store/src/entity-service'; import { ActionState } from '../../../../../../../../store/src/reducers/api-request-reducer/types'; import { APIResource, EntityInfo } from '../../../../../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/cli-info-application/cli-info-application.component.ts b/src/frontend/packages/cloud-foundry/src/features/applications/cli-info-application/cli-info-application.component.ts index 9785603d75..e18ca983cf 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/cli-info-application/cli-info-application.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/applications/cli-info-application/cli-info-application.component.ts @@ -2,11 +2,11 @@ import { Component, OnInit } from '@angular/core'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { filter, first, map } from 'rxjs/operators'; -import { EntityService } from '../../../../../store/src/entity-service'; -import { EntityServiceFactory } from '../../../../../store/src/entity-service-factory.service'; -import { getFullEndpointApiUrl } from '../../../../../core/src/features/endpoints/endpoint-helpers'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; import { GetAllEndpoints } from '../../../../../store/src/actions/endpoint.actions'; +import { getFullEndpointApiUrl } from '../../../../../store/src/endpoint-utils'; +import { EntityService } from '../../../../../store/src/entity-service'; +import { EntityServiceFactory } from '../../../../../store/src/entity-service-factory.service'; import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { CFAppCLIInfoContext } from '../../../shared/components/cli-info/cli-info.component'; import { ApplicationService } from '../application.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.ts index 82ddcf4295..3449967904 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.ts @@ -5,9 +5,9 @@ import { first, map } from 'rxjs/operators'; import { CFAppState } from '../../../../../cloud-foundry/src/cf-app-state'; import { CFAppCLIInfoContext } from '../../../../../cloud-foundry/src/shared/components/cli-info/cli-info.component'; -import { getFullEndpointApiUrl } from '../../../../../core/src/features/endpoints/endpoint-helpers'; import { IHeaderBreadcrumb } from '../../../../../core/src/shared/components/page-header/page-header.types'; import { RouterNav } from '../../../../../store/src/actions/router.actions'; +import { getFullEndpointApiUrl } from '../../../../../store/src/endpoint-utils'; import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types'; import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { getPreviousRoutingState } from '../../../../../store/src/types/routing.type'; diff --git a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts index 91491b642b..c14286bdc8 100644 --- a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.ts @@ -10,6 +10,7 @@ import { GetAllEndpoints, RegisterEndpoint } from '../../../../../../store/src/a import { GeneralEntityAppState } from '../../../../../../store/src/app-state'; import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../../../../../store/src/base-entity-schemas'; import { EndpointsEffect } from '../../../../../../store/src/effects/endpoint.effects'; +import { getFullEndpointApiUrl } from '../../../../../../store/src/endpoint-utils'; import { entityCatalog } from '../../../../../../store/src/entity-catalog/entity-catalog'; import { StratosCatalogEndpointEntity, @@ -21,7 +22,7 @@ import { getIdFromRoute } from '../../../../core/utils.service'; import { IStepperStep, StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; import { SnackBarService } from '../../../../shared/services/snackbar.service'; import { ConnectEndpointConfig } from '../../connect.service'; -import { getFullEndpointApiUrl, getSSOClientRedirectURI } from '../../endpoint-helpers'; +import { getSSOClientRedirectURI } from '../../endpoint-helpers'; /* tslint:disable:no-access-missing-member https://github.com/mgechev/codelyzer/issues/191*/ @Component({ diff --git a/src/frontend/packages/core/src/features/endpoints/edit-endpoint/edit-endpoint-step/edit-endpoint-step.component.ts b/src/frontend/packages/core/src/features/endpoints/edit-endpoint/edit-endpoint-step/edit-endpoint-step.component.ts index 1376e3e6b7..bae73a9c0f 100644 --- a/src/frontend/packages/core/src/features/endpoints/edit-endpoint/edit-endpoint-step/edit-endpoint-step.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/edit-endpoint/edit-endpoint-step/edit-endpoint-step.component.ts @@ -6,10 +6,11 @@ import { Observable, Subscription } from 'rxjs'; import { filter, first, map, pairwise, switchMap } from 'rxjs/operators'; import { AppState } from '../../../../../../store/src/app-state'; +import { getFullEndpointApiUrl } from '../../../../../../store/src/endpoint-utils'; import { entityCatalog } from '../../../../../../store/src/entity-catalog/entity-catalog'; import { selectUpdateInfo } from '../../../../../../store/src/selectors/api.selectors'; import { StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; -import { getFullEndpointApiUrl, getSSOClientRedirectURI } from '../../endpoint-helpers'; +import { getSSOClientRedirectURI } from '../../endpoint-helpers'; import { UpdateEndpoint } from './../../../../../../store/src/actions/endpoint.actions'; import { EntityCatalogSchemas, diff --git a/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts b/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts index 2f0187bb62..10b9a13fff 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts +++ b/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts @@ -11,10 +11,6 @@ import { import { EndpointModel } from '../../../../store/src/types/endpoint.types'; import { EndpointListDetailsComponent } from '../../shared/components/list/list-types/endpoint/endpoint-list.helpers'; -export function getFullEndpointApiUrl(endpoint: EndpointModel) { - return endpoint && endpoint.api_endpoint ? - `${endpoint.api_endpoint.Scheme}://${endpoint.api_endpoint.Host}${endpoint.api_endpoint.Path}` : 'Unknown'; -} export function getEndpointUsername(endpoint: EndpointModel) { return endpoint && endpoint.user ? endpoint.user.name : '-'; diff --git a/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts b/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts index ef5b53a8b6..b277606cb3 100644 --- a/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts +++ b/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts @@ -1,7 +1,8 @@ import { Observable, of as observableOf } from 'rxjs'; +import { getFullEndpointApiUrl } from '../../../../store/src/endpoint-utils'; import { StratosStatus } from '../../shared/shared.types'; -import { EndpointIcon, getFullEndpointApiUrl } from '../endpoints/endpoint-helpers'; +import { EndpointIcon } from '../endpoints/endpoint-helpers'; import { entityCatalog } from './../../../../store/src/entity-catalog/entity-catalog'; import { MetricsEndpointProvider } from './services/metrics-service'; diff --git a/src/frontend/packages/core/src/features/metrics/services/metrics-service.ts b/src/frontend/packages/core/src/features/metrics/services/metrics-service.ts index 6fca8aaefc..52b3db2e88 100644 --- a/src/frontend/packages/core/src/features/metrics/services/metrics-service.ts +++ b/src/frontend/packages/core/src/features/metrics/services/metrics-service.ts @@ -3,11 +3,11 @@ import { Observable } from 'rxjs'; import { map, publishReplay, refCount } from 'rxjs/operators'; import { endpointEntitySchema } from '../../../../../store/src/base-entity-schemas'; +import { getFullEndpointApiUrl } from '../../../../../store/src/endpoint-utils'; import { PaginationMonitor } from '../../../../../store/src/monitors/pagination-monitor'; import { PaginationMonitorFactory } from '../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types'; import { endpointListKey, EndpointModel } from '../../../../../store/src/types/endpoint.types'; -import { getFullEndpointApiUrl } from '../../endpoints/endpoint-helpers'; export interface MetricsEndpointProvider { provider: EndpointModel; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts index e975236944..902e33500b 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts @@ -14,6 +14,7 @@ import { AppState } from 'frontend/packages/store/src/app-state'; import { Observable, of, ReplaySubject, Subscription } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; +import { getFullEndpointApiUrl } from '../../../../../../../../store/src/endpoint-utils'; import { entityCatalog } from '../../../../../../../../store/src/entity-catalog/entity-catalog'; import { StratosCatalogEndpointEntity, @@ -22,10 +23,7 @@ import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorit import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; -import { - coreEndpointListDetailsComponents, - getFullEndpointApiUrl, -} from '../../../../../../features/endpoints/endpoint-helpers'; +import { coreEndpointListDetailsComponents } from '../../../../../../features/endpoints/endpoint-helpers'; import { StratosStatus } from '../../../../../shared.types'; import { createMetaCardMenuItemSeparator, diff --git a/src/frontend/packages/store/src/endpoint-utils.ts b/src/frontend/packages/store/src/endpoint-utils.ts new file mode 100644 index 0000000000..00f3677f32 --- /dev/null +++ b/src/frontend/packages/store/src/endpoint-utils.ts @@ -0,0 +1,6 @@ +import { EndpointModel } from './types/endpoint.types'; + +export function getFullEndpointApiUrl(endpoint: EndpointModel) { + return endpoint && endpoint.api_endpoint ? + `${endpoint.api_endpoint.Scheme}://${endpoint.api_endpoint.Host}${endpoint.api_endpoint.Path}` : 'Unknown'; +} diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts index 3f48831325..942b3ea9b9 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts @@ -1,8 +1,8 @@ import { ActionReducer } from '@ngrx/store'; -import { getFullEndpointApiUrl } from '../../../../core/src/features/endpoints/endpoint-helpers'; import { IRequestEntityTypeState } from '../../app-state'; import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE } from '../../base-entity-schemas'; +import { getFullEndpointApiUrl } from '../../endpoint-utils'; import { EntitiesFetchHandler, EntitiesInfoHandler, From 0b84a67c6e800d04fa10577d58ca0295923785e4 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Thu, 18 Jun 2020 21:44:46 +0100 Subject: [PATCH 75/82] Move StratosStatus --- .../cloud-foundry/services/cloud-foundry-org-space-quota.ts | 2 +- .../services/cloud-foundry-organization-quota.ts | 2 +- .../cloud-foundry/services/cloud-foundry-space-quota.ts | 2 +- .../cloud-foundry-cell-summary.component.ts | 2 +- .../src/features/service-catalog/services-helper.ts | 2 +- .../select-plan-step/select-plan-step.component.ts | 2 +- .../cards/card-app-instances/card-app-instances.component.ts | 2 +- .../cards/card-app-status/card-app-status.component.ts | 2 +- .../cards/card-app-usage/card-app-usage.component.ts | 2 +- .../compact-app-card/compact-app-card.component.ts | 2 +- .../app-service-binding-card.component.ts | 2 +- .../list/list-types/app/card/card-app.component.ts | 2 +- .../list-types/cf-orgs/cf-org-card/cf-org-card.component.ts | 2 +- .../cf-spaces/cf-space-card/cf-space-card.component.ts | 2 +- .../service-instance-card/service-instance-card.component.ts | 2 +- .../user-provided-service-instance-card.component.ts | 2 +- .../service-plan-public.component.spec.ts | 2 +- .../service-plan-public/service-plan-public.component.ts | 2 +- .../src/shared/services/application-state.service.ts | 2 +- .../src/core/stateful-icon/stateful-icon.component.spec.ts | 2 +- .../core/src/core/stateful-icon/stateful-icon.component.ts | 5 +++-- .../features/error-page/error-page/error-page.component.ts | 2 +- .../packages/core/src/features/metrics/metrics.helpers.ts | 2 +- .../application-state-icon.component.ts | 2 +- .../application-state/application-state.component.ts | 2 +- .../cards/card-number-metric/card-number-metric.component.ts | 2 +- .../components/cards/card-status/card-status.component.ts | 2 +- .../favorites-meta-card/favorites-meta-card.component.ts | 2 +- .../meta-card/meta-card-base/meta-card.component.spec.ts | 2 +- .../meta-card/meta-card-base/meta-card.component.ts | 2 +- .../endpoint/endpoint-card/endpoint-card.component.ts | 2 +- .../table-cell-endpoint-address.component.ts | 2 +- .../shared/components/page-header/page-header.component.ts | 2 +- .../packages/core/src/shared/global-events.service.ts | 2 +- .../store/src/entity-catalog/entity-catalog.types.ts | 2 +- .../{core/src/shared => store/src/types}/shared.types.ts | 4 ++-- 36 files changed, 39 insertions(+), 38 deletions(-) rename src/frontend/packages/{core/src/shared => store/src/types}/shared.types.ts (79%) diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-org-space-quota.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-org-space-quota.ts index 0e89121107..e02ed1ae30 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-org-space-quota.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-org-space-quota.ts @@ -3,9 +3,9 @@ import { filter, first, map, switchMap } from 'rxjs/operators'; import { truthyIncludingZero } from '../../../../../core/src/core/utils.service'; import { determineCardStatus } from '../../../../../core/src/shared/components/cards/card-status/card-status.component'; -import { StratosStatus } from '../../../../../core/src/shared/shared.types'; import { EntityMonitorFactory } from '../../../../../store/src/monitors/entity-monitor.factory.service'; import { APIResource } from '../../../../../store/src/types/api.types'; +import { StratosStatus } from '../../../../../store/src/types/shared.types'; import { IApp, IOrganization, ISpace } from '../../../cf-api.types'; import { CFEntityConfig } from '../../../cf-types'; import { CloudFoundryEndpointService } from './cloud-foundry-endpoint.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-organization-quota.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-organization-quota.ts index 932894115e..9c3bcbf845 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-organization-quota.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-organization-quota.ts @@ -1,9 +1,9 @@ import { Observable } from 'rxjs'; import { organizationEntityType } from '../../../../../cloud-foundry/src/cf-entity-types'; -import { StratosStatus } from '../../../../../core/src/shared/shared.types'; import { EntityMonitorFactory } from '../../../../../store/src/monitors/entity-monitor.factory.service'; import { APIResource } from '../../../../../store/src/types/api.types'; +import { StratosStatus } from '../../../../../store/src/types/shared.types'; import { IApp, IOrganization } from '../../../cf-api.types'; import { getEntityFlattenedList, getStartedAppInstanceCount } from '../../../cf.helpers'; import { CloudFoundryEndpointService } from './cloud-foundry-endpoint.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space-quota.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space-quota.ts index 1be45b3e30..692fad26d8 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space-quota.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/services/cloud-foundry-space-quota.ts @@ -1,9 +1,9 @@ import { Observable } from 'rxjs'; import { spaceEntityType } from '../../../../../cloud-foundry/src/cf-entity-types'; -import { StratosStatus } from '../../../../../core/src/shared/shared.types'; import { EntityMonitorFactory } from '../../../../../store/src/monitors/entity-monitor.factory.service'; import { APIResource } from '../../../../../store/src/types/api.types'; +import { StratosStatus } from '../../../../../store/src/types/shared.types'; import { IApp, ISpace } from '../../../cf-api.types'; import { getStartedAppInstanceCount } from '../../../cf.helpers'; import { CloudFoundryEndpointService } from './cloud-foundry-endpoint.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.ts index e3427cd79b..2109f6dee5 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.ts @@ -3,7 +3,7 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { ListConfig } from '../../../../../../../../core/src/shared/components/list/list.component.types'; -import { StratosStatus } from '../../../../../../../../core/src/shared/shared.types'; +import { StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { CfCellHealthListConfigService, } from '../../../../../../shared/components/list/list-types/cf-cell-health/cf-cell-health-list-config.service'; diff --git a/src/frontend/packages/cloud-foundry/src/features/service-catalog/services-helper.ts b/src/frontend/packages/cloud-foundry/src/features/service-catalog/services-helper.ts index 9f55596f21..d3fce2628e 100644 --- a/src/frontend/packages/cloud-foundry/src/features/service-catalog/services-helper.ts +++ b/src/frontend/packages/cloud-foundry/src/features/service-catalog/services-helper.ts @@ -5,10 +5,10 @@ import { combineLatest, filter, first, map, share, switchMap } from 'rxjs/operat import { createEntityRelationPaginationKey } from '../../../../cloud-foundry/src/entity-relations/entity-relations.types'; import { getIdFromRoute, safeStringToObj } from '../../../../core/src/core/utils.service'; -import { StratosStatus } from '../../../../core/src/shared/shared.types'; import { EntityService } from '../../../../store/src/entity-service'; import { PaginationMonitorFactory } from '../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource } from '../../../../store/src/types/api.types'; +import { StratosStatus } from '../../../../store/src/types/shared.types'; import { IService, IServiceBroker, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/select-plan-step/select-plan-step.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/select-plan-step/select-plan-step.component.ts index 961ada73a1..e1b2c4d645 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/select-plan-step/select-plan-step.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/add-service-instance/select-plan-step/select-plan-step.component.ts @@ -39,8 +39,8 @@ import { } from '../../../../../../cloud-foundry/src/store/selectors/create-service-instance.selectors'; import { safeUnsubscribe } from '../../../../../../core/src/core/utils.service'; import { StepOnNextResult } from '../../../../../../core/src/shared/components/stepper/step/step.component'; -import { StratosStatus } from '../../../../../../core/src/shared/shared.types'; import { APIResource } from '../../../../../../store/src/types/api.types'; +import { StratosStatus } from '../../../../../../store/src/types/shared.types'; import { IServicePlan } from '../../../../cf-api-svc.types'; import { CreateServiceInstanceHelperServiceFactory } from '../create-service-instance-helper-service-factory.service'; import { CreateServiceInstanceHelper } from '../create-service-instance-helper.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts index 048e57ddac..6604494482 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-instances/card-app-instances.component.ts @@ -8,7 +8,7 @@ import { ApplicationService } from '../../../../../../cloud-foundry/src/features import { CurrentUserPermissionsService } from '../../../../../../core/src/core/permissions/current-user-permissions.service'; import { ConfirmationDialogConfig } from '../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../core/src/shared/components/confirmation-dialog.service'; -import { StratosStatus } from '../../../../../../core/src/shared/shared.types'; +import { StratosStatus } from '../../../../../../store/src/types/shared.types'; import { CfCurrentUserPermissions } from '../../../../user-permissions/cf-user-permissions-checkers'; const appInstanceScaleToZeroConfirmation = new ConfirmationDialogConfig('Set Instance count to 0', diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-status/card-app-status.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-status/card-app-status.component.ts index def16fda0d..c7e9633951 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-status/card-app-status.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-status/card-app-status.component.ts @@ -3,7 +3,7 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { ApplicationService } from '../../../../../../cloud-foundry/src/features/applications/application.service'; -import { StratosStatus } from '../../../../../../core/src/shared/shared.types'; +import { StratosStatus } from '../../../../../../store/src/types/shared.types'; @Component({ selector: 'app-card-app-status', diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-usage/card-app-usage.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-usage/card-app-usage.component.ts index b8dcea269a..8e47a9ab46 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-usage/card-app-usage.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-app-usage/card-app-usage.component.ts @@ -7,7 +7,7 @@ import { } from '../../../../../../cloud-foundry/src/features/applications/application-monitor.service'; import { ApplicationService } from '../../../../../../cloud-foundry/src/features/applications/application.service'; import { pathGet } from '../../../../../../core/src/core/utils.service'; -import { StratosStatus } from '../../../../../../core/src/shared/shared.types'; +import { StratosStatus } from '../../../../../../store/src/types/shared.types'; @Component({ selector: 'app-card-app-usage', diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-cf-recent-apps/compact-app-card/compact-app-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-cf-recent-apps/compact-app-card/compact-app-card.component.ts index a6c13b1af5..d982f91991 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-cf-recent-apps/compact-app-card/compact-app-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cards/card-cf-recent-apps/compact-app-card/compact-app-card.component.ts @@ -7,7 +7,7 @@ import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state' import { ApplicationService } from '../../../../../../../cloud-foundry/src/features/applications/application.service'; import { ActiveRouteCfOrgSpace } from '../../../../../../../cloud-foundry/src/features/cloud-foundry/cf-page.types'; import { BREADCRUMB_URL_PARAM } from '../../../../../../../core/src/shared/components/breadcrumbs/breadcrumbs.types'; -import { StratosStatus } from '../../../../../../../core/src/shared/shared.types'; +import { StratosStatus } from '../../../../../../../store/src/types/shared.types'; import { ApplicationStateData, ApplicationStateService } from '../../../../services/application-state.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts index f72b232704..b584a05878 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts @@ -12,8 +12,8 @@ import { MetaCardMenuItem, } from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell, IListRowCell } from '../../../../../../../../core/src/shared/components/list/list.types'; -import { ComponentEntityMonitorConfig } from '../../../../../../../../core/src/shared/shared.types'; import { APIResource, EntityInfo } from '../../../../../../../../store/src/types/api.types'; +import { ComponentEntityMonitorConfig } from '../../../../../../../../store/src/types/shared.types'; import { IService, IServiceBinding, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts index 4fdef71b47..39a18e5336 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/card/card-app.component.ts @@ -7,9 +7,9 @@ import { CFAppState } from '../../../../../../../../cloud-foundry/src/cf-app-sta import { applicationEntityType } from '../../../../../../../../cloud-foundry/src/cf-entity-types'; import { IAppFavMetadata } from '../../../../../../../../cloud-foundry/src/cf-metadata-types'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; -import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../core/src/shared/shared.types'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; +import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { IApp, ISpace } from '../../../../../../cf-api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts index 2e7f605c23..bcdd032bd2 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts @@ -15,13 +15,13 @@ import { MetaCardMenuItem, } from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; -import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../core/src/shared/shared.types'; import { RouterNav } from '../../../../../../../../store/src/actions/router.actions'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { PaginationMonitorFactory } from '../../../../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { EndpointUser } from '../../../../../../../../store/src/types/endpoint.types'; +import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { IApp, IOrganization } from '../../../../../../cf-api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts index 189604d778..c31213505f 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts @@ -16,13 +16,13 @@ import { MetaCardMenuItem, } from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; -import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../core/src/shared/shared.types'; import { RouterNav } from '../../../../../../../../store/src/actions/router.actions'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; import { PaginationMonitorFactory } from '../../../../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { EndpointUser } from '../../../../../../../../store/src/types/endpoint.types'; +import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { IApp, ISpace } from '../../../../../../cf-api.types'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts index e9ac71ae99..85a9dd63be 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts @@ -12,8 +12,8 @@ import { MetaCardMenuItem, } from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; -import { ComponentEntityMonitorConfig } from '../../../../../../../../core/src/shared/shared.types'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; +import { ComponentEntityMonitorConfig } from '../../../../../../../../store/src/types/shared.types'; import { IServiceInstance } from '../../../../../../cf-api-svc.types'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; import { diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts index 8c2564b26c..a7b8310c88 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts @@ -12,8 +12,8 @@ import { MetaCardMenuItem, } from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; -import { ComponentEntityMonitorConfig } from '../../../../../../../../core/src/shared/shared.types'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; +import { ComponentEntityMonitorConfig } from '../../../../../../../../store/src/types/shared.types'; import { IUserProvidedServiceInstance } from '../../../../../../cf-api-svc.types'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; import { CfCurrentUserPermissions } from '../../../../../../user-permissions/cf-user-permissions-checkers'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/service-plan-public/service-plan-public.component.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/components/service-plan-public/service-plan-public.component.spec.ts index 0ecf090c2a..d7788eb41e 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/service-plan-public/service-plan-public.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/service-plan-public/service-plan-public.component.spec.ts @@ -1,9 +1,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; -import { StratosStatus } from '../../../../../core/src/shared/shared.types'; import { EntityService } from '../../../../../store/src/entity-service'; import { EntityMonitorFactory } from '../../../../../store/src/monitors/entity-monitor.factory.service'; +import { StratosStatus } from '../../../../../store/src/types/shared.types'; import { generateCfBaseTestModulesNoShared } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; import * as servicesHelpers from '../../../features/service-catalog/services-helper'; import { ServicesService } from '../../../features/service-catalog/services.service'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/service-plan-public/service-plan-public.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/service-plan-public/service-plan-public.component.ts index e4e4ba6ef9..8d47ae46c6 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/service-plan-public/service-plan-public.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/service-plan-public/service-plan-public.component.ts @@ -6,8 +6,8 @@ import { getServicePlanAccessibilityCardStatus, } from '../../../../../cloud-foundry/src/features/service-catalog/services-helper'; import { ServicesService } from '../../../../../cloud-foundry/src/features/service-catalog/services.service'; -import { StratosStatus } from '../../../../../core/src/shared/shared.types'; import { APIResource } from '../../../../../store/src/types/api.types'; +import { StratosStatus } from '../../../../../store/src/types/shared.types'; import { IServiceBroker, IServicePlan } from '../../../cf-api-svc.types'; import { cfEntityCatalog } from '../../../cf-entity-catalog'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/services/application-state.service.ts b/src/frontend/packages/cloud-foundry/src/shared/services/application-state.service.ts index 751994c0f0..af5283b27f 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/services/application-state.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/services/application-state.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; -import { StratosStatus, StratosStatusMetadata } from '../../../../core/src/shared/shared.types'; +import { StratosStatus, StratosStatusMetadata } from '../../../../store/src/types/shared.types'; import { AppStat } from '../../store/types/app-metadata.types'; export interface ApplicationStateData extends StratosStatusMetadata { diff --git a/src/frontend/packages/core/src/core/stateful-icon/stateful-icon.component.spec.ts b/src/frontend/packages/core/src/core/stateful-icon/stateful-icon.component.spec.ts index f258f527ae..1a8cd63bc7 100644 --- a/src/frontend/packages/core/src/core/stateful-icon/stateful-icon.component.spec.ts +++ b/src/frontend/packages/core/src/core/stateful-icon/stateful-icon.component.spec.ts @@ -1,6 +1,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { StratosStatus } from '../../shared/shared.types'; +import { StratosStatus } from '../../../../store/src/types/shared.types'; import { MDAppModule } from '../md.module'; import { StatefulIconComponent } from './stateful-icon.component'; diff --git a/src/frontend/packages/core/src/core/stateful-icon/stateful-icon.component.ts b/src/frontend/packages/core/src/core/stateful-icon/stateful-icon.component.ts index 5ad05aa35d..fdcd63847a 100644 --- a/src/frontend/packages/core/src/core/stateful-icon/stateful-icon.component.ts +++ b/src/frontend/packages/core/src/core/stateful-icon/stateful-icon.component.ts @@ -1,5 +1,6 @@ -import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { StratosStatus } from '../../shared/shared.types'; +import { Component, Input, TemplateRef } from '@angular/core'; + +import { StratosStatus } from '../../../../store/src/types/shared.types'; interface IconDefinition { icon: string; diff --git a/src/frontend/packages/core/src/features/error-page/error-page/error-page.component.ts b/src/frontend/packages/core/src/features/error-page/error-page/error-page.component.ts index 7de769a04c..b21a8b228a 100644 --- a/src/frontend/packages/core/src/features/error-page/error-page/error-page.component.ts +++ b/src/frontend/packages/core/src/features/error-page/error-page/error-page.component.ts @@ -14,7 +14,7 @@ import { InternalEventMonitorFactory } from '../../../../../store/src/monitors/i import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { InternalEventState } from '../../../../../store/src/types/internal-events.types'; import { getPreviousRoutingState } from '../../../../../store/src/types/routing.type'; -import { StratosStatus } from '../../../shared/shared.types'; +import { StratosStatus } from '../../../../../store/src/types/shared.types'; import { eventReturnUrlParam } from '../../event-page/events-page/events-page.component'; @Component({ diff --git a/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts b/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts index b277606cb3..7522903bdf 100644 --- a/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts +++ b/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts @@ -1,7 +1,7 @@ import { Observable, of as observableOf } from 'rxjs'; import { getFullEndpointApiUrl } from '../../../../store/src/endpoint-utils'; -import { StratosStatus } from '../../shared/shared.types'; +import { StratosStatus } from '../../../../store/src/types/shared.types'; import { EndpointIcon } from '../endpoints/endpoint-helpers'; import { entityCatalog } from './../../../../store/src/entity-catalog/entity-catalog'; import { MetricsEndpointProvider } from './services/metrics-service'; diff --git a/src/frontend/packages/core/src/shared/components/application-state/application-state-icon/application-state-icon.component.ts b/src/frontend/packages/core/src/shared/components/application-state/application-state-icon/application-state-icon.component.ts index 0172efd67e..32c02fe9ca 100644 --- a/src/frontend/packages/core/src/shared/components/application-state/application-state-icon/application-state-icon.component.ts +++ b/src/frontend/packages/core/src/shared/components/application-state/application-state-icon/application-state-icon.component.ts @@ -1,6 +1,6 @@ import { Component, Input } from '@angular/core'; -import { StratosStatus } from '../../../shared.types'; +import { StratosStatus } from '../../../../../../store/src/types/shared.types'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/application-state/application-state.component.ts b/src/frontend/packages/core/src/shared/components/application-state/application-state.component.ts index f548f70336..635c090751 100644 --- a/src/frontend/packages/core/src/shared/components/application-state/application-state.component.ts +++ b/src/frontend/packages/core/src/shared/components/application-state/application-state.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; -import { StratosStatus, StratosStatusMetadata } from '../../shared.types'; +import { StratosStatus, StratosStatusMetadata } from '../../../../../store/src/types/shared.types'; @Component({ selector: 'app-application-state', diff --git a/src/frontend/packages/core/src/shared/components/cards/card-number-metric/card-number-metric.component.ts b/src/frontend/packages/core/src/shared/components/cards/card-number-metric/card-number-metric.component.ts index ca4bfcbc57..f0170d28b4 100644 --- a/src/frontend/packages/core/src/shared/components/cards/card-number-metric/card-number-metric.component.ts +++ b/src/frontend/packages/core/src/shared/components/cards/card-number-metric/card-number-metric.component.ts @@ -4,8 +4,8 @@ import { BehaviorSubject } from 'rxjs'; import { RouterNav } from '../../../../../../store/src/actions/router.actions'; import { AppState } from '../../../../../../store/src/app-state'; +import { StratosStatus } from '../../../../../../store/src/types/shared.types'; import { UtilsService } from '../../../../core/utils.service'; -import { StratosStatus } from '../../../shared.types'; import { determineCardStatus } from '../card-status/card-status.component'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/cards/card-status/card-status.component.ts b/src/frontend/packages/core/src/shared/components/cards/card-status/card-status.component.ts index 7fa6a0607c..eb41e0c7b0 100644 --- a/src/frontend/packages/core/src/shared/components/cards/card-status/card-status.component.ts +++ b/src/frontend/packages/core/src/shared/components/cards/card-status/card-status.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { Observable } from 'rxjs'; -import { StratosStatus } from '../../../shared.types'; +import { StratosStatus } from '../../../../../../store/src/types/shared.types'; export function determineCardStatus(value: number, limit: number): StratosStatus { diff --git a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts index db9713e8aa..ac7488867a 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts @@ -11,10 +11,10 @@ import { userFavoritesEntitySchema } from '../../../../../store/src/base-entity- import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; import { IFavoritesMetaCardConfig } from '../../../../../store/src/favorite-config-mapper'; import { endpointEntitiesSelector } from '../../../../../store/src/selectors/endpoint.selectors'; +import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../store/src/types/shared.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../store/src/types/user-favorites.types'; import { IFavoriteEntity } from '../../../../../store/src/user-favorite-manager'; import { isEndpointConnected } from '../../../features/endpoints/connect.service'; -import { ComponentEntityMonitorConfig, StratosStatus } from '../../shared.types'; import { ConfirmationDialogConfig } from '../confirmation-dialog.config'; import { ConfirmationDialogService } from '../confirmation-dialog.service'; import { MetaCardMenuItem } from '../list/list-cards/meta-card/meta-card-base/meta-card.component'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts index 4a35630e03..2ccb12a2be 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.spec.ts @@ -8,12 +8,12 @@ import { Observable, of } from 'rxjs'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntitySchema } from '../../../../../../../../store/src/helpers/entity-schema'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; +import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import * as favoriteHelpers from '../../../../../../../../store/src/user-favorite-helpers'; import { UserFavoriteManager } from '../../../../../../../../store/src/user-favorite-manager'; import { CoreTestingModule } from '../../../../../../../test-framework/core-test.modules'; import { SharedModule } from '../../../../../shared.module'; -import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../shared.types'; import { MetaCardComponent } from './meta-card.component'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts index 2a180f646f..bfcc9d7644 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts @@ -4,10 +4,10 @@ import { first, map, tap } from 'rxjs/operators'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; +import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; -import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../shared.types'; import { MetaCardItemComponent } from '../meta-card-item/meta-card-item.component'; import { MetaCardTitleComponent } from '../meta-card-title/meta-card-title.component'; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts index 902e33500b..3ef07992cf 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts @@ -21,10 +21,10 @@ import { } from '../../../../../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; import { coreEndpointListDetailsComponents } from '../../../../../../features/endpoints/endpoint-helpers'; -import { StratosStatus } from '../../../../../shared.types'; import { createMetaCardMenuItemSeparator, MetaCardMenuItem, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts index 32956ffa4b..206f52ca40 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-address/table-cell-endpoint-address.component.ts @@ -3,9 +3,9 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { GetAllEndpoints } from '../../../../../../../../store/src/actions/endpoint.actions'; +import { getFullEndpointApiUrl } from '../../../../../../../../store/src/endpoint-utils'; import { EntityServiceFactory } from '../../../../../../../../store/src/entity-service-factory.service'; import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; -import { getFullEndpointApiUrl } from '../../../../../../features/endpoints/endpoint-helpers'; import { TableCellCustom } from '../../../list.types'; import { RowWithEndpointId } from '../table-cell-endpoint-name/table-cell-endpoint-name.component'; diff --git a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts index a032a1d887..6e836e74b3 100644 --- a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts +++ b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts @@ -13,12 +13,12 @@ import { EntityCatalogHelpers } from '../../../../../store/src/entity-catalog/en import { FavoritesConfigMapper } from '../../../../../store/src/favorite-config-mapper'; import { selectIsMobile } from '../../../../../store/src/selectors/dashboard.selectors'; import { InternalEventSeverity } from '../../../../../store/src/types/internal-events.types'; +import { StratosStatus } from '../../../../../store/src/types/shared.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../store/src/types/user-favorites.types'; import { TabNavService } from '../../../../tab-nav.service'; import { UserProfileService } from '../../../core/user-profile.service'; import { IPageSideNavTab } from '../../../features/dashboard/page-side-nav/page-side-nav.component'; import { GlobalEventService, IGlobalEvent } from '../../global-events.service'; -import { StratosStatus } from '../../shared.types'; import { selectDashboardState } from './../../../../../store/src/selectors/dashboard.selectors'; import { UserProfileInfo } from './../../../../../store/src/types/user-profile.types'; import { BREADCRUMB_URL_PARAM, IHeaderBreadcrumb, IHeaderBreadcrumbLink } from './page-header.types'; diff --git a/src/frontend/packages/core/src/shared/global-events.service.ts b/src/frontend/packages/core/src/shared/global-events.service.ts index fb59101347..ff9675a57e 100644 --- a/src/frontend/packages/core/src/shared/global-events.service.ts +++ b/src/frontend/packages/core/src/shared/global-events.service.ts @@ -3,8 +3,8 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, combineLatest, Observable, ReplaySubject } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, publishReplay, refCount, startWith } from 'rxjs/operators'; +import { StratosStatus } from '../../../store/src/types/shared.types'; import { GeneralEntityAppState } from './../../../store/src/app-state'; -import { StratosStatus } from './shared.types'; export type GlobalEventTypes = 'warning' | 'error' | 'process' | 'complete'; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts index 33b6fea18f..d218f7ba89 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.types.ts @@ -1,7 +1,6 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { StratosStatus } from '../../../core/src/shared/shared.types'; import { GeneralEntityAppState } from '../app-state'; import { ApiErrorMessageHandler, @@ -22,6 +21,7 @@ import { EndpointAuthTypeConfig } from '../extension-types'; import { FavoritesConfigMapper } from '../favorite-config-mapper'; import { EntitySchema } from '../helpers/entity-schema'; import { EndpointModel } from '../types/endpoint.types'; +import { StratosStatus } from '../types/shared.types'; import { UserFavorite } from '../types/user-favorites.types'; export interface EntityCatalogEntityConfig { diff --git a/src/frontend/packages/core/src/shared/shared.types.ts b/src/frontend/packages/store/src/types/shared.types.ts similarity index 79% rename from src/frontend/packages/core/src/shared/shared.types.ts rename to src/frontend/packages/store/src/types/shared.types.ts index a3da5a1e89..a0d38a623e 100644 --- a/src/frontend/packages/core/src/shared/shared.types.ts +++ b/src/frontend/packages/store/src/types/shared.types.ts @@ -1,5 +1,5 @@ -import { AppState } from '../../../store/src/app-state'; -import { EntitySchema } from '../../../store/src/helpers/entity-schema'; +import { AppState } from '../app-state'; +import { EntitySchema } from '../helpers/entity-schema'; export class ComponentEntityMonitorConfig { From fdd7edef1ae0d33df383d5b1ddd15e4072ee844c Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Fri, 19 Jun 2020 10:30:04 +0100 Subject: [PATCH 76/82] Move generateStratosEntities back to core --- .../src/cloud-foundry-test.module.ts | 2 +- .../current-user-permissions.service.spec.ts | 2 +- .../test-framework/cf-test-helper.ts | 2 +- src/frontend/packages/core/src/app.module.ts | 2 +- .../current-user-permissions.service.spec.ts | 2 +- .../packages/core/src/stratos-entities.ts | 33 ++++++++++++++++ .../core/test-framework/core-test.modules.ts | 2 +- .../packages/store/src/base-entity-types.ts | 38 +++---------------- 8 files changed, 44 insertions(+), 39 deletions(-) create mode 100644 src/frontend/packages/core/src/stratos-entities.ts diff --git a/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts b/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts index 128aed0b52..7f1d67b662 100644 --- a/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts +++ b/src/frontend/packages/cloud-foundry/src/cloud-foundry-test.module.ts @@ -5,7 +5,7 @@ import { EffectsModule } from '@ngrx/effects'; import { generateASEntities } from '../../cf-autoscaler/src/store/autoscaler-entity-generator'; import { getGitHubAPIURL, GITHUB_API_URL } from '../../core/src/core/github.helpers'; import { LoggerService } from '../../core/src/core/logger.service'; -import { generateStratosEntities } from '../../store/src/base-entity-types'; +import { generateStratosEntities } from '../../core/src/stratos-entities'; import { CATALOGUE_ENTITIES, EntityCatalogFeatureModule } from '../../store/src/entity-catalog.module'; import { entityCatalog, TestEntityCatalog } from '../../store/src/entity-catalog/entity-catalog'; import { testSCFEndpointGuid } from '../../store/testing/public-api'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts index f807720b7d..c3536ed8a9 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/services/current-user-permissions.service.spec.ts @@ -15,10 +15,10 @@ import { import { PermissionConfig } from '../../../../core/src/core/permissions/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; import { StratosScopeStrings } from '../../../../core/src/core/permissions/stratos-user-permissions.checker'; +import { generateStratosEntities } from '../../../../core/src/stratos-entities'; import { AppTestModule } from '../../../../core/test-framework/core-test.helper'; import { AppState } from '../../../../store/src/app-state'; import { endpointEntitySchema } from '../../../../store/src/base-entity-schemas'; -import { generateStratosEntities } from '../../../../store/src/base-entity-types'; import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../../../store/src/entity-catalog-test.module'; import { EntityCatalogEntityConfig } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { APIResource } from '../../../../store/src/types/api.types'; diff --git a/src/frontend/packages/cloud-foundry/test-framework/cf-test-helper.ts b/src/frontend/packages/cloud-foundry/test-framework/cf-test-helper.ts index 780d481f28..fda8621a50 100644 --- a/src/frontend/packages/cloud-foundry/test-framework/cf-test-helper.ts +++ b/src/frontend/packages/cloud-foundry/test-framework/cf-test-helper.ts @@ -1,5 +1,5 @@ +import { generateStratosEntities } from '../../core/src/stratos-entities'; import { BaseTestModules } from '../../core/test-framework/core-test.helper'; -import { generateStratosEntities } from '../../store/src/base-entity-types'; import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../store/src/entity-catalog-test.module'; import { generateCFEntities } from '../src/cf-entity-generator'; diff --git a/src/frontend/packages/core/src/app.module.ts b/src/frontend/packages/core/src/app.module.ts index 5143286c99..f70ee4210e 100644 --- a/src/frontend/packages/core/src/app.module.ts +++ b/src/frontend/packages/core/src/app.module.ts @@ -15,7 +15,6 @@ import { } from '../../store/src/actions/user-favourites-actions/update-user-favorite-metadata-action'; import { GeneralEntityAppState, GeneralRequestDataState } from '../../store/src/app-state'; import { STRATOS_ENDPOINT_TYPE } from '../../store/src/base-entity-schemas'; -import { generateStratosEntities } from '../../store/src/base-entity-types'; import { EntityCatalogModule } from '../../store/src/entity-catalog.module'; import { entityCatalog } from '../../store/src/entity-catalog/entity-catalog'; import { EntityCatalogHelper } from '../../store/src/entity-catalog/entity-catalog-entity/entity-catalog.service'; @@ -52,6 +51,7 @@ import { CustomReuseStrategy } from './route-reuse-stragegy'; import { endpointEventKey, GlobalEventData, GlobalEventService } from './shared/global-events.service'; import { SidePanelService } from './shared/services/side-panel.service'; import { SharedModule } from './shared/shared.module'; +import { generateStratosEntities } from './stratos-entities'; // Create action for router navigation. See // - https://github.com/ngrx/platform/issues/68 diff --git a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts index 0fa151e46d..60d39f5ace 100644 --- a/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts +++ b/src/frontend/packages/core/src/core/permissions/current-user-permissions.service.spec.ts @@ -4,13 +4,13 @@ import { first, tap } from 'rxjs/operators'; import { AppState } from '../../../../store/src/app-state'; import { endpointEntitySchema } from '../../../../store/src/base-entity-schemas'; -import { generateStratosEntities } from '../../../../store/src/base-entity-types'; import { EntityCatalogTestModule, TEST_CATALOGUE_ENTITIES } from '../../../../store/src/entity-catalog-test.module'; import { EntityCatalogEntityConfig } from '../../../../store/src/entity-catalog/entity-catalog.types'; import { EndpointModel } from '../../../../store/src/types/endpoint.types'; import { BaseEntityValues } from '../../../../store/src/types/entity.types'; import { PaginationState } from '../../../../store/src/types/pagination.types'; import { AppTestModule } from '../../../test-framework/core-test.helper'; +import { generateStratosEntities } from '../../stratos-entities'; import { PermissionConfig } from './current-user-permissions.config'; import { CurrentUserPermissionsService } from './current-user-permissions.service'; import { StratosPermissionStrings, StratosPermissionTypes, StratosScopeStrings } from './stratos-user-permissions.checker'; diff --git a/src/frontend/packages/core/src/stratos-entities.ts b/src/frontend/packages/core/src/stratos-entities.ts new file mode 100644 index 0000000000..a2d8844f60 --- /dev/null +++ b/src/frontend/packages/core/src/stratos-entities.ts @@ -0,0 +1,33 @@ +import { + DefaultEndpointCatalogEntity, + SystemInfoCatalogEntity, + UserFavoriteCatalogEntity, + UserProfileCatalogEntity, +} from '../../store/src/base-entity-types'; +import { BaseEndpointAuth } from '../../store/src/endpoint-auth'; +import { StratosCatalogEndpointEntity } from '../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { + MetricsEndpointDetailsComponent, +} from './features/metrics/metrics-endpoint-details/metrics-endpoint-details.component'; + +export function generateStratosEntities() { + return [ + new DefaultEndpointCatalogEntity(), + new SystemInfoCatalogEntity(), + new UserFavoriteCatalogEntity(), + new UserProfileCatalogEntity(), + // TODO: metrics location to be sorted - STRAT-152 + new StratosCatalogEndpointEntity({ + type: 'metrics', + label: 'Metrics', + labelPlural: 'Metrics', + tokenSharing: true, + logoUrl: '/core/assets/endpoint-icons/metrics.svg', + authTypes: [BaseEndpointAuth.UsernamePassword, BaseEndpointAuth.None], + renderPriority: 1, + listDetailsComponent: MetricsEndpointDetailsComponent, + }, + metadata => `/endpoints/metrics/${metadata.guid}` + ) + ]; +} diff --git a/src/frontend/packages/core/test-framework/core-test.modules.ts b/src/frontend/packages/core/test-framework/core-test.modules.ts index f433ecb5e6..d38e89193a 100644 --- a/src/frontend/packages/core/test-framework/core-test.modules.ts +++ b/src/frontend/packages/core/test-framework/core-test.modules.ts @@ -1,8 +1,8 @@ import { NgModule } from '@angular/core'; -import { generateStratosEntities } from '../../store/src/base-entity-types'; import { CATALOGUE_ENTITIES, EntityCatalogFeatureModule } from '../../store/src/entity-catalog.module'; import { entityCatalog, TestEntityCatalog } from '../../store/src/entity-catalog/entity-catalog'; +import { generateStratosEntities } from '../src/stratos-entities'; @NgModule({ imports: [ diff --git a/src/frontend/packages/store/src/base-entity-types.ts b/src/frontend/packages/store/src/base-entity-types.ts index e9cf682103..207786a571 100644 --- a/src/frontend/packages/store/src/base-entity-types.ts +++ b/src/frontend/packages/store/src/base-entity-types.ts @@ -1,6 +1,3 @@ -import { - MetricsEndpointDetailsComponent, -} from '../../core/src/features/metrics/metrics-endpoint-details/metrics-endpoint-details.component'; import { endpointEntitySchema, STRATOS_ENDPOINT_TYPE, @@ -8,11 +5,7 @@ import { userFavoritesEntitySchema, userProfileEntitySchema, } from './base-entity-schemas'; -import { BaseEndpointAuth } from './endpoint-auth'; -import { - StratosCatalogEndpointEntity, - StratosCatalogEntity, -} from './entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { StratosCatalogEntity } from './entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { addOrUpdateUserFavoriteMetadataReducer, deleteUserFavoriteMetadataReducer } from './reducers/favorite.reducer'; import { systemEndpointsReducer } from './reducers/system-endpoints.reducer'; @@ -34,7 +27,7 @@ const stratosType = { * DefaultEndpointEntityType is used to represent a general endpoint * This should not be used to actually attempt to render an endpoint and is instead used as a way to fill the */ -class DefaultEndpointCatalogEntity extends StratosCatalogEntity { +export class DefaultEndpointCatalogEntity extends StratosCatalogEntity { constructor() { super({ schema: endpointEntitySchema, @@ -48,7 +41,7 @@ class DefaultEndpointCatalogEntity extends StratosCatalogEntity { } } -class UserFavoriteCatalogEntity extends StratosCatalogEntity { +export class UserFavoriteCatalogEntity extends StratosCatalogEntity { constructor() { super({ schema: userFavoritesEntitySchema, @@ -63,7 +56,7 @@ class UserFavoriteCatalogEntity extends StratosCatalogEntity { } } -class UserProfileCatalogEntity extends StratosCatalogEntity { +export class UserProfileCatalogEntity extends StratosCatalogEntity { constructor() { super({ schema: userProfileEntitySchema, @@ -73,7 +66,7 @@ class UserProfileCatalogEntity extends StratosCatalogEntity { } } -class SystemInfoCatalogEntity extends StratosCatalogEntity { +export class SystemInfoCatalogEntity extends StratosCatalogEntity { constructor() { super({ schema: systemInfoEntitySchema, @@ -83,25 +76,4 @@ class SystemInfoCatalogEntity extends StratosCatalogEntity { } } -export function generateStratosEntities() { - return [ - new DefaultEndpointCatalogEntity(), - new SystemInfoCatalogEntity(), - new UserFavoriteCatalogEntity(), - new UserProfileCatalogEntity(), - // TODO: metrics location to be sorted - STRAT-152 - new StratosCatalogEndpointEntity({ - type: 'metrics', - label: 'Metrics', - labelPlural: 'Metrics', - tokenSharing: true, - logoUrl: '/core/assets/endpoint-icons/metrics.svg', - authTypes: [BaseEndpointAuth.UsernamePassword, BaseEndpointAuth.None], - renderPriority: 1, - listDetailsComponent: MetricsEndpointDetailsComponent, - }, - metadata => `/endpoints/metrics/${metadata.guid}` - ) - ]; -} From b86f9128898a1864570490d4d121566fab280905 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Fri, 19 Jun 2020 13:43:46 +0100 Subject: [PATCH 77/82] Finish store -> core sep --- .../cloud-foundry/src/cf-entity-generator.ts | 2 +- .../app-service-binding-card.component.ts | 6 ++-- .../cf-org-card/cf-org-card.component.ts | 6 ++-- .../cf-space-card/cf-space-card.component.ts | 6 ++-- .../service-instance-card.component.ts | 6 ++-- ...rovided-service-instance-card.component.ts | 6 ++-- .../shared/data-services/cf-user.service.ts | 4 +-- .../src => core/src/core}/endpoint-auth.ts | 12 +++---- .../connect-endpoint.component.ts | 2 +- .../favorites-entity-list.component.ts | 2 +- .../favorites-global-list.component.ts | 9 ++--- .../favorites-meta-card.component.ts | 6 ++-- .../list-data-source.ts | 2 +- .../local-list-controller.ts | 2 +- .../meta-card-base/meta-card.component.ts | 16 +++------ .../endpoint-card/endpoint-card.component.ts | 8 ++--- .../packages/core/src/stratos-entities.ts | 2 +- src/frontend/packages/store/ng-package.json | 2 +- src/frontend/packages/store/package.json | 2 +- .../src/entity-catalog/entity-catalog.spec.ts | 9 ++--- .../store/src/favorite-config-mapper.ts | 6 ++-- .../src/helpers}/local-list.helpers.ts | 4 +-- .../store/src/helpers/store-helpers.ts | 2 +- .../store/src/monitors/pagination-monitor.ts | 4 +-- .../pagination-reducer-max-reached.ts | 4 +-- .../store/src/types/menu-item.types.ts | 11 +++++++ .../src/types/user-favorite-manager.types.ts | 27 +++++++++++++++ .../store/src/types/user-favorites.types.ts | 6 ++++ .../store/src/user-favorite-manager.ts | 33 ++----------------- .../packages/store/testing/ng-package.json | 4 +-- .../packages/store/testing/package.json | 8 ----- 31 files changed, 94 insertions(+), 125 deletions(-) rename src/frontend/packages/{store/src => core/src/core}/endpoint-auth.ts (68%) rename src/frontend/packages/{core/src/shared/components/list/data-sources-controllers => store/src/helpers}/local-list.helpers.ts (86%) create mode 100644 src/frontend/packages/store/src/types/menu-item.types.ts create mode 100644 src/frontend/packages/store/src/types/user-favorite-manager.types.ts delete mode 100644 src/frontend/packages/store/testing/package.json diff --git a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts index a0eae51b11..bc6f27b556 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts @@ -3,10 +3,10 @@ import * as moment from 'moment'; import { combineLatest, Observable, of } from 'rxjs'; import { first, map } from 'rxjs/operators'; +import { BaseEndpointAuth } from '../../core/src/core/endpoint-auth'; import { urlValidationExpression } from '../../core/src/core/utils.service'; import { AppState, GeneralEntityAppState } from '../../store/src/app-state'; import { metricEntityType } from '../../store/src/base-entity-schemas'; -import { BaseEndpointAuth } from '../../store/src/endpoint-auth'; import { StratosBaseCatalogEntity, StratosCatalogEndpointEntity, diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts index b584a05878..50fb563f34 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts @@ -8,11 +8,9 @@ import { CurrentUserPermissionsService, } from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; -import { - MetaCardMenuItem, -} from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell, IListRowCell } from '../../../../../../../../core/src/shared/components/list/list.types'; import { APIResource, EntityInfo } from '../../../../../../../../store/src/types/api.types'; +import { MenuItem } from '../../../../../../../../store/src/types/menu-item.types'; import { ComponentEntityMonitorConfig } from '../../../../../../../../store/src/types/shared.types'; import { IService, @@ -55,7 +53,7 @@ export class AppServiceBindingCardComponent extends CardCell; customStyle?: string; }[]; - cardMenu: MetaCardMenuItem[]; + cardMenu: MenuItem[]; service$: Observable> | null>; serviceInstance$: Observable>>; tags$: Observable[]>; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts index bcdd032bd2..f7e4ff459b 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-orgs/cf-org-card/cf-org-card.component.ts @@ -11,9 +11,6 @@ import { import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; -import { - MetaCardMenuItem, -} from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; import { RouterNav } from '../../../../../../../../store/src/actions/router.actions'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; @@ -21,6 +18,7 @@ import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors import { PaginationMonitorFactory } from '../../../../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { EndpointUser } from '../../../../../../../../store/src/types/endpoint.types'; +import { MenuItem } from '../../../../../../../../store/src/types/menu-item.types'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; @@ -47,7 +45,7 @@ import { CF_ENDPOINT_TYPE } from './../../../../../../cf-types'; styleUrls: ['./cf-org-card.component.scss'] }) export class CfOrgCardComponent extends CardCell> implements OnInit, OnDestroy { - cardMenu: MetaCardMenuItem[]; + cardMenu: MenuItem[]; orgGuid: string; normalisedMemoryUsage: number; memoryLimit: string; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts index c31213505f..322d4bc454 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/cf-spaces/cf-space-card/cf-space-card.component.ts @@ -12,9 +12,6 @@ import { import { truthyIncludingZeroString } from '../../../../../../../../core/src/core/utils.service'; import { ConfirmationDialogConfig } from '../../../../../../../../core/src/shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../../../../../core/src/shared/components/confirmation-dialog.service'; -import { - MetaCardMenuItem, -} from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; import { RouterNav } from '../../../../../../../../store/src/actions/router.actions'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; @@ -22,6 +19,7 @@ import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors import { PaginationMonitorFactory } from '../../../../../../../../store/src/monitors/pagination-monitor.factory'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { EndpointUser } from '../../../../../../../../store/src/types/endpoint.types'; +import { MenuItem } from '../../../../../../../../store/src/types/menu-item.types'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; @@ -47,7 +45,7 @@ import { CfUserService } from '../../../../../data-services/cf-user.service'; styleUrls: ['./cf-space-card.component.scss'] }) export class CfSpaceCardComponent extends CardCell> implements OnInit, OnDestroy { - cardMenu: MetaCardMenuItem[]; + cardMenu: MenuItem[]; spaceGuid: string; appInstancesCount: number; appInstancesLimit: string; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts index 85a9dd63be..640c95bcf2 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts @@ -8,11 +8,9 @@ import { CurrentUserPermissionsService, } from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; -import { - MetaCardMenuItem, -} from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; +import { MenuItem } from '../../../../../../../../store/src/types/menu-item.types'; import { ComponentEntityMonitorConfig } from '../../../../../../../../store/src/types/shared.types'; import { IServiceInstance } from '../../../../../../cf-api-svc.types'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; @@ -104,7 +102,7 @@ export class ServiceInstanceCardComponent extends CardCell; cfGuid: string; - cardMenu: MetaCardMenuItem[]; + cardMenu: MenuItem[]; serviceInstanceTags: AppChip[]; hasMultipleBindings = new BehaviorSubject(true); diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts index a7b8310c88..0103bc36be 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/services-wall/user-provided-service-instance-card/user-provided-service-instance-card.component.ts @@ -8,11 +8,9 @@ import { CurrentUserPermissionsService, } from '../../../../../../../../core/src/core/permissions/current-user-permissions.service'; import { AppChip } from '../../../../../../../../core/src/shared/components/chips/chips.component'; -import { - MetaCardMenuItem, -} from '../../../../../../../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../../../../../../core/src/shared/components/list/list.types'; import { APIResource } from '../../../../../../../../store/src/types/api.types'; +import { MenuItem } from '../../../../../../../../store/src/types/menu-item.types'; import { ComponentEntityMonitorConfig } from '../../../../../../../../store/src/types/shared.types'; import { IUserProvidedServiceInstance } from '../../../../../../cf-api-svc.types'; import { cfEntityFactory } from '../../../../../../cf-entity-factory'; @@ -30,7 +28,7 @@ import { CSI_CANCEL_URL } from '../../../../add-service-instance/csi-mode.servic export class UserProvidedServiceInstanceCardComponent extends CardCell> { serviceInstanceEntity: APIResource; cfGuid: string; - cardMenu: MetaCardMenuItem[]; + cardMenu: MenuItem[]; serviceInstanceTags: AppChip[]; hasMultipleBindings = new BehaviorSubject(true); diff --git a/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-user.service.ts b/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-user.service.ts index 30a0022d4b..e797eab3c8 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-user.service.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/data-services/cf-user.service.ts @@ -7,10 +7,8 @@ import { CFAppState } from '../../../../cloud-foundry/src/cf-app-state'; import { cfUserEntityType, organizationEntityType, spaceEntityType } from '../../../../cloud-foundry/src/cf-entity-types'; import { createEntityRelationPaginationKey } from '../../../../cloud-foundry/src/entity-relations/entity-relations.types'; import { getCurrentUserCFGlobalStates } from '../../../../cloud-foundry/src/store/selectors/cf-current-user-role.selectors'; -import { - LocalPaginationHelpers, -} from '../../../../core/src/shared/components/list/data-sources-controllers/local-list.helpers'; import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog'; +import { LocalPaginationHelpers } from '../../../../store/src/helpers/local-list.helpers'; import { PaginationMonitorFactory } from '../../../../store/src/monitors/pagination-monitor.factory'; import { getDefaultPaginationEntityState, diff --git a/src/frontend/packages/store/src/endpoint-auth.ts b/src/frontend/packages/core/src/core/endpoint-auth.ts similarity index 68% rename from src/frontend/packages/store/src/endpoint-auth.ts rename to src/frontend/packages/core/src/core/endpoint-auth.ts index c5f857da8b..0fa06e90d1 100644 --- a/src/frontend/packages/store/src/endpoint-auth.ts +++ b/src/frontend/packages/core/src/core/endpoint-auth.ts @@ -1,15 +1,11 @@ import { Validators } from '@angular/forms'; +import { EndpointAuthTypeConfig, EndpointType } from '../../../store/src/extension-types'; import { CredentialsAuthFormComponent, -} from '../../core/src/features/endpoints/connect-endpoint-dialog/auth-forms/credentials-auth-form.component'; -import { - NoneAuthFormComponent, -} from '../../core/src/features/endpoints/connect-endpoint-dialog/auth-forms/none-auth-form.component'; -import { - SSOAuthFormComponent, -} from '../../core/src/features/endpoints/connect-endpoint-dialog/auth-forms/sso-auth-form.component'; -import { EndpointAuthTypeConfig, EndpointType } from './extension-types'; +} from '../features/endpoints/connect-endpoint-dialog/auth-forms/credentials-auth-form.component'; +import { NoneAuthFormComponent } from '../features/endpoints/connect-endpoint-dialog/auth-forms/none-auth-form.component'; +import { SSOAuthFormComponent } from '../features/endpoints/connect-endpoint-dialog/auth-forms/sso-auth-form.component'; export enum EndpointAuthTypeNames { CREDS = 'creds', diff --git a/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts b/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts index 78c10d099a..0f6bc94595 100644 --- a/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/connect-endpoint/connect-endpoint.component.ts @@ -14,9 +14,9 @@ import { import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Subscription } from 'rxjs'; -import { BaseEndpointAuth } from '../../../../../store/src/endpoint-auth'; import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; import { EndpointAuthTypeConfig, IAuthForm, IEndpointAuthComponent } from '../../../../../store/src/extension-types'; +import { BaseEndpointAuth } from '../../../core/endpoint-auth'; import { safeUnsubscribe } from '../../../core/utils.service'; import { ConnectEndpointConfig, ConnectEndpointData, ConnectEndpointService } from '../connect.service'; diff --git a/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts b/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts index aeeca51973..06800db5f3 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-entity-list/favorites-entity-list.component.ts @@ -3,7 +3,7 @@ import { combineLatest, Observable, ReplaySubject, Subject } from 'rxjs'; import { distinctUntilChanged, map, scan, startWith } from 'rxjs/operators'; import { FavoritesConfigMapper, IFavoriteTypes } from '../../../../../store/src/favorite-config-mapper'; -import { IFavoriteEntity } from '../../../../../store/src/user-favorite-manager'; +import { IFavoriteEntity } from '../../../../../store/src/types/user-favorite-manager.types'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/favorites-global-list/favorites-global-list.component.ts b/src/frontend/packages/core/src/shared/components/favorites-global-list/favorites-global-list.component.ts index aff1a3bb08..f8313df5a2 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-global-list/favorites-global-list.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-global-list/favorites-global-list.component.ts @@ -5,12 +5,9 @@ import { map } from 'rxjs/operators'; import { AppState } from '../../../../../store/src/app-state'; import { getFavoriteInfoObservable } from '../../../../../store/src/helpers/store-helpers'; -import { - IFavoriteEntity, - IFavoritesInfo, - IGroupedFavorites, - UserFavoriteManager, -} from '../../../../../store/src/user-favorite-manager'; +import { IFavoriteEntity, IGroupedFavorites } from '../../../../../store/src/types/user-favorite-manager.types'; +import { IFavoritesInfo } from '../../../../../store/src/types/user-favorites.types'; +import { UserFavoriteManager } from '../../../../../store/src/user-favorite-manager'; @Component({ diff --git a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts index ac7488867a..44948e8559 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorites-meta-card.component.ts @@ -11,13 +11,13 @@ import { userFavoritesEntitySchema } from '../../../../../store/src/base-entity- import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; import { IFavoritesMetaCardConfig } from '../../../../../store/src/favorite-config-mapper'; import { endpointEntitiesSelector } from '../../../../../store/src/selectors/endpoint.selectors'; +import { MenuItem } from '../../../../../store/src/types/menu-item.types'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../store/src/types/shared.types'; +import { IFavoriteEntity } from '../../../../../store/src/types/user-favorite-manager.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../store/src/types/user-favorites.types'; -import { IFavoriteEntity } from '../../../../../store/src/user-favorite-manager'; import { isEndpointConnected } from '../../../features/endpoints/connect.service'; import { ConfirmationDialogConfig } from '../confirmation-dialog.config'; import { ConfirmationDialogService } from '../confirmation-dialog.service'; -import { MetaCardMenuItem } from '../list/list-cards/meta-card/meta-card-base/meta-card.component'; @Component({ @@ -64,7 +64,7 @@ export class FavoritesMetaCardComponent { public endpointConnected$: Observable; public name$: Observable; public routerLink$: Observable; - public actions$: Observable; + public actions$: Observable; // Optional icon for the favorite public iconUrl$: Observable; diff --git a/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source.ts b/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source.ts index b1fdfc75c7..16ea225294 100644 --- a/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source.ts @@ -31,6 +31,7 @@ import { IgnorePaginationMaxedState, SetResultCount } from '../../../../../../st import { AppState } from '../../../../../../store/src/app-state'; import { entityCatalog } from '../../../../../../store/src/entity-catalog/entity-catalog'; import { EntitySchema } from '../../../../../../store/src/helpers/entity-schema'; +import { LocalPaginationHelpers } from '../../../../../../store/src/helpers/local-list.helpers'; import { PaginationMonitor } from '../../../../../../store/src/monitors/pagination-monitor'; import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; import { PaginatedAction, PaginationEntityState, PaginationParam } from '../../../../../../store/src/types/pagination.types'; @@ -46,7 +47,6 @@ import { } from './list-data-source-types'; import { getDataFunctionList } from './local-filtering-sorting'; import { LocalListController } from './local-list-controller'; -import { LocalPaginationHelpers } from './local-list.helpers'; export type DataFunctionDefinitionType = 'sort' | 'filter'; diff --git a/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/local-list-controller.ts b/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/local-list-controller.ts index bb0fb7391f..2d53920886 100644 --- a/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/local-list-controller.ts +++ b/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/local-list-controller.ts @@ -2,10 +2,10 @@ import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { tag } from 'rxjs-spy/operators/tag'; import { distinctUntilChanged, map, publishReplay, refCount, switchMap, tap } from 'rxjs/operators'; +import { LocalPaginationHelpers } from '../../../../../../store/src/helpers/local-list.helpers'; import { PaginationEntityState } from '../../../../../../store/src/types/pagination.types'; import { DataFunction } from './list-data-source'; import { splitCurrentPage } from './local-list-controller.helpers'; -import { LocalPaginationHelpers } from './local-list.helpers'; export class LocalListController { public page$: Observable; diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts index bfcc9d7644..59a95244d6 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.ts @@ -4,6 +4,7 @@ import { first, map, tap } from 'rxjs/operators'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EntityMonitorFactory } from '../../../../../../../../store/src/monitors/entity-monitor.factory.service'; +import { MenuItem } from '../../../../../../../../store/src/types/menu-item.types'; import { ComponentEntityMonitorConfig, StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../../../../store/src/types/user-favorites.types'; import { getFavoriteFromEntity } from '../../../../../../../../store/src/user-favorite-helpers'; @@ -12,15 +13,6 @@ import { MetaCardItemComponent } from '../meta-card-item/meta-card-item.componen import { MetaCardTitleComponent } from '../meta-card-title/meta-card-title.component'; -export interface MetaCardMenuItem { - icon?: string; - label: string; - action: () => void; - can?: Observable; - disabled?: Observable; - separator?: boolean; -} - export function createMetaCardMenuItemSeparator() { return { label: '-', @@ -89,7 +81,7 @@ export class MetaCardComponent implements OnDestroy { } @Input('actionMenu') - set actionMenu(actionMenu: MetaCardMenuItem[]) { + set actionMenu(actionMenu: MenuItem[]) { if (actionMenu) { this.pActionMenu = actionMenu.map(menuItem => { if (!menuItem.can) { @@ -107,7 +99,7 @@ export class MetaCardComponent implements OnDestroy { ); } } - get actionMenu(): MetaCardMenuItem[] { + get actionMenu(): MenuItem[] { return this.pActionMenu; } @@ -115,7 +107,7 @@ export class MetaCardComponent implements OnDestroy { public showMenu$: Observable; public isDeleting$: Observable = observableOf(false); - private pActionMenu: MetaCardMenuItem[]; + private pActionMenu: MenuItem[]; constructor( private entityMonitorFactory: EntityMonitorFactory, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts index 3ef07992cf..f275f03966 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts @@ -21,14 +21,12 @@ import { } from '../../../../../../../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { FavoritesConfigMapper } from '../../../../../../../../store/src/favorite-config-mapper'; import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { MenuItem } from '../../../../../../../../store/src/types/menu-item.types'; import { StratosStatus } from '../../../../../../../../store/src/types/shared.types'; import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types'; import { safeUnsubscribe } from '../../../../../../core/utils.service'; import { coreEndpointListDetailsComponents } from '../../../../../../features/endpoints/endpoint-helpers'; -import { - createMetaCardMenuItemSeparator, - MetaCardMenuItem, -} from '../../../list-cards/meta-card/meta-card-base/meta-card.component'; +import { createMetaCardMenuItemSeparator } from '../../../list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell } from '../../../list.types'; import { BaseEndpointsDataSource } from '../base-endpoints-data-source'; import { EndpointListDetailsComponent, EndpointListHelper } from '../endpoint-list.helpers'; @@ -46,7 +44,7 @@ export class EndpointCardComponent extends CardCell implements On public rowObs = new ReplaySubject(); public favorite: UserFavoriteEndpoint; public address: string; - public cardMenu: MetaCardMenuItem[]; + public cardMenu: MenuItem[]; public endpointCatalogEntity: StratosCatalogEndpointEntity; public hasDetails = true; public endpointLink: string = null; diff --git a/src/frontend/packages/core/src/stratos-entities.ts b/src/frontend/packages/core/src/stratos-entities.ts index a2d8844f60..539aec7e4c 100644 --- a/src/frontend/packages/core/src/stratos-entities.ts +++ b/src/frontend/packages/core/src/stratos-entities.ts @@ -4,8 +4,8 @@ import { UserFavoriteCatalogEntity, UserProfileCatalogEntity, } from '../../store/src/base-entity-types'; -import { BaseEndpointAuth } from '../../store/src/endpoint-auth'; import { StratosCatalogEndpointEntity } from '../../store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity'; +import { BaseEndpointAuth } from './core/endpoint-auth'; import { MetricsEndpointDetailsComponent, } from './features/metrics/metrics-endpoint-details/metrics-endpoint-details.component'; diff --git a/src/frontend/packages/store/ng-package.json b/src/frontend/packages/store/ng-package.json index c77901ef24..babd6c3d91 100644 --- a/src/frontend/packages/store/ng-package.json +++ b/src/frontend/packages/store/ng-package.json @@ -2,6 +2,6 @@ "$schema": "../../../../node_modules/ng-packagr/ng-package.schema.json", "dest": "../../../../dist/store", "lib": { - "entryFile": "src/public_api.ts" + "entryFile": "src/public-api.ts" } } \ No newline at end of file diff --git a/src/frontend/packages/store/package.json b/src/frontend/packages/store/package.json index cb014d0a39..0184d8f74d 100644 --- a/src/frontend/packages/store/package.json +++ b/src/frontend/packages/store/package.json @@ -1,5 +1,5 @@ { - "name": "store", + "name": "@stratosui/store", "version": "0.0.1", "peerDependencies": { "@angular/common": "^6.0.0-rc.0 || ^6.0.0", diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts index 38bd2aec54..bea826fdf0 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog.spec.ts @@ -2,13 +2,12 @@ import { EndpointListDetailsComponent, } from '../../../core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers'; import { endpointEntitySchema } from '../base-entity-schemas'; -import { BaseEndpointAuth } from '../endpoint-auth'; import { EntitySchema } from '../helpers/entity-schema'; import { TestEntityCatalog } from './entity-catalog'; import { StratosCatalogEndpointEntity, StratosCatalogEntity } from './entity-catalog-entity/entity-catalog-entity'; import { EntityCatalogSchemas, IStratosEndpointDefinition } from './entity-catalog.types'; -describe('EntityCatalogService', () => { +fdescribe('EntityCatalogService', () => { let entityCatalog: TestEntityCatalog; function getEndpointDefinition() { return { @@ -18,7 +17,7 @@ describe('EntityCatalogService', () => { icon: 'cloud_foundry', iconFont: 'stratos-icons', logoUrl: '/core/assets/endpoint-icons/cloudfoundry.png', - authTypes: [BaseEndpointAuth.UsernamePassword, BaseEndpointAuth.SSO], + authTypes: [], listDetailsComponent: EndpointListDetailsComponent, } as IStratosEndpointDefinition; } @@ -124,9 +123,7 @@ describe('EntityCatalogService', () => { urlValidation: false, unConnectable: true, urlValidationRegexString: 'redjecks', - authTypes: [ - BaseEndpointAuth.SSO - ] + authTypes: [] }; const definition = { ...endpoint, diff --git a/src/frontend/packages/store/src/favorite-config-mapper.ts b/src/frontend/packages/store/src/favorite-config-mapper.ts index 7a5faf9b60..76b8a8e2b2 100644 --- a/src/frontend/packages/store/src/favorite-config-mapper.ts +++ b/src/frontend/packages/store/src/favorite-config-mapper.ts @@ -1,14 +1,12 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { - MetaCardMenuItem, -} from '../../core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component'; import { entityCatalog } from './entity-catalog/entity-catalog'; import { StratosBaseCatalogEntity } from './entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { EntityCatalogHelpers } from './entity-catalog/entity-catalog.helper'; import { IEntityMetadata, IStratosEntityDefinition } from './entity-catalog/entity-catalog.types'; import { EndpointModel } from './types/endpoint.types'; +import { MenuItem } from './types/menu-item.types'; import { EntityRequestAction } from './types/request.types'; import { IFavoriteMetadata, IFavoriteTypeInfo, UserFavorite, UserFavoriteEndpoint } from './types/user-favorites.types'; @@ -28,7 +26,7 @@ export interface IFavoritesMetaCardConfig { lines?: TFavoritesMetaCardLine[]; routerLink?: string; name: string; - menuItems?: MetaCardMenuItem[]; + menuItems?: MenuItem[]; } export interface IFavoriteConfig { diff --git a/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/local-list.helpers.ts b/src/frontend/packages/store/src/helpers/local-list.helpers.ts similarity index 86% rename from src/frontend/packages/core/src/shared/components/list/data-sources-controllers/local-list.helpers.ts rename to src/frontend/packages/store/src/helpers/local-list.helpers.ts index c84c1c7402..2810937aac 100644 --- a/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/local-list.helpers.ts +++ b/src/frontend/packages/store/src/helpers/local-list.helpers.ts @@ -1,5 +1,5 @@ -import { entityCatalog } from '../../../../../../store/src/entity-catalog/entity-catalog'; -import { PaginationEntityState } from '../../../../../../store/src/types/pagination.types'; +import { entityCatalog } from '../entity-catalog/entity-catalog'; +import { PaginationEntityState } from '../types/pagination.types'; export class LocalPaginationHelpers { diff --git a/src/frontend/packages/store/src/helpers/store-helpers.ts b/src/frontend/packages/store/src/helpers/store-helpers.ts index 597e43ecf9..cac7ba4e0a 100644 --- a/src/frontend/packages/store/src/helpers/store-helpers.ts +++ b/src/frontend/packages/store/src/helpers/store-helpers.ts @@ -6,7 +6,7 @@ import { AppState } from '../app-state'; import { MultiActionListEntity } from '../monitors/pagination-monitor'; import { errorFetchingFavoritesSelector, fetchingFavoritesSelector } from '../selectors/favorite-groups.selectors'; import { APIResource } from '../types/api.types'; -import { IFavoritesInfo } from '../user-favorite-manager'; +import { IFavoritesInfo } from '../types/user-favorites.types'; export function getDashboardStateSessionId(username?: string) { diff --git a/src/frontend/packages/store/src/monitors/pagination-monitor.ts b/src/frontend/packages/store/src/monitors/pagination-monitor.ts index a55f2910dd..c19b9db3da 100644 --- a/src/frontend/packages/store/src/monitors/pagination-monitor.ts +++ b/src/frontend/packages/store/src/monitors/pagination-monitor.ts @@ -14,14 +14,12 @@ import { withLatestFrom, } from 'rxjs/operators'; -import { - LocalPaginationHelpers, -} from '../../../core/src/shared/components/list/data-sources-controllers/local-list.helpers'; import { AppState, GeneralEntityAppState, GeneralRequestDataState } from '../app-state'; import { entityCatalog } from '../entity-catalog/entity-catalog'; import { StratosBaseCatalogEntity } from '../entity-catalog/entity-catalog-entity/entity-catalog-entity'; import { EntityCatalogEntityConfig } from '../entity-catalog/entity-catalog.types'; import { EntitySchema } from '../helpers/entity-schema'; +import { LocalPaginationHelpers } from '../helpers/local-list.helpers'; import { ActionState, ListActionState } from '../reducers/api-request-reducer/types'; import { getCurrentPageRequestInfo } from '../reducers/pagination-reducer/pagination-reducer.types'; import { getAPIRequestDataState, selectEntities } from '../selectors/api.selectors'; diff --git a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-max-reached.ts b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-max-reached.ts index 3d8080a705..906dc3fbe7 100644 --- a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-max-reached.ts +++ b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-max-reached.ts @@ -1,8 +1,6 @@ -import { - LocalPaginationHelpers, -} from '../../../../core/src/shared/components/list/data-sources-controllers/local-list.helpers'; import { IgnorePaginationMaxedState, UpdatePaginationMaxedState } from '../../actions/pagination.actions'; import { entityCatalog } from '../../entity-catalog/entity-catalog'; +import { LocalPaginationHelpers } from '../../helpers/local-list.helpers'; import { PaginationEntityTypeState, PaginationState } from '../../types/pagination.types'; import { getDefaultPaginationEntityState } from './pagination-reducer-reset-pagination'; diff --git a/src/frontend/packages/store/src/types/menu-item.types.ts b/src/frontend/packages/store/src/types/menu-item.types.ts new file mode 100644 index 0000000000..bb55c8f11a --- /dev/null +++ b/src/frontend/packages/store/src/types/menu-item.types.ts @@ -0,0 +1,11 @@ +import { Observable } from 'rxjs'; + + +export interface MenuItem { + icon?: string; + label: string; + action: () => void; + can?: Observable; + disabled?: Observable; + separator?: boolean; +} diff --git a/src/frontend/packages/store/src/types/user-favorite-manager.types.ts b/src/frontend/packages/store/src/types/user-favorite-manager.types.ts new file mode 100644 index 0000000000..3b170661a2 --- /dev/null +++ b/src/frontend/packages/store/src/types/user-favorite-manager.types.ts @@ -0,0 +1,27 @@ +import { TFavoriteMapperFunction } from '../favorite-config-mapper'; +import { IEndpointFavMetadata, IFavoriteMetadata, UserFavorite } from './user-favorites.types'; + +export interface IFavoriteEntity { + type: string; + prettyName: string; + cardMapper: TFavoriteMapperFunction; + favorite: UserFavorite; +} + +export interface IGroupedFavorites { + endpoint: IHydrationResults; + entities: IHydrationResults[]; +} + +export interface IAllFavorites { + fetching: boolean; + error: boolean; + entityGroups: IGroupedFavorites[]; +} + +export interface IHydrationResults { + type: string; + cardMapper: TFavoriteMapperFunction; + prettyName: string; + favorite: UserFavorite; +} diff --git a/src/frontend/packages/store/src/types/user-favorites.types.ts b/src/frontend/packages/store/src/types/user-favorites.types.ts index b9a52c3ffa..b92b043b41 100644 --- a/src/frontend/packages/store/src/types/user-favorites.types.ts +++ b/src/frontend/packages/store/src/types/user-favorites.types.ts @@ -2,6 +2,12 @@ import { IEntityMetadata } from '../entity-catalog/entity-catalog.types'; export const userFavoritesPaginationKey = 'userFavorites'; + +export interface IFavoritesInfo { + fetching: boolean; + error: boolean; +} + /** * A user favorite blueprint. Can be used to fetch the full entity from a particular endpoint. */ diff --git a/src/frontend/packages/store/src/user-favorite-manager.ts b/src/frontend/packages/store/src/user-favorite-manager.ts index d6420bf804..b3fae3896c 100644 --- a/src/frontend/packages/store/src/user-favorite-manager.ts +++ b/src/frontend/packages/store/src/user-favorite-manager.ts @@ -6,7 +6,7 @@ import { filter, map, switchMap, tap } from 'rxjs/operators'; import { ToggleUserFavoriteAction } from './actions/user-favourites-actions/toggle-user-favorite-action'; import { GeneralEntityAppState, IRequestEntityTypeState } from './app-state'; import { entityCatalog } from './entity-catalog/entity-catalog'; -import { FavoritesConfigMapper, TFavoriteMapperFunction } from './favorite-config-mapper'; +import { FavoritesConfigMapper } from './favorite-config-mapper'; import { endpointEntitiesSelector } from './selectors/endpoint.selectors'; import { errorFetchingFavoritesSelector, @@ -16,38 +16,9 @@ import { } from './selectors/favorite-groups.selectors'; import { isFavorite } from './selectors/favorite.selectors'; import { IUserFavoritesGroups } from './types/favorite-groups.types'; +import { IGroupedFavorites, IHydrationResults } from './types/user-favorite-manager.types'; import { IEndpointFavMetadata, IFavoriteMetadata, UserFavorite } from './types/user-favorites.types'; -export interface IFavoriteEntity { - type: string; - prettyName: string; - cardMapper: TFavoriteMapperFunction; - favorite: UserFavorite; -} - -export interface IGroupedFavorites { - endpoint: IHydrationResults; - entities: IHydrationResults[]; -} - - -export interface IAllFavorites { - fetching: boolean; - error: boolean; - entityGroups: IGroupedFavorites[]; -} - -export interface IFavoritesInfo { - fetching: boolean; - error: boolean; -} - -export interface IHydrationResults { - type: string; - cardMapper: TFavoriteMapperFunction; - prettyName: string; - favorite: UserFavorite; -} @Injectable({ providedIn: 'root' }) diff --git a/src/frontend/packages/store/testing/ng-package.json b/src/frontend/packages/store/testing/ng-package.json index 87392138a4..bfa6b062cf 100644 --- a/src/frontend/packages/store/testing/ng-package.json +++ b/src/frontend/packages/store/testing/ng-package.json @@ -1,7 +1,7 @@ { - "$schema": "../../../../node_modules/ng-packagr/ng-package.schema.json", + "$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json", "dest": "../../../../dist/store/testing", "lib": { - "entryFile": "public_api.ts" + "entryFile": "public-api.ts" } } \ No newline at end of file diff --git a/src/frontend/packages/store/testing/package.json b/src/frontend/packages/store/testing/package.json deleted file mode 100644 index 7dd43ac8c1..0000000000 --- a/src/frontend/packages/store/testing/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "store/testing", - "version": "0.0.1", - "peerDependencies": { - "@angular/common": "^6.0.0-rc.0 || ^6.0.0", - "@angular/core": "^6.0.0-rc.0 || ^6.0.0" - } -} \ No newline at end of file From 91f889b5259174e1d912c4baf0357cb1f55e95fe Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Mon, 22 Jun 2020 15:24:00 +0100 Subject: [PATCH 78/82] Address PR feedback --- .../packages/core/src/core/utils.service.ts | 32 ------------- .../entity-catalog-entity.ts | 9 +--- .../entity-catalog-entity.types.ts | 14 +----- .../entity-catalog-entity/type.helpers.ts | 46 +++++++++++++++++++ .../packages/store/src/types/auth.types.ts | 2 +- 5 files changed, 51 insertions(+), 52 deletions(-) create mode 100644 src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/type.helpers.ts diff --git a/src/frontend/packages/core/src/core/utils.service.ts b/src/frontend/packages/core/src/core/utils.service.ts index 37de7d5cab..a99ddf6708 100644 --- a/src/frontend/packages/core/src/core/utils.service.ts +++ b/src/frontend/packages/core/src/core/utils.service.ts @@ -11,38 +11,6 @@ export function getIdFromRoute(activatedRoute: ActivatedRoute, id: string) { return null; } -export type OptionalKeys = Exclude<{ - [K in keyof T]: T extends Record - ? K - : never -}[keyof T], undefined> - -export type NeverKeys = Exclude<{ - [K in keyof T]: T[K] extends never - ? K - : never -}[keyof T], undefined> - -/** - * Pick all properties who's function has the specified return type U - */ -export type FilteredByReturnType any }, U> = { - [P in keyof T]: ReturnType extends U ? T[P] : never -}; - -/** - * Pick all properties who's function do not have the specified return type U - */ -export type FilteredByNotReturnType any }, U> = { - [P in keyof T]: ReturnType extends U ? never : T[P] -}; - -// Note - Adding }[keyof T] to [P in keyof T] types should filter out properties of type `never`, however this fails with generics! -export type FilteredByValueType any }, U> = { - [P in keyof T]: T[P] extends U ? never : T[P] -}; - - export const urlValidationExpression = '^' + // protocol identifier diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts index 0bf0715cbc..5ad125609d 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.ts @@ -35,13 +35,8 @@ import { } from '../entity-catalog.types'; import { ActionBuilderConfigMapper } from './action-builder-config.mapper'; import { ActionDispatchers, EntityCatalogEntityStoreHelpers } from './entity-catalog-entity-store-helpers'; -import { EntityCatalogEntityStore, KnownKeys } from './entity-catalog-entity.types'; - -type NonOptionalKeys = Exclude<{ - [K in keyof T]: T extends Record - ? K - : never -}[keyof T], undefined> +import { EntityCatalogEntityStore } from './entity-catalog-entity.types'; +import { KnownKeys, NonOptionalKeys } from './type.helpers'; export type KnownActionBuilders = Pick>>>; diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts index 93a0b5e40b..36aa23b7bb 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts @@ -1,20 +1,10 @@ -import { FilteredByNotReturnType, FilteredByReturnType, NeverKeys } from '../../../../core/src/core/utils.service'; import { EntityService } from '../../entity-service'; import { EntityMonitor } from '../../monitors/entity-monitor'; import { PaginationMonitor } from '../../monitors/pagination-monitor'; import { PaginationObservables } from '../../reducers/pagination-reducer/pagination-reducer.types'; import { PaginatedAction } from '../../types/pagination.types'; import { OrchestratedActionBuilders, OrchestratedActionCoreBuilders } from '../action-orchestrator/action-orchestrator'; - -/** - * Remove keys such as typed indexes (i.e. [key: string]) - * For magic see - * - https://github.com/Microsoft/TypeScript/issues/25987#issuecomment-441224690 - * - https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-414808995 - */ -export type KnownKeys = { - [K in keyof T]: string extends K ? never : number extends K ? never : K -} extends { [_ in keyof T]: infer U } ? ({} extends U ? never : U) : never; +import { FilteredByReturnType, KnownKeys, NeverKeys } from './type.helpers'; /** * Core entity and entities access (entity/entities monitors and services) @@ -110,7 +100,7 @@ export type CustomEntityCatalogEntityStore = { + [K in keyof T]: string extends K ? never : number extends K ? never : K +} extends { [_ in keyof T]: infer U } ? ({} extends U ? never : U) : never; + +export type NonOptionalKeys = Exclude<{ + [K in keyof T]: T extends Record + ? K + : never +}[keyof T], undefined> + +export type OptionalKeys = Exclude<{ + [K in keyof T]: T extends Record + ? K + : never +}[keyof T], undefined> + +export type NeverKeys = Exclude<{ + [K in keyof T]: T[K] extends never + ? K + : never +}[keyof T], undefined> + +/** + * Pick all properties who's function has the specified return type U + */ +export type FilteredByReturnType any }, U> = { + [P in keyof T]: ReturnType extends U ? T[P] : never +}; + +/** + * Pick all properties who's function do not have the specified return type U + */ +export type FilteredByNotReturnType any }, U> = { + [P in keyof T]: ReturnType extends U ? never : T[P] +}; + +// Note - Adding }[keyof T] to [P in keyof T] types should filter out properties of type `never`, however this fails with generics! +export type FilteredByValueType any }, U> = { + [P in keyof T]: T[P] extends U ? never : T[P] +}; diff --git a/src/frontend/packages/store/src/types/auth.types.ts b/src/frontend/packages/store/src/types/auth.types.ts index 7795c7e242..cef354d888 100644 --- a/src/frontend/packages/store/src/types/auth.types.ts +++ b/src/frontend/packages/store/src/types/auth.types.ts @@ -9,7 +9,7 @@ export interface SessionUser { admin: boolean; guid: string; name: string; - scopes: []; + scopes: string[]; } export interface PluginConfig { userInvitationsEnabled: 'true' | 'false'; From 80e974553017ad6e23c2503ba680ad00ba15ae93 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Mon, 22 Jun 2020 16:01:35 +0100 Subject: [PATCH 79/82] Fix compilation issue --- .../entity-catalog-entity/entity-catalog-entity.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts index 36aa23b7bb..84c0592670 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts @@ -4,7 +4,7 @@ import { PaginationMonitor } from '../../monitors/pagination-monitor'; import { PaginationObservables } from '../../reducers/pagination-reducer/pagination-reducer.types'; import { PaginatedAction } from '../../types/pagination.types'; import { OrchestratedActionBuilders, OrchestratedActionCoreBuilders } from '../action-orchestrator/action-orchestrator'; -import { FilteredByReturnType, KnownKeys, NeverKeys } from './type.helpers'; +import { FilteredByNotReturnType, FilteredByReturnType, KnownKeys, NeverKeys } from './type.helpers'; /** * Core entity and entities access (entity/entities monitors and services) From 083c78f4659ec6eb64018fbbfa6fb39e49cff293 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 23 Jun 2020 09:33:04 +0100 Subject: [PATCH 80/82] Fix merge weirdness --- .../entity-catalog-entity.types.ts | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts index 10b0b5014d..ac6e5e3ae3 100644 --- a/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts +++ b/src/frontend/packages/store/src/entity-catalog/entity-catalog-entity/entity-catalog-entity.types.ts @@ -4,27 +4,8 @@ import { PaginationMonitor } from '../../monitors/pagination-monitor'; import { PaginationObservables } from '../../reducers/pagination-reducer/pagination-reducer.types'; import { PaginatedAction } from '../../types/pagination.types'; import { OrchestratedActionBuilders, OrchestratedActionCoreBuilders } from '../action-orchestrator/action-orchestrator'; -import { KnownKeys } from './type.helpers'; +import { FilteredByNotReturnType, FilteredByReturnType, KnownKeys, NeverKeys } from './type.helpers'; -type NeverKeys = Exclude<{ - [K in keyof T]: T[K] extends never - ? K - : never -}[keyof T], undefined> - -/** - * Pick all properties who's function has the specified return type U - */ -type FilteredByReturnType any }, U> = { - [P in keyof T]: ReturnType extends U ? T[P] : never -}; - -/** - * Pick all properties who's function do not have the specified return type U - */ -type FilteredByNotReturnType any }, U> = { - [P in keyof T]: ReturnType extends U ? never : T[P] -}; /** * Core entity and entities access (entity/entities monitors and services) From 7e4fb63480a43afe52be4a4bb11e8f4eaf8cf8fa Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 23 Jun 2020 10:16:19 +0100 Subject: [PATCH 81/82] Merge downstream (#4369) * src based changes * changes to ./build * ./docs * ./ * Changes following review --- README.md | 6 +- angular.json | 60 +- build/combine-coverage.js | 10 - build/karma.conf.creator.js | 8 +- build/karma.test.reporter.js | 85 +- build/tools/changelog.sh | 5 +- deploy/ci/console-dev-releases.yml | 12 +- docs/planning/metrics.md | 2 +- package-lock.json | 7981 ++++++++++------- package.json | 5 +- protractor.conf.js | 4 +- ...scaler-metric-chart-card.component.spec.ts | 2 - ...r-metric-chart-list-config.service.spec.ts | 3 - .../src/actions/buildpack.action.ts | 3 +- .../src/actions/domains.actions.ts | 3 +- .../src/actions/relation.actions.ts | 12 +- .../src/actions/security-groups-actions.ts | 3 +- .../src/actions/service-bindings.actions.ts | 3 +- .../src/actions/service-broker.actions.ts | 3 +- .../service-plan-visibility.actions.ts | 3 +- .../src/actions/service-plan.actions.ts | 3 +- .../cli-info-cloud-foundry.component.spec.ts | 2 - .../manage-users/cf-roles.service.spec.ts | 2 - .../list-types/app/cf-apps-data-source.ts | 2 +- .../core/sass/components/mat-table.scss | 16 +- src/frontend/packages/core/src/app.routing.ts | 2 +- .../core/src/core/endpoints.service.ts | 5 +- .../dashboard-base.component.ts | 2 +- .../backup-endpoints.component.html | 4 +- .../src/features/metrics/metrics.helpers.ts | 2 +- .../metrics/metrics/metrics.component.html | 29 +- .../entity-summary-title.component.scss | 3 + .../ring-chart/ring-chart.component.html | 9 +- .../ring-chart/ring-chart.component.ts | 17 +- .../packages/store/src/base-entity-types.ts | 18 +- .../store/src/effects/metrics.effects.ts | 10 +- .../packages/store/src/types/request.types.ts | 2 +- .../application/application-view-e2e.spec.ts | 8 +- .../cloud-foundry-list-cf-e2e.spec.ts | 29 +- src/test-e2e/e2e.ts | 8 + src/test-e2e/endpoints/endpoints-e2e.spec.ts | 34 +- src/test-e2e/helpers/cf-e2e-helpers.ts | 2 + src/test-e2e/po/component.po.ts | 5 + src/test-e2e/po/list.po.ts | 5 + src/tsconfig.spec.json | 2 +- 45 files changed, 5201 insertions(+), 3233 deletions(-) delete mode 100644 build/combine-coverage.js diff --git a/README.md b/README.md index 2d11e96b2f..397d3aaabd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@   - + [![GitHub release](https://img.shields.io/github/release/cloudfoundry/stratos.svg)](https://github.com/cloudfoundry/stratos/releases/latest) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/cloudfoundry/stratos/blob/master/LICENSE) [![slack.cloudfoundry.org](https://slack.cloudfoundry.org/badge.svg)](https://cloudfoundry.slack.com/messages/C80EP4Y57/) @@ -46,9 +46,9 @@ Get an [Overview](docs/overview.md) of Stratos, its components and the different Take a look at the [Development Roadmap](docs/roadmap.md) to see where we are heading. We update our status page each week to summarize what we are working on - see the [Status Page](docs/status_updates.md). -Browse through features and issues in the project's [issues](https://github.com/cloudfoundry/stratos/issues) page or [Zenhub Board](https://github.com/cloudfoundry-incubator/stratos#boards). +Browse through features and issues in the project's [issues](https://github.com/cloudfoundry/stratos/issues) page. -What kind of code is in Stratos? We've integrated [Code Climate](https://codeclimate.com) for some code quality and maintainability metrics. Take a stroll around the [project page](https://codeclimate.com/github/cloudfoundry-incubator/stratos) +What kind of code is in Stratos? We've integrated [Code Climate](https://codeclimate.com) for some code quality and maintainability metrics. Take a stroll around the [project page](https://codeclimate.com/github/cloudfoundry/stratos) ## Contributing diff --git a/angular.json b/angular.json index 12d5d6f658..75d6a32748 100644 --- a/angular.json +++ b/angular.json @@ -36,12 +36,10 @@ }, "configurations": { "production": { - "budgets": [ - { - "type": "anyComponentStyle", - "maximumWarning": "6kb" - } - ], + "budgets": [{ + "type": "anyComponentStyle", + "maximumWarning": "6kb" + }], "optimization": true, "outputHashing": "all", "sourceMap": false, @@ -51,12 +49,10 @@ "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, - "fileReplacements": [ - { - "replace": "src/frontend/packages/core/src/environments/environment.ts", - "with": "src/frontend/packages/core/src/environments/environment.prod.ts" - } - ] + "fileReplacements": [{ + "replace": "src/frontend/packages/core/src/environments/environment.ts", + "with": "src/frontend/packages/core/src/environments/environment.prod.ts" + }] } } }, @@ -132,18 +128,14 @@ }, "configurations": { "production": { - "budgets": [ - { - "type": "anyComponentStyle", - "maximumWarning": "6kb" - } - ], - "fileReplacements": [ - { - "replace": "src/frontend/packages/core/src/environments/environment.ts", - "with": "src/frontend/packages/core/src/environments/environment.prod.ts" - } - ], + "budgets": [{ + "type": "anyComponentStyle", + "maximumWarning": "6kb" + }], + "fileReplacements": [{ + "replace": "src/frontend/packages/core/src/environments/environment.ts", + "with": "src/frontend/packages/core/src/environments/environment.prod.ts" + }], "optimization": true, "outputHashing": "all", "sourceMap": false, @@ -229,13 +221,13 @@ "options": { "tsConfig": "src/frontend/packages/store/tsconfig.lib.json", "project": "src/frontend/packages/store/ng-package.json" - } - , "configurations": { + }, + "configurations": { "production": { "tsConfig": "src/frontend/packages/store/tsconfig.lib.prod.json" } } -}, + }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { @@ -272,13 +264,13 @@ "options": { "tsConfig": "src/frontend/packages/cloud-foundry/tsconfig.lib.json", "project": "src/frontend/packages/cloud-foundry/ng-package.json" - } - , "configurations": { + }, + "configurations": { "production": { "tsConfig": "src/frontend/packages/cloud-foundry/tsconfig.lib.prod.json" } } -}, + }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { @@ -315,13 +307,13 @@ "options": { "tsConfig": "src/frontend/packages/cf-autoscaler/tsconfig.lib.json", "project": "src/frontend/packages/cf-autoscaler/ng-package.json" - } - , "configurations": { + }, + "configurations": { "production": { "tsConfig": "src/frontend/packages/cf-autoscaler/tsconfig.lib.prod.json" } } -}, + }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { @@ -361,4 +353,4 @@ "cli": { "_defaultCollection": "@nrwl/angular" } -} \ No newline at end of file +} diff --git a/build/combine-coverage.js b/build/combine-coverage.js deleted file mode 100644 index e7cb729cbc..0000000000 --- a/build/combine-coverage.js +++ /dev/null @@ -1,10 +0,0 @@ -const createReporter = require('istanbul-api').createReporter; -const istanbulCoverage = require('istanbul-lib-coverage'); -const coverage = require('../coverage/coverage-final.json'); - -const map = istanbulCoverage.createCoverageMap(); -Object.keys(coverage).forEach(filename => map.addFileCoverage(coverage[filename])); - -const reporter = createReporter(); -reporter.addAll(['html', 'lcovonly', 'json']); -reporter.write(map); diff --git a/build/karma.conf.creator.js b/build/karma.conf.creator.js index f530d5e903..d516e0fceb 100644 --- a/build/karma.conf.creator.js +++ b/build/karma.conf.creator.js @@ -27,7 +27,13 @@ module.exports = function (project) { coverageIstanbulReporter: { dir: path.join(repoRoot, 'coverage', project), reports: ['html', 'lcovonly', 'json'], - fixWebpackSourcePaths: true + fixWebpackSourcePaths: true, + 'report-config': { + json: { + // Collate all coverage-final files into a single dir for nyc to combine (it can't pick them out from `coverage`) + file: path.join('..', 'nyc', project + '-coverage-final.json') + } + }, }, reporters: ['spec', 'kjhtml', 'stratos'], specReporter: { diff --git a/build/karma.test.reporter.js b/build/karma.test.reporter.js index edf859c2f7..cdb20c8b9d 100644 --- a/build/karma.test.reporter.js +++ b/build/karma.test.reporter.js @@ -1,4 +1,3 @@ - (function () { 'use strict'; @@ -75,7 +74,7 @@ fs.unlinkSync(this.summaryFile); } - const all = this.runningTotals; + const all = this.runningTotals; this.writeSummaryFile(`${this.bold}${this.cyan}================================================================================${this.reset}`); this.writeSummaryFile(`${this.bold}${this.cyan}Test Summary${this.reset}`); @@ -106,47 +105,47 @@ try { - this.writeFile(`${this.bold}${this.cyan}Test results for package ${this.bluebg} ${process.env.NG_TEST_SUITE} ${this.reset}`); - this.writeFile(`Total : ${this.bold}${this.cyan}${this.total}${this.reset}`) - this.writeFile(`Passed : ${this.bold}${this.cyan}${passed}${this.reset}`) - this.writeFile(`Failed : ${this.bold}${this.red}${this.failed.length}${this.reset}`) - this.writeFile(`Skipped : ${this.bold}${this.yellow}${this.skipped}${this.reset}`) - - if (this.failed.length === 0) { - fs.appendFileSync(this.file, 'All tests passed\n') - } else { - this.writeFile('Test failures:'); - this.failed.forEach(f => { - this.writeFile(`${this.red}${this.bold} - ${f.fullName}${this.reset}`); - const logs = f.log || []; - logs.forEach(l => fs.appendFileSync(this.file, `${this.grey} ${l}${this.reset}`)); - // Add empty line - this.writeFile(''); - }); - } - - // Update running totals JSON - this.runningTotals.total += this.total; - this.runningTotals.passed += passed; - this.runningTotals.failed += this.failed.length; - this.runningTotals.skipped += this.skipped; - fs.writeFileSync(this.jsonFile, JSON.stringify(this.runningTotals)); - - this.generateSummary(); - - // Write exit code - let newExitCode = this.exitCode; - if (result.exitCode > 0) { - newExitCode = result.exitCode - } - - fs.writeFileSync(this.exitCodeFile, newExitCode.toString()); - - // Dump the summary for this test suite - var contents = fs.readFileSync(this.file, 'utf8'); - console.log(contents); - - } catch(e) { + this.writeFile(`${this.bold}${this.cyan}Test results for package ${this.bluebg} ${process.env.NG_TEST_SUITE} ${this.reset}`); + this.writeFile(`Total : ${this.bold}${this.cyan}${this.total}${this.reset}`) + this.writeFile(`Passed : ${this.bold}${this.cyan}${passed}${this.reset}`) + this.writeFile(`Failed : ${this.bold}${this.red}${this.failed.length}${this.reset}`) + this.writeFile(`Skipped : ${this.bold}${this.yellow}${this.skipped}${this.reset}`) + + if (this.failed.length === 0) { + fs.appendFileSync(this.file, 'All tests passed\n') + } else { + this.writeFile('Test failures:'); + this.failed.forEach(f => { + this.writeFile(`${this.red}${this.bold} - ${f.fullName}${this.reset}`); + const logs = f.log || []; + logs.forEach(l => fs.appendFileSync(this.file, `${this.grey} ${l}${this.reset}`)); + // Add empty line + this.writeFile(''); + }); + } + + // Update running totals JSON + this.runningTotals.total += this.total; + this.runningTotals.passed += passed; + this.runningTotals.failed += this.failed.length; + this.runningTotals.skipped += this.skipped; + fs.writeFileSync(this.jsonFile, JSON.stringify(this.runningTotals)); + + this.generateSummary(); + + // Write exit code + let newExitCode = this.exitCode; + if (result.exitCode > 0) { + newExitCode = result.exitCode + } + + fs.writeFileSync(this.exitCodeFile, newExitCode.toString()); + + // Dump the summary for this test suite + var contents = fs.readFileSync(this.file, 'utf8'); + console.log(contents); + + } catch (e) { console.log('ERROR while reporting test result'); console.log(e); } diff --git a/build/tools/changelog.sh b/build/tools/changelog.sh index 85cacfdd16..c1fd74daae 100755 --- a/build/tools/changelog.sh +++ b/build/tools/changelog.sh @@ -67,9 +67,11 @@ function log() { echo $1 | tee -a ${CHANGELOG} } +COMPARE_REPO=${REPO} QUERY="repo:${REPO}+milestone:${MILESTONE}+state:closed" if [ -n "${FORK}" ]; then FORK_QUERY="repo:${FORK}+milestone:${MILESTONE}+state:closed" + COMPARE_REPO=${FORK} fi BUGS="+label:bug" @@ -77,6 +79,7 @@ NON_BUGS="+-label:bug" mv ${CHANGELOG} CHANGELOG.old + echo "" echo -e "${CYAN}${BOLD}Generating Change log - content for version ${MILESTONE} will be shown below" echo -e "---------------------------------------------------------------------${RESET}" @@ -85,7 +88,7 @@ echo "# Change Log" > ${CHANGELOG} log "" log "## ${MILESTONE}" log "" -log "[Full Changelog](https://github.com/${REPO}/compare/${CURRENT}...${MILESTONE})" +log "[Full Changelog](https://github.com/${COMPARE_REPO}/compare/${CURRENT}...${MILESTONE})" log "" log "This release contains a number of fixes and improvements:" log "" diff --git a/deploy/ci/console-dev-releases.yml b/deploy/ci/console-dev-releases.yml index ab099c4629..4696f6a39b 100644 --- a/deploy/ci/console-dev-releases.yml +++ b/deploy/ci/console-dev-releases.yml @@ -121,18 +121,18 @@ jobs: build_args_file: image-tag/build-args patch_base_reg: ((patch-base-reg)) patch_base_tag: ((patch-base-tag)) - - put: config-init-image + - put: mariadb-image params: - dockerfile: stratos/deploy/Dockerfile.init - build: stratos/ + dockerfile: stratos/deploy/db/Dockerfile.mariadb + build: stratos/deploy/db tag: image-tag/v2-alpha-tag patch_base_reg: ((patch-base-reg)) patch_base_tag: ((patch-base-tag)) - do: - - put: mariadb-image + - put: config-init-image params: - dockerfile: stratos/deploy/db/Dockerfile.mariadb - build: stratos/deploy/db + dockerfile: stratos/deploy/Dockerfile.init + build: stratos/ tag: image-tag/v2-alpha-tag patch_base_reg: ((patch-base-reg)) patch_base_tag: ((patch-base-tag)) diff --git a/docs/planning/metrics.md b/docs/planning/metrics.md index 60ea270fa3..95f8d98bce 100644 --- a/docs/planning/metrics.md +++ b/docs/planning/metrics.md @@ -32,4 +32,4 @@ In the case of Cloud Foundry metrics, the Stratos back-end will check the user's 1. https://prometheus.io/docs/prometheus/latest/querying/basics/ 2. https://prometheus.io/docs/prometheus/latest/querying/api/ -3. https://github.com/bosh-prometheus/firehose_exporter +3. https://github.com/bosh-prometheus/firehose_exporter \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0d6c170b63..200d6f47de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,12 +5,12 @@ "requires": true, "dependencies": { "@angular-devkit/architect": { - "version": "0.901.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.5.tgz", - "integrity": "sha512-VO+8qBkaq54xAjdtvhEhQ86gZxS0V1wC9hGblw3O+XXri/euHky4811B2BbEylPy8/kRy5sUYcuwcyZrVxJ2TQ==", + "version": "0.901.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.7.tgz", + "integrity": "sha512-yW/PUEqle55QihOFbmeNXaVTodhfeXkteoFDUpz+YpX3xiQDXDtNbIJSzKOQTojtBKdSMKMvZkQLr+RAa7/1EA==", "dev": true, "requires": { - "@angular-devkit/core": "9.1.5", + "@angular-devkit/core": "9.1.7", "rxjs": "6.5.4" }, "dependencies": { @@ -26,21 +26,21 @@ } }, "@angular-devkit/build-angular": { - "version": "0.901.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.901.5.tgz", - "integrity": "sha512-XottEBXE7cmkx6LPu33lXJCSAlxFkIu2ErWvV1oy+La6aZEuoJVntxzIKLprJmTiiD/4IDDQLWwp4m+EC96kyg==", + "version": "0.901.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.901.7.tgz", + "integrity": "sha512-NiBwapx/XJqYGzSmENff78i6Yif9PjYDJ9BB+59t2eDofkCZUcPFrhQmRgliO7rt6RATvT81lDP89+LBXCTQPw==", "dev": true, "requires": { - "@angular-devkit/architect": "0.901.5", - "@angular-devkit/build-optimizer": "0.901.5", - "@angular-devkit/build-webpack": "0.901.5", - "@angular-devkit/core": "9.1.5", + "@angular-devkit/architect": "0.901.7", + "@angular-devkit/build-optimizer": "0.901.7", + "@angular-devkit/build-webpack": "0.901.7", + "@angular-devkit/core": "9.1.7", "@babel/core": "7.9.0", "@babel/generator": "7.9.3", "@babel/preset-env": "7.9.0", "@babel/template": "7.8.6", "@jsdevtools/coverage-istanbul-loader": "3.0.3", - "@ngtools/webpack": "9.1.5", + "@ngtools/webpack": "9.1.7", "ajv": "6.12.0", "autoprefixer": "9.7.4", "babel-loader": "8.0.6", @@ -87,7 +87,7 @@ "tree-kill": "1.2.2", "webpack": "4.42.0", "webpack-dev-middleware": "3.7.2", - "webpack-dev-server": "3.10.3", + "webpack-dev-server": "3.11.0", "webpack-merge": "4.2.2", "webpack-sources": "1.4.3", "webpack-subresource-integrity": "1.4.0", @@ -100,20 +100,6 @@ "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", "dev": true }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "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" - } - }, "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", @@ -149,35 +135,16 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true - }, - "terser": { - "version": "4.6.10", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.10.tgz", - "integrity": "sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } } } }, "@angular-devkit/build-ng-packagr": { - "version": "0.901.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-ng-packagr/-/build-ng-packagr-0.901.5.tgz", - "integrity": "sha512-/2H8TIxzGOhtZIVSHT2FRTO/Gs17iVO8tNfKVgHLnkv58gsMdppPfIcZo2DY+DjnhXrVPcwwODCWFf2NG3ZU+w==", + "version": "0.901.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-ng-packagr/-/build-ng-packagr-0.901.7.tgz", + "integrity": "sha512-HJ6nzXIUyI8yUuXGtdk26qDgLzlmfSwsSuc8JWdeqieP82fz/qokf78vVAqyHyJ9gi90IZiPO2+oh6Ot6UMo+g==", "dev": true, "requires": { - "@angular-devkit/architect": "0.901.5", + "@angular-devkit/architect": "0.901.7", "rxjs": "6.5.4" }, "dependencies": { @@ -193,9 +160,9 @@ } }, "@angular-devkit/build-optimizer": { - "version": "0.901.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.901.5.tgz", - "integrity": "sha512-xmAMvLMSa8BvqlZ0wsC37Qop/7/pEaQRKLeowC3CCI3jiYDF10Tihar+Hjc04NVSal8ZBP9/+Gp3Yr0x61HcFA==", + "version": "0.901.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.901.7.tgz", + "integrity": "sha512-Xuce3StdxhcgLYb0BAaFGr3Bzj5EM2OsAqIT15PkikWY1k5cK50vPxoC/BkX4QDL9eXSHtqAfMBfA6h5N422vw==", "dev": true, "requires": { "loader-utils": "2.0.0", @@ -220,13 +187,13 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.901.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.901.5.tgz", - "integrity": "sha512-4HHOFFRu3yUBe0otaDHh4PID99XvnBJj7hYzvbB5BvP0ULif4/W0aoU2STnern4lH4pJmrtqYawBZ84ETXN/Ag==", + "version": "0.901.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.901.7.tgz", + "integrity": "sha512-pTLW5Eqy9cHgv78LKiH0e30lxqKzUPjh1djvNtFsEemOHsfKQdAfjLjikoaQvqMoBKVaUU7r2vmyyS17cH+1yw==", "dev": true, "requires": { - "@angular-devkit/architect": "0.901.5", - "@angular-devkit/core": "9.1.5", + "@angular-devkit/architect": "0.901.7", + "@angular-devkit/core": "9.1.7", "rxjs": "6.5.4" }, "dependencies": { @@ -242,9 +209,9 @@ } }, "@angular-devkit/core": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.5.tgz", - "integrity": "sha512-i0BJ6Ad3bcDE6e4Ev9Flbw7P0bz9p94FDVfEOPGBTrbJQZSqOm3CqaH2y5LGfl7acSPUi54hK481h1QRUFBkTQ==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.7.tgz", + "integrity": "sha512-guvolu9Cl+qYMTtedLZD9wCqustJjdqzJ2psD2C1Sr1LrX9T0mprmDldR/YnhsitThveJEb6sM/0EvqWxoSvKw==", "dev": true, "requires": { "ajv": "6.12.0", @@ -272,12 +239,12 @@ } }, "@angular-devkit/schematics": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.5.tgz", - "integrity": "sha512-nkNiGrVl7xLaYYj/oT1wOBowa4Driv2f4abn78AJI/pd/EXA45G/rI9gO/kEG8lHn+FAMQedaywX9N4JDOxCGg==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.7.tgz", + "integrity": "sha512-oeHPJePBcPp/bd94jHQeFUnft93PGF5iJiKV9szxqS8WWC5OMZ5eK7icRY0PwvLyfenspAZxdZcNaqJqPMul5A==", "dev": true, "requires": { - "@angular-devkit/core": "9.1.5", + "@angular-devkit/core": "9.1.7", "ora": "4.0.3", "rxjs": "6.5.4" }, @@ -294,29 +261,29 @@ } }, "@angular/animations": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.1.6.tgz", - "integrity": "sha512-7Pp7aqNNcH4fu1BnOVpvqJJHjE7RZ5K1oD396OWCh35pgpLowLSpFjhbVhzGrcAuxHyKnnHSX3etLn2hDaHxmQ==" + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.1.9.tgz", + "integrity": "sha512-qWVi0TxmU6HeXAgEsfpQvFFygh+a0kH2kGe6bWij4XvG6dWfV3xZjlaFwSIYGk+yK4yL0+9+PAXH+ENfxNw+Cw==" }, "@angular/cdk": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.2.3.tgz", - "integrity": "sha512-tQr/yt8GNGsZ/DTT+PMq7XdRmL56hwVCyf8F12JQAawutSLfTfMb+S1lpN7L/0Pb/L5JBuCfG2HmXK7vHo02gw==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.2.4.tgz", + "integrity": "sha512-iw2+qHMXHYVC6K/fttHeNHIieSKiTEodVutZoOEcBu9rmRTGbLB26V/CRsfIRmA1RBk+uFYWc6UQZnMC3RdnJQ==", "requires": { "parse5": "^5.0.0" } }, "@angular/cli": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-9.1.5.tgz", - "integrity": "sha512-Decn0p+s0SLc5p2GN7k8dUrOY43hBuCz8PxueW0gEln7NjlpdmHk+6JQn0ZRl2/2Dbk+eTGzPXyCxGwqsW3jjw==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-9.1.7.tgz", + "integrity": "sha512-NhsIa725S/U/n7nDxp6ForusdYHEXF4aSIvsFRdoK6vbQ889c5e1Rdj+T5EWXLmpQZxeprSKhLI2alNX0nVhhQ==", "dev": true, "requires": { - "@angular-devkit/architect": "0.901.5", - "@angular-devkit/core": "9.1.5", - "@angular-devkit/schematics": "9.1.5", - "@schematics/angular": "9.1.5", - "@schematics/update": "0.901.5", + "@angular-devkit/architect": "0.901.7", + "@angular-devkit/core": "9.1.7", + "@angular-devkit/schematics": "9.1.7", + "@schematics/angular": "9.1.7", + "@schematics/update": "0.901.7", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "4.1.1", @@ -379,19 +346,19 @@ } }, "@angular/common": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-9.1.6.tgz", - "integrity": "sha512-L9vw//wE+8QcSArOA411uJ68znnszCiPrbzSBV0BRZeadc7X68MwANA9qjtiTWZx5Xh9pNfHHwsCUyv2lUeinQ==" + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-9.1.9.tgz", + "integrity": "sha512-y/tJtkuOJhV2kcaXZyrLZH84i4uQ1r+vaaEHvXj+JZYfYfcMMd/TDqMiPcIkUb3RxqghtZ+q0ZNW5D1Nlru3Pw==" }, "@angular/compiler": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.1.6.tgz", - "integrity": "sha512-tHOQEjWuWqSkrk6/vI6BK7uJnpAyFajCXPW37rH5xspF/aMbetrpoOiGBNUQg/HLaFh04nOAnnFntjLkW0ooaA==" + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.1.9.tgz", + "integrity": "sha512-kjFgaTB2ckr9lgmkS1dOGRT7kmzpQueydxsxXSHWgICNVE6F/u1PHyeSOyJRpxW0GnrkLq3QM2EUFnQGGga5bg==" }, "@angular/compiler-cli": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-9.1.6.tgz", - "integrity": "sha512-1b7m9tvSQJE4y95wNCdi34MORcsmXPC1vaylYlzChVM2et9Y2eKHYcRs+4g329j66irLBGpS/7cgTT2pgJ+IbA==", + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-9.1.9.tgz", + "integrity": "sha512-aLr2eaDlREN8XybgTbelvjtSZ8eAkxBPilnkddc700BgiC6ImyUSKaItOwa8bnjQwq4Wlz5eVG0ibsrX+5MXwg==", "dev": true, "requires": { "canonical-path": "1.0.0", @@ -424,47 +391,6 @@ "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", - "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" - } - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -491,15 +417,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -521,49 +438,12 @@ "universalify": "^0.1.0" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -573,12 +453,6 @@ "p-locate": "^4.1.0" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -609,21 +483,6 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -656,15 +515,6 @@ "ansi-regex": "^5.0.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -714,59 +564,59 @@ } }, "@angular/core": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.1.6.tgz", - "integrity": "sha512-iXgPh5DebLwkMzLtQ6WKiv/mo4hpwMOwYex3O4F2CKToR2tKPnXbV5WC/ADGm0XYXiocSKQPiyL4ZrUjVeKEqA==" + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.1.9.tgz", + "integrity": "sha512-q/DERgVU6vK2LtTcdVCGGBcoO424WsEfImh3Vcuy+P/ZVmthlDUC/+q+tSKt8MMf4hLpxFDQJE8vUSkktj7QEw==" }, "@angular/flex-layout": { - "version": "9.0.0-beta.29", - "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-9.0.0-beta.29.tgz", - "integrity": "sha512-93sxR+kYfYMOdnlWL0Q77FZ428gg8XnBu0YZm6GsCdkw/vLggIT/G1ZAqHlCPIODt6pxmCJ5KXh4ShvniIYDsA==" + "version": "9.0.0-beta.31", + "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-9.0.0-beta.31.tgz", + "integrity": "sha512-g94u2mecDl87ORvFRuOBshV/S/ETE4bybClU2e1xXKWNG+rhRHchChneHSonc29ZLyROTjHhmAtKOYojL92uLA==" }, "@angular/forms": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-9.1.6.tgz", - "integrity": "sha512-3KiFjLDipZVgS5rfnZ8EoKlkUokOR8dmuw2xdjKHgzflWFFeuaY9ZtQgjZGw9/jkwWlc9P38BOSEHbK8NakdDw==" + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-9.1.9.tgz", + "integrity": "sha512-r675yImnb/0pY7K5W3V2ITa7YETu1I2AS+bRfII6UQ6gthyeFFOHb5noa7YneC2yqQiM6E4DQmF5ig3daPuFNg==" }, "@angular/language-service": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-9.1.6.tgz", - "integrity": "sha512-pB18hVoAbIuk1Wus8ur7yUxSukfPR4pCXiOfbxDQ94qlCzLAzIwXbaNV4erpBfL/fUKxMY3h8RrVt0dfm6M5RQ==", + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-9.1.9.tgz", + "integrity": "sha512-yT6HPpdAe2mD9HRoTCiWFog1MRJt+0j+CLbI/Ql7C6pH6vbjmfsJ55xMmQ7eS6trsnebpMWTUv1f2GRykv3ygw==", "dev": true }, "@angular/material": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-9.2.3.tgz", - "integrity": "sha512-QJltLNp8a/eoozPgkFLISEWgdlX9q9+fZaLJ8c9tHEp2IT5sFYBFHf8dPl0pUyxgOXkS/0HD43I1qki71/T7Kw==" + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-9.2.4.tgz", + "integrity": "sha512-LkoTXE6B0slvMhvfZDdPWaz4yaYLkaAp5VSPunI9pxGsPxzqEV9e210wC1/sjG/76Nk8Ep7/2z9XKac8Q9bMwA==" }, "@angular/material-moment-adapter": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-9.2.3.tgz", - "integrity": "sha512-+B+njuV0rr2GKOglgXlFzgT6Pq7VMsPsMHhTkJWeRe96RVEIuT6pMehlHJAEQgaFi+LRjH1MIHLH2jcc0myDvg==" + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-9.2.4.tgz", + "integrity": "sha512-V5xkL+YUec3nDGRaJB72mJTUtdUvGaG9WCQEdr45viDWFGjQaEpS6msuScBLp0PwsN8Wt0n69eZg0ULgxPBa5g==" }, "@angular/platform-browser": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.1.6.tgz", - "integrity": "sha512-ebQhbT0Z55vwlQwAY4+s3Bcf1Q4wEN5Yk43iCuVt4g2kFkg09UP0z8aYtbuh7VQDyv/W4TTIGX8smGBWstoedQ==" + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.1.9.tgz", + "integrity": "sha512-V861X3MxJp1AlMTnkUPldpBLIJbApXF3ka0A5Dq2nVJCyOFeteGkaRWSBgqe2jxmq+LVpJbzcNvtDFXw6mQ0jA==" }, "@angular/platform-browser-dynamic": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.6.tgz", - "integrity": "sha512-7AL3hWu4oY0LRiMS9ZEFXPW2uqybWcVNFDHjPp3UwsDIT4+sW3DIm8P+UvAOFkkRwaHpPDqm4chTTiAHygC/1Q==" + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.9.tgz", + "integrity": "sha512-b9MG5MWne+IuL3uLm8jwPhlJzqYaGBGk/qibOqb17T24j1iyrlO7T5bZ8zO6pUy5iT/TahVfHPnPJC1qTK5OmA==" }, "@angular/platform-server": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-9.1.6.tgz", - "integrity": "sha512-hLAwh/J9a2v9opLIZVIiykPIsxmRozY3OjXH1phbIDFQQCHCNLlODOowxVnn7DF90DyVSLCTKNnqNjZW3DdlVg==", + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-9.1.9.tgz", + "integrity": "sha512-PtOUE6Vxnrg03/zJbjnZ6BbctAEdFjAbHr8zbGhHa2q504DlY9OJACRCqcP8tIpW9nbDDKqvr/RENONmISichA==", "requires": { "domino": "^2.1.2", "xhr2": "^0.2.0" } }, "@angular/router": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-9.1.6.tgz", - "integrity": "sha512-Oz4nVQUR6t68DSzZuSrVaqrzmA7/0PIEi0sc85CE+UuOEoAqGMwN0NdQYizFT62WZ16DRI/1tZ+TTWvdmpEv8w==" + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-9.1.9.tgz", + "integrity": "sha512-4u+CWMPB4hCkAsFCEzC94YEWT0wVozqGkc/Dortt2hFaqvZpIegg6iJVZlDxuyDjzFYBPnnbTDdgiTTA8ckfuA==" }, "@babel/code-frame": { "version": "7.5.5", @@ -778,12 +628,12 @@ } }, "@babel/compat-data": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz", - "integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz", + "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==", "dev": true, "requires": { - "browserslist": "^4.11.1", + "browserslist": "^4.12.0", "invariant": "^2.2.4", "semver": "^5.5.0" } @@ -813,34 +663,31 @@ }, "dependencies": { "@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.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.8.3" + "@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.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "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.9.0", + "@babel/helper-validator-identifier": "^7.10.1", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -871,263 +718,293 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", - "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", + "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" + }, + "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 + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", - "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz", + "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-explode-assignable-expression": "^7.10.1", + "@babel/types": "^7.10.1" + }, + "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 + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-compilation-targets": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz", - "integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz", + "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==", "dev": true, "requires": { - "@babel/compat-data": "^7.9.6", - "browserslist": "^4.11.1", + "@babel/compat-data": "^7.10.1", + "browserslist": "^4.12.0", "invariant": "^2.2.4", "levenary": "^1.1.1", "semver": "^5.5.0" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", - "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz", + "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-regex": "^7.8.3", + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-regex": "^7.10.1", "regexpu-core": "^4.7.0" } }, "@babel/helper-define-map": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", - "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz", + "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/helper-function-name": "^7.10.1", + "@babel/types": "^7.10.1", "lodash": "^4.17.13" + }, + "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-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==", + "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": { + "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==", + "dev": true, + "requires": { + "@babel/types": "^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" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-explode-assignable-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", - "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", - "dev": true, - "requires": { - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", - "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz", + "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-module-imports": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-module-transforms": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", - "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.9.0", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", - "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", - "dev": true, - "requires": { - "lodash": "^4.17.13" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", - "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-wrap-function": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-replace-supers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", - "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" }, "dependencies": { "@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.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.8.3" + "@babel/highlight": "^7.10.1" } }, "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", "dev": true, "requires": { - "@babel/types": "^7.9.6", + "@babel/types": "^7.10.2", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "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": { + "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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@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==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" + "@babel/types": "^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.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "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.9.0", + "@babel/helper-validator-identifier": "^7.10.1", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", "dev": true }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", + "@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", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", + "@babel/helper-validator-identifier": "^7.10.1", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@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==", - "dev": true - } } }, "debug": { @@ -1139,12 +1016,6 @@ "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", @@ -1153,137 +1024,356 @@ } } }, - "@babel/helper-simple-access": { + "@babel/helper-function-name": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", "dev": true, "requires": { + "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", "@babel/types": "^7.8.3" } }, - "@babel/helper-split-export-declaration": { + "@babel/helper-get-function-arity": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, "requires": { "@babel/types": "^7.8.3" } }, - "@babel/helper-validator-identifier": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", - "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "@babel/helper-hoist-variables": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz", + "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + }, + "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 + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + }, + "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 + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + }, + "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 + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@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==", + "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" + }, + "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-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==", + "dev": true, + "requires": { + "@babel/types": "^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" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + }, + "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 + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@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==", "dev": true }, - "@babel/helper-wrap-function": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", - "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "@babel/helper-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz", + "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "lodash": "^4.17.13" } }, - "@babel/helpers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", - "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "@babel/helper-remap-async-to-generator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz", + "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-wrap-function": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" }, "dependencies": { "@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.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.8.3" + "@babel/highlight": "^7.10.1" } }, "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", "dev": true, "requires": { - "@babel/types": "^7.9.6", + "@babel/types": "^7.10.2", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "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": { + "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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@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==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" + "@babel/types": "^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.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "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.9.0", + "@babel/helper-validator-identifier": "^7.10.1", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", "dev": true }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", + "@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", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", + "@babel/helper-validator-identifier": "^7.10.1", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@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==", - "dev": true - } } }, "debug": { @@ -1295,12 +1385,6 @@ "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", @@ -1309,121 +1393,624 @@ } } }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "@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==", "dev": true, "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" + "@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" }, "dependencies": { - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "@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/generator": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@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==", + "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": { + "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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/types": "^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" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@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==", + "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", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "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 } } }, - "@babel/parser": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", - "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", - "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-remap-async-to-generator": "^7.8.3", - "@babel/plugin-syntax-async-generators": "^7.8.0" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", - "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", - "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "@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==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + "@babel/template": "^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" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, - "@babel/plugin-proposal-numeric-separator": { + "@babel/helper-split-export-declaration": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", - "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3" + "@babel/types": "^7.8.3" } }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz", - "integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.9.5" - } + "@babel/helper-validator-identifier": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "dev": true }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "@babel/helper-wrap-function": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz", + "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + "@babel/helper-function-name": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^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/generator": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@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==", + "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": { + "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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/types": "^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" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@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==", + "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", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "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 + } } }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", - "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "@babel/helpers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" + "@babel/template": "^7.10.1", + "@babel/traverse": "^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/generator": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@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==", + "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": { + "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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/types": "^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" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@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==", + "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", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "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 + } + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + } + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz", + "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-remap-async-to-generator": "^7.10.1", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz", + "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz", + "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz", + "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", + "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz", + "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.10.1" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz", + "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz", + "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", - "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz", + "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.8", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-syntax-async-generators": { @@ -1499,232 +2086,357 @@ } }, "@babel/plugin-syntax-top-level-await": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", - "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz", + "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", - "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz", + "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", - "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz", + "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-remap-async-to-generator": "^7.8.3" + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-remap-async-to-generator": "^7.10.1" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", - "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz", + "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", - "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz", + "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", "lodash": "^4.17.13" } }, "@babel/plugin-transform-classes": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz", - "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-define-map": "^7.8.3", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-split-export-declaration": "^7.8.3", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz", + "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-define-map": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", "globals": "^11.1.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-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "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": { + "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==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@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==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" + "@babel/types": "^7.10.1" } }, "@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.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" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", "dev": true }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", + "@babel/helper-validator-identifier": "^7.10.1", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } - }, - "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 } } }, "@babel/plugin-transform-computed-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", - "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz", + "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-destructuring": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz", - "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz", + "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", - "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz", + "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", - "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz", + "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", - "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz", + "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-for-of": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", - "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz", + "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", - "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz", + "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-plugin-utils": "^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-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==", + "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": { + "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==", + "dev": true, + "requires": { + "@babel/types": "^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" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", - "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz", + "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", - "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz", + "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz", - "integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz", + "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz", - "integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz", + "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz", - "integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz", + "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.8.3", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-hoist-variables": "^7.10.1", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", - "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz", + "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-named-capturing-groups-regex": { @@ -1737,116 +2449,144 @@ } }, "@babel/plugin-transform-new-target": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", - "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz", + "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-object-super": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", - "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz", + "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1" } }, "@babel/plugin-transform-parameters": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz", - "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz", + "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + }, + "dependencies": { + "@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==", + "dev": true, + "requires": { + "@babel/types": "^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/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-property-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", - "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz", + "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-regenerator": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", - "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz", + "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", - "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz", + "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", - "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz", + "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", - "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz", + "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", - "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz", + "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-regex": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-regex": "^7.10.1" } }, "@babel/plugin-transform-template-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", - "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz", + "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", - "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz", + "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", - "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz", + "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/preset-env": { @@ -1931,9 +2671,9 @@ } }, "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz", + "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -2061,6 +2801,76 @@ "lodash-es": "^4.17.15" } }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "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": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", @@ -2080,15 +2890,6 @@ "schema-utils": "^2.6.4" }, "dependencies": { - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -2112,32 +2913,32 @@ } }, "@ngrx/effects": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-9.1.2.tgz", - "integrity": "sha512-H9jbGUzP5izk9Ap8BQJicO1+xheyDyHBbvv6b1NkaRHpDizhPOSBjoFWExFfsejXo0dafaIsu6aI+y+Fp+LSsg==" + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-9.2.0.tgz", + "integrity": "sha512-8V09zDIPehGpzgfcgyczelovsVYJvDQhN9wHt37K5A+YCG0CI8nj8FmKokHATwv/S62YqFrOVnr/TZacxpDhBw==" }, "@ngrx/router-store": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-9.1.2.tgz", - "integrity": "sha512-zqAm7fOdJ34dY2Tlts2YV9MDcDP2CqB+hLEytjo/bOIkUo/lQA1R5VAUI+Z8+tUlmPqSVIJkzsGuCxO6XnLEjQ==" + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-9.2.0.tgz", + "integrity": "sha512-thu6aU9YWM64oNEk4Srx/mNSeQ2SPJKlTji8MSzfr06qgCMyPSXZBYlfs8HqY+af3eB7XBEhb/4ew4JJ6xC9zw==" }, "@ngrx/store": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-9.1.2.tgz", - "integrity": "sha512-FQXFonF8hSGJDqgLaoWHy2mkeJwVdoa3jLoT1YpkJWxsFMG4U0T6JYG4VrtuymDgo9XwWBBJqIiNpdTgHhofSQ==" + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-9.2.0.tgz", + "integrity": "sha512-V8AI3mxbMztVpbZpALkLZYlGkofKcu9GaOCY5e+sZ1VcJ90oxhFjBpnmd6MuVdmhep1XAHALb1B8ZbBFn+xsgQ==" }, "@ngrx/store-devtools": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-9.1.2.tgz", - "integrity": "sha512-i9gwj9FlUVrei9yMwwFx15RV0JWOI73cjbjKhZ2lUWmCF6bfZeuPYZmEs3/80L8r3R9nZWnBoX9xxQslte65iw==" + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-9.2.0.tgz", + "integrity": "sha512-/FvgcpjO4IvwNFnRVoHGikAvckr6fxKf4NgYoTQ9giI8xavolLvuQUHxzH20legi5dgZz34ii2m2g1Q7OxEV8w==" }, "@ngtools/webpack": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.5.tgz", - "integrity": "sha512-6VzmlXRnf7phwLOiy0WrxHFHD5TuNQgVVpD/VFkZjtCTOsZyGQYGVPfaqxvn13M4Mm8bjrN4mk06VowCFm2oHw==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.7.tgz", + "integrity": "sha512-A7VB2I42Kn+7jl0tDKzGNLAoZLWSqkKo9Hg1bmKpvAAIz+DSbq3uV+JWgGgTprM3tn0lfkVgmqk4H17HKwAOcg==", "dev": true, "requires": { - "@angular-devkit/core": "9.1.5", + "@angular-devkit/core": "9.1.7", "enhanced-resolve": "4.1.1", "rxjs": "6.5.4", "webpack-sources": "1.4.3" @@ -2217,14 +3018,80 @@ "resolve": "^1.14.2" }, "dependencies": { + "@angular-devkit/core": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.3.tgz", + "integrity": "sha512-E49GCnn06q79Xd5SC/+8CDRF1wp9wQqP6HKJVVMijoi3NOrMQTuHTesPURvve2xbkCYqQOVlMEonhOJF5vpnoQ==", + "requires": { + "ajv": "6.10.2", + "fast-json-stable-stringify": "2.0.0", + "magic-string": "0.25.3", + "rxjs": "6.4.0" + } + }, + "@angular-devkit/schematics": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-8.3.3.tgz", + "integrity": "sha512-t5I77YeRCWpr5PJMQn8iCu2zHqnQt7qqxt66ejmsDnFgCQDw2G1IQl48AzjegJybIoRCaWX12yUZaS5aaJm5Cg==", + "requires": { + "@angular-devkit/core": "8.3.3", + "rxjs": "6.4.0" + } + }, + "@schematics/angular": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-8.3.3.tgz", + "integrity": "sha512-8dRe7mBPqesscXG56pg7bWgDz+xb8jmU/Yp6LizOL3U0EoO/QV6yuVgPkgiIMSaGQaP3PBzZ7h0xuOOogWJ6ig==", + "requires": { + "@angular-devkit/core": "8.3.3", + "@angular-devkit/schematics": "8.3.3" + } + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "magic-string": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", + "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, "resolve": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.0.tgz", - "integrity": "sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" } + }, + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "requires": { + "tslib": "^1.9.0" + } } } }, @@ -2239,29 +3106,51 @@ "micromatch": "^4.0.2" }, "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "requires": { - "fill-range": "^7.0.1" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "requires": { - "to-regex-range": "^5.0.1" + "invert-kv": "^2.0.0" } }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0" + } }, "micromatch": { "version": "4.0.2", @@ -2273,35 +3162,98 @@ "picomatch": "^2.0.5" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "requires": { - "is-number": "^7.0.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yargs": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.1.tgz", + "integrity": "sha512-PRU7gJrJaXv3q3yQZ/+/X6KBswZiaQ+zOmdprZcouPYtQgvNU35i+68M4b1ZHLZtYFT5QObFLV+ZkmJYcwKdiw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + }, + "dependencies": { + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.0.0.tgz", + "integrity": "sha512-+DHejWujTVYeMHLff8U96rLc4uE4Emncoftvn5AjhB1Jw1pWxLzgBUT/WYbPrHmy6YPEBTZQx5myHhVcuuu64g==", + "requires": { + "camelcase": "^4.1.0" } } } }, "@schematics/angular": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-9.1.5.tgz", - "integrity": "sha512-kMscfnwd9TGLo8V+dE/Pzu4wNxZej/6F6z5XzMOQVFTbL+RqMDvtkHf9CarhiKBd5ogm4npfKV8ToNTUecFJkA==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-9.1.7.tgz", + "integrity": "sha512-ld3WcoMWvup04V3OWioQ+AFGQBzz7IDM4Fxc5+Qc3wILWkDJnNkrc4EmJAow96Ab4/T1+Wl1vof3tV4At0BTzA==", "dev": true, "requires": { - "@angular-devkit/core": "9.1.5", - "@angular-devkit/schematics": "9.1.5" + "@angular-devkit/core": "9.1.7", + "@angular-devkit/schematics": "9.1.7" } }, "@schematics/update": { - "version": "0.901.5", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.901.5.tgz", - "integrity": "sha512-JmB+AuU6C9eM8x/CxeBEDigRuypzuWx7gnloK9D5i2gP9r39clFNtWT7eM3YW3kl4uyEMzrQHx6esMWNUScVBw==", + "version": "0.901.7", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.901.7.tgz", + "integrity": "sha512-6IpQVFvbu47CrXfqqHAzv2vi7AOdfi1S+SiayXU6FWTeA2wV47H8R60VjxurL8JkDGoVhFgC4+lK6KG++g3dQw==", "dev": true, "requires": { - "@angular-devkit/core": "9.1.5", - "@angular-devkit/schematics": "9.1.5", + "@angular-devkit/core": "9.1.7", + "@angular-devkit/schematics": "9.1.7", "@yarnpkg/lockfile": "1.1.0", "ini": "1.3.5", "npm-package-arg": "^8.0.0", @@ -2335,9 +3287,9 @@ "dev": true }, "@swimlane/ngx-charts": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-13.0.3.tgz", - "integrity": "sha512-WPgMZwqND/hGgxY+fJ+iN3ctL6Ps93kZ6j2jeWRgKfXdUVNnKQ4XeUBWpU+70jhq1i36PzYEg46evWdHp6vMuw==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-13.0.4.tgz", + "integrity": "sha512-4EvwclbctVQ5VzPBC63DJsg+jwQU/NlR/yQ9ObVH5acefEbS8kupn3cp/gaWftLTQ0jdXqRqycHNkLOQZfa3XQ==", "requires": { "d3-array": "^2.4.0", "d3-brush": "^1.1.5", @@ -2352,6 +3304,24 @@ "d3-transition": "^1.3.2" } }, + "@swimlane/ngx-graph": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@swimlane/ngx-graph/-/ngx-graph-7.0.1.tgz", + "integrity": "sha512-V85EuEJr61AM3J24slsiUkg6eak6J8IBy5zeD55fywLl3QbndRELRp3l/T2wu/HNpzyHzrC0/qpkEauqcHtRsA==", + "requires": { + "@swimlane/ngx-charts": "^13.0.1", + "d3-dispatch": "^1.0.3", + "d3-ease": "^1.0.5", + "d3-force": "^1.1.0", + "d3-selection": "^1.2.0", + "d3-shape": "^1.2.0", + "d3-timer": "^1.0.7", + "d3-transition": "^1.1.1", + "dagre": "^0.8.4", + "transformation-matrix": "^1.15.3", + "webcola": "^3.3.8" + } + }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -2395,19 +3365,12 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", "dev": true, "requires": { - "@types/events": "*", "@types/minimatch": "*", "@types/node": "*" } @@ -2427,6 +3390,12 @@ "@types/jasmine": "*" } }, + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, "@types/karma": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/karma/-/karma-5.0.0.tgz", @@ -2457,9 +3426,9 @@ } }, "@types/node": { - "version": "13.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.1.tgz", - "integrity": "sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==", + "version": "13.13.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.11.tgz", + "integrity": "sha512-FX7mIFKfnGCfq10DGWNhfCNxhACEeqH5uulT6wRRA1KEt7zgLe0HdrAd9/QQkObDqp2Z0KEV3OAmNgs0lTx5tQ==", "dev": true }, "@types/normalize-package-data": { @@ -2532,9 +3501,9 @@ "dev": true }, "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.8.tgz", + "integrity": "sha512-JHB2/xZlXOjzjBB6fMOpH1eQAfsrpqVVIbneE0Rok16WXwFaznaI5vfg75U5WgGJm7V9W1c4xeRQDjX/zwvghA==", "dev": true, "requires": { "@types/node": "*", @@ -2755,9 +3724,9 @@ } }, "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", "dev": true }, "accepts": { @@ -2771,9 +3740,9 @@ } }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", "dev": true }, "acorn-jsx": { @@ -2847,14 +3816,12 @@ "ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" }, "ajv-keywords": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" }, "alphanum-sort": { "version": "1.0.2", @@ -2978,13 +3945,12 @@ "dev": true }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "app-root-path": { @@ -3222,9 +4188,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -3397,6 +4363,32 @@ "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" + }, + "dependencies": { + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" } }, "json5": { @@ -3419,6 +4411,40 @@ "json5": "^1.0.1" } }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.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": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.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 + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -3565,8 +4591,7 @@ "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "binary-extensions": { "version": "1.13.1", @@ -3596,9 +4621,9 @@ "dev": true }, "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", "dev": true }, "body-parser": { @@ -3770,32 +4795,12 @@ } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "fill-range": "^7.0.1" } }, "brorand": { @@ -3852,17 +4857,17 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } }, "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", + "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", "dev": true, "requires": { "bn.js": "^5.1.1", @@ -3872,7 +4877,8 @@ "elliptic": "^6.5.2", "inherits": "^2.0.4", "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" }, "dependencies": { "readable-stream": { @@ -3885,6 +4891,12 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true } } }, @@ -3898,13 +4910,13 @@ } }, "browserslist": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz", - "integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", + "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001038", - "electron-to-chromium": "^1.3.390", + "caniuse-lite": "^1.0.30001043", + "electron-to-chromium": "^1.3.413", "node-releases": "^1.1.53", "pkg-up": "^2.0.0" } @@ -4101,6 +5113,33 @@ "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + } + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" } }, "mkdirp": { @@ -4152,6 +5191,12 @@ "pump": "^3.0.0" } }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -4176,6 +5221,35 @@ } } }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", @@ -4225,9 +5299,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001039", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz", - "integrity": "sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q==", + "version": "1.0.30001079", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001079.tgz", + "integrity": "sha512-2KaYheg0iOY+CMmDuAB3DHehrXhhb4OZU4KBVGDr/YKyYAcpudaiUQ9PJ9rxrPlKEoJ3ATasQ5AN48MqpwS43Q==", "dev": true }, "canonical-path": { @@ -4271,24 +5345,30 @@ "dev": true }, "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, "chownr": { @@ -4415,6 +5495,18 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + } } }, "clone": { @@ -4490,9 +5582,9 @@ "dev": true }, "codecov": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.6.5.tgz", - "integrity": "sha512-v48WuDMUug6JXwmmfsMzhCHRnhUf8O3duqXvltaYJKrO1OekZWpB/eH6iIoaxMl8Qli0+u3OxptdsBOYiD7VAQ==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.7.0.tgz", + "integrity": "sha512-uIixKofG099NbUDyzRk1HdGtaG8O+PBUAg3wfmjwXw2+ek+PZp+puRvbTohqrVfuudaezivJHFgTtSC3M8MXww==", "dev": true, "requires": { "argv": "0.0.2", @@ -4500,17 +5592,6 @@ "js-yaml": "3.13.1", "teeny-request": "6.0.1", "urlgrey": "0.4.4" - }, - "dependencies": { - "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - } } }, "codelyzer": { @@ -4782,9 +5863,9 @@ "dev": true }, "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -4886,20 +5967,6 @@ "pkg-dir": "^3.0.0" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "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" - } - }, "globby": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", @@ -4934,12 +6001,6 @@ "json5": "^1.0.1" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -5041,9 +6102,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -5079,7 +6140,6 @@ "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", @@ -5190,12 +6250,6 @@ "json5": "^1.0.1" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -5436,10 +6490,15 @@ "d3-transition": "1" } }, + "d3-collection": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" + }, "d3-color": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz", - "integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", + "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" }, "d3-dispatch": { "version": "1.0.6", @@ -5460,6 +6519,17 @@ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.6.tgz", "integrity": "sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ==" }, + "d3-force": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz", + "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==", + "requires": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, "d3-format": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz", @@ -5483,6 +6553,11 @@ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" }, + "d3-quadtree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz", + "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA==" + }, "d3-scale": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.1.tgz", @@ -5539,6 +6614,15 @@ "d3-timer": "1" } }, + "dagre": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz", + "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==", + "requires": { + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + } + }, "damerau-levenshtein": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", @@ -5578,8 +6662,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", @@ -5903,9 +6986,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -6018,6 +7101,14 @@ "dev": true, "requires": { "is-obj": "^2.0.0" + }, + "dependencies": { + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + } } }, "duplexer": { @@ -6071,9 +7162,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.397", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.397.tgz", - "integrity": "sha512-zcUd1p/7yzTSdWkCTrqGvbnEOASy96d0RJL/lc5BDJoO23Z3G/VHd0yIPbguDU9n8QNUTCigLO7oEdtOb7fp2A==", + "version": "1.3.465", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.465.tgz", + "integrity": "sha512-K/lUeT3NLAsJ5SHRDhK3/zd0tw7OUllYD8w+fTOXm6ljCPsp2qq+vMzxpLo8u1M27ZjZAjRbsA6rirvne2nAMQ==", "dev": true }, "elliptic": { @@ -6092,9 +7183,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -6102,14 +7193,12 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, "encodeurl": { "version": "1.0.2", @@ -6127,10 +7216,9 @@ } }, "end-of-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.3.tgz", - "integrity": "sha512-cbNhPFS6MlYlWTGncSiDYbdqKhwWFy7kNeb1YSOG6K65i/wPTkLVCJQj0hXA4j0m5Da+hBWnqopEnu1FFelisQ==", - "dev": true, + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { "once": "^1.4.0" } @@ -6332,6 +7420,12 @@ "next-tick": "^1.0.0" } }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", @@ -6571,6 +7665,12 @@ "object-assign": "^4.1.0" } }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, "inquirer": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", @@ -6730,9 +7830,9 @@ } }, "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", "dev": true }, "events": { @@ -6764,7 +7864,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -7023,39 +8122,15 @@ "picomatch": "^2.2.1" }, "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "is-glob": "^4.0.1" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -7065,15 +8140,6 @@ "braces": "^3.0.1", "picomatch": "^2.0.5" } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } } } }, @@ -7095,9 +8161,9 @@ "dev": true }, "fastq": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.7.0.tgz", - "integrity": "sha512-YOadQRnHd5q6PogvAR/x62BGituF2ufiEA6s8aavQANw5YKHERI4AREboX6KotzP8oX2klxYF2wcV/7bn1clfQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -7145,6 +8211,42 @@ "requires": { "loader-utils": "^2.0.0", "schema-utils": "^2.6.5" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + } } }, "fileset": { @@ -7158,26 +8260,12 @@ } }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "to-regex-range": "^5.0.1" } }, "finalhandler": { @@ -7291,7 +8379,6 @@ "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" } @@ -7469,6 +8556,59 @@ "for-in": "^1.0.1" } }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "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" + } + }, + "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 + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -7523,6 +8663,12 @@ "readable-stream": "^2.0.0" } }, + "fromentries": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz", + "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==", + "dev": true + }, "front-matter": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-2.1.2.tgz", @@ -7569,6 +8715,17 @@ "dev": true, "requires": { "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "fs-mkdirp-stream": { @@ -7600,714 +8757,692 @@ "dev": true }, "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "^1.0.0" + } + }, + "genfun": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", + "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "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-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, - "optional": true, "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, - "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "is-extglob": "^2.1.0" } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + } + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + } + }, + "glob-watcher": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", + "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "object.defaults": "^1.1.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, - "optional": true + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "optional": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" } }, - "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, - "optional": true, "requires": { - "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" + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + } } }, - "has-unicode": { + "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { - "number-is-nan": "^1.0.0" + "is-extendable": "^0.1.0" } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, - "optional": true, "requires": { - "brace-expansion": "^1.1.7" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "optional": true }, - "minipass": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, - "optional": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "binary-extensions": "^1.0.0" } }, - "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "optional": true, "requires": { - "minipass": "^2.2.1" + "kind-of": "^3.0.2" } }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "optional": true, "requires": { - "minimist": "0.0.8" + "is-buffer": "^1.1.5" } }, - "ms": { + "normalize-path": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz", - "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, - "optional": true, "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" + "remove-trailing-separator": "^1.0.1" } }, - "node-pre-gyp": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, - "optional": true, "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, - "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } + } + } + }, + "global-dirs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "dev": true, + "requires": { + "ini": "^1.3.5" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "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 + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true }, - "npm-bundled": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", - "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "optional": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "path-type": "^4.0.0" } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, + "globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dev": true, + "requires": { + "sparkles": "^1.0.0" + } + }, + "gonzales-pe-sl": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz", + "integrity": "sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y=", + "dev": true, + "requires": { + "minimist": "1.1.x" + }, + "dependencies": { + "minimist": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz", + "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=", + "dev": true + } + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.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 + }, + "graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "requires": { + "lodash": "^4.17.15" + } + }, + "gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "dev": true, + "requires": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + }, + "dependencies": { + "ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, - "optional": true, "requires": { - "wrappy": "1" + "ansi-wrap": "^0.1.0" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true - }, - "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, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "gulp-cli": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", + "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", "dev": true, - "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.4.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.2.0", + "yargs": "^7.1.0" } }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", "dev": true, - "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "homedir-polyfill": "^1.0.1" } + } + } + }, + "gulp-zip": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.0.1.tgz", + "integrity": "sha512-M/IWLh9RvOpuofDZkgDirtiyz9J3yIqnDOJ3muzk2D/XnZ1ruqPlPLRIpXnl/aZU+xXwKPdOIxjRzkUcVEQyZQ==", + "dev": true, + "requires": { + "get-stream": "^5.1.0", + "plugin-error": "^1.0.1", + "through2": "^3.0.1", + "vinyl": "^2.1.0", + "yazl": "^2.5.1" + }, + "dependencies": { + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", "dev": true, - "optional": true, "requires": { - "glob": "^7.1.3" + "pump": "^3.0.0" } }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": 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==" }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "requires": { - "safe-buffer": "~5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==" }, - "tar": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", - "dev": true, - "optional": 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==", "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "has-flag": "^4.0.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "through2": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", "dev": true, - "optional": true, "requires": { - "string-width": "^1.0.2 || 2" + "readable-stream": "2 || 3" } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true } } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", "dev": true, "requires": { - "is-property": "^1.0.2" + "glogg": "^1.0.0" } }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "handlebars": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", "dev": true, "requires": { - "is-property": "^1.0.0" + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, - "genfun": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", - "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "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==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } }, - "get-caller-file": { + "has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { - "pump": "^3.0.0" - }, - "dependencies": { - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } + "function-bind": "^1.1.1" } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "ansi-regex": "^2.0.0" } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", "dev": true, "requires": { - "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" + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz", + "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "^3.0.0" }, "dependencies": { "is-glob": { @@ -8321,524 +9456,175 @@ } } }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - } - }, - "glob-watcher": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", - "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "object.defaults": "^1.1.0" - } - }, - "global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", - "dev": true, - "requires": { - "ini": "^1.3.5" - } - }, - "global-modules": { + "has-symbols": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", - "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "path-type": "^4.0.0" + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "dev": true - }, - "path-type": { + "kind-of": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } - } - }, - "globule": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", - "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", - "dev": true, - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - } - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "gonzales-pe-sl": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz", - "integrity": "sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y=", - "dev": true, - "requires": { - "minimist": "1.1.x" - }, - "dependencies": { - "minimist": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz", - "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=", - "dev": true - } - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", - "dev": true - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "gulp-cli": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", - "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.1.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.0.1", - "yargs": "^7.1.0" + "is-buffer": "^1.1.5" } } } }, - "gulp-zip": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.0.1.tgz", - "integrity": "sha512-M/IWLh9RvOpuofDZkgDirtiyz9J3yIqnDOJ3muzk2D/XnZ1ruqPlPLRIpXnl/aZU+xXwKPdOIxjRzkUcVEQyZQ==", + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", "dev": true, "requires": { - "get-stream": "^5.1.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "vinyl": "^2.1.0", - "yazl": "^2.5.1" + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" }, "dependencies": { - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "dev": true, - "requires": { - "readable-stream": "2 || 3" - } + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true } } }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, "requires": { - "glogg": "^1.0.0" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" } }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "handlebars": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.3.0.tgz", - "integrity": "sha512-7XlnO8yBXOdi7AzowjZssQr47Ctidqm7GbgARapOaqSN9HQhlClnOkR9HieGauIT3A8MBC6u9wPCXs97PCYpWg==", + "hasha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz", + "integrity": "sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw==", "dev": true, "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", "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==", + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, - "has": { + "homedir-polyfill": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "requires": { - "function-bind": "^1.1.1" + "parse-passwd": "^1.0.0" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "hosted-git-info": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "dev": true, - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz", - "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=", - "dev": true, - "requires": { - "is-glob": "^3.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", - "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", - "dev": true - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" } }, "hsl-regex": { @@ -8871,12 +9657,6 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -8904,16 +9684,10 @@ } } }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "requires": { "eventemitter3": "^4.0.0", @@ -9066,9 +9840,9 @@ "dev": true }, "immer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/immer/-/immer-6.0.3.tgz", - "integrity": "sha512-12VvNrfSrXZdm/BJgi/KDW2soq5freVSf3I1+4CLunUM8mAGx2/0Njy0xBVzi5zewQZiwM7z1/1T+8VaI7NkmQ==" + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/immer/-/immer-6.0.9.tgz", + "integrity": "sha512-SyCYnAuiRf67Lvk0VkwFvwtDoEiCMjeamnHvRfnVDyc7re1/rQrNxuL+jJ7lA3WvdC4uznrvbmm+clJ9+XXatg==" }, "import-cwd": { "version": "2.1.0", @@ -9287,12 +10061,6 @@ "ipaddr.js": "^1.9.0" } }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true - }, "intersect": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/intersect/-/intersect-1.0.1.tgz", @@ -9380,12 +10148,18 @@ "dev": true }, "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "^2.0.0" + }, + "dependencies": { + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" + } } }, "is-buffer": { @@ -9489,8 +10263,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -9572,29 +10345,9 @@ "dev": true }, "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "is-path-cwd": { @@ -9624,8 +10377,7 @@ "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" }, "is-plain-object": { "version": "2.0.4", @@ -9643,12 +10395,20 @@ "dev": true }, "is-reference": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz", - "integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.0.tgz", + "integrity": "sha512-ZVxq+5TkOx6GQdnoMm2aRdCKADdcrOWXLGzGT+vIA8DMpqEJaRk5AL1bS80zJ2bjHunVmjdzfCt0e4BymIEqKQ==", "dev": true, "requires": { - "@types/estree": "0.0.39" + "@types/estree": "0.0.44" + }, + "dependencies": { + "@types/estree": { + "version": "0.0.44", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.44.tgz", + "integrity": "sha512-iaIVzr+w2ZJ5HkidlZ3EJM8VTZb2MJLCjw3V+505yVts0gRC4UMvjw0d1HPtGqI/HQC/KdsYtayfzl+AXY2R8g==", + "dev": true + } } }, "is-regex": { @@ -9684,8 +10444,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-svg": { "version": "3.0.0", @@ -9768,8 +10527,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -9805,12 +10563,6 @@ "wordwrap": "^1.0.0" }, "dependencies": { - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -9953,26 +10705,108 @@ } } }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" }, "dependencies": { - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "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" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "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 - } - } - }, - "istanbul-lib-source-maps": { + }, + "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" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "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 + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + } + } + }, + "istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", @@ -10195,11 +11029,11 @@ }, "json-stable-stringify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, "requires": { - "jsonify": "~0.0.0" + "kind-of": "^6.0.2" } }, "json-stable-stringify-without-jsonify": { @@ -10238,12 +11072,6 @@ "graceful-fs": "^4.1.6" } }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -10638,6 +11466,123 @@ "requires": { "istanbul-api": "^2.1.6", "minimatch": "^3.0.4" + }, + "dependencies": { + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==" + }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "istanbul-api": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.7.tgz", + "integrity": "sha512-LYTOa2UrYFyJ/aSczZi/6lBykVMjCCvUmT64gOe+jPZFy4w6FYfPGqFT2IiQ2BxVHHDOvCD7qrIXb0EOh4uGWw==", + "dev": true, + "requires": { + "async": "^2.6.2", + "compare-versions": "^3.4.0", + "fileset": "^2.0.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.5", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "minimatch": "^3.0.4", + "once": "^1.4.0" + } + }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + } + }, + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0" + } + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } } }, "karma-jasmine": { @@ -10900,11 +11845,21 @@ "strip-bom": "^2.0.0" }, "dependencies": { + "istanbul-lib-coverage": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==" + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=" } } }, @@ -10929,7 +11884,6 @@ "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" @@ -10938,8 +11892,7 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash-es": { "version": "4.17.15", @@ -10958,10 +11911,10 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "lodash.kebabcase": { @@ -11018,6 +11971,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "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==" } } }, @@ -11134,20 +12092,6 @@ "y18n": "^4.0.0" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "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" - } - }, "http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", @@ -11184,7 +12128,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, "requires": { "p-defer": "^1.0.0" } @@ -11232,74 +12175,109 @@ "stack-trace": "0.0.10" }, "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, "requires": { "homedir-polyfill": "^1.0.1" } }, - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" + "to-regex-range": "^5.0.1" } }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==" }, "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, "requires": { "is-extglob": "^2.1.0" } }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - } - } - }, - "matched": { - "version": "1.0.2", + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.0.0.tgz", + "integrity": "sha512-PiVO95TKvhiwgSwg1IdLYlCTdul38yZxZMIcnDSFIBUm4BNZha2qpQ4GpJ++15bHoKDtrW2D69lMfFwdFYtNZQ==" + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "matched": { + "version": "1.0.2", "resolved": "https://registry.npmjs.org/matched/-/matched-1.0.2.tgz", "integrity": "sha512-7ivM1jFZVTOOS77QsR+TtYHH0ecdLclMkqbf5qiJdX2RorqfhsL65QHySPZgDE0ZjHoh+mQUNHTanNXIlzXd0Q==", "dev": true, @@ -11405,9 +12383,9 @@ "dev": true }, "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "methods": { @@ -11435,6 +12413,90 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.2" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, "miller-rabin": { @@ -11448,9 +12510,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -11479,8 +12541,7 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "mimic-response": { "version": "1.0.1", @@ -11569,16 +12630,24 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "requires": { - "yallist": "^4.0.0" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + }, + "dependencies": { + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } } }, "minipass-collect": { @@ -11588,6 +12657,17 @@ "dev": true, "requires": { "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "minipass-flush": { @@ -11597,6 +12677,17 @@ "dev": true, "requires": { "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "minipass-pipeline": { @@ -11606,6 +12697,17 @@ "dev": true, "requires": { "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "minizlib": { @@ -11616,6 +12718,17 @@ "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "mississippi": { @@ -11634,18 +12747,6 @@ "pumpify": "^1.3.3", "stream-each": "^1.1.0", "through2": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } } }, "mixin-deep": { @@ -11753,13 +12854,6 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -11798,17 +12892,17 @@ "dev": true }, "ng-packagr": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-9.1.1.tgz", - "integrity": "sha512-20umbeklnsntUoTXBKuQQj4Oyw1tauVU7TZPRFC+n3bXuB29rb+91HIBtt8k7l0BuXN5G4HiXgmPW8xDGu7HWg==", + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-9.1.5.tgz", + "integrity": "sha512-biuNfM15uLkCW+Vvj8bnuwjX37oX7j5icGm+l71FhM6ydlEl+Cl7PdFXpy9rrIlKFYlYRiPiiiWazGwVGn1icQ==", "dev": true, "requires": { "@rollup/plugin-commonjs": "^11.0.2", "@rollup/plugin-json": "^4.0.0", "@rollup/plugin-node-resolve": "^7.1.0", "ajv": "^6.10.2", - "autoprefixer": "^9.6.5", - "browserslist": "^4.7.0", + "autoprefixer": "^9.7.6", + "browserslist": "^4.12.0", "chalk": "^4.0.0", "chokidar": "^3.2.1", "clean-css": "^4.1.11", @@ -11822,8 +12916,8 @@ "postcss-url": "^8.0.0", "read-pkg-up": "^5.0.0", "rimraf": "^3.0.0", - "rollup": "2.6.1", - "rollup-plugin-sourcemaps": "^0.5.0", + "rollup": "2.7.5", + "rollup-plugin-sourcemaps": "^0.6.0", "rxjs": "^6.5.0", "sass": "^1.23.0", "stylus": "^0.54.7", @@ -11831,65 +12925,91 @@ "update-notifier": "^4.0.0" }, "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" + "autoprefixer": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", + "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001061", + "chalk": "^2.4.2", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.30", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "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" + } + }, + "postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + } } }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" - } - }, - "chokidar": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", - "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.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 + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "color-convert": { @@ -11913,15 +13033,6 @@ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -11931,43 +13042,6 @@ "locate-path": "^3.0.0" } }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.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 - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -11978,12 +13052,6 @@ "path-exists": "^3.0.0" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -12042,15 +13110,6 @@ "read-pkg": "^5.0.0" } }, - "readdirp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", - "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.7" - } - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -12061,30 +13120,47 @@ } }, "rollup": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.6.1.tgz", - "integrity": "sha512-1RhFDRJeg027YjBO6+JxmVWkEZY0ASztHhoEUEWxOwkh4mjO58TFD6Uo7T7Y3FbmDpRTfKhM5NVxJyimCn0Elg==", + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.7.5.tgz", + "integrity": "sha512-xQSM8uzhgtF6tTnTVEvOQThrcG3LPUP3T/4l4EukzDp0kbTY1QRDuXjiwtYzs9odKj9Bj/PccRG6viFfS7DmCQ==", "dev": true, "requires": { "fsevents": "~2.1.2" } }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "rollup-plugin-sourcemaps": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.2.tgz", + "integrity": "sha512-9AwTKg3yRykwzemfLt71ySe0LvrAci+bpsOL1LaTYFk5BX4HF6X7DQfpHa74ANfSja3hyjiQkXCR8goSOnW//Q==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "@rollup/pluginutils": "^3.0.9", + "source-map-resolve": "^0.6.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", "dev": true, "requires": { - "is-number": "^7.0.0" + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } }, "type-fest": { @@ -12114,8 +13190,7 @@ "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-fetch": { "version": "2.6.0", @@ -12179,10 +13254,19 @@ } } }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, "node-releases": { - "version": "1.1.53", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", - "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==", + "version": "1.1.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", + "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==", "dev": true }, "node-sass-tilde-importer": { @@ -12216,13 +13300,9 @@ } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-range": { "version": "0.1.2", @@ -12273,209 +13353,529 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true - } - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true - }, - "npm-package-arg": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.0.1.tgz", - "integrity": "sha512-/h5Fm6a/exByzFSTm7jAyHbgOqErl9qSNJDQF32Si/ZzgwT2TERVxRxn3Jurw1wflgyVVAxnFR4fRHPM7y1ClQ==", - "dev": true, - "requires": { - "hosted-git-info": "^3.0.2", - "semver": "^7.0.0", - "validate-npm-package-name": "^3.0.0" - }, - "dependencies": { - "hosted-git-info": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", - "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", + } + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "npm-package-arg": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.0.1.tgz", + "integrity": "sha512-/h5Fm6a/exByzFSTm7jAyHbgOqErl9qSNJDQF32Si/ZzgwT2TERVxRxn3Jurw1wflgyVVAxnFR4fRHPM7y1ClQ==", + "dev": true, + "requires": { + "hosted-git-info": "^3.0.2", + "semver": "^7.0.0", + "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", + "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", + "dev": true, + "requires": { + "lru-cache": "^5.1.1" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-pick-manifest": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.0.0.tgz", + "integrity": "sha512-PdJpXMvjqt4nftNEDpCgjBUF8yI3Q3MyuAmVB9nemnnCg32F4BPL/JFBfdj8DubgHCYUFQhtLWmBPvdsFtjWMg==", + "dev": true, + "requires": { + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.0.0", + "semver": "^7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "npm-registry-fetch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.4.tgz", + "integrity": "sha512-6jb34hX/iYNQebqWUHtU8YF6Cjb1H6ouTFPClYsyiW6lpFkljTpdeftm53rRojtja1rKAvKNIIiTS5Sjpw4wsA==", + "dev": true, + "requires": { + "JSONStream": "^1.3.4", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "npm-package-arg": "^6.1.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "npm-package-arg": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "dev": true, + "requires": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.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" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.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 + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "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 + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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" + } + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "requires": { + "strip-bom": "^4.0.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" + } + }, + "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 + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "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" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "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 + }, + "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 + }, + "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": { - "lru-cache": "^5.1.1" + "glob": "^7.1.3" } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - } - } - }, - "npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "dev": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-pick-manifest": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.0.0.tgz", - "integrity": "sha512-PdJpXMvjqt4nftNEDpCgjBUF8yI3Q3MyuAmVB9nemnnCg32F4BPL/JFBfdj8DubgHCYUFQhtLWmBPvdsFtjWMg==", - "dev": true, - "requires": { - "npm-install-checks": "^4.0.0", - "npm-package-arg": "^8.0.0", - "semver": "^7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - } - } - }, - "npm-registry-fetch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.4.tgz", - "integrity": "sha512-6jb34hX/iYNQebqWUHtU8YF6Cjb1H6ouTFPClYsyiW6lpFkljTpdeftm53rRojtja1rKAvKNIIiTS5Sjpw4wsA==", - "dev": true, - "requires": { - "JSONStream": "^1.3.4", - "bluebird": "^3.5.1", - "figgy-pudding": "^3.4.1", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "npm-package-arg": "^6.1.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "npm-package-arg": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "hosted-git-info": "^2.7.1", - "osenv": "^0.1.5", - "semver": "^5.6.0", - "validate-npm-package-name": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.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==", + "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": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "ansi-regex": "^5.0.0" } }, - "load-json-file": { + "strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "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==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "has-flag": "^4.0.0" } }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -12485,8 +13885,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-component": { "version": "0.0.3", @@ -12578,18 +13977,18 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "object-inspect": { @@ -12708,18 +14107,18 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "object-inspect": { @@ -12830,18 +14229,18 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "object-inspect": { @@ -12899,7 +14298,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -12965,17 +14363,17 @@ } }, "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "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.4", + "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "word-wrap": "~1.2.3" } }, "ora": { @@ -13125,26 +14523,17 @@ "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "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" } @@ -13153,7 +14542,6 @@ "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" } @@ -13179,8 +14567,19 @@ "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 + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } }, "package-json": { "version": "6.5.0", @@ -13194,6 +14593,34 @@ "semver": "^6.2.0" }, "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -13261,22 +14688,6 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "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" - } - } } }, "fs-minipass": { @@ -13288,16 +14699,6 @@ "minipass": "^2.6.0" } }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, "minizlib": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", @@ -13422,8 +14823,7 @@ "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" }, "parse5": { "version": "5.1.1", @@ -13476,8 +14876,7 @@ "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 + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "path-is-absolute": { "version": "1.0.1", @@ -13494,8 +14893,7 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.6", @@ -13543,9 +14941,9 @@ } }, "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -13564,8 +14962,7 @@ "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, "pidtree": { "version": "0.3.0", @@ -14171,6 +15568,44 @@ "postcss-value-parser": "^3.0.0" }, "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.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==" + }, "postcss-value-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", @@ -14343,17 +15778,17 @@ }, "dependencies": { "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true } } }, "postcss-value-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", - "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", "dev": true }, "prelude-ls": { @@ -14365,8 +15800,7 @@ "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "pretty-hrtime": { "version": "1.0.3", @@ -14392,6 +15826,15 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, "progress": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", @@ -14688,18 +16131,17 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } }, "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -14714,6 +16156,18 @@ "duplexify": "^3.6.0", "inherits": "^2.0.3", "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } } }, "punycode": { @@ -14752,7 +16206,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, "requires": { "object-assign": "^4.1.0", "strict-uri-encode": "^1.0.0" @@ -14995,14 +16448,12 @@ } }, "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "picomatch": "^2.2.1" } }, "readline2": { @@ -15127,18 +16578,18 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "object-inspect": { @@ -15226,6 +16677,15 @@ } } }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, "remove-bom-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", @@ -15355,26 +16815,6 @@ "path-exists": "^4.0.0" } }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "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" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -15397,9 +16837,9 @@ } }, "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "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" @@ -15426,12 +16866,6 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -15498,9 +16932,9 @@ } }, "yargs-parser": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", - "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -15560,13 +16994,12 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "require-uncached": { @@ -15743,40 +17176,6 @@ "dev": true, "requires": { "fsevents": "~2.1.2" - }, - "dependencies": { - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - } - } - }, - "rollup-plugin-sourcemaps": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.5.0.tgz", - "integrity": "sha512-xp2vvRvgnYiXydgf/JFFFgYxrqMaQaOrK/g6yZvgwT9R1TSYjD3HKku1pD7iQNjQHkl5yGpokvJLp7cP/lR+aQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.0.1", - "source-map-resolve": "^0.5.3" - }, - "dependencies": { - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - } } }, "run-async": { @@ -16230,13 +17629,28 @@ "dev": true }, "schema-utils": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz", - "integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", "dev": true, "requires": { - "ajv": "^6.12.0", + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", "ajv-keywords": "^3.4.1" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + } } }, "select-hose": { @@ -16280,8 +17694,7 @@ "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, "semver-diff": { "version": "3.1.1", @@ -16418,8 +17831,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-immediate-shim": { "version": "1.0.1", @@ -16485,7 +17897,6 @@ "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" } @@ -16493,8 +17904,7 @@ "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 + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "shell-quote": { "version": "1.7.2", @@ -16505,8 +17915,7 @@ "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "simple-swizzle": { "version": "0.2.2", @@ -16755,13 +18164,22 @@ } }, "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", "dev": true, "requires": { "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "sockjs-client": { @@ -16839,7 +18257,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, "requires": { "is-plain-obj": "^1.0.0" } @@ -16888,12 +18305,12 @@ } }, "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, "requires": { - "atob": "^2.1.1", + "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", @@ -16901,9 +18318,9 @@ } }, "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -16927,8 +18344,7 @@ "sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, "sparkles": { "version": "1.0.1", @@ -16936,6 +18352,55 @@ "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", "dev": true }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "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" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", @@ -17097,6 +18562,17 @@ "dev": true, "requires": { "minipass": "^3.1.1" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "stable": { @@ -17263,9 +18739,9 @@ } }, "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, "streamroller": { @@ -17312,8 +18788,7 @@ "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, "string-width": { "version": "1.0.2", @@ -17384,18 +18859,18 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "object-inspect": { @@ -17495,18 +18970,18 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "object-inspect": { @@ -17569,8 +19044,7 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-json-comments": { "version": "2.0.1", @@ -17637,6 +19111,21 @@ "indexes-of": "^1.0.1", "uniq": "^1.0.1" } + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" } } }, @@ -17883,6 +19372,15 @@ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -17986,9 +19484,9 @@ "dev": true }, "terser": { - "version": "4.6.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.7.tgz", - "integrity": "sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==", + "version": "4.6.10", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.10.tgz", + "integrity": "sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA==", "dev": true, "requires": { "commander": "^2.20.0", @@ -18047,18 +19545,13 @@ "unique-filename": "^1.1.1" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "dev": true, "requires": { - "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" + "yallist": "^4.0.0" } }, "p-limit": { @@ -18094,6 +19587,17 @@ } } }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -18229,13 +19733,12 @@ } }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "to-through": { @@ -18263,6 +19766,11 @@ "punycode": "^2.1.1" } }, + "transformation-matrix": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-1.15.3.tgz", + "integrity": "sha512-ThJH58GNFKhCw3gIoOtwf3tNwuYjbyEeiGdeq4mNMYWdJctnI896KUqn6PVt7jmNVepqa1bcKQtnMB1HtjsDMA==" + }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -18293,9 +19801,9 @@ "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" }, "tslint": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.1.tgz", - "integrity": "sha512-kd6AQ/IgPRpLn6g5TozqzPdGNZ0q0jtXW4//hRcj10qLYBaa3mTUU2y2MCG+RXZm8Zx+KZi0eA+YCrMyNlF4UA==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.2.tgz", + "integrity": "sha512-UyNrLdK3E0fQG/xWNqAFAC5ugtFyPO4JJR1KyyfQAyzR8W0fTRrC91A8Wej4BntFzcvETdCSDa/4PnNYJQLYiA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -18319,12 +19827,6 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -18425,20 +19927,19 @@ "dev": true }, "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.4.tgz", + "integrity": "sha512-8RZBJq5smLOa7KslsNsVcSH+KOXf1uDU8yqLeNuVKwmT0T3FA0ZoXlinQfRad7SDcbZZRZE4ov+2v71EnxNyCA==", "dev": true, "optional": true, "requires": { - "commander": "~2.20.0", - "source-map": "~0.6.1" + "commander": "~2.20.3" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, "optional": true } @@ -18900,18 +20401,18 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "object-inspect": { @@ -18956,15 +20457,6 @@ "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", "dev": true }, - "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -19073,6 +20565,17 @@ "now-and-later": "^2.0.0", "remove-bom-buffer": "^3.0.0", "vinyl": "^2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } } }, "vm-browserify": { @@ -19088,14 +20591,143 @@ "dev": true }, "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", + "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", "dev": true, "requires": { - "chokidar": "^2.1.8", + "chokidar": "^3.4.0", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true, + "optional": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "optional": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" }, "dependencies": { "chokidar": { @@ -19103,26 +20735,162 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "optional": true + } + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "dev": true, + "optional": true + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "optional": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, @@ -19149,6 +20917,17 @@ "resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.2.tgz", "integrity": "sha512-TOMFWtQdxzjWp8qx4DAraTWTsdhxVSiWa6NkPFSaPtZ1diKUxTn4yTix73A1euG1WbSOMMPcY51cnjTIHrGtDA==" }, + "webcola": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/webcola/-/webcola-3.4.0.tgz", + "integrity": "sha512-4BiLXjXw3SJHo3Xd+rF+7fyClT6n7I+AR6TkBqyQ4kTsePSAMDLRCXY1f3B/kXJeP9tYn4G1TblxTO+jAt0gaw==", + "requires": { + "d3-dispatch": "^1.0.3", + "d3-drag": "^1.0.4", + "d3-shape": "^1.3.5", + "d3-timer": "^1.0.5" + } + }, "webdriver-js-extender": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", @@ -19321,6 +21100,17 @@ "terser": "^4.1.2", "webpack-sources": "^1.4.0", "worker-farm": "^1.7.0" + }, + "dependencies": { + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + } } } } @@ -19349,17 +21139,17 @@ } }, "mime": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", - "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true } } }, "webpack-dev-server": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz", - "integrity": "sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -19370,39 +21160,78 @@ "debug": "^4.1.1", "del": "^4.1.1", "express": "^4.17.1", - "html-entities": "^1.2.1", + "html-entities": "^1.3.1", "http-proxy-middleware": "0.19.1", "import-local": "^2.0.0", "internal-ip": "^4.3.0", "ip": "^1.1.5", "is-absolute-url": "^3.0.3", "killable": "^1.0.1", - "loglevel": "^1.6.6", + "loglevel": "^1.6.8", "opn": "^5.5.0", "p-retry": "^3.0.1", - "portfinder": "^1.0.25", + "portfinder": "^1.0.26", "schema-utils": "^1.0.0", "selfsigned": "^1.10.7", "semver": "^6.3.0", "serve-index": "^1.9.1", - "sockjs": "0.3.19", + "sockjs": "0.3.20", "sockjs-client": "1.4.0", - "spdy": "^4.0.1", + "spdy": "^4.0.2", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", "url": "^0.11.0", "webpack-dev-middleware": "^3.7.2", "webpack-log": "^2.0.0", "ws": "^6.2.1", - "yargs": "12.0.5" + "yargs": "^13.3.2" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, "chokidar": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", @@ -19424,23 +21253,23 @@ } }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" }, "dependencies": { "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } } } @@ -19454,6 +21283,33 @@ "ms": "^2.1.1" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -19463,11 +21319,12 @@ "locate-path": "^3.0.0" } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true }, "is-absolute-url": { "version": "3.0.3", @@ -19475,19 +21332,37 @@ "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "dev": true }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "invert-kv": "^2.0.0" + "kind-of": "^3.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" } }, "locate-path": { @@ -19500,40 +21375,12 @@ "path-exists": "^3.0.0" } }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.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 }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -19558,6 +21405,17 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -19576,26 +21434,37 @@ "dev": true }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { + "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "strip-ansi": "^5.1.0" }, "dependencies": { "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } } } }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -19603,29 +21472,27 @@ "dev": true }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -19681,13 +21548,11 @@ } }, "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", "dev": true, "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -19707,7 +21572,6 @@ "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" } @@ -19761,21 +21625,18 @@ } } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, "worker-plugin": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/worker-plugin/-/worker-plugin-4.0.3.tgz", @@ -19808,20 +21669,60 @@ } }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "0.2.1", @@ -19950,6 +21851,18 @@ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", diff --git a/package.json b/package.json index 6e9df37e0c..9e9e517679 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "test-frontend:store": "NG_TEST_SUITE=store ng test store --code-coverage --watch=false", "test-frontend:cloud-foundry": "NG_TEST_SUITE=cloud-foundry ng test cloud-foundry --code-coverage --watch=false", "test-frontend:cf-autoscaler": "NG_TEST_SUITE=autoscaler ng test cf-autoscaler --code-coverage --watch=false", - "posttest": "istanbul report json && node build/combine-coverage.js", + "posttest": "nyc report --reporter=html --reporter=lcovonly --reporter=json --tempDir=coverage/nyc", "codecov": "codecov -f coverage/coverage-final.json", "lint": "ng lint --format stylish", "sass-lint": "sass-lint -v", @@ -133,6 +133,7 @@ "mktemp": "^1.0.0", "ng-packagr": "^9.1.1", "npm-run-all": "^4.1.5", + "nyc": "^15.1.0", "protractor": "^5.4.3", "protractor-console": "^3.0.0", "ps-node": "^0.1.6", @@ -143,7 +144,7 @@ "rxjs-tslint": "^0.1.8", "sass-lint": "^1.12.1", "stratos-protractor-reporter": "^1.2.3", - "ts-node": "~8.8.2", + "ts-node": "^8.8.2", "tslint": "~6.1.1", "typescript": "3.8.3" } diff --git a/protractor.conf.js b/protractor.conf.js index fc90778a5c..b41a046f68 100644 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -173,7 +173,7 @@ const config = { plugins: [{ package: 'protractor-console', logLevels: ['info', 'warning', 'severe'] - }], + }], onPrepare() { // https://webdriver.io/docs/api/chromium.html#setnetworkconditions // browser.driver.setNetworkConditions({ @@ -185,7 +185,7 @@ const config = { // Ensuer base URL does NOT end with a / if (browser.baseUrl.endsWith('/')) { - browser.baseUrl = browser.baseUrl.substr(0, browser.baseUrl.length -1); + browser.baseUrl = browser.baseUrl.substr(0, browser.baseUrl.length - 1); } skipPlugin.install(jasmine); diff --git a/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-card/app-autoscaler-metric-chart-card.component.spec.ts b/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-card/app-autoscaler-metric-chart-card.component.spec.ts index a6495afa68..6444356618 100644 --- a/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-card/app-autoscaler-metric-chart-card.component.spec.ts +++ b/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-card/app-autoscaler-metric-chart-card.component.spec.ts @@ -26,8 +26,6 @@ import { AppAutoscalerMetricChartCardComponent } from './app-autoscaler-metric-c import { AppAutoscalerComboChartComponent } from './combo-chart/combo-chart.component'; import { AppAutoscalerComboSeriesVerticalComponent } from './combo-chart/combo-series-vertical.component'; -/* tslint:disable:max-line-length */ -/* tslint:enable:max-line-length */ describe('AppAutoscalerMetricChartCardComponent', () => { let component: AppAutoscalerMetricChartCardComponent; diff --git a/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-list-config.service.spec.ts b/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-list-config.service.spec.ts index a731e3f8a7..d4bf8da651 100644 --- a/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-list-config.service.spec.ts +++ b/src/frontend/packages/cf-autoscaler/src/shared/list-types/app-autoscaler-metric-chart/app-autoscaler-metric-chart-list-config.service.spec.ts @@ -18,9 +18,6 @@ import { PaginationMonitorFactory } from '../../../../../store/src/monitors/pagi import { CfAutoscalerTestingModule } from '../../../cf-autoscaler-testing.module'; import { AppAutoscalerMetricChartListConfigService } from './app-autoscaler-metric-chart-list-config.service'; -/* tslint:disable:max-line-length */ - -/* tslint:enable:max-line-length */ describe('AppAutoscalerMetricChartListConfigService', () => { beforeEach(() => { diff --git a/src/frontend/packages/cloud-foundry/src/actions/buildpack.action.ts b/src/frontend/packages/cloud-foundry/src/actions/buildpack.action.ts index 8fe4445485..d7a40dee9d 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/buildpack.action.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/buildpack.action.ts @@ -1,9 +1,10 @@ +import { HttpRequest } from '@angular/common/http'; + import { getActions } from '../../../store/src/actions/action.helper'; import { PaginatedAction } from '../../../store/src/types/pagination.types'; import { cfEntityFactory } from '../cf-entity-factory'; import { buildpackEntityType } from '../cf-entity-types'; import { CFStartAction } from './cf-action.types'; -import { HttpRequest } from '@angular/common/http'; export class FetchAllBuildpacks extends CFStartAction implements PaginatedAction { constructor(public endpointGuid: string, public paginationKey: string) { diff --git a/src/frontend/packages/cloud-foundry/src/actions/domains.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/domains.actions.ts index 6d56f47d8d..13d4f6d59b 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/domains.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/domains.actions.ts @@ -1,3 +1,5 @@ +import { HttpRequest } from '@angular/common/http'; + import { endpointSchemaKey } from '../../../store/src/helpers/entity-factory'; import { PaginatedAction } from '../../../store/src/types/pagination.types'; import { ICFAction } from '../../../store/src/types/request.types'; @@ -5,7 +7,6 @@ import { cfEntityFactory } from '../cf-entity-factory'; import { domainEntityType } from '../cf-entity-types'; import { createEntityRelationPaginationKey } from '../entity-relations/entity-relations.types'; import { CFStartAction } from './cf-action.types'; -import { HttpRequest } from '@angular/common/http'; export const GET_DOMAIN = '[domain] Get domain '; export const GET_DOMAIN_SUCCESS = '[domain] Get domain success'; diff --git a/src/frontend/packages/cloud-foundry/src/actions/relation.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/relation.actions.ts index 1d8e1129fd..b0d2154801 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/relation.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/relation.actions.ts @@ -1,13 +1,11 @@ +import { HttpParams, HttpRequest } from '@angular/common/http'; + import { EntityCatalogEntityConfig } from '../../../store/src/entity-catalog/entity-catalog.types'; -import { - EntityInlineChildAction, - EntityInlineParentAction, -} from '../entity-relations/entity-relations.types'; import { PaginatedAction } from '../../../store/src/types/pagination.types'; -import { RequestEntityLocation, RequestActionEntity } from '../../../store/src/types/request.types'; -import { CFStartAction } from './cf-action.types'; +import { RequestActionEntity, RequestEntityLocation } from '../../../store/src/types/request.types'; import { EntityTreeRelation } from '../entity-relations/entity-relation-tree'; -import { HttpRequest, HttpParams } from '@angular/common/http'; +import { EntityInlineChildAction, EntityInlineParentAction } from '../entity-relations/entity-relations.types'; +import { CFStartAction } from './cf-action.types'; const relationActionId = 'FetchRelationAction'; diff --git a/src/frontend/packages/cloud-foundry/src/actions/security-groups-actions.ts b/src/frontend/packages/cloud-foundry/src/actions/security-groups-actions.ts index 1930e67071..8d882c6a44 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/security-groups-actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/security-groups-actions.ts @@ -1,10 +1,11 @@ +import { HttpRequest } from '@angular/common/http'; + import { getActions } from '../../../store/src/actions/action.helper'; import { PaginatedAction } from '../../../store/src/types/pagination.types'; import { cfEntityFactory } from '../cf-entity-factory'; import { securityGroupEntityType, spaceEntityType } from '../cf-entity-types'; import { createEntityRelationKey, EntityInlineParentAction } from '../entity-relations/entity-relations.types'; import { CFStartAction } from './cf-action.types'; -import { HttpRequest } from '@angular/common/http'; export class GetAllSecurityGroups extends CFStartAction implements PaginatedAction, EntityInlineParentAction { constructor( diff --git a/src/frontend/packages/cloud-foundry/src/actions/service-bindings.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/service-bindings.actions.ts index d0a2763cfb..cd7763a255 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/service-bindings.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/service-bindings.actions.ts @@ -1,10 +1,11 @@ +import { HttpParams, HttpRequest } from '@angular/common/http'; + import { getActions } from '../../../store/src/actions/action.helper'; import { PaginatedAction, PaginationParam } from '../../../store/src/types/pagination.types'; import { ICFAction } from '../../../store/src/types/request.types'; import { cfEntityFactory } from '../cf-entity-factory'; import { serviceBindingEntityType } from '../cf-entity-types'; import { CFStartAction } from './cf-action.types'; -import { HttpRequest, HttpParams } from '@angular/common/http'; export const DELETE_SERVICE_BINDING_ACTION = '[ Service Instances ] Delete Service Binding'; export const DELETE_SERVICE_BINDING_ACTION_SUCCESS = '[ Service Instances ] Delete Service Binding success'; diff --git a/src/frontend/packages/cloud-foundry/src/actions/service-broker.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/service-broker.actions.ts index a598c73a26..5dfefc6e7b 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/service-broker.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/service-broker.actions.ts @@ -1,10 +1,11 @@ +import { HttpRequest } from '@angular/common/http'; + import { getActions } from '../../../store/src/actions/action.helper'; import { PaginatedAction } from '../../../store/src/types/pagination.types'; import { EntityRequestAction } from '../../../store/src/types/request.types'; import { cfEntityFactory } from '../cf-entity-factory'; import { serviceBrokerEntityType } from '../cf-entity-types'; import { CFStartAction } from './cf-action.types'; -import { HttpRequest } from '@angular/common/http'; export class GetServiceBrokers extends CFStartAction implements PaginatedAction { constructor( diff --git a/src/frontend/packages/cloud-foundry/src/actions/service-plan-visibility.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/service-plan-visibility.actions.ts index 34e8b3dde4..42adf48a73 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/service-plan-visibility.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/service-plan-visibility.actions.ts @@ -1,3 +1,5 @@ +import { HttpRequest } from '@angular/common/http'; + import { getActions } from '../../../store/src/actions/action.helper'; import { PaginatedAction } from '../../../store/src/types/pagination.types'; import { cfEntityFactory } from '../cf-entity-factory'; @@ -9,7 +11,6 @@ import { } from '../cf-entity-types'; import { createEntityRelationKey } from '../entity-relations/entity-relations.types'; import { CFStartAction } from './cf-action.types'; -import { HttpRequest } from '@angular/common/http'; export class GetServicePlanVisibilities extends CFStartAction implements PaginatedAction { constructor( diff --git a/src/frontend/packages/cloud-foundry/src/actions/service-plan.actions.ts b/src/frontend/packages/cloud-foundry/src/actions/service-plan.actions.ts index d12c5e0ee3..a7b2621cda 100644 --- a/src/frontend/packages/cloud-foundry/src/actions/service-plan.actions.ts +++ b/src/frontend/packages/cloud-foundry/src/actions/service-plan.actions.ts @@ -1,3 +1,5 @@ +import { HttpRequest } from '@angular/common/http'; + import { getActions } from '../../../store/src/actions/action.helper'; import { PaginatedAction } from '../../../store/src/types/pagination.types'; import { cfEntityFactory } from '../cf-entity-factory'; @@ -12,7 +14,6 @@ import { } from '../cf-entity-types'; import { createEntityRelationKey } from '../entity-relations/entity-relations.types'; import { CFStartAction } from './cf-action.types'; -import { HttpRequest } from '@angular/common/http'; export class GetServicePlanServiceInstances extends CFStartAction implements PaginatedAction { constructor( diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.spec.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.spec.ts index 197bf2ee0b..25e3004052 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/cli-info-cloud-foundry/cli-info-cloud-foundry.component.spec.ts @@ -13,7 +13,6 @@ import { CloudFoundryUserProvidedServicesService, } from '../../../shared/services/cloud-foundry-user-provided-services.service'; import { ActiveRouteCfOrgSpace } from '../cf-page.types'; -import { CloudFoundryEndpointService } from '../services/cloud-foundry-endpoint.service'; import { CliInfoCloudFoundryComponent } from './cli-info-cloud-foundry.component'; describe('CliInfoCloudFoundryComponent', () => { @@ -30,7 +29,6 @@ describe('CliInfoCloudFoundryComponent', () => { ], imports: generateCfBaseTestModules(), providers: [ - CloudFoundryEndpointService, generateTestCfEndpointServiceProvider(), ActiveRouteCfOrgSpace, ApplicationStateService, diff --git a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.spec.ts b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.spec.ts index 7ce6fa5e4a..14e0a46dd7 100644 --- a/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/features/cloud-foundry/users/manage-users/cf-roles.service.spec.ts @@ -8,8 +8,6 @@ import { CloudFoundryModule } from '../../cloud-foundry.module'; import { CfRolesService } from './cf-roles.service'; import { HttpClientModule } from '@angular/common/http'; - - describe('CfRolesService', () => { beforeEach(() => { TestBed.configureTestingModule({ diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/cf-apps-data-source.ts b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/cf-apps-data-source.ts index d5617f8f14..0e4e9e1269 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/cf-apps-data-source.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/list/list-types/app/cf-apps-data-source.ts @@ -5,7 +5,6 @@ import { tag } from 'rxjs-spy/operators/tag'; import { debounceTime, delay, distinctUntilChanged, map, withLatestFrom } from 'rxjs/operators'; import { GetAllApplications } from '../../../../../../../cloud-foundry/src/actions/application.actions'; -import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; import { applicationEntityType, organizationEntityType, @@ -31,6 +30,7 @@ import { cfEntityFactory } from '../../../../../cf-entity-factory'; import { cfOrgSpaceFilter } from '../../../../../features/cloud-foundry/cf.helpers'; import { CFListDataSource } from '../../../../cf-list-data-source'; import { createCfOrSpaceMultipleFilterFn } from '../../../../data-services/cf-org-space-service.service'; +import { CFAppState } from '../../../../../../../cloud-foundry/src/cf-app-state'; export class CfAppsDataSource extends CFListDataSource { diff --git a/src/frontend/packages/core/sass/components/mat-table.scss b/src/frontend/packages/core/sass/components/mat-table.scss index 6eef03a63d..c623288894 100644 --- a/src/frontend/packages/core/sass/components/mat-table.scss +++ b/src/frontend/packages/core/sass/components/mat-table.scss @@ -16,10 +16,18 @@ $mat-table-header-paginator-font-size: 13px; padding: 10px 10px 10px 0; } - // Use margin, not padding for the left side of the first cell in the row/header/footer - .mat-cell:first-of-type, mat-footer-cell:first-of-type, mat-header-cell:first-of-type { - margin-left: 20px; - padding-left: 0; + .app-table { + // Use margin, not padding for the left side of the first cell in the row/header/footer + .mat-cell:first-of-type, mat-footer-cell:first-of-type, mat-header-cell:first-of-type { + margin-left: 20px; + padding-left: 0; + } + .has-expanded-row { + // Override the margin-left from above, there's a lot of white space going on + .mat-cell:first-of-type, mat-footer-cell:first-of-type, mat-header-cell:first-of-type { + margin-left: 10px; + } + } } // Use margin, not padding for the right side of the first cell in the row/header/footer diff --git a/src/frontend/packages/core/src/app.routing.ts b/src/frontend/packages/core/src/app.routing.ts index 7f5feb542d..7f85939c8b 100644 --- a/src/frontend/packages/core/src/app.routing.ts +++ b/src/frontend/packages/core/src/app.routing.ts @@ -89,7 +89,7 @@ const appRoutes: Routes = [ path: '', loadChildren: () => import('./features/endpoints/endpoints.module').then(m => m.EndpointsModule), }] - }, + }, { path: 'marketplace', loadChildren: () => import('../../cloud-foundry/src/features/service-catalog/service-catalog.module') diff --git a/src/frontend/packages/core/src/core/endpoints.service.ts b/src/frontend/packages/core/src/core/endpoints.service.ts index 1d82326027..6354590f8a 100644 --- a/src/frontend/packages/core/src/core/endpoints.service.ts +++ b/src/frontend/packages/core/src/core/endpoints.service.ts @@ -139,8 +139,11 @@ export class EndpointsService implements CanActivate { map(ep => { return Object.values(ep) .filter(endpoint => { + if (endpoint.cnsi_type !== type) { + return; + } const epType = entityCatalog.getEndpoint(endpoint.cnsi_type, endpoint.sub_type).definition; - return endpoint.cnsi_type === type && (epType.unConnectable || endpoint.connectionStatus === 'connected'); + return epType.unConnectable || endpoint.connectionStatus === 'connected'; }); }) ); diff --git a/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.ts b/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.ts index c409c37976..a3bff217b1 100644 --- a/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.ts +++ b/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.ts @@ -190,7 +190,7 @@ export class DashboardBaseComponent implements OnInit, OnDestroy, AfterViewInit link: path + '/' + route.path }; if (item.requiresEndpointType) { - // Upstream always likes to show Cloud Foundry related endpoints - other distributions can chane this behaviour + // Upstream always likes to show Cloud Foundry related endpoints - other distributions can change this behaviour const alwaysShow = this.cs.get().alwaysShowNavForEndpointTypes ? this.cs.get().alwaysShowNavForEndpointTypes(item.requiresEndpointType) : (item.requiresEndpointType === 'cf'); item.hidden = alwaysShow ? of(false) : this.endpointsService.doesNotHaveConnectedEndpointType(item.requiresEndpointType); diff --git a/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints/backup-endpoints.component.html b/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints/backup-endpoints.component.html index bfbec70bda..b86b52acc0 100644 --- a/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints/backup-endpoints.component.html +++ b/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints/backup-endpoints.component.html @@ -14,7 +14,9 @@

Backup Endpoints

- + +

There are no endpoints to backup

diff --git a/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts b/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts index ef5b53a8b6..fc31d4b577 100644 --- a/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts +++ b/src/frontend/packages/core/src/features/metrics/metrics.helpers.ts @@ -53,7 +53,7 @@ export function mapMetricsData(ep: MetricsEndpointProvider): MetricsEndpointInfo const hasEndpoint = data.findIndex(i => i.url === endp.url || i.url === endp.cfEndpoint) !== -1; if (!hasEndpoint) { const catalogEndpoint = entityCatalog.getEndpoint(endp.type, ''); - if (catalogEndpoint) { // Provider metadata could give k8 endpoint + if (catalogEndpoint) { // Provider metadata could give unknown endpoint data.push({ known: false, name: '', diff --git a/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.html b/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.html index 6407fa952b..d1558f2b9d 100644 --- a/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.html +++ b/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.html @@ -24,11 +24,11 @@

-
    -
  • - +
      +
    • + - +
      {{info.icon.name }}
-
- +
\ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/entity-summary-title/entity-summary-title.component.scss b/src/frontend/packages/core/src/shared/components/entity-summary-title/entity-summary-title.component.scss index 82c922af76..64db61cfc3 100644 --- a/src/frontend/packages/core/src/shared/components/entity-summary-title/entity-summary-title.component.scss +++ b/src/frontend/packages/core/src/shared/components/entity-summary-title/entity-summary-title.component.scss @@ -7,6 +7,9 @@ } &__img { align-self: center; + height: 64px; + object-fit: contain; + width: 64px; } &__logo { font-size: 54px; diff --git a/src/frontend/packages/core/src/shared/components/ring-chart/ring-chart.component.html b/src/frontend/packages/core/src/shared/components/ring-chart/ring-chart.component.html index 40cd0d4a96..e69cdf1c90 100644 --- a/src/frontend/packages/core/src/shared/components/ring-chart/ring-chart.component.html +++ b/src/frontend/packages/core/src/shared/components/ring-chart/ring-chart.component.html @@ -1,6 +1,7 @@
- +
@@ -8,8 +9,10 @@
{{ label }}
-
-
+ \ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/ring-chart/ring-chart.component.ts b/src/frontend/packages/core/src/shared/components/ring-chart/ring-chart.component.ts index 0e96a6cece..be9557639d 100644 --- a/src/frontend/packages/core/src/shared/components/ring-chart/ring-chart.component.ts +++ b/src/frontend/packages/core/src/shared/components/ring-chart/ring-chart.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, Input, OnChanges, OnInit, ViewEncapsulation } from '@angular/core'; import { ColorHelper } from '@swimlane/ngx-charts'; @Component({ @@ -7,7 +7,7 @@ import { ColorHelper } from '@swimlane/ngx-charts'; styleUrls: ['./ring-chart.component.scss'], encapsulation: ViewEncapsulation.None, }) -export class RingChartComponent implements OnInit { +export class RingChartComponent implements OnInit, OnChanges { domain: any[]; colors: ColorHelper; @@ -24,17 +24,26 @@ export class RingChartComponent implements OnInit { @Input() nameFormatting: (value: string) => any = label => label; @Input() percentageFormatting: (value: number) => any = percentage => percentage; - constructor() { } - ngOnInit() { if (!this.data) { this.data = []; } + } + + ngOnChanges() { + this.update(); + } + + update() { this.domain = this.getDomain(); this.setColors(); } setColors(): void { + if (!this.domain) { + // Not set yet, can't set colour without it + return; + } this.colors = new ColorHelper(this.scheme, 'ordinal', this.domain, this.customColors || []); } diff --git a/src/frontend/packages/store/src/base-entity-types.ts b/src/frontend/packages/store/src/base-entity-types.ts index e9cf682103..905cdf96bd 100644 --- a/src/frontend/packages/store/src/base-entity-types.ts +++ b/src/frontend/packages/store/src/base-entity-types.ts @@ -41,10 +41,10 @@ class DefaultEndpointCatalogEntity extends StratosCatalogEntity { type: endpointEntitySchema.entityType, endpoint: stratosType, }, { - dataReducers: [ - systemEndpointsReducer - ] - }); + dataReducers: [ + systemEndpointsReducer + ] + }); } } @@ -55,11 +55,11 @@ class UserFavoriteCatalogEntity extends StratosCatalogEntity { type: userFavoritesEntitySchema.entityType, endpoint: stratosType, }, { - dataReducers: [ - addOrUpdateUserFavoriteMetadataReducer, - deleteUserFavoriteMetadataReducer, - ] - }); + dataReducers: [ + addOrUpdateUserFavoriteMetadataReducer, + deleteUserFavoriteMetadataReducer, + ] + }); } } diff --git a/src/frontend/packages/store/src/effects/metrics.effects.ts b/src/frontend/packages/store/src/effects/metrics.effects.ts index ca3d6932f0..098b0f174c 100644 --- a/src/frontend/packages/store/src/effects/metrics.effects.ts +++ b/src/frontend/packages/store/src/effects/metrics.effects.ts @@ -60,11 +60,11 @@ export class MetricsEffect { errObservable.message, action, 'fetch', { - endpointIds: [action.endpointGuid], - url: errObservable.url || fullUrl, - eventCode: errObservable.status ? errObservable.status + '' : '500', - message: 'Metric request error', - } + endpointIds: [action.endpointGuid], + url: errObservable.url || fullUrl, + eventCode: errObservable.status ? errObservable.status + '' : '500', + message: 'Metric request error', + } ) ]; })); diff --git a/src/frontend/packages/store/src/types/request.types.ts b/src/frontend/packages/store/src/types/request.types.ts index 1e14568f76..e1b855210c 100644 --- a/src/frontend/packages/store/src/types/request.types.ts +++ b/src/frontend/packages/store/src/types/request.types.ts @@ -1,9 +1,9 @@ import { HttpRequest } from '@angular/common/http'; import { Action } from '@ngrx/store'; +import { ApiActionTypes, RequestTypes } from '../actions/request.actions'; import { BasePipelineRequestAction } from '../entity-catalog/action-orchestrator/action-orchestrator'; import { EntityCatalogEntityConfig } from '../entity-catalog/entity-catalog.types'; -import { ApiActionTypes, RequestTypes } from '../actions/request.actions'; import { EntitySchema } from '../helpers/entity-schema'; import { ApiRequestTypes } from '../reducers/api-request-reducer/request-helpers'; import { NormalizedResponse } from './api.types'; diff --git a/src/test-e2e/application/application-view-e2e.spec.ts b/src/test-e2e/application/application-view-e2e.spec.ts index 8c78955f9c..48244d2916 100644 --- a/src/test-e2e/application/application-view-e2e.spec.ts +++ b/src/test-e2e/application/application-view-e2e.spec.ts @@ -242,14 +242,16 @@ describe('Application View -', () => { const envVarValue = 'new env var value'; appVariables.addVariable(envVarName, envVarValue); + appVariables.list.table.waitUntilNotBusy(); + expect(appVariables.list.table.getRows().count()).toBe(1); - expect(appVariables.list.table.getCell(0, 1).getText()).toBe(envVarName); - expect(appVariables.list.table.getCell(0, 2).getText()).toBe(envVarValue); + appVariables.list.table.waitForCellText(0, 1, envVarName); + appVariables.list.table.waitForCellText(0, 2, envVarValue); // Edit Env Var const envVarValueEdited = `${envVarValue}-edited`; appVariables.editVariable(0, envVarValueEdited); - expect(appVariables.list.table.getCell(0, 2).getText()).toBe(envVarValueEdited); + appVariables.list.table.waitForCellText(0, 2, envVarValueEdited); // Delete Env Var appVariables.deleteVariable(0, envVarName); diff --git a/src/test-e2e/cloud-foundry/cloud-foundry-list-cf-e2e.spec.ts b/src/test-e2e/cloud-foundry/cloud-foundry-list-cf-e2e.spec.ts index a981256978..83b73b37ca 100644 --- a/src/test-e2e/cloud-foundry/cloud-foundry-list-cf-e2e.spec.ts +++ b/src/test-e2e/cloud-foundry/cloud-foundry-list-cf-e2e.spec.ts @@ -1,4 +1,5 @@ -import { e2e } from '../e2e'; +import { CF_ENDPOINT_TYPE } from '../../frontend/packages/cloud-foundry/src/cf-types'; +import { E2E, e2e } from '../e2e'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { ListComponent } from '../po/list.po'; import { SideNavigation, SideNavMenuItem } from '../po/side-nav.po'; @@ -15,18 +16,24 @@ describe('CF Endpoints Dashboard - ', () => { .clearAllEndpoints(); }); - beforeEach(() => { - nav.goto(SideNavMenuItem.CloudFoundry); - cloudFoundry.loadingIndicator.waitUntilNotShown(); - }); + if (!E2E.customization.alwaysShowNavForEndpointTypes || E2E.customization.alwaysShowNavForEndpointTypes(CF_ENDPOINT_TYPE)) { + beforeEach(() => { + nav.goto(SideNavMenuItem.CloudFoundry); + cloudFoundry.loadingIndicator.waitUntilNotShown(); + }); - it('should be the Endpoints page', () => { - expect(cloudFoundry.isActivePage()).toBeTruthy(); - }); + it('should be the Endpoints page', () => { + expect(cloudFoundry.isActivePage()).toBeTruthy(); + }); - it('should show the `no registered endpoints` message', () => { - expect(cloudFoundry.hasNoCloudFoundryMessage).toBeTruthy(); - }); + it('should show the `no registered endpoints` message', () => { + expect(cloudFoundry.hasNoCloudFoundryMessage).toBeTruthy(); + }); + } else { + it('No CF side nav when no CF connected', () => { + expect(nav.isMenuItemPresent(SideNavMenuItem.CloudFoundry)).toBeFalsy(); + }); + } }); describe('Single endpoint - ', () => { diff --git a/src/test-e2e/e2e.ts b/src/test-e2e/e2e.ts index 49318abf03..a4215aaa53 100644 --- a/src/test-e2e/e2e.ts +++ b/src/test-e2e/e2e.ts @@ -1,5 +1,6 @@ import { browser, promise, protractor } from 'protractor'; +import { CustomizationsMetadata } from '../frontend/packages/core/src/core/customizations.types'; import { ConsoleUserType, E2EHelpers } from './helpers/e2e-helpers'; import { RequestHelpers } from './helpers/request-helpers'; import { ResetsHelpers } from './helpers/reset-helpers'; @@ -15,6 +16,13 @@ export class E2E { // Turn on debug logging for test helpers public static DEBUG_LOGGING = !!process.env.STRATOS_E2E_DEBUG || false; + /** + * Temporary location for customization, we should in future look to fetch this a better way from client side code + */ + public static customization: CustomizationsMetadata = { + alwaysShowNavForEndpointTypes: (epType) => true + } + // General helpers public helper = new E2EHelpers(); diff --git a/src/test-e2e/endpoints/endpoints-e2e.spec.ts b/src/test-e2e/endpoints/endpoints-e2e.spec.ts index 72e9737ec2..c954a5869a 100644 --- a/src/test-e2e/endpoints/endpoints-e2e.spec.ts +++ b/src/test-e2e/endpoints/endpoints-e2e.spec.ts @@ -1,8 +1,9 @@ import { browser } from 'protractor'; +import { CF_ENDPOINT_TYPE } from '../../frontend/packages/cloud-foundry/src/cf-types'; import { ApplicationsPage } from '../applications/applications.po'; import { CfTopLevelPage } from '../cloud-foundry/cf-level/cf-top-level-page.po'; -import { e2e } from '../e2e'; +import { E2E, e2e } from '../e2e'; import { ConsoleUserType } from '../helpers/e2e-helpers'; import { MenuComponent } from '../po/menu.po'; import { SideNavMenuItem } from '../po/side-nav.po'; @@ -67,21 +68,26 @@ describe('Endpoints', () => { expect(endpointsPage.isActivePage()).toBeTruthy(); }); - it('Should show application wall with \'no clusters\' message', () => { - endpointsPage.sideNav.goto(SideNavMenuItem.Applications); - expect(applications.hasNoCloudFoundryMessage()).toBeTruthy(); - }); - - it('Should show services view with \'no clusters\' message', () => { - endpointsPage.sideNav.goto(SideNavMenuItem.Services); - expect(services.hasNoCloudFoundryMessage()).toBeTruthy(); - }); + if (!E2E.customization.alwaysShowNavForEndpointTypes || E2E.customization.alwaysShowNavForEndpointTypes(CF_ENDPOINT_TYPE)) { + it('Should show application wall with \'no clusters\' message', () => { + endpointsPage.sideNav.goto(SideNavMenuItem.Applications); + expect(applications.hasNoCloudFoundryMessage()).toBeTruthy(); + }); - it('Should show Cloud Foundry view with \'no clusters\' message', () => { - endpointsPage.sideNav.goto(SideNavMenuItem.CloudFoundry); - expect(cloudFoundry.hasNoCloudFoundryMessage()).toBeTruthy(); - }); + it('Should show services view with \'no clusters\' message', () => { + endpointsPage.sideNav.goto(SideNavMenuItem.Services); + expect(services.hasNoCloudFoundryMessage()).toBeTruthy(); + }); + it('Should show Cloud Foundry view with \'no clusters\' message', () => { + endpointsPage.sideNav.goto(SideNavMenuItem.CloudFoundry); + expect(cloudFoundry.hasNoCloudFoundryMessage()).toBeTruthy(); + }); + } else { + it('No CF side nav when no CF connected', () => { + expect(endpointsPage.sideNav.isMenuItemPresent(SideNavMenuItem.CloudFoundry)).toBeFalsy(); + }); + } }); }); diff --git a/src/test-e2e/helpers/cf-e2e-helpers.ts b/src/test-e2e/helpers/cf-e2e-helpers.ts index defc5602f9..a18d65e8d0 100644 --- a/src/test-e2e/helpers/cf-e2e-helpers.ts +++ b/src/test-e2e/helpers/cf-e2e-helpers.ts @@ -50,6 +50,8 @@ export class CFHelpers { return promise.fullyResolved({}); } return this.fetchUsers(cnsiGuid).then(users => { + expect(users).toBeDefined(`No users fetched from endpoint with api ${endpoint.url}`); + expect(users.length).toBeGreaterThanOrEqual(2, `Less than two users detected`); const testUser = this.findUser(users, endpoint.creds.nonAdmin.username); const testAdminUser = this.findUser(users, endpoint.creds.admin.username); expect(testUser).toBeDefined('Could not find test user'); diff --git a/src/test-e2e/po/component.po.ts b/src/test-e2e/po/component.po.ts index acdd84ebe6..fac898cb23 100644 --- a/src/test-e2e/po/component.po.ts +++ b/src/test-e2e/po/component.po.ts @@ -54,6 +54,11 @@ export class Component { return browser.wait(until.invisibilityOf(this.locator), 20000, description); } + waitForText(text: string, elementDescription = 'Element', waitDuration = 5000) { + return browser.wait(until.textToBePresentInElement(this.getComponent(), text), waitDuration, + `${elementDescription} with text '${text}' taking too long to appear in the DOM`); + } + scrollIntoView(): promise.Promise { return Component.scrollIntoView(this.locator); } diff --git a/src/test-e2e/po/list.po.ts b/src/test-e2e/po/list.po.ts index c5811e91cd..4b1d2a9e43 100644 --- a/src/test-e2e/po/list.po.ts +++ b/src/test-e2e/po/list.po.ts @@ -33,6 +33,11 @@ export class ListTableComponent extends Component { return this.getRows().get(row).all(by.css('.app-table__cell')).get(column); } + waitForCellText(row: number, column: number, text: string) { + const component = new Component(this.getCell(row, column)); + return component.waitForText(text); + } + findRowByCellContent(content) { const cell = this.locator.all(by.css('.app-table__cell')).filter(elem => elem.getText().then(text => text === content) diff --git a/src/tsconfig.spec.json b/src/tsconfig.spec.json index b757b63ed4..4b6895009b 100644 --- a/src/tsconfig.spec.json +++ b/src/tsconfig.spec.json @@ -8,4 +8,4 @@ "node" ] }, -} \ No newline at end of file +} From acb1cbe6790255d3823ccdfa97f88043e52a5535 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Tue, 23 Jun 2020 11:13:54 +0100 Subject: [PATCH 82/82] Address PR feedback --- .../cloud-foundry/src/cf-error-helpers.ts | 3 +-- .../backup-endpoints.component.ts | 2 +- .../restore-endpoints.component.ts | 2 +- .../packages/core/src/jetstream.helpers.ts | 24 ------------------- src/frontend/packages/store/src/jetstream.ts | 24 +++++++++++++++++++ 5 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts b/src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts index 81e86196ad..da3efe70ec 100644 --- a/src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts +++ b/src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts @@ -1,5 +1,4 @@ -import { jetStreamErrorResponseToSafeString } from '../../core/src/jetstream.helpers'; -import { JetStreamErrorResponse } from '../../store/src/jetstream'; +import { JetStreamErrorResponse, jetStreamErrorResponseToSafeString } from '../../store/src/jetstream'; export interface CfErrorObject { code: number; diff --git a/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints/backup-endpoints.component.ts b/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints/backup-endpoints.component.ts index 3ad6856b48..f1a2a345da 100644 --- a/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints/backup-endpoints.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/backup-restore/backup-endpoints/backup-endpoints.component.ts @@ -8,10 +8,10 @@ import { filter, first, map } from 'rxjs/operators'; import { GetAllEndpoints } from '../../../../../../store/src/actions/endpoint.actions'; import { AppState } from '../../../../../../store/src/app-state'; import { entityCatalog } from '../../../../../../store/src/entity-catalog/entity-catalog'; +import { httpErrorResponseToSafeString } from '../../../../../../store/src/jetstream'; import { PaginationMonitorFactory } from '../../../../../../store/src/monitors/pagination-monitor.factory'; import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; import { EndpointModel } from '../../../../../../store/src/types/endpoint.types'; -import { httpErrorResponseToSafeString } from '../../../../jetstream.helpers'; import { ConfirmationDialogConfig } from '../../../../shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../shared/components/confirmation-dialog.service'; import { ITableListDataSource } from '../../../../shared/components/list/data-sources-controllers/list-data-source-types'; diff --git a/src/frontend/packages/core/src/features/endpoints/backup-restore/restore-endpoints/restore-endpoints.component.ts b/src/frontend/packages/core/src/features/endpoints/backup-restore/restore-endpoints/restore-endpoints.component.ts index c3483dca50..72e4f53b1d 100644 --- a/src/frontend/packages/core/src/features/endpoints/backup-restore/restore-endpoints/restore-endpoints.component.ts +++ b/src/frontend/packages/core/src/features/endpoints/backup-restore/restore-endpoints/restore-endpoints.component.ts @@ -7,8 +7,8 @@ import { first, map } from 'rxjs/operators'; import { GetAllEndpoints } from '../../../../../../store/src/actions/endpoint.actions'; import { GeneralEntityAppState } from '../../../../../../store/src/app-state'; +import { httpErrorResponseToSafeString } from '../../../../../../store/src/jetstream'; import { getEventFiles } from '../../../../core/browser-helper'; -import { httpErrorResponseToSafeString } from '../../../../jetstream.helpers'; import { ConfirmationDialogConfig } from '../../../../shared/components/confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../../shared/components/confirmation-dialog.service'; import { StepOnNextFunction, StepOnNextResult } from '../../../../shared/components/stepper/step/step.component'; diff --git a/src/frontend/packages/core/src/jetstream.helpers.ts b/src/frontend/packages/core/src/jetstream.helpers.ts index e6f191b74f..7de9c29e1e 100644 --- a/src/frontend/packages/core/src/jetstream.helpers.ts +++ b/src/frontend/packages/core/src/jetstream.helpers.ts @@ -2,27 +2,3 @@ import { HttpErrorResponse } from '@angular/common/http'; import { isHttpErrorResponse, JetStreamErrorResponse } from '../../store/src/jetstream'; - -export function jetStreamErrorResponseToSafeString(response: JetStreamErrorResponse): string { - return response.error && response.error.status && response.error.statusCode ? - `${response.error.status}. Status Code ${response.error.statusCode}` : - null; -} - -/** - * Attempt to create a sensible string explaining the error object returned from a failed http request - * @param err The raw error from a http request - */ -export function httpErrorResponseToSafeString(err: any): string { - const httpResponse: HttpErrorResponse = isHttpErrorResponse(err); - if (httpResponse) { - if (httpResponse.error) { - if (typeof (httpResponse.error) === 'string') { - return httpResponse.error + ` (${httpResponse.status})`; - } - return httpResponse.error.error + ` (${httpResponse.status})`; - } - return JSON.stringify(httpResponse.error) + ` (${httpResponse.status})`; - } - return err.message; -} diff --git a/src/frontend/packages/store/src/jetstream.ts b/src/frontend/packages/store/src/jetstream.ts index c41746d425..12477fabba 100644 --- a/src/frontend/packages/store/src/jetstream.ts +++ b/src/frontend/packages/store/src/jetstream.ts @@ -32,6 +32,30 @@ export function isHttpErrorResponse(obj: any): HttpErrorResponse { ) ? obj as HttpErrorResponse : null; } +export function jetStreamErrorResponseToSafeString(response: JetStreamErrorResponse): string { + return response.error && response.error.status && response.error.statusCode ? + `${response.error.status}. Status Code ${response.error.statusCode}` : + null; +} + +/** + * Attempt to create a sensible string explaining the error object returned from a failed http request + * @param err The raw error from a http request + */ +export function httpErrorResponseToSafeString(err: any): string { + const httpResponse: HttpErrorResponse = isHttpErrorResponse(err); + if (httpResponse) { + if (httpResponse.error) { + if (typeof (httpResponse.error) === 'string') { + return httpResponse.error + ` (${httpResponse.status})`; + } + return httpResponse.error.error + ` (${httpResponse.status})`; + } + return JSON.stringify(httpResponse.error) + ` (${httpResponse.status})`; + } + return err.message; +} + // TODO It would be nice if the BE could return a unique para for us to check for. #3827 // There is always a chance that this will return a false positive (more so with extensions). export function hasJetStreamError(pages: Partial[]): JetStreamErrorResponse {