diff --git a/angular.json b/angular.json index e25bd66899..4375210ea4 100644 --- a/angular.json +++ b/angular.json @@ -80,14 +80,6 @@ "protractorConfig": "./protractor.conf.js", "devServerTarget": "stratos:serve" } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "src/test-e2e/tsconfig.e2e.json" - ] - } } } }, @@ -175,7 +167,8 @@ "tsConfig": ["src/tsconfig.json"], "tslintConfig": "src/frontend/packages/core/tslint.json", "files": [ - "src/frontend/packages/core/src/**/*.ts" + "src/frontend/packages/core/src/**/*.ts", + "src/frontend/packages/core/src/custom/**/*.ts" ] } } diff --git a/build/karma.conf.creator.js b/build/karma.conf.creator.js index 6e0018855f..9375ca788e 100644 --- a/build/karma.conf.creator.js +++ b/build/karma.conf.creator.js @@ -43,13 +43,8 @@ module.exports = function (project) { }, singleRun: process.env.CI_ENV ? true : false, files: [{ - pattern: './src/**/*.spec.ts', - watched: false - }, - { - pattern: path.join(repoRoot, 'node_modules/@angular/material/prebuilt-themes/indigo-pink.css') - } - ], + pattern: path.join(repoRoot, 'node_modules/@angular/material/prebuilt-themes/indigo-pink.css') + }], exclude: [ '**/*-e2e.spec.ts' ] diff --git a/custom-src/frontend/app/custom/kubernetes/helm-release/helm-release-summary/helm-release-summary-card/helm-release-summary-card.component.ts b/custom-src/frontend/app/custom/kubernetes/helm-release/helm-release-summary/helm-release-summary-card/helm-release-summary-card.component.ts index 839e7d6512..bf5d72c0f5 100644 --- a/custom-src/frontend/app/custom/kubernetes/helm-release/helm-release-summary/helm-release-summary-card/helm-release-summary-card.component.ts +++ b/custom-src/frontend/app/custom/kubernetes/helm-release/helm-release-summary/helm-release-summary-card/helm-release-summary-card.component.ts @@ -1,9 +1,9 @@ -import { Component, OnInit } from '@angular/core'; -import { HelmReleaseService } from '../../../services/helm-release.service'; +import { Component } from '@angular/core'; import { combineLatest, Observable } from 'rxjs'; -import { deepStrictEqual } from 'assert'; import { map } from 'rxjs/operators'; +import { HelmReleaseService } from '../../../services/helm-release.service'; + @Component({ selector: 'app-helm-release-summary-card', templateUrl: './helm-release-summary-card.component.html', @@ -19,12 +19,12 @@ export class HelmReleaseSummaryCardComponent { this.chartName$ = combineLatest(this.helmReleaseService.deployments$, this.helmReleaseService.statefulSets$).pipe( map(([deployments, statefulsets]) => { if (deployments.length !== 0) { - return deployments[0].metadata.labels['chart']; + return deployments[0].metadata.labels.chart; } if (statefulsets.length !== 0) { - return statefulsets[0].metadata.labels['chart']; + return statefulsets[0].metadata.labels.chart; } }) ); - } + } } diff --git a/custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-endpoints/kubernetes-endpoints-list-config.service.ts b/custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-endpoints/kubernetes-endpoints-list-config.service.ts index 54a167f4a6..759c3cac8e 100644 --- a/custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-endpoints/kubernetes-endpoints-list-config.service.ts +++ b/custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-endpoints/kubernetes-endpoints-list-config.service.ts @@ -1,15 +1,17 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; +import { AppState } from '../../../../../../store/src/app-state'; +import { EndpointModel } from '../../../../../../store/src/types/endpoint.types'; import { ITableColumn } from '../../../../shared/components/list/list-table/table.types'; +import { + BaseEndpointsDataSource, +} from '../../../../shared/components/list/list-types/cf-endpoints/base-endpoints-data-source'; import { EndpointCardComponent, -} from '../../../../shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component'; +} from '../../../../shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component'; import { endpointColumns } from '../../../../shared/components/list/list-types/endpoint/endpoints-list-config.service'; import { IListConfig, ListViewTypes } from '../../../../shared/components/list/list.component.types'; -import { AppState } from '../../../../../../store/src/app-state'; -import { EndpointModel } from '../../../../../../store/src/types/endpoint.types'; -import { BaseEndpointsDataSource } from '../../../../shared/components/list/list-types/cf-endpoints/base-endpoints-data-source'; @Injectable() export class KubernetesEndpointsListConfigService implements IListConfig { diff --git a/custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-nodes/kubernetes-node-summary/kubernetes-node-condition-card/kubernetes-node-condition/kubernetes-node-condition.component.ts b/custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-nodes/kubernetes-node-summary/kubernetes-node-condition-card/kubernetes-node-condition/kubernetes-node-condition.component.ts index 25aee1fb36..42a5df256f 100644 --- a/custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-nodes/kubernetes-node-summary/kubernetes-node-condition-card/kubernetes-node-condition/kubernetes-node-condition.component.ts +++ b/custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-nodes/kubernetes-node-summary/kubernetes-node-condition-card/kubernetes-node-condition/kubernetes-node-condition.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit, Input } from '@angular/core'; -import { ConditionType, Condition } from '../../../../../store/kube.types'; -import { KubernetesNodeService } from '../../../../../services/kubernetes-node.service'; -import { map, filter } from 'rxjs/operators'; +import { Component, Input, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; +import { filter, map } from 'rxjs/operators'; + +import { KubernetesNodeService } from '../../../../../services/kubernetes-node.service'; +import { Condition, ConditionType } from '../../../../../store/kube.types'; @Component({ selector: 'app-kubernetes-node-condition', @@ -20,17 +21,17 @@ export class KubernetesNodeConditionComponent implements OnInit { inverse = false; public titles = { - 'Ready': 'Ready', - 'OutOfDisk': 'Out of Disk', - 'MemoryPressure': 'Memory Pressure', - 'DiskPressure': 'Disk Pressure' + Ready: 'Ready', + OutOfDisk: 'Out of Disk', + MemoryPressure: 'Memory Pressure', + DiskPressure: 'Disk Pressure' }; public icons = { - 'Ready': ['done_outline', 'material-icons'], - 'OutOfDisk': ['storage', 'material-icons'], - 'MemoryPressure': ['memory', 'material-icons'], - 'DiskPressure': ['storage', 'material-icons'], + Ready: ['done_outline', 'material-icons'], + OutOfDisk: ['storage', 'material-icons'], + MemoryPressure: ['memory', 'material-icons'], + DiskPressure: ['storage', 'material-icons'], }; constructor( diff --git a/custom-src/frontend/app/custom/kubernetes/pod-metrics/pod-metrics.component.ts b/custom-src/frontend/app/custom/kubernetes/pod-metrics/pod-metrics.component.ts index 867fd53e9f..7712fb4e15 100644 --- a/custom-src/frontend/app/custom/kubernetes/pod-metrics/pod-metrics.component.ts +++ b/custom-src/frontend/app/custom/kubernetes/pod-metrics/pod-metrics.component.ts @@ -5,6 +5,11 @@ import * as moment from 'moment'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { AppState } from '../../../../../store/src/app-state'; +import { entityFactory } from '../../../../../store/src/helpers/entity-factory'; +import { EntityInfo } from '../../../../../store/src/types/api.types'; +import { ChartSeries, IMetricMatrixResult } from '../../../../../store/src/types/base-metric.types'; +import { IMetricApplication } from '../../../../../store/src/types/metric.types'; import { EntityServiceFactory } from '../../../core/entity-service-factory.service'; import { getIdFromRoute } from '../../../features/cloud-foundry/cf.helpers'; import { MetricsConfig } from '../../../shared/components/metrics-chart/metrics-chart.component'; @@ -14,11 +19,6 @@ import { getMetricsChartConfigBuilder, } from '../../../shared/components/metrics-chart/metrics.component.helpers'; import { IHeaderBreadcrumb } from '../../../shared/components/page-header/page-header.types'; -import { AppState } from '../../../../../store/src/app-state'; -import { entityFactory } from '../../../../../store/src/helpers/entity-factory'; -import { EntityInfo } from '../../../../../store/src/types/api.types'; -import { ChartSeries, IMetricMatrixResult } from '../../../../../store/src/types/base-metric.types'; -import { IMetricApplication } from '../../../../../store/src/types/metric.types'; import { BaseKubeGuid } from '../kubernetes-page.types'; import { HelmReleaseService } from '../services/helm-release.service'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; @@ -66,12 +66,12 @@ export class PodMetricsComponent { public entityServiceFactory: EntityServiceFactory, public kubeEndpointService: KubernetesEndpointService ) { - this.podName = activatedRoute.snapshot.params['podName']; + this.podName = activatedRoute.snapshot.params.podName; this.namespaceName = getIdFromRoute(activatedRoute, 'namespaceName'); const namespace = getIdFromRoute(activatedRoute, 'namespace') ? getIdFromRoute(activatedRoute, 'namespace') : this.namespaceName; const chartConfigBuilder = getMetricsChartConfigBuilder(result => `${result.metric.container_name}`); const cpuChartConfigBuilder = getMetricsChartConfigBuilder - (result => !!result.metric.cpu ? `${result.metric.container_name}:${result.metric.cpu}` : `${result.metric.container_name}`); + (result => !!result.metric.cpu ? `${result.metric.container_name}:${result.metric.cpu}` : `${result.metric.container_name}`); const networkChartConfigBuilder = getMetricsChartConfigBuilder (result => `Network Interface: ${result.metric.interface}`); this.instanceMetricConfigs = [ diff --git a/custom-src/frontend/app/custom/kubernetes/services/helm-release.service.ts b/custom-src/frontend/app/custom/kubernetes/services/helm-release.service.ts index eb09495561..a40b7a9944 100644 --- a/custom-src/frontend/app/custom/kubernetes/services/helm-release.service.ts +++ b/custom-src/frontend/app/custom/kubernetes/services/helm-release.service.ts @@ -4,15 +4,15 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable } from 'rxjs'; import { filter, first, map, share } from 'rxjs/operators'; -import { getIdFromRoute } from '../../../features/cloud-foundry/cf.helpers'; -import { PaginationMonitorFactory } from '../../../shared/monitors/pagination-monitor.factory'; import { AppState } from '../../../../../store/src/app-state'; import { entityFactory } from '../../../../../store/src/helpers/entity-factory'; import { getPaginationObservables } from '../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { getIdFromRoute } from '../../../features/cloud-foundry/cf.helpers'; +import { PaginationMonitorFactory } from '../../../shared/monitors/pagination-monitor.factory'; import { KubernetesApp, KubernetesDeployment, KubernetesPod, KubernetesStatefulSet, KubeService } from '../store/kube.types'; import { GetKubernetesApps, GetKubernetesServices } from '../store/kubernetes.actions'; -import { KubernetesEndpointService } from './kubernetes-endpoint.service'; import { kubernetesAppsSchemaKey, kubernetesServicesSchemaKey } from '../store/kubernetes.entities'; +import { KubernetesEndpointService } from './kubernetes-endpoint.service'; @Injectable() export class HelmReleaseService { @@ -37,7 +37,7 @@ export class HelmReleaseService { this.helmRelease$ = getPaginationObservables({ store: this.store, - action: action, + action, paginationMonitor: this.paginationMonitorFactory.create( action.paginationKey, entityFactory(kubernetesAppsSchemaKey) @@ -71,7 +71,7 @@ export class HelmReleaseService { filter(p => !!p), map(p => { return p.filter(r => { - return r.metadata.labels['release'] === this.helmReleaseName; + return r.metadata.labels.release === this.helmReleaseName; }); }), diff --git a/custom-src/frontend/app/custom/kubernetes/store/kubernetes.effects.ts b/custom-src/frontend/app/custom/kubernetes/store/kubernetes.effects.ts index 5ebdeac665..e443041dee 100644 --- a/custom-src/frontend/app/custom/kubernetes/store/kubernetes.effects.ts +++ b/custom-src/frontend/app/custom/kubernetes/store/kubernetes.effects.ts @@ -1,19 +1,9 @@ -import { - kubernetesNodesSchemaKey, - kubernetesNamespacesSchemaKey, - kubernetesPodsSchemaKey, - kubernetesServicesSchemaKey, - kubernetesDeploymentsSchemaKey, - kubernetesStatefulSetsSchemaKey, - kubernetesAppsSchemaKey -} from './kubernetes.entities'; import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; -import { catchError, flatMap, mergeMap, combineLatest } from 'rxjs/operators'; +import { catchError, combineLatest, flatMap, mergeMap } from 'rxjs/operators'; -import { environment } from '../../../environments/environment'; import { AppState } from '../../../../../store/src/app-state'; import { NormalizedResponse } from '../../../../../store/src/types/api.types'; import { @@ -21,7 +11,9 @@ import { WrapperRequestActionFailed, WrapperRequestActionSuccess, } from '../../../../../store/src/types/request.types'; +import { environment } from '../../../environments/environment'; import { + ConfigMap, KubernetesConfigMap, KubernetesDeployment, KubernetesNamespace, @@ -29,7 +21,6 @@ import { KubernetesPod, KubernetesStatefulSet, KubeService, - ConfigMap, } from './kube.types'; import { GeKubernetesDeployments, @@ -37,30 +28,39 @@ import { GET_KUBE_POD, GET_KUBE_STATEFULSETS, GET_KUBERNETES_APP_INFO, + GET_NAMESPACE_INFO, GET_NAMESPACES_INFO, GET_NODE_INFO, + GET_NODES_INFO, GET_POD_INFO, + GET_PODS_IN_NAMESPACE_INFO, + GET_PODS_ON_NODE_INFO, + GET_RELEASE_POD_INFO, GET_SERVICE_INFO, GetKubernetesApps, + GetKubernetesNamespace, GetKubernetesNamespaces, + GetKubernetesNode, GetKubernetesNodes, GetKubernetesPod, GetKubernetesPods, + GetKubernetesPodsInNamespace, + GetKubernetesPodsOnNode, + GetKubernetesReleasePods, GetKubernetesServices, GetKubernetesStatefulSets, KubeAction, - GET_NODES_INFO, - GetKubernetesNode, - GetKubernetesPodsOnNode, - GET_PODS_ON_NODE_INFO, KubePaginationAction, - GetKubernetesReleasePods, - GET_RELEASE_POD_INFO, - GetKubernetesNamespace, - GET_NAMESPACE_INFO, - GetKubernetesPodsInNamespace, - GET_PODS_IN_NAMESPACE_INFO, } from './kubernetes.actions'; +import { + kubernetesAppsSchemaKey, + kubernetesDeploymentsSchemaKey, + kubernetesNamespacesSchemaKey, + kubernetesNodesSchemaKey, + kubernetesPodsSchemaKey, + kubernetesServicesSchemaKey, + kubernetesStatefulSetsSchemaKey, +} from './kubernetes.entities'; export type GetID = (p: T) => string; export type Filter = (p: T) => boolean; @@ -75,7 +75,8 @@ export class KubernetesEffects { ) { } @Effect() - fetchReleasePodsInfo$ = this.actions$.ofType(GET_RELEASE_POD_INFO).pipe( + fetchReleasePodsInfo$ = this.actions$.pipe( + ofType(GET_RELEASE_POD_INFO), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction( @@ -88,14 +89,16 @@ export class KubernetesEffects { ); @Effect() - fetchNodesInfo$ = this.actions$.ofType(GET_NODES_INFO).pipe( + fetchNodesInfo$ = this.actions$.pipe( + ofType(GET_NODES_INFO), flatMap(action => { return this.processNodeAction(action); }) ); @Effect() - fetchNodeInfo$ = this.actions$.ofType(GET_NODE_INFO).pipe( + fetchNodeInfo$ = this.actions$.pipe( + ofType(GET_NODE_INFO), flatMap(action => { const getUid: GetID = (p) => p.metadata.name; return this.processSingleItemAction(action, @@ -106,7 +109,8 @@ export class KubernetesEffects { ); @Effect() - fetchNamespaceInfo$ = this.actions$.ofType(GET_NAMESPACE_INFO).pipe( + fetchNamespaceInfo$ = this.actions$.pipe( + ofType(GET_NAMESPACE_INFO), flatMap(action => { const getUid: GetID = (p) => p.metadata.name; return this.processSingleItemAction(action, @@ -117,7 +121,8 @@ export class KubernetesEffects { ); @Effect() - fetchPodsInfo$ = this.actions$.ofType(GET_POD_INFO).pipe( + fetchPodsInfo$ = this.actions$.pipe( + ofType(GET_POD_INFO), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction(action, @@ -128,7 +133,8 @@ export class KubernetesEffects { ); @Effect() - fetchPodsOnNodeInfo$ = this.actions$.ofType(GET_PODS_ON_NODE_INFO).pipe( + fetchPodsOnNodeInfo$ = this.actions$.pipe( + ofType(GET_PODS_ON_NODE_INFO), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction(action, @@ -140,7 +146,8 @@ export class KubernetesEffects { ); @Effect() - fetchPodsInNamespaceInfo$ = this.actions$.ofType(GET_PODS_IN_NAMESPACE_INFO).pipe( + fetchPodsInNamespaceInfo$ = this.actions$.pipe( + ofType(GET_PODS_IN_NAMESPACE_INFO), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction(action, @@ -152,7 +159,8 @@ export class KubernetesEffects { ); @Effect() - fetchPodInfo$ = this.actions$.ofType(GET_KUBE_POD).pipe( + fetchPodInfo$ = this.actions$.pipe( + ofType(GET_KUBE_POD), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction(action, @@ -163,7 +171,8 @@ export class KubernetesEffects { ); @Effect() - fetchServicesInfo$ = this.actions$.ofType(GET_SERVICE_INFO).pipe( + fetchServicesInfo$ = this.actions$.pipe( + ofType(GET_SERVICE_INFO), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction(action, @@ -174,7 +183,8 @@ export class KubernetesEffects { ); @Effect() - fetchNamespacesInfo$ = this.actions$.ofType(GET_NAMESPACES_INFO).pipe( + fetchNamespacesInfo$ = this.actions$.pipe( + ofType(GET_NAMESPACES_INFO), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction(action, @@ -185,7 +195,8 @@ export class KubernetesEffects { ); @Effect() - fetchStatefulSets$ = this.actions$.ofType(GET_KUBE_STATEFULSETS).pipe( + fetchStatefulSets$ = this.actions$.pipe( + ofType(GET_KUBE_STATEFULSETS), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction(action, @@ -196,7 +207,8 @@ export class KubernetesEffects { ); @Effect() - fetchDeployments$ = this.actions$.ofType(GET_KUBE_DEPLOYMENT).pipe( + fetchDeployments$ = this.actions$.pipe( + ofType(GET_KUBE_DEPLOYMENT), flatMap(action => { const getUid: GetID = (p) => p.metadata.uid; return this.processListAction(action, @@ -207,12 +219,13 @@ export class KubernetesEffects { ); @Effect() - fetchKubernetesAppsInfo$ = this.actions$.ofType(GET_KUBERNETES_APP_INFO).pipe( + fetchKubernetesAppsInfo$ = this.actions$.pipe( + ofType(GET_KUBERNETES_APP_INFO), flatMap(action => { this.store.dispatch(new StartRequestAction(action)); const headers = new HttpHeaders({ 'x-cap-cnsi-list': action.kubeGuid }); const requestArgs = { - headers: headers + headers }; return this.http .get(`/pp/${this.proxyAPIVersion}/proxy/api/v1/configmaps`, requestArgs) @@ -221,10 +234,10 @@ export class KubernetesEffects { this.http.get(`/pp/${this.proxyAPIVersion}/proxy/apis/apps/v1/deployments`, requestArgs), this.http.get(`/pp/${this.proxyAPIVersion}/proxy/apis/apps/v1/statefulsets`, requestArgs)), mergeMap(([configMapsResponse, deploymentsResponse, statefulesetResponse]) => { - const id = action.kubeGuid; - const items = configMapsResponse[id].items as Array; - const deployments = deploymentsResponse[id].items as Array; - const statefulSets = statefulesetResponse[id].items as Array; + const { kubeGuid: kubeId } = action; + const items = configMapsResponse[kubeId].items as Array; + const deployments = deploymentsResponse[kubeId].items as Array; + const statefulSets = statefulesetResponse[kubeId].items as Array; const getChartName = (name: string, labelName: string): string => { const releaseDeployment = deployments.filter(d => d.metadata.labels['app.kubernetes.io/instance'] === name); @@ -244,7 +257,7 @@ export class KubernetesEffects { ) .map((configMap: KubernetesConfigMap) => ({ name: configMap.metadata.labels.NAME, - kubeId: action.kubeGuid, + kubeId, createdAt: configMap.metadata.creationTimestamp, status: configMap.metadata.labels.STATUS, version: configMap.metadata.labels.VERSION, @@ -252,10 +265,10 @@ export class KubernetesEffects { appVersion: getChartName(configMap.metadata.labels.NAME, 'app.kubernetes.io/version') }) ).reduce((res, app) => { - const _id = `${app.kubeId}-${app.name}`; - res.entities[kubernetesAppsSchemaKey][_id] = app; - if (res.result.indexOf(_id) === -1) { - res.result.push(_id); + const id = `${app.kubeId}-${app.name}`; + res.entities[kubernetesAppsSchemaKey][id] = app; + if (res.result.indexOf(id) === -1) { + res.result.push(id); } return res; }, { @@ -298,7 +311,7 @@ export class KubernetesEffects { this.store.dispatch(new StartRequestAction(action)); const headers = new HttpHeaders({ 'x-cap-cnsi-list': action.kubeGuid }); const requestArgs = { - headers: headers, + headers, params: null }; const paginationAction = action as KubePaginationAction; @@ -340,7 +353,7 @@ export class KubernetesEffects { this.store.dispatch(new StartRequestAction(action)); const headers = new HttpHeaders({ 'x-cap-cnsi-list': action.kubeGuid }); const requestArgs = { - headers: headers + headers }; return this.http .get(url, requestArgs) diff --git a/custom-src/frontend/app/custom/suse-login/suse-login.component.html b/custom-src/frontend/app/custom/suse-login/suse-login.component.html index b273fa740b..fd794c1b33 100644 --- a/custom-src/frontend/app/custom/suse-login/suse-login.component.html +++ b/custom-src/frontend/app/custom/suse-login/suse-login.component.html @@ -17,7 +17,8 @@

SUSE
Cloud Application
Platform

- @@ -25,7 +26,8 @@

SUSE
Cloud Application
Platform

- @@ -35,7 +37,7 @@

SUSE
Cloud Application
Platform

- + \ No newline at end of file diff --git a/docs/cf-api-v3.md b/docs/cf-api-v3.md index 33c50ae90a..d26cc0be98 100644 --- a/docs/cf-api-v3.md +++ b/docs/cf-api-v3.md @@ -80,8 +80,13 @@ Then Stratos should either .. - For instance new v3 entities are not `include`s (`/apps` - `package`, `processes`, `route_mappings`, `environment_variables`, `droplets`, `tasks`) - ~~Not supported by common CFs used to develop with (SCF, PCFDev)~~. - Entities do not contain all properties that were in v2 (where functionality has not changed) - - Covers simple values and entities (one to one and one to many) + - Covers simple values and entities (one to one and one to many) - For instance `/organizations` and `/spaces` endpoints are not completed and contain only guid, create/updated date and name (space additionally has experimental `organization`) +- Entities returned by v2/v3 endpoints are not consistent + - For example + - push an app with `v3-push` and it shows up in `v2/apps` + - `v3/service_bindings` does not return service bindings that aren't attached to a v3 app + - Without knowing exactly all these occurrences we won't be able to work in a mixed v2/v3 endpoint state - ~~Cannot determine if a CF supports v3 or when it does support v3 which endpoints it has~~ - v3 version and supported endpoints can be determined by response to `` and `/v3` - ~~Getting the v2 version is simple, I don't know if there's correlation to v3 version~~ @@ -126,15 +131,259 @@ Then Stratos should either .. ### Questions - ~~Will `include` cover children of children? For instance `app` --> `route` --> `domain`~~ - ~~How will lists be covered? For instance `organization` --> `space` --> `service instances`~~ -- How will the deprecation of v2 endpoints happen? +- How will the deprecation of v2 endpoints happen? - One by one? - All together once v2 parity is reached? - Will duplicated `include`ed entities only appear once in a top level (entity or pagination) `included`? For example..conceptually.. - Fetch an application, the application's space, the application's routes and application routes spaces all in a single request - - If the application's space appeared in the route's space, would it only appear once in the application's`included` section... or appear twice (once + - If the application's space appeared in the route's space, would it only appear once in the application's`included` section... or appear twice (once in application `included` and again in route `included`)? - The style guide references a way to fetch one to many relationships as `/v3/apps/:app_guid/relationships/routes` (https://github.com/cloudfoundry/cc-api-v3-style-guide#viewing-1) - This doesn't seem to work (404), is it yet to be implemented? - `/v3/apps/:app_guid/routes` also does not work (404) - `/v3/apps/:app_guid/route_mappings` works, but there doesn't seem to be a way to `include` the `route` such that it appears in the response - Which version is the `include=space,space.organization` notation supported in? + +## v3 Required `include`s, `order_by`, filters, missing properties + +A few UX examples have been provided, however it's quite hard to list all requirements without a deep dive into the code. Most requirements +for existing endpoints come from the need to either .. + +- Fetch properties, properties of properties, etc inline instead of making additional request. For the application wall's application list +this can be the difference between making 21 calls and then a subsequent 18 calls.. rather than receive everything with the apps request. +- Switch from a local list (sorting and filtering done locally due to lack of support in v2) to a non-local list (pagination, sorting and +filtering done via v3 api) + +### `/apps` +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +~~`include`~~ | ~~`space`~~ | | | +`include` | Organization via `space.organization` | [HIGH] | Used in application wall's application list to filter local lists by org, show org name on app wall app entries, upfront fetch leading to quicker navigation to app summary | See ([non-local lists](cf-api-v2-usage.md#Lists) for more detail on local and non-local lists). +`include` | `packages` | [HIGH] | See [1] | Required to determine application state (state, updated_at) +`include` | `processes` | [HIGH] | See [1] | Required to determine application state (instances) +`include` | Stats via `processes.stats` | [HIGH] | See [1] | Required to determine application state (state). +`include` | `current_droplet` | [HIGH] | See [1] | Required to determine application state (state). +`include` | Builds via `packages.builds` | [HIGH] | See [1] | v3 currently has no link or relation. Required to determine application state (state). +`order_by` | sum of `processes` `instances` count [See below for notes](#v3-Required-Features) | [MEDIUM] | See [2] | +`order_by` | sum of `processes` `disk_in_mb` count [See below for notes](#v3-Required-Features) | [MEDIUM] | See [2] | +`order_by` | sum of `processes` `memory_in_mb` count [See below for notes](#v3-Required-Features) | [MEDIUM] | See [2] | +filter | `processes` state | [MEDIUM] | User wishes to find all apps that have errored processes +filter | organization name | [MEDIUM] | See [3] | +filter | space name | [MEDIUM] | See [3] | + +[1] Property/s used to determine application state without spamming requests ([app state](#Application-State)). On the application wall +page we determine the state of up to 9 apps at a time. Returning this information in a single request, or during the initial request, will +save apps x missing property's endpoints (packages, process, process stats, current_droplet, etc). This could lead to 21 concurrent calls +followed by another 18 (given the results of the first run). + +[2] Enables sorting by instance count in tables. See ([non-local lists](cf-api-v2-usage.md#Lists) for more information on local and non-local list sorting). + +[3] Allows free text search by org or space name in application wall (rather than manual selection of cf, org and then space). For instance a user types part of an org name in a +special org drop down and is presented with list of apps in matching orgs. This is a short cut for the user having to scroll down a list in a +drop down. + +### `/app/${guid}` +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +`include` | `route_mappings` | [HIGH] | See [1] | See [2] +`include` | Route via `route_mappings.route` | [HIGH] | See [1] | See [2]. `/route` has no v3 equivalent +`include` | Domain via `route_mappings.route.domain` | [HIGH] | See [1] | See [2]. `/domain` has no v3 equivalent. Required to display complete route url. From Greg `We are thinking about adding a fqdn on the routes object, which may be another way to achieve the same objective.` +links | `service_bindings` | [HIGH] | See [3] | See [2] +`include` | `service_bindings` | [HIGH] | See [3] | See [2] +~~`include`~~ | ~~`space`~~ +`include` | `space.organization` | [HIGH] | Display the name of the organisation | See [2] +`include` | `packages` | [HIGH] | See [4] | See [2]. Required to determine application state (state, updated_at) +`include` | `processes` | [HIGH] | See [4] | See [2]. Required to determine app state (instances) +`include` | `processes.stats` | [HIGH] | See [4] | See [2]. Required to determine app state (state). +`include` | `current_droplet` | [HIGH] | See [4] | See [2]. Required to determine app state (state). +`include` | `packages.builds` | [HIGH] | See [4] | See [2]. v3 currently has no link or relation. Required to determine app state (state). +links | `features` | [MEDIUM] | Display current app settings (ssh enabled and revisions enabled). | See [2]. There's a top level ssh enabled flag, however this will show if at the app level ssh is enabled +`include` | `features` | [MEDIUM] | See above | See above +`include` | `droplets` | [MEDIUM] | We don't currently use this, however displaying these in a list to the user would be beneficial. | See [2] +`include` | `tasks` | [MEDIUM] | We don't currently use this, however displaying these in a list to the user would be beneficial. | See [2] +~~property~~ | ~~stack guid/whole entity~~ | | | Stack name is included inline in an inlined `lifecycle` object. This placement seems like an odd pattern. It's not an entity on it's own with it's own endpoint... but does contain an inline entity (stack). The inlined stack contains only a name and not guid/rest of stack entity. From Greg `Stack is referenced by name rather than guid due to some windows usage patterns. The window's stacks are not associated with a rootfs like the linux ones are, so they can add new stacks without having to update the stacks of all windows apps.`. +~~property~~ | ~~buildpack guid/whole entity~~ | | | As per stack guid above. From Greg `Similarly with buildpacks, having associations by name rather than guid allows for upgrades across stack versions (for example the recent upgrade from cflinuxfs2 -> cflinuxfs3) without having to re-associated apps with the new stack's version of the buildpack.` +~~property~~ | ~~`enable_ssh`~~ | | | ~~.. or similar property to determine if ssh'ing to an instance is allowed at the app level~~. See `/v3/apps/:guid/ssh_enabled` + +[1] Display bound route count & list of routes + +[2] Display information quicker on the Application pages without having to make additional requests (either once for a single entity or +multiple times in the case of 1:M, for example `route_mappings` would require multiple requests to `routes` to fetch each one) + +[3] Display bound service instance count & list of services, determine if a service is already bound when user is binding existing service to app, etc + +[4] Property/s used to determine application state without spamming endpoints ([app state](#Application-State)). + + +### `/apps/{guid}/packages` +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +links | `builds` | [HIGH] | See explanation in `/app/${guid}` - `packages.builds` | See [1] +`include` | `builds` | [HIGH] | See above | See above +`include` | `app` | [LOW] | This might come in handy in the future, more specifically if we list all `packages` | + +[1] If at some point we've fetched an app without this property we will make a separate request to fetch it, so the same includes/links are required + +### `/apps/{guid}/processes` +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +`include` | `stats` | [HIGH] | See explanation in `/app/${guid}` - `processes.stats` | See [1] +`order_by` | `state` | [MEDIUM] | In the app summary page instances tab we show a list of instances and their properties. This needs updating, but it's easy to imagine that we will display a list of processes in v3 | See [2] +`order_by` | `stats` `usage.time` | [MEDIUM] | See above | See [2] [See below for notes](#v3-Required-Features) +`order_by` | `stats` `usage.cpu` | [MEDIUM] | See above | See [2] [See below for notes](#v3-Required-Features) +`order_by` | `stats` `usage.mem` | [MEDIUM] | See above | See [2] [See below for notes](#v3-Required-Features) +`order_by` | `stats` `usage.disk` | [MEDIUM] | See above | See [2] [See below for notes](#v3-Required-Features) +filter | `state` | [MEDIUM] | See above | + +[1] If at some point we've fetched an app without this property we will make a separate request to fetch it, so the same includes/links are required + +[2] This will be required in order to switch from local (fetch allll entities in a list and sort locally) to non-local (use CF api pagination including sorting). See ([non-local lists](cf-api-v2-usage.md#Lists) for more detail on local and non-local lists. + +### `/service_bindings` (functionality for missing /apps/{guid}/service_bindings only) + +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +links | `service_instance` | [HIGH] | See [1] | See [2] +`include` | `service_instance` | [HIGH] | See above | See above +links | `service_instance.service` | [HIGH] | See above | See above +`include` | `service_instance.service` | [HIGH] | See above | See above +links | `service_instance.service_plan` | [HIGH] | See above | See above +`include` | `service_instance.service_plan` | [HIGH] | See above | See above +links | `service_instance.tags` | [HIGH] | See above | See above +`include` | `service_instance.tags` | [HIGH] | See above | See above +`order_by` | service instance name | [MEDIUM] | See [1] | See [3] +`order_by` | service name | [MEDIUM] | See above | See above +`order_by` | service plan name | [MEDIUM] | See above | See above +filter | service instance name | [MEDIUM] | See above | See above +filter | service name | [MEDIUM] | See above | See above +filter | service plan name | [MEDIUM] | See above | See above + +[1] Display a list of service instances associated with a specific application + +[2] Fetching this information inline avoids making lots of additional requests + +[3] This will be required in order to switch from local (fetch allll entities in a list and sort locally) to non-local (use CF api pagination including sorting). See ([non-local lists](cf-api-v2-usage.md#Lists) for more detail on local and non-local lists). + + +### `/spaces` +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +links | `service_instances` | [LOW] | Show the count of service instances in the space | In the medium to long term we will determine this another way +`include` | `service_instances` | [LOW] | See above | See above +links | `space_quota_definition` | [HIGH] | Display the space quota information information per space | See [3] +`include` | `space_quota_definition` | [HIGH] | See above | See above +~~`include`~~ | ~~`applications`~~ | | | Previous requirement pre-scaling change +`order_by` | `created_at` | [MEDIUM] | See [1] | See [2] +`order_by` | `name` | [MEDIUM] | See [1] | See [2] +filter | name | [MEDIUM] | See [1]. Pre-check to ensure a space name is not taken before attempting to create. | See [2] + +[1] Display a list of spaces in an organisation + +[2] This will be required in order to switch from local (fetch allll entities in a list and sort locally) to non-local (use CF api pagination including sorting). See ([non-local lists](cf-api-v2-usage.md#Lists) for more detail on local and non-local lists). + +[3] Avoids making additional requests. Particularly important when viewing multiple spaces at the same time. + + +### `/spaces/${guid}` +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +links | `organization` | [HIGH] | Basic location information, display name and other information | Avoids making additional requests +`include` | `organization` | [HIGH] | See above | See above +links | `domains` | [MEDIUM] | Efficiency request, better to get these here than separately | `/domains` has no v3 equivalent +`include` | `domains` | [MEDIUM] | See above | See above +links | `routes` | [LOW] | Display the number of routes in this organisation | `/routes` has no v3 equivalent. See [1] +`include` | `routes` | [LOW] | See above | See above +~~links~~ | ~~`routes.domain`~~ | | | Depending on the list of routes is bad due to scaling. We're removing this functionality +~~`include`~~ | ~~`routes.domain`~~ | | | See above +~~links~~ | ~~`routes.applications`~~ | | | See above +~~`include`~~ | ~~`routes.applications`~~ | | | See above +~~`include`~~ | ~~`applications`~~ | | | Previous requirement pre-scaling change +links | `service_instances` | [LOW] | Display the number of service instances in this organisation | See [1] +`include` | `service_instances` | [LOW] | See above | See above +~~links~~ | ~~`service_instances.service_bindings`~~ | | | Depending on the list of service instances is bad due to scaling. We're removing this functionality +~~`include~~` | ~~`service_instances.service_bindings`~~ +links | space quota | [HIGH] | Display quota information, when possible how close user is to various quotas, etc | space quota has no v3 equivalent +`include` | space quota | [HIGH] | See above | See above +property | allow_ssh | [HIGH] | Display value to user. Important from an admin sense | +links | `space.developers` | [HIGH] | See [2] | we might be able to fetch this via new users endpoints described in https://docs.google.com/document/d/1EA65UN3Xsi0EuX-3YfbFNqtJGseFr6FGBt2SR9c4Aqk/edit#heading=h.n1xhc33y2wyj +`include` | `space.developers` | [HIGH] | See [2] | we might be able to fetch this via new users endpoints described in https://docs.google.com/document/d/1EA65UN3Xsi0EuX-3YfbFNqtJGseFr6FGBt2SR9c4Aqk/edit#heading=h.n1xhc33y2wyj +links | `space.managers` | [HIGH] | See [2] | we might be able to fetch this via new users endpoints described in https://docs.google.com/document/d/1EA65UN3Xsi0EuX-3YfbFNqtJGseFr6FGBt2SR9c4Aqk/edit#heading=h.n1xhc33y2wyj +`include` | `space.managers` | [HIGH] | See [2] | we might be able to fetch this via new users endpoints described in https://docs.google.com/document/d/1EA65UN3Xsi0EuX-3YfbFNqtJGseFr6FGBt2SR9c4Aqk/edit#heading=h.n1xhc33y2wyj +links | `space.auditors` | [HIGH] | See [2] | we might be able to fetch this via new users endpoints described in https://docs.google.com/document/d/1EA65UN3Xsi0EuX-3YfbFNqtJGseFr6FGBt2SR9c4Aqk/edit#heading=h.n1xhc33y2wyj +`include` | `space.auditors` | [HIGH] | See [2] | we might be able to fetch this via new users endpoints described in https://docs.google.com/document/d/1EA65UN3Xsi0EuX-3YfbFNqtJGseFr6FGBt2SR9c4Aqk/edit#heading=h.n1xhc33y2wyj + +[1] Pre-scaling change. We just want the total count of entities. In the medium to long term we will determine this another way + +[2] Display a list of users and their roles + +### `/routes` (functionality for `/spaces/${guid}/routes only) + +> Note - There doesn't seem to be a way to list routes in a space. This is separate to the concept of listing them inline in a space (with +some overlap though). This endpoint would be used to fetch a list of routes for a specific space and display them to the user. +> The `/v3/route_mappings` endpoint provides a way to search for routes by app or route but not by space. + +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +filter | space guid | [HIGH] | Display a list of routes that are in a space +links | `domain` | [LOW] | Display the url of the route | Not required if the fqdn is returned in the base route +`include` | `domain` | [LOW] | See above | See above +links | `applications` | [HIGH] | Display a list of the apps that are bound to the route | Avoids making a request to `/v3/route_mappings` for each route (could be a massive amount). We expect these relations to be 1-to-not-many +`include` | `applications` | [HIGH] | See above | See above + +### `/service_instances` (functionality for /spaces/{guid}/service_instances only) + +> There's lots more that could be added here when taking into account our service instance lists in places other than the space details page +(mainly including space and space.organisation). + + +Type | Name | Priority | UX Example | Notes +--- | --- | --- | --- | --- +link | `service_instance.applications`| [HIGH] | Display bound applications in a list of service instances | Not sure if this will be implemented the same as routes and route mappings, but would need similar functionality to fetch list inline +`include` | `service_instance.applications`| [HIGH] | See above | See above +link | `service_plan`| [HIGH] | Display service plan information per SI in a list of SI | See [2]. `/service_plan` has no v3 equivalent +`include` | `service_plan` | [HIGH] | See above | See above +link | `service`| [HIGH] | Display service information per SI in a list of SI | See [2] `/service` has no v3 equivalent +`include` | `service` | [HIGH] | See above | See above +filter | space guid | [MEDIUM] | | See [3] +filter | org guid | [MEDIUM] | | See [3] +filter | `name` | [MEDIUM] | | See [3] +`include` | space | [HIGH] | When showing all SI in a CF fetch inlined space to space name and allow local filtering by space and org + +[1] Display list of service instances in a space + +[2] Avoids making additional requests per service instance + +[3] This will be required in order to switch from local (fetch allll entities in a list and sort locally) to non-local (use CF api pagination including sorting). See ([non-local lists](cf-api-v2-usage.md#Lists) for more detail on local and non-local lists). + +### `/user_provided_service_instances` + +We've recently integrated user provided service instances into Stratos. There doesn't seem to be any current support for this in v3. We'd +need similar functionality to `/service_instances` (where there's cross over). + +## v3 Required Features + +### Single 'included` section per request +There should hopefully be a single `included` section even if `included` elements have their own `include`s. Not quite a requirement, but a real nice to have. + +### `include`d lists +Ability to set `include` for lists of entities. See https://github.com/cloudfoundry/cc-api-v3-style-guide#proposal-pagination-of-related-resources + +Use case - Routes, packages, builds, process stats, etc in an application + +### `order_by` values in `include`d entities +Ability to use properties of entities that are from the `included` section in `order_by`. + +Covers simple case of sorting by a property in a 1:1 `include` and also summation of numerical properties in 1:M relationship. + +Use case - sort applications by instance count. Requires `process` as an `include` and ability to sort applications by sum of `process`s `instance` values + +Use case - as above, but instead of instances the sum of memory in a `processes` `memory_in_mb`. Need to consider whether `processes` state value should be taken into account (only include processes that are running) + +Use case - as above, but the sum of `processes` `stats` `usage.mem`. + +### filter values in `include`d +As per `order_by`, delve into an `included` entity and filter out given a specific path. + +Use case - Filter a list of service bindings by service instance name, service name or service plan name + +Use case - Filter a list of apps by organization or space diff --git a/docs/status_updates.md b/docs/status_updates.md index 3e6eab87a5..d495aa0499 100644 --- a/docs/status_updates.md +++ b/docs/status_updates.md @@ -2,6 +2,23 @@ Weekly status updates are published here. +## 8 March 2019 + +This week: + +- Added a card view to the endpoints view +- Continued to refine the support for User Provided Service Instances +- Working on support to allow list views to show different entity types in the same list +- Ensured features requiring persistence database are not enabled when using SQLite + +## 1 March 2019 + +This week: + +- Updated the front-end code to use Angular 7 (in review) +- Continued to add support for User Provided Service Instances +- Reviewed, tweaked and merged our first phase of work on improving extensions support + ## 22 February 2019 This week: diff --git a/examples/custom-src/frontend/app/custom/acme-support-info/acme-support-info.component.html b/examples/custom-src/frontend/app/custom/acme-support-info/acme-support-info.component.html index 0f7afe396f..47556fc1ca 100644 --- a/examples/custom-src/frontend/app/custom/acme-support-info/acme-support-info.component.html +++ b/examples/custom-src/frontend/app/custom/acme-support-info/acme-support-info.component.html @@ -1,12 +1,12 @@ ACME Support Info - https://docs.cloudfoundry.org + https://docs.cloudfoundry.org - https://www.suse.com + https://www.suse.com support@acme.com - + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8ad990b146..647a801c77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,134 +5,260 @@ "requires": true, "dependencies": { "@angular-devkit/architect": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.7.4.tgz", - "integrity": "sha512-qcxLtA5XhUCqNyyMOD+s7oIVywNnhUNE1qoopnm6MN0FJ1n7iQMU5TPZBTiXDWQVnbGODObi7tGo7gFnEBML5Q==", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.2.tgz", + "integrity": "sha512-wcUdMzcpsxzscEa+wrhV1SE2PsHS6FnHJlRURFOtQmKvQAq3Y8gVw28l008SMt5d0bTrRV4xLL2lgvwJJoc7LA==", "dev": true, "requires": { - "@angular-devkit/core": "0.7.4", - "rxjs": "6.2.0" + "@angular-devkit/core": "7.3.2", + "rxjs": "6.3.3" + }, + "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } + } } }, "@angular-devkit/build-angular": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.7.4.tgz", - "integrity": "sha512-aNVhnWHxhx8s8VHn2ixKhrgK/I4h/fyQQd+FtvysvDia5jOb7ckiTeM4I+2hpPI/66Kr2CxSVxuPTlJkRAH+jQ==", - "dev": true, - "requires": { - "@angular-devkit/architect": "0.7.4", - "@angular-devkit/build-optimizer": "0.7.4", - "@angular-devkit/build-webpack": "0.7.4", - "@angular-devkit/core": "0.7.4", - "@ngtools/webpack": "6.1.4", - "ajv": "6.4.0", - "autoprefixer": "8.6.5", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.13.2.tgz", + "integrity": "sha512-zRrV/dknx8891XSjXTh5JcTZnX4h+YsCHi6u8GABnIZW9JyiCl9QZpv0mRIyGTEaK2udmfMo2Yp5qZo1sd8jeQ==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.13.2", + "@angular-devkit/build-optimizer": "0.13.2", + "@angular-devkit/build-webpack": "0.13.2", + "@angular-devkit/core": "7.3.2", + "@ngtools/webpack": "7.3.2", + "ajv": "6.9.1", + "autoprefixer": "9.4.6", "circular-dependency-plugin": "5.0.2", "clean-css": "4.2.1", - "copy-webpack-plugin": "4.5.2", - "file-loader": "1.1.11", - "glob": "7.1.2", - "html-webpack-plugin": "3.2.0", - "istanbul": "0.4.5", + "copy-webpack-plugin": "4.6.0", + "file-loader": "3.0.1", + "glob": "7.1.3", "istanbul-instrumenter-loader": "3.0.1", "karma-source-map-support": "1.3.0", - "less": "3.8.1", + "less": "3.9.0", "less-loader": "4.1.0", - "license-webpack-plugin": "1.4.0", - "loader-utils": "1.1.0", - "mini-css-extract-plugin": "0.4.1", + "license-webpack-plugin": "2.1.0", + "loader-utils": "1.2.3", + "mini-css-extract-plugin": "0.5.0", "minimatch": "3.0.4", - "node-sass": "4.9.3", - "opn": "5.3.0", + "node-sass": "4.11.0", + "opn": "5.4.0", "parse5": "4.0.0", - "portfinder": "1.0.16", - "postcss": "6.0.23", - "postcss-import": "11.1.0", - "postcss-loader": "2.1.6", - "postcss-url": "7.3.2", - "raw-loader": "0.5.1", - "rxjs": "6.2.0", - "sass-loader": "6.0.7", - "semver": "5.5.0", + "postcss": "7.0.14", + "postcss-import": "12.0.1", + "postcss-loader": "3.0.0", + "raw-loader": "1.0.0", + "rxjs": "6.3.3", + "sass-loader": "7.1.0", + "semver": "5.6.0", "source-map-loader": "0.2.4", - "source-map-support": "0.5.6", - "stats-webpack-plugin": "0.6.2", - "style-loader": "0.21.0", + "source-map-support": "0.5.10", + "speed-measure-webpack-plugin": "1.3.0", + "stats-webpack-plugin": "0.7.0", + "style-loader": "0.23.1", "stylus": "0.54.5", "stylus-loader": "3.0.2", - "tree-kill": "1.2.0", - "uglifyjs-webpack-plugin": "1.3.0", - "url-loader": "1.1.1", - "webpack": "4.9.2", - "webpack-dev-middleware": "3.1.3", - "webpack-dev-server": "3.1.10", - "webpack-merge": "4.1.4", - "webpack-sources": "1.1.0", - "webpack-subresource-integrity": "1.1.0-rc.4" - } - }, - "@angular-devkit/build-ng-packagr": { - "version": "0.8.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-ng-packagr/-/build-ng-packagr-0.8.9.tgz", - "integrity": "sha512-RzzSzDM9xdnSfRf1m2FgOIMvs9B1uqufNIBlJPNlW5td076+KegTxsTTnmdn/kMlsgpSnYrCKsFmXS6ZbLHcyA==", - "dev": true, - "requires": { - "@angular-devkit/architect": "0.8.9", - "@angular-devkit/core": "0.8.9", - "rxjs": "6.2.2", - "semver": "5.6.0" + "terser-webpack-plugin": "1.2.2", + "tree-kill": "1.2.1", + "webpack": "4.29.0", + "webpack-dev-middleware": "3.5.1", + "webpack-dev-server": "3.1.14", + "webpack-merge": "4.2.1", + "webpack-sources": "1.3.0", + "webpack-subresource-integrity": "1.1.0-rc.6" }, "dependencies": { - "@angular-devkit/architect": { - "version": "0.8.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.8.9.tgz", - "integrity": "sha512-2tiGPkvJyFY/G3a27uC8r6Jj3H5m8SxjMqhjNUQ5AtNumweTBPt3YIYMNAvHUmxG0nA9upDolVXFmoQGK9AhKQ==", + "ajv": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "dev": true, "requires": { - "@angular-devkit/core": "0.8.9", - "rxjs": "6.2.2" + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" } }, - "@angular-devkit/core": { - "version": "0.8.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.8.9.tgz", - "integrity": "sha512-Umax3YKBPTQy360TeoSNaIIOJOKoXvN/S2WNTV8wDjSWWNiWLTIlckWMb9DVsafAifjUi0mtOLRFuM4YatKgTw==", + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true, + "optional": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "optional": true, "requires": { - "ajv": "6.4.0", - "chokidar": "2.0.4", - "rxjs": "6.2.2", - "source-map": "0.5.7" + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" } }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "optional": true + }, + "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=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.2.4", - "glob-parent": "3.1.0", + "fs.realpath": "1.0.0", + "inflight": "1.0.6", "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "lodash.debounce": "4.0.8", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0", - "upath": "1.1.0" + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "less": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", + "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", + "dev": true, + "requires": { + "clone": "2.1.2", + "errno": "0.1.7", + "graceful-fs": "4.1.11", + "image-size": "0.5.5", + "mime": "1.6.0", + "mkdirp": "0.5.1", + "promise": "7.3.1", + "request": "2.88.0", + "source-map": "0.6.1" + } + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true, + "optional": true + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "optional": true, + "requires": { + "mime-db": "1.38.0" + } + }, + "node-sass": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.11.0.tgz", + "integrity": "sha512-bHUdHTphgQJZaF1LASx0kAviPH7sGlcyNhWade4eVIpFp6tsn7SV8xNMTbsQFpEV9VXpnwTTnNYlfsZXgGgmkA==", + "dev": true, + "optional": true, + "requires": { + "async-foreach": "0.1.3", + "chalk": "1.1.3", + "cross-spawn": "3.0.1", + "gaze": "1.1.3", + "get-stdin": "4.0.1", + "glob": "7.1.3", + "in-publish": "2.0.0", + "lodash.assign": "4.2.0", + "lodash.clonedeep": "4.5.0", + "lodash.mergewith": "4.6.1", + "meow": "3.7.0", + "mkdirp": "0.5.1", + "nan": "2.10.0", + "node-gyp": "3.8.0", + "npmlog": "4.1.2", + "request": "2.88.0", + "sass-graph": "2.2.4", + "stdout-stream": "1.4.0", + "true-case-path": "1.0.2" + }, + "dependencies": { + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.8.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.2", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.1.3", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.22", + "oauth-sign": "0.9.0", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.4.3", + "tunnel-agent": "0.6.0", + "uuid": "3.3.2" + } + } + } + }, + "opn": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "dev": true, + "requires": { + "is-wsl": "1.1.0" } }, "rxjs": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.2.tgz", - "integrity": "sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "semver": { @@ -142,172 +268,291 @@ "dev": true }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "optional": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "2.1.1" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true, + "optional": true + } + } + }, + "@angular-devkit/build-ng-packagr": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-ng-packagr/-/build-ng-packagr-0.13.2.tgz", + "integrity": "sha512-QJc4B2Q+dK++Ns17yLIo8Q/1HRn6f4AheayiskaOMEEvYqDNohaqb+6xDp30WAn4zgjRObiuH1EFb3XdTLMrCQ==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.13.2", + "@angular-devkit/core": "7.3.2", + "rxjs": "6.3.3", + "semver": "5.6.0" + }, + "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true } } }, "@angular-devkit/build-optimizer": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.7.4.tgz", - "integrity": "sha512-R+Icu9XjIaKcYFscaMBJ1DyBK2prxK3JQSFi0S//0MdNP4gBFIpCtNdOQsNXovCkpVZ7YlgmdE5+vSb39GVHHA==", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.13.2.tgz", + "integrity": "sha512-pM3t+6VD+gdcesgwuThR41DFdsZ9ZVQ97Hhr0JXHLbLyRt4eXxWi2+B5VL0jjAaX0RIiUIe8wgScwE6m/dxemg==", "dev": true, "requires": { - "loader-utils": "1.1.0", + "loader-utils": "1.2.3", "source-map": "0.5.6", - "typescript": "2.9.2", - "webpack-sources": "1.1.0" + "typescript": "3.2.4", + "webpack-sources": "1.3.0" }, "dependencies": { "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", + "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", "dev": true } } }, "@angular-devkit/build-webpack": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.7.4.tgz", - "integrity": "sha512-5oezCFtovcZ8fEkFyNEjs30b/t/DM6HIs3L1bP2xy2SFRNfwcWA0uyb5eag1DytZrzws2GEEmyO9qPtfwKjX7g==", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.13.2.tgz", + "integrity": "sha512-Uemur2KhFu7VGU2QQmfRiMwmoSKprZrMZRZXwZdCQPN5srIcMAgGjm1PGbZuCUddhwd2XRP9dKY6zOZpMzm84Q==", "dev": true, "requires": { - "@angular-devkit/architect": "0.7.4", - "@angular-devkit/core": "0.7.4", - "rxjs": "6.2.0" + "@angular-devkit/architect": "0.13.2", + "@angular-devkit/core": "7.3.2", + "rxjs": "6.3.3" + }, + "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } + } } }, "@angular-devkit/core": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.7.4.tgz", - "integrity": "sha512-Blh44vzZVzE8B9xIwjRoo7hXPGSDdlrrax0rntvt3DDGVTjsSGm43qT95aDmXiwJruOCJNC5DsaP3+tTAkAyQQ==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.2.tgz", + "integrity": "sha512-W5KjkHRNVBcZRUNJamAn52IAj9Gl1zUjPA2r75JJK7k199xOA8UZqcIukQOgM1N7rwKCWht08i4FsdcTDghMhQ==", "dev": true, "requires": { - "ajv": "6.4.0", - "chokidar": "2.0.3", - "rxjs": "6.2.0", - "source-map": "0.5.6" + "ajv": "6.9.1", + "chokidar": "2.0.4", + "fast-json-stable-stringify": "2.0.0", + "rxjs": "6.3.3", + "source-map": "0.7.3" + }, + "dependencies": { + "ajv": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", + "dev": true, + "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" + } + }, + "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.1", + "braces": "2.3.2", + "fsevents": "1.2.7", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "lodash.debounce": "4.0.8", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.1.0" + } + }, + "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=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "2.1.1" + } + } } }, "@angular-devkit/schematics": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.8.7.tgz", - "integrity": "sha512-Xu49OH0tpfqKLMdLy0ghbMwsYVHLlnjsKm8JQKkDah9oYMnj94ZoqESi1xVorYVHHJ1Jbi9Xm3ZY3QGF+x0j7g==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.3.2.tgz", + "integrity": "sha512-pxPzMfgVNFq1V6aTrBRYKGATSHfzj67IFYOqKWYt6EnUQxHuAOdFqbB6vIKfZhsYko2anp9Q0dAs6mfesBThNQ==", "dev": true, "requires": { - "@angular-devkit/core": "0.8.7", - "rxjs": "6.2.2" + "@angular-devkit/core": "7.3.2", + "rxjs": "6.3.3" }, "dependencies": { - "@angular-devkit/core": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.8.7.tgz", - "integrity": "sha512-r9w+ppbUdBQlZLfLsU+lqg3VPxKoSbF9Aic0K6hC53VxI/lN5GpRkdIcDWfAYGlsj9GGgk/JAX6Q22LskSfGYg==", - "dev": true, - "requires": { - "ajv": "6.4.0", - "chokidar": "2.0.3", - "rxjs": "6.2.2", - "source-map": "0.5.6" - } - }, "rxjs": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.2.tgz", - "integrity": "sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } } } }, "@angular/animations": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-6.1.1.tgz", - "integrity": "sha512-6o15ZtoTWlvZgu/qTz2xj25A1ZRr+BGRHxkhQDZ4hADEIUyYi96dVQxkUttXTtmACRAhK4oXkL7xleVm5iN6ow==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.6.tgz", + "integrity": "sha512-ICKPS+bKabhQNqnPoVZegUAhgNPbVFlrxHoJ+ZZeVGxw5iBE8TnP3a2sRvakdMTKhykDlwVVGMKLxu2Y34uhmg==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/cdk": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-6.4.0.tgz", - "integrity": "sha512-JEJ7OsVxoyEgsWG5c48mXLFGOUq0I8Mijar1ktI+TcIqdoLwO1XClcoh8MbgwImp3ZISfOghHVqcjLxhp4UASA==", + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-7.3.3.tgz", + "integrity": "sha512-0M3nwq+c9+d+p0XeU12I9djutlsajRrxcu7AvHQXUs/5grYFsXsX0f468qXDiKmcgqGUBNtN2fBOUhGNlispuQ==", "requires": { - "tslib": "1.9.2" + "parse5": "5.1.0", + "tslib": "1.9.3" + }, + "dependencies": { + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "optional": true + } } }, "@angular/cli": { - "version": "6.2.6", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-6.2.6.tgz", - "integrity": "sha512-50oGL9EyhaRFXkXFy4wE2s+g+BHKACyICSCxNGncvRKR2/KfhMSrs2UiFm8IiiaHCr4sAg3Hsc40D6lksnR4hA==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.2.tgz", + "integrity": "sha512-M1AtkjB27XjMs+CuJNEv2v7vTu7sMJPw0e41SDPik22+ErOK6YnV6m5VG10fCZZYwCjnWOVNP5Du7Lsdyd/vNQ==", "dev": true, "requires": { - "@angular-devkit/architect": "0.8.6", - "@angular-devkit/core": "0.8.6", - "@angular-devkit/schematics": "0.8.6", - "@schematics/angular": "0.8.6", - "@schematics/update": "0.8.6", - "json-schema-traverse": "0.4.1", + "@angular-devkit/architect": "0.13.2", + "@angular-devkit/core": "7.3.2", + "@angular-devkit/schematics": "7.3.2", + "@schematics/angular": "7.3.2", + "@schematics/update": "0.13.2", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "inquirer": "6.2.1", + "npm-package-arg": "6.1.0", "opn": "5.4.0", - "rxjs": "6.2.2", + "pacote": "9.4.0", "semver": "5.6.0", - "symbol-observable": "1.2.0", - "yargs-parser": "10.1.0" + "symbol-observable": "1.2.0" }, "dependencies": { - "@angular-devkit/architect": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.8.6.tgz", - "integrity": "sha512-sFre4udJvUj1UXUYlG0mEp08mU/hk5Nae2hdk97eVJo41o2diJsnMXZHrR/gtcCSVk8rCePSCY/+YN4f9I/L0Q==", - "dev": true, - "requires": { - "@angular-devkit/core": "0.8.6", - "rxjs": "6.2.2" - } - }, - "@angular-devkit/core": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.8.6.tgz", - "integrity": "sha512-VEx363a5u2nJYgng7wZZ5yXp/SXyw28LBR7P8Rudux7RpquH3Wfoss0rIScIykhXC8sDbRidwxmi1mSd9KEKKw==", - "dev": true, + "ajv": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "requires": { - "ajv": "6.4.0", - "chokidar": "2.0.4", - "rxjs": "6.2.2", - "source-map": "0.5.7" + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" } }, - "@angular-devkit/schematics": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.8.6.tgz", - "integrity": "sha512-PRpyKYnD8VK8MfECP4igyRsxwpIlgvCE/pGHQjfMf0HU30JoVC7oO4gwcZz/LhuwgUp7v2SZ5NgpUY09HxRZUw==", - "dev": true, - "requires": { - "@angular-devkit/core": "0.8.6", - "rxjs": "6.2.2" - } + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "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.1", "braces": "2.3.2", - "fsevents": "1.2.4", + "fsevents": "1.2.7", "glob-parent": "3.1.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", @@ -319,12 +564,76 @@ "upath": "1.1.0" } }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "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=" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "inquirer": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", + "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", + "dev": true, + "requires": { + "ansi-escapes": "3.2.0", + "chalk": "2.2.2", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "3.0.3", + "figures": "2.0.0", + "lodash": "4.17.10", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rxjs": "6.3.3", + "string-width": "2.1.1", + "strip-ansi": "5.0.0", + "through": "2.3.8" + } + }, + "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 + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, "opn": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", @@ -334,13 +643,32 @@ "is-wsl": "1.1.0" } }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, "rxjs": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.2.tgz", - "integrity": "sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "semver": { @@ -350,180 +678,250 @@ "dev": true }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "camelcase": "4.1.0" + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "2.1.1" } } } }, "@angular/common": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-6.1.1.tgz", - "integrity": "sha512-mrMG0Q+BUPuiez3RKWkrMCv3r/9iJl1DoTLhLNsgWvpj0IRGcARUyJgmTZqVVVCeacjFQEM+DopbVQ7AjQCkoA==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.6.tgz", + "integrity": "sha512-jzWUgsgS0dmPy7yDHX4qCqVpt7ZZmHhApgkg5RkzTAlp+0cvZ/KsDpBgHXnZUIfmk/5g1/EtTbkbClgp1kCkIg==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/compiler": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-6.1.1.tgz", - "integrity": "sha512-60qSglzK8lncRI13axHaJryjGvdnue5yI8yXiJEEXMHba+AJ9xfoXH2aPPqBHvUX7bU4p4fsSVGDOe7kryo/ow==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.6.tgz", + "integrity": "sha512-GXdvgH8oxK8HRh/FelN3U5p0tsTUwGh8b/iuuJKaunBSSDDjIy7pPnn3zT+lN4YeEi6qN1XWudt+HpWHYHyymg==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/compiler-cli": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-6.1.1.tgz", - "integrity": "sha512-J1FJbeN95Oe3hLNZnNFQUpKFxh5mb11EPKHhGScqajK1+2eZrmKfw6SRi2n4R1FPODerML+q4+uJjywjV5QSOw==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.6.tgz", + "integrity": "sha512-sB0Bc5hE1zoXKwK4E9pC/UblCEHi3CwLBT/1nmVMYBdGzSSUxO4FaioJi+SCeGJJ+kk85Vny2up08gnupmLKqA==", "dev": true, "requires": { - "chokidar": "1.7.0", + "canonical-path": "1.0.0", + "chokidar": "2.1.2", + "convert-source-map": "1.5.1", + "dependency-graph": "0.7.2", + "magic-string": "0.25.2", "minimist": "1.2.0", - "reflect-metadata": "0.1.12", - "tsickle": "0.32.1" + "reflect-metadata": "0.1.13", + "shelljs": "0.8.3", + "source-map": "0.6.1", + "tslib": "1.9.3", + "yargs": "9.0.1" }, "dependencies": { - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" - } + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chokidar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz", + "integrity": "sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==", "dev": true, "requires": { - "arr-flatten": "1.1.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.1", + "is-glob": "4.0.0", + "normalize-path": "3.0.0", + "path-is-absolute": "1.0.1", + "readdirp": "2.2.1", + "upath": "1.1.0" } }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } } }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.2.4", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" } }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "mimic-fn": "1.2.0" } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "is-extglob": "1.0.0" + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" } }, - "glob-parent": { + "path-type": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { - "is-glob": "2.0.1" + "pify": "2.3.0" } }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" } }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "find-up": "2.1.0", + "read-pkg": "2.0.0" } }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "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": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "graceful-fs": "4.1.11", + "micromatch": "3.1.10", + "readable-stream": "2.3.6" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } }, "source-map": { "version": "0.6.1", @@ -531,107 +929,169 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "tsickle": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.32.1.tgz", - "integrity": "sha512-JW9j+W0SaMSZGejIFZBk0AiPfnhljK3oLx5SaqxrJhjlvzFyPml5zqG1/PuScUj6yTe1muEqwk5CnDK0cOZmKw==", + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "jasmine-diff": "0.1.3", - "minimist": "1.2.0", - "mkdirp": "0.5.1", - "source-map": "0.6.1", - "source-map-support": "0.5.6" + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "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 + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "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 + }, + "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 + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" } } } }, "@angular/core": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-6.1.1.tgz", - "integrity": "sha512-4h/8abB4N5meQHg69IV1wtNKUKe8e0w9z9s/0ZYbvFPVqWB9OkcSihsS2xmfSD3glIgSgS5424/jmiTB9G0Tcw==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.6.tgz", + "integrity": "sha512-MZg17DWH1KUoDa9wFYK9Z+3F7DnUW2DjSwGyIi9U4cB54IWFhgt1JsA0mcuSYuRSRpvwaArCDC2AN90f+0/EFA==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/flex-layout": { - "version": "6.0.0-beta.18", - "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-6.0.0-beta.18.tgz", - "integrity": "sha512-1Alv3YSIZYp0CTUIESIaSQLoSVyLzuNKPa5bGM/RzOmeSrndm5plVgI9wopGfJUDiwM18R97rq/4XjDvNT/+ig==", + "version": "7.0.0-beta.23", + "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-7.0.0-beta.23.tgz", + "integrity": "sha512-jH2i3i/M7SbK6scVlj2urVL5OhzwavbQ7KwvUjyc/UwccKnnzuOuWEGCINLja/aoaUO3I35LluCLv6a6VN0olA==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/forms": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-6.1.1.tgz", - "integrity": "sha512-NiEMJN0INoK6khjS+YJAqt3FS2nXy3JH4J10m55e2gwzldHrsU94bWUDEOEMbPfm7dFC8G1114p/MneleoXTvg==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.6.tgz", + "integrity": "sha512-At72AJNGe+Zzmryb7DDIG+iws7zKdgZx/eEVjZ/Obu/yREefbZY4R7q83U90Vljtn97BwJPx9ur9ttxE9WpnlA==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/http": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-6.1.1.tgz", - "integrity": "sha512-1VtFTSJeo1Q3pgbQ65NyMZFV3f+Jd8i4XMbmqOf+L7StosI1HE8eiDbm1SgQOuXZv0MFwgKMEXy7lzfnyl9Udw==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.6.tgz", + "integrity": "sha512-B5TC8JFW/I+ms5iJthGjf/eg1tKKqpO6yrOpDSQofHG7Dd4dozyGXGznFJTRFfNda5rku61/qnQaa8SyQyuplQ==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/language-service": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-6.1.1.tgz", - "integrity": "sha512-DRJAvBMMfbkadaD6mRJpk2DUdMCbqvJmJndi+ewdZ7BpC1+/tzJFtvIHbS59kGbuMvda4YS9gfYk+x13VQfthg==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.6.tgz", + "integrity": "sha512-iFKgaat5MZlixsO5dqy1Km3tb4q3iAU+ZPMJCk7DN419aizF38UFnQY1gCYkw3dxZLZGIkXnwy8szGXUEhra/A==", "dev": true }, "@angular/material": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-6.2.0.tgz", - "integrity": "sha512-4vC2Ycrf1ORP6iGIy9qExVpbjqHJ/ObEQd72pVDQyK127O8cxhGhEiX8QvxdeAGREVxqwfhUGEK/vjH3o110fQ==", + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-7.3.3.tgz", + "integrity": "sha512-DZdJaVpXsd5QlfpN5P871llw8AKh5QvRiyro3QRmEajYN85Xiawqpbt7O60TrwcFM6DzYLI3UeyWq8LFdmi/+Q==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/material-moment-adapter": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-6.4.7.tgz", - "integrity": "sha512-OGdDtpu/yRioOQXhJFCNuiOF2OgiL9VUj8ewFPi1lDtFGUFfVwU2h3hWkKLn+yuPW+DBVYla11tCNsn5dLElmA==", + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-7.3.3.tgz", + "integrity": "sha512-Fp2EcFpwdwa5qWWBa7G1mJZuaQ3oD3pohyo04HD2ud8YFP5IPbeoHVc65JC7TIwQFbVKk0lojXK3b2vQXZOapw==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/platform-browser": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-6.1.1.tgz", - "integrity": "sha512-YgFP6NQgk7ZkKKfywmLC3wBZuepYLttjIvzWhbvutJpRahAw1qDQaeCXdv75DU4U8fqHDKkllZS/kIdkc3cxQw==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.6.tgz", + "integrity": "sha512-VE4yS4l8Cdx6DlvrbOFOZDKmQuyz1RhVcshgSt9hKlkehvAXMtX8Sqnp6po7z0aPykTh0TZZtMtLEerkFEe+DA==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/platform-browser-dynamic": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-6.1.1.tgz", - "integrity": "sha512-OYXMgVapk6XmRwWgW05fN30dj1fSSiJjCXMzxxG/y+hIMe/O9HLfShADQHee9XRQJhZEdDB0rr7tOFYmH1c5Uw==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.6.tgz", + "integrity": "sha512-/co/q4v11nKin2MFscCMZyixbW103I2FxbPgCAYBN5NSvfIwTrt5J6xWmDoKJ8HkZBqL3R9B+uhYdzsRN/pQxg==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@angular/platform-server": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-6.1.1.tgz", - "integrity": "sha512-fss9CRIAK599lb7X5aOcKdGXZ3qr5t/QfkMEYfIc7A/nJ7wupa5L2pGFvifxClJIkFMB7Q7GMQn57WgnPaU5zw==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-7.2.6.tgz", + "integrity": "sha512-rtLT0BxgEGJDYGMeFNYfna3H91JITFfm4Qd86nH7EmR1mVWa563lSQle1VWwbQhRbj5fDhwt+anbVwz7SEn7ew==", "requires": { - "domino": "2.0.2", - "tslib": "1.9.2", + "domino": "2.1.2", + "tslib": "1.9.3", "xhr2": "0.1.4" } }, "@angular/router": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-6.1.1.tgz", - "integrity": "sha512-pYvB0wQI7/TS/BLeEy707t1wMujvM8fAlSw+BJs4iqYJwYuG9nGG3IzKvR90fZDVdseNFNa72WokXaK1BPSs8Q==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.6.tgz", + "integrity": "sha512-ayMVor4Mu4wk7JKpt51UxHovnLB4munZ8ELR1CA4w+s0rJsSSwyB4WXElC+DbgCyl7BYLAaGui2c5DbTAJ9jlw==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "@mrmlnc/readdir-enhanced": { @@ -645,24 +1105,24 @@ } }, "@ngrx/effects": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-6.0.1.tgz", - "integrity": "sha512-YS68D7E1qKbbOIzV6Iyfv6BY3CrTNi8nBgGJ6whTi6f7Y0apXySvNj9aOQyzuJsePWziu6h0uJhy2ZFT/iELyg==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-7.2.0.tgz", + "integrity": "sha512-vymKSoubYlUWGbiclPK0N/LwB409sB9atjSTQRy2EisZfFtQ2tCDqmk4JGgDy/gV9SqZWrwPSy1xXsLqYnyN3g==" }, "@ngrx/router-store": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-6.0.1.tgz", - "integrity": "sha512-Nz6HI6cGcWZtRP8Z1eWH0jhkmukQYSpH5AptCcXMjOP2MorHv23Ddw1O+0W6hF8SYX1JvGdaQ2BUJS00MaKfKw==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-7.2.0.tgz", + "integrity": "sha512-deXDZg4FffuqxlFXqAaR8+lEy4yCJgTmKn2avKHltF3GP+8bxIRiD6GDCYjYJVhLFiBK8U3AFhgfoEuUUpFCag==" }, "@ngrx/store": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-6.0.1.tgz", - "integrity": "sha512-cSgfT8CgpOr6BOQac9M3DH6QQC5gxCVjdEcZH//Zn/kwdse86X73iK7KWv6B6AiIEdyVbFfggXNZwd/HiyLGOA==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-7.2.0.tgz", + "integrity": "sha512-E9c0cDot0HeE0mXyeqw18SwmJ2+eKnA5mMMfwvoskpMInCYGI2pq1i6/lCVQ2wrEHSH+KvObK4PQbepcA9vP+w==" }, "@ngrx/store-devtools": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-6.0.1.tgz", - "integrity": "sha512-eZyguQvIltJuhCVgPPR1IyMAztykRuvGalwCH1G2ODWKGZPNrWlJbxVMqzUeSJTBS268RIFIkMTwEDKi/xCQoQ==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-7.2.0.tgz", + "integrity": "sha512-t+8K1IG8+MvFqLIuRSM+ZE1EkZIuUExJ0JsqZR4r4K3MRPRoGy1ZqlStBWYaYLumEToesiCOGxuJYQ4zyVwlZg==" }, "@ngtools/json-schema": { "version": "1.1.0", @@ -671,15 +1131,27 @@ "dev": true }, "@ngtools/webpack": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-6.1.4.tgz", - "integrity": "sha512-LiDAvHWKdTyOp8YvjWH1oZtIY8qod13UomvTRQ2FuXXjJwNmi4Bk1VpfGCq3hhtdpo4x/aWHFBuBBpPxoJ74SQ==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.2.tgz", + "integrity": "sha512-q98nt7HUTcdEtP+aJjsm5HUMDL+BXwLz80TthtFlu/f7JYdKxMSWZRHEv+q8Rs69pWMpwxj8RuHm8XiKD/8Cpg==", "dev": true, "requires": { - "@angular-devkit/core": "0.7.4", - "rxjs": "6.2.0", - "tree-kill": "1.2.0", - "webpack-sources": "1.1.0" + "@angular-devkit/core": "7.3.2", + "enhanced-resolve": "4.1.0", + "rxjs": "6.3.3", + "tree-kill": "1.2.1", + "webpack-sources": "1.3.0" + }, + "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } + } } }, "@nodelib/fs.stat": { @@ -689,9 +1161,9 @@ "dev": true }, "@nrwl/schematics": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@nrwl/schematics/-/schematics-6.4.0.tgz", - "integrity": "sha512-KPE8qDSGsJWbI99osctREgIqjj9pFxKPEqQ36JPtEA4mAWJbR6NUykOpbh2LWl7V/kMSLKGacmOLEOjrrpyKeA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@nrwl/schematics/-/schematics-7.6.0.tgz", + "integrity": "sha512-rt+YzuNpmVGIt5agPM5Z61cMaSLRmEcpiI4HdVL8eOBw7HicVk2N894rHbQdU3/LHZUt592zq8Z7jOFUtbV3JQ==", "dev": true, "requires": { "@types/yargs": "11.1.2", @@ -699,8 +1171,10 @@ "cosmiconfig": "4.0.0", "fs-extra": "6.0.0", "graphviz": "0.0.8", - "npm-run-all": "4.1.2", + "ignore": "5.0.4", + "npm-run-all": "4.1.5", "opn": "5.3.0", + "rxjs": "6.3.3", "semver": "5.4.1", "strip-json-comments": "2.0.1", "tmp": "0.0.33", @@ -732,17 +1206,6 @@ "wrap-ansi": "2.1.0" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "4.1.3", - "shebang-command": "1.2.0", - "which": "1.3.1" - } - }, "fs-extra": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.0.tgz", @@ -754,6 +1217,12 @@ "universalify": "0.1.1" } }, + "ignore": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.0.4.tgz", + "integrity": "sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g==", + "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", @@ -769,18 +1238,6 @@ "graceful-fs": "4.1.11" } }, - "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.11", - "parse-json": "4.0.0", - "pify": "3.0.0", - "strip-bom": "3.0.0" - } - }, "mem": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", @@ -790,23 +1247,6 @@ "mimic-fn": "1.2.0" } }, - "npm-run-all": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.2.tgz", - "integrity": "sha512-Z2aRlajMK4SQ8u19ZA75NZZu7wupfCNQWdYosIi8S6FgBdGf/8Y6Hgyjdc8zU2cYmIRVCx1nM80tJPkdEd+UYg==", - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "chalk": "2.2.2", - "cross-spawn": "5.1.0", - "memorystream": "0.3.1", - "minimatch": "3.0.4", - "ps-tree": "1.2.0", - "read-pkg": "3.0.0", - "shell-quote": "1.6.1", - "string.prototype.padend": "3.0.0" - } - }, "os-locale": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", @@ -818,25 +1258,13 @@ "mem": "1.1.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.2" - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "load-json-file": "4.0.0", - "normalize-package-data": "2.4.0", - "path-type": "3.0.0" + "tslib": "1.9.3" } }, "semver": { @@ -864,12 +1292,6 @@ "ansi-regex": "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 - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -931,93 +1353,189 @@ } }, "@schematics/angular": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.8.6.tgz", - "integrity": "sha512-2GOtt7jWQmT4XtNAPk4JbPPdVVS5iihX9gtoTHI5bxIg+R3qNo1Tq6d7b4EXKwSTSztlx37Zh66vKe+gtdTmtw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.3.2.tgz", + "integrity": "sha512-ClqG1qA919QqsikIXIP/jKl2Boj70lihCbpXhZgjsahLY8UJgq9oh8K1QuvYJtz4AI4GADfG1fGzPdYfy94+kg==", "dev": true, "requires": { - "@angular-devkit/core": "0.8.6", - "@angular-devkit/schematics": "0.8.6", - "typescript": "2.9.2" + "@angular-devkit/core": "7.3.2", + "@angular-devkit/schematics": "7.3.2", + "typescript": "3.2.4" }, "dependencies": { - "@angular-devkit/core": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.8.6.tgz", - "integrity": "sha512-VEx363a5u2nJYgng7wZZ5yXp/SXyw28LBR7P8Rudux7RpquH3Wfoss0rIScIykhXC8sDbRidwxmi1mSd9KEKKw==", - "dev": true, + "ajv": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "requires": { - "ajv": "6.4.0", - "chokidar": "2.0.3", - "rxjs": "6.2.0", - "source-map": "0.5.6" + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" } }, - "@angular-devkit/schematics": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.8.6.tgz", - "integrity": "sha512-PRpyKYnD8VK8MfECP4igyRsxwpIlgvCE/pGHQjfMf0HU30JoVC7oO4gwcZz/LhuwgUp7v2SZ5NgpUY09HxRZUw==", - "dev": true, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "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.1", + "is-glob": "4.0.0", + "lodash.debounce": "4.0.8", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.1.0" + } + }, + "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=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "requires": { + "tslib": "1.9.3" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + }, + "typescript": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", + "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "requires": { - "@angular-devkit/core": "0.8.6", - "rxjs": "6.2.0" + "punycode": "2.1.1" } } } }, "@schematics/update": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.8.6.tgz", - "integrity": "sha512-a/uouXXUxEyoJH2Wc3weqP1WF1TeJynmK2NrY4gHW0sv1prFYRUvtgI9RMIw6/uYvjZ0zq87nu6JB1U6+yD+9w==", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.13.2.tgz", + "integrity": "sha512-w3ONb59VXN/ypEvi6IlLhuHAAgmtJwrnuZ5I7hPzDJYSuajGjwO238/HZvUeh+R/ttyq9RSFi/0SQJpi7b4yvw==", "dev": true, "requires": { - "@angular-devkit/core": "0.8.6", - "@angular-devkit/schematics": "0.8.6", - "npm-registry-client": "8.6.0", - "rxjs": "6.2.0", - "semver": "5.5.0", + "@angular-devkit/core": "7.3.2", + "@angular-devkit/schematics": "7.3.2", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "pacote": "9.4.0", + "rxjs": "6.3.3", + "semver": "5.6.0", "semver-intersect": "1.4.0" }, "dependencies": { - "@angular-devkit/core": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.8.6.tgz", - "integrity": "sha512-VEx363a5u2nJYgng7wZZ5yXp/SXyw28LBR7P8Rudux7RpquH3Wfoss0rIScIykhXC8sDbRidwxmi1mSd9KEKKw==", - "dev": true, + "ajv": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "requires": { - "ajv": "6.4.0", - "chokidar": "2.0.3", - "rxjs": "6.2.0", - "source-map": "0.5.6" + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" + } + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "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.1", + "is-glob": "4.0.0", + "lodash.debounce": "4.0.8", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.1.0" } }, - "@angular-devkit/schematics": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.8.6.tgz", - "integrity": "sha512-PRpyKYnD8VK8MfECP4igyRsxwpIlgvCE/pGHQjfMf0HU30JoVC7oO4gwcZz/LhuwgUp7v2SZ5NgpUY09HxRZUw==", + "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=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "@angular-devkit/core": "0.8.6", - "rxjs": "6.2.0" + "tslib": "1.9.3" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "2.1.1" } } } }, "@swimlane/ngx-charts": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-9.0.0.tgz", - "integrity": "sha512-XmiEclr09p5EiZyXPqPyGD//Ai4GUpJbMYw90A24UJdFwvh8BQDDeZ1QUNIuTWkpN5XMZ8TzQ4P4qjaTypsZPw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-10.1.0.tgz", + "integrity": "sha512-0nZ3ub5o/qQfFMz+av89u/VKqsqiVhPFBDDOOPq2qimP83i+pcb0i3MEao7PSxIbKAEkL/pwRcEJw4KDZ8B67w==", "requires": { + "d3": "4.13.0", "d3-array": "1.2.4", "d3-brush": "1.0.6", "d3-color": "1.2.3", - "d3-force": "1.1.2", + "d3-force": "1.2.0", "d3-format": "1.3.2", "d3-hierarchy": "1.1.8", "d3-interpolate": "1.3.2", "d3-scale": "1.0.7", - "d3-selection": "1.3.2", - "d3-shape": "1.2.2", + "d3-selection": "1.4.0", + "d3-shape": "1.3.4", "d3-time-format": "2.1.3" } }, @@ -1027,9 +1545,9 @@ "integrity": "sha1-IfibcJuvxLMDra56g7TzWg2eR5Y=" }, "@types/bluebird": { - "version": "3.5.20", - "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.20.tgz", - "integrity": "sha512-Wk41MVdF+cHBfVXj/ufUHJeO3BlIQr1McbHZANErMykaCWeDSZbH5erGjNBw2/3UlRdSxZbLfSuQTzFmPOYFsA==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.25.tgz", + "integrity": "sha512-yfhIBix+AIFTmYGtkC0Bi+XGjSkOINykqKvO/Wqdz/DuXlAKK7HmhLAXdPIGsV4xzKcL3ev/zYc4yLNo+OvGaw==", "dev": true }, "@types/caseless": { @@ -1055,7 +1573,7 @@ "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", "dev": true, "requires": { - "@types/node": "6.0.111" + "@types/node": "11.9.4" } }, "@types/jasmine": { @@ -1074,19 +1592,20 @@ } }, "@types/karma": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@types/karma/-/karma-1.7.3.tgz", - "integrity": "sha512-26J5wva11NjLWWitm4JMRc51NtTnSf912tPonmujsPcISitGXz1KcfwQk6SRcyM1ikb09zq3aGwVcj7HYkmW6A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/karma/-/karma-3.0.2.tgz", + "integrity": "sha512-xm+iMKgLSpTPo1Z7wLKbrZt8aLzA1udb9UOb9+OSDMFIufqlbp0DXQpY75EQ3ETi6EJiaohIodBlMs+UD4NSMQ==", "dev": true, "requires": { - "@types/bluebird": "3.5.20", - "@types/node": "6.0.111" + "@types/bluebird": "3.5.25", + "@types/node": "11.9.4", + "log4js": "3.0.6" } }, "@types/node": { - "version": "6.0.111", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.111.tgz", - "integrity": "sha512-DoWK5a544Jcr6C1qBadalyj3gQT5V9B87qFBb+uOOq1Id309Lbe10zwsCGCURZEOBoS/pOsmbDN4FnD4sOwJaw==", + "version": "11.9.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.9.4.tgz", + "integrity": "sha512-Zl8dGvAcEmadgs1tmSPcvwzO1YRsz38bVJQvH1RvRqSR9/5n61Q1ktcDL0ht3FXWR+ZpVmXVwN1LuH4Ax23NsA==", "dev": true }, "@types/q": { @@ -1096,15 +1615,15 @@ "dev": true }, "@types/request": { - "version": "2.47.0", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.47.0.tgz", - "integrity": "sha512-/KXM5oev+nNCLIgBjkwbk8VqxmzI56woD4VUxn95O+YeQ8hJzcSmIZ1IN3WexiqBb6srzDo2bdMbsXxgXNkz5Q==", + "version": "2.48.1", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz", + "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==", "dev": true, "requires": { "@types/caseless": "0.12.1", "@types/form-data": "2.2.1", - "@types/node": "6.0.111", - "@types/tough-cookie": "2.3.3" + "@types/node": "11.9.4", + "@types/tough-cookie": "2.3.5" } }, "@types/selenium-webdriver": { @@ -1113,17 +1632,42 @@ "integrity": "sha512-ikB0JHv6vCR1KYUQAzTO4gi/lXLElT4Tx+6De2pc/OZwizE9LRNiTa+U8TBFKBD/nntPnr/MPSHSnOTybjhqNA==", "dev": true }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, "@types/stacktrace-js": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/stacktrace-js/-/stacktrace-js-0.0.32.tgz", "integrity": "sha512-SdxmlrHfO0BxgbBP9HZWMUo2rima8lwMjPiWm6S0dyKkDa5CseamktFhXg8umu3TPVBkSlX6ZoB5uUDJK89yvg==" }, "@types/tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha512-MDQLxNFRLasqS4UlkWMSACMKeSm1x4Q3TxzUC7KQUsh6RK1ZrQ0VEyE3yzXcBu+K8ejVj4wuX32eUG02yNp+YQ==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", + "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==", "dev": true }, + "@types/webpack-sources": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.5.tgz", + "integrity": "sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w==", + "dev": true, + "requires": { + "@types/node": "11.9.4", + "@types/source-list-map": "0.1.2", + "source-map": "0.6.1" + }, + "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 + } + } + }, "@types/yargs": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-11.1.2.tgz", @@ -1131,258 +1675,203 @@ "dev": true }, "@webassemblyjs/ast": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.4.3.tgz", - "integrity": "sha512-S6npYhPcTHDYe9nlsKa9CyWByFi8Vj8HovcAgtmMAQZUOczOZbQ8CnwMYKYC5HEZzxEE+oY0jfQk4cVlI3J59Q==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", + "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", "dev": true, "requires": { - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/wast-parser": "1.4.3", - "debug": "3.1.0", - "webassemblyjs": "1.4.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.4.3.tgz", - "integrity": "sha512-3zTkSFswwZOPNHnzkP9ONq4bjJSeKVMcuahGXubrlLmZP8fmTIJ58dW7h/zOVWiFSuG2em3/HH3BlCN7wyu9Rw==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", + "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", + "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.4.3.tgz", - "integrity": "sha512-e8+KZHh+RV8MUvoSRtuT1sFXskFnWG9vbDy47Oa166xX+l0dD5sERJ21g5/tcH8Yo95e9IN3u7Jc3NbhnUcSkw==", - "dev": true, - "requires": { - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", + "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", + "dev": true }, "@webassemblyjs/helper-code-frame": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.4.3.tgz", - "integrity": "sha512-9FgHEtNsZQYaKrGCtsjswBil48Qp1agrzRcPzCbQloCoaTbOXLJ9IRmqT+uEZbenpULLRNFugz3I4uw18hJM8w==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", + "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", "dev": true, "requires": { - "@webassemblyjs/wast-printer": "1.4.3" + "@webassemblyjs/wast-printer": "1.7.11" } }, "@webassemblyjs/helper-fsm": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.4.3.tgz", - "integrity": "sha512-JINY76U+702IRf7ePukOt037RwmtH59JHvcdWbTTyHi18ixmQ+uOuNhcdCcQHTquDAH35/QgFlp3Y9KqtyJsCQ==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", + "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", + "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", "dev": true }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.4.3.tgz", - "integrity": "sha512-I7bS+HaO0K07Io89qhJv+z1QipTpuramGwUSDkwEaficbSvCcL92CUZEtgykfNtk5wb0CoLQwWlmXTwGbNZUeQ==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", + "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.4.3.tgz", - "integrity": "sha512-p0yeeO/h2r30PyjnJX9xXSR6EDcvJd/jC6xa/Pxg4lpfcNi7JUswOpqDToZQ55HMMVhXDih/yqkaywHWGLxqyQ==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", + "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-buffer": "1.4.3", - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/wasm-gen": "1.4.3", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11" } }, - "@webassemblyjs/leb128": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.4.3.tgz", - "integrity": "sha512-4u0LJLSPzuRDWHwdqsrThYn+WqMFVqbI2ltNrHvZZkzFPO8XOZ0HFQ5eVc4jY/TNHgXcnwrHjONhPGYuuf//KQ==", + "@webassemblyjs/ieee754": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", + "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", "dev": true, "requires": { - "leb": "0.3.0" + "@xtuc/ieee754": "1.2.0" } }, - "@webassemblyjs/validation": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/validation/-/validation-1.4.3.tgz", - "integrity": "sha512-R+rRMKfhd9mq0rj2mhU9A9NKI2l/Rw65vIYzz4lui7eTKPcCu1l7iZNi4b9Gen8D42Sqh/KGiaQNk/x5Tn/iBQ==", + "@webassemblyjs/leb128": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", + "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3" + "@xtuc/long": "4.2.1" } }, + "@webassemblyjs/utf8": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", + "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", + "dev": true + }, "@webassemblyjs/wasm-edit": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.4.3.tgz", - "integrity": "sha512-qzuwUn771PV6/LilqkXcS0ozJYAeY/OKbXIWU3a8gexuqb6De2p4ya/baBeH5JQ2WJdfhWhSvSbu86Vienttpw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-buffer": "1.4.3", - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/helper-wasm-section": "1.4.3", - "@webassemblyjs/wasm-gen": "1.4.3", - "@webassemblyjs/wasm-opt": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "@webassemblyjs/wast-printer": "1.4.3", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", + "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/helper-wasm-section": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-opt": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "@webassemblyjs/wast-printer": "1.7.11" } }, "@webassemblyjs/wasm-gen": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.4.3.tgz", - "integrity": "sha512-eR394T8dHZfpLJ7U/Z5pFSvxl1L63JdREebpv9gYc55zLhzzdJPAuxjBYT4XqevUdW67qU2s0nNA3kBuNJHbaQ==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", + "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/leb128": "1.4.3" + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" } }, "@webassemblyjs/wasm-opt": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.4.3.tgz", - "integrity": "sha512-7Gp+nschuKiDuAL1xmp4Xz0rgEbxioFXw4nCFYEmy+ytynhBnTeGc9W9cB1XRu1w8pqRU2lbj2VBBA4cL5Z2Kw==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", + "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-buffer": "1.4.3", - "@webassemblyjs/wasm-gen": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11" } }, "@webassemblyjs/wasm-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.4.3.tgz", - "integrity": "sha512-KXBjtlwA3BVukR/yWHC9GF+SCzBcgj0a7lm92kTOaa4cbjaTaa47bCjXw6cX4SGQpkncB9PU2hHGYVyyI7wFRg==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", + "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/leb128": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "webassemblyjs": "1.4.3" + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" } }, "@webassemblyjs/wast-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.4.3.tgz", - "integrity": "sha512-QhCsQzqV0CpsEkRYyTzQDilCNUZ+5j92f+g35bHHNqS22FppNTywNFfHPq8ZWZfYCgbectc+PoghD+xfzVFh1Q==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", + "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/floating-point-hex-parser": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-code-frame": "1.7.11", + "@webassemblyjs/helper-fsm": "1.7.11", + "@xtuc/long": "4.2.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", + "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/floating-point-hex-parser": "1.4.3", - "@webassemblyjs/helper-code-frame": "1.4.3", - "@webassemblyjs/helper-fsm": "1.4.3", - "long": "3.2.0", - "webassemblyjs": "1.4.3" + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11", + "@xtuc/long": "4.2.1" } }, - "@webassemblyjs/wast-printer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.4.3.tgz", - "integrity": "sha512-EgXk4anf8jKmuZJsqD8qy5bz2frEQhBvZruv+bqwNoLWUItjNSFygk8ywL3JTEz9KtxTlAmqTXNrdD1d9gNDtg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/wast-parser": "1.4.3", - "long": "3.2.0" - } + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", + "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", + "dev": true + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true }, - "@webpack-contrib/schema-utils": { - "version": "1.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@webpack-contrib/schema-utils/-/schema-utils-1.0.0-beta.0.tgz", - "integrity": "sha512-LonryJP+FxQQHsjGBi6W786TQB1Oym+agTpY0c+Kj8alnIw+DLUJb6SI8Y1GHGhLCH1yPRrucjObUmxNICQ1pg==", + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "requires": { - "ajv": "6.4.0", - "ajv-keywords": "3.2.0", - "chalk": "2.4.1", - "strip-ansi": "4.0.0", - "text-table": "0.2.0", - "webpack-log": "1.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.4.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - } + "jsonparse": "1.3.1", + "through": "2.3.8" } }, "abbrev": { @@ -1402,19 +1891,16 @@ } }, "acorn": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", + "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==", "dev": true }, "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "5.5.3" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true }, "acorn-jsx": { "version": "3.0.1", @@ -1454,28 +1940,51 @@ "es6-promisify": "5.0.0" } }, + "agentkeepalive": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "dev": true, + "requires": { + "humanize-ms": "1.2.1" + } + }, "ajv": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz", - "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "dev": true, "requires": { - "fast-deep-equal": "1.1.0", + "fast-deep-equal": "2.0.1", "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1", - "uri-js": "3.0.2" + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" + }, + "dependencies": { + "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=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "ajv-errors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.0.tgz", - "integrity": "sha1-7PAh+hCP0X37Xms4Py3SM+Mf/Fk=", + "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 }, "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", "dev": true }, "align-text": { @@ -1629,7 +2138,6 @@ "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.10", "normalize-path": "2.1.1" @@ -1685,6 +2193,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "requires": { "sprintf-js": "1.0.3" } @@ -1698,8 +2207,7 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" }, "arr-filter": { "version": "1.1.2", @@ -1713,8 +2221,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "arr-map": { "version": "2.0.2", @@ -1728,8 +2235,7 @@ "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, "array-each": { "version": "1.0.1", @@ -1750,9 +2256,9 @@ "dev": true }, "array-flatten": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", - "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, "array-initial": { @@ -1845,8 +2351,7 @@ "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "arraybuffer.slice": { "version": "0.0.7", @@ -1901,8 +2406,7 @@ "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "async": { "version": "1.5.2", @@ -1939,8 +2443,7 @@ "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" }, "async-foreach": { "version": "0.1.3", @@ -1972,21 +2475,20 @@ "atob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", - "dev": true + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=" }, "autoprefixer": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz", - "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==", + "version": "9.4.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.6.tgz", + "integrity": "sha512-Yp51mevbOEdxDUy5WjiKtpQaecqYq9OqZSL04rSoCiry7Tc5I9FEyo3bfxiTJc1DfHeKwSFCUYbBAiOQ2VGfiw==", "dev": true, "requires": { - "browserslist": "3.2.8", - "caniuse-lite": "1.0.30000877", + "browserslist": "4.4.1", + "caniuse-lite": "1.0.30000938", "normalize-range": "0.1.2", "num2fraction": "1.2.2", - "postcss": "6.0.23", - "postcss-value-parser": "3.3.0" + "postcss": "7.0.14", + "postcss-value-parser": "3.3.1" } }, "aws-sign2": { @@ -1996,9 +2498,9 @@ "dev": true }, "aws4": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, "babel-code-frame": { @@ -2078,7 +2580,7 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", + "core-js": "2.6.5", "regenerator-runtime": "0.11.1" } }, @@ -2162,7 +2664,6 @@ "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, "requires": { "cache-base": "1.0.1", "class-utils": "0.3.6", @@ -2177,7 +2678,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "1.0.2" } @@ -2186,7 +2686,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -2195,7 +2694,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -2204,7 +2702,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "1.0.0", "is-data-descriptor": "1.0.0", @@ -2257,21 +2754,20 @@ } }, "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, "binary-extensions": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" }, "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", "dev": true }, "block-stream": { @@ -2313,9 +2809,9 @@ "dev": true }, "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "dev": true, "requires": { "bytes": "3.0.0", @@ -2323,18 +2819,21 @@ "debug": "2.6.9", "depd": "1.1.2", "http-errors": "1.6.3", - "iconv-lite": "0.4.19", + "iconv-lite": "0.4.23", "on-finished": "2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", + "qs": "6.5.2", + "raw-body": "2.3.3", "type-is": "1.6.16" }, "dependencies": { - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": "2.1.2" + } } } }, @@ -2344,7 +2843,7 @@ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", "dev": true, "requires": { - "array-flatten": "2.1.1", + "array-flatten": "2.1.2", "deep-equal": "1.0.1", "dns-equal": "1.0.0", "dns-txt": "2.0.2", @@ -2352,12 +2851,6 @@ "multicast-dns-service-types": "1.1.0" } }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", @@ -2425,7 +2918,6 @@ "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", @@ -2443,7 +2935,6 @@ "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.1" } @@ -2500,7 +2991,7 @@ "dev": true, "requires": { "bn.js": "4.11.8", - "randombytes": "2.0.6" + "randombytes": "2.1.0" } }, "browserify-sign": { @@ -2515,7 +3006,7 @@ "create-hmac": "1.1.7", "elliptic": "6.4.1", "inherits": "2.0.3", - "parse-asn1": "5.1.1" + "parse-asn1": "5.1.4" } }, "browserify-zlib": { @@ -2528,13 +3019,14 @@ } }, "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", + "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000877", - "electron-to-chromium": "1.3.58" + "caniuse-lite": "1.0.30000938", + "electron-to-chromium": "1.3.113", + "node-releases": "1.1.8" } }, "browserstack": { @@ -2664,7 +3156,7 @@ "dev": true, "requires": { "bluebird": "3.5.1", - "chownr": "1.0.1", + "chownr": "1.1.1", "glob": "7.1.2", "graceful-fs": "4.1.11", "lru-cache": "4.1.3", @@ -2674,7 +3166,7 @@ "promise-inflight": "1.0.1", "rimraf": "2.6.2", "ssri": "5.3.0", - "unique-filename": "1.1.0", + "unique-filename": "1.1.1", "y18n": "4.0.0" } }, @@ -2682,7 +3174,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, "requires": { "collection-visit": "1.0.0", "component-emitter": "1.2.1", @@ -2722,16 +3213,6 @@ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "requires": { - "no-case": "2.3.2", - "upper-case": "1.1.3" - } - }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", @@ -2758,9 +3239,15 @@ } }, "caniuse-lite": { - "version": "1.0.30000877", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000877.tgz", - "integrity": "sha512-h04kV/lcuhItU1CZTJOxUEk/9R+1XeJqgc67E+XC8J9TjPM8kzVgOn27ZtRdDUo8O5F8U4QRCzDWJrVym3w3Cg==", + "version": "1.0.30000938", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000938.tgz", + "integrity": "sha512-ekW8NQ3/FvokviDxhdKLZZAx7PptXNwxKgXtnR5y+PR3hckwuP3yJ1Ir+4/c97dsHNqtAyfKUGdw8P4EYzBNgw==", + "dev": true + }, + "canonical-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", + "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", "dev": true }, "capture-stack-trace": { @@ -2814,6 +3301,12 @@ } } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "chokidar": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", @@ -2823,7 +3316,7 @@ "anymatch": "2.0.0", "async-each": "1.0.1", "braces": "2.3.2", - "fsevents": "1.2.4", + "fsevents": "1.2.7", "glob-parent": "3.1.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", @@ -2835,16 +3328,19 @@ } }, "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true }, "chrome-trace-event": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz", - "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", + "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } }, "ci-info": { "version": "1.6.0", @@ -2877,7 +3373,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, "requires": { "arr-union": "3.1.0", "define-property": "0.2.5", @@ -2889,7 +3384,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "0.1.6" } @@ -3015,22 +3509,22 @@ "dev": true, "requires": { "argv": "0.0.2", - "request": "2.87.0", + "request": "2.88.0", "urlgrey": "0.4.4" } }, "codelyzer": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.4.4.tgz", - "integrity": "sha512-JgFMudx0n50IuE/ydAfnkksCwQkWSVWgYvhDPHZgDUbmsiYC22VuEXKu5l8Hhx9UJsLgjWDLjTAFGj2WaW5DUA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.5.0.tgz", + "integrity": "sha512-oO6vCkjqsVrEsmh58oNlnJkRXuA30hF8cdNAQV9DytEalDwyOFRvHMnlKFzmOStNerOmPGZU9GAHnBo4tGvtiQ==", "dev": true, "requires": { "app-root-path": "2.1.0", - "css-selector-tokenizer": "0.7.0", + "css-selector-tokenizer": "0.7.1", "cssauron": "1.4.0", "semver-dsl": "1.0.1", "source-map": "0.5.7", - "sprintf-js": "1.1.1" + "sprintf-js": "1.1.2" }, "dependencies": { "source-map": { @@ -3040,9 +3534,9 @@ "dev": true }, "sprintf-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", - "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true } } @@ -3062,7 +3556,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, "requires": { "map-visit": "1.0.0", "object-visit": "1.0.1" @@ -3116,8 +3609,7 @@ "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, "commondir": { "version": "1.0.1", @@ -3140,8 +3632,7 @@ "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, "component-inherit": { "version": "0.0.3", @@ -3150,18 +3641,18 @@ "dev": true }, "compressible": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", - "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz", + "integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==", "dev": true, "requires": { - "mime-db": "1.37.0" + "mime-db": "1.38.0" }, "dependencies": { "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", "dev": true } } @@ -3174,7 +3665,7 @@ "requires": { "accepts": "1.3.5", "bytes": "3.0.0", - "compressible": "2.0.15", + "compressible": "2.0.16", "debug": "2.6.9", "on-headers": "1.0.1", "safe-buffer": "5.1.2", @@ -3248,9 +3739,9 @@ } }, "connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "dev": true }, "connected-domain": { @@ -3327,8 +3818,7 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "copy-props": { "version": "2.0.4", @@ -3341,19 +3831,19 @@ } }, "copy-webpack-plugin": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.2.tgz", - "integrity": "sha512-zmC33E8FFSq3AbflTvqvPvBo621H36Afsxlui91d+QyZxPIuXghfnTsa1CuqiAaCPgJoSUWfTFbKJnadZpKEbQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz", + "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==", "dev": true, "requires": { "cacache": "10.0.4", "find-cache-dir": "1.0.0", "globby": "7.1.1", "is-glob": "4.0.0", - "loader-utils": "1.1.0", + "loader-utils": "1.2.3", "minimatch": "3.0.4", "p-limit": "1.2.0", - "serialize-javascript": "1.5.0" + "serialize-javascript": "1.6.1" }, "dependencies": { "globby": { @@ -3373,15 +3863,14 @@ } }, "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" }, "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 + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cosmiconfig": { "version": "4.0.0", @@ -3434,7 +3923,7 @@ "requires": { "cipher-base": "1.0.4", "inherits": "2.0.3", - "md5.js": "1.3.4", + "md5.js": "1.3.5", "ripemd160": "2.0.2", "sha.js": "2.4.11" } @@ -3476,9 +3965,9 @@ "create-hmac": "1.1.7", "diffie-hellman": "5.0.3", "inherits": "2.0.3", - "pbkdf2": "3.0.16", - "public-encrypt": "4.0.2", - "randombytes": "2.0.6", + "pbkdf2": "3.0.17", + "public-encrypt": "4.0.3", + "randombytes": "2.1.0", "randomfill": "1.0.4" } }, @@ -3494,35 +3983,17 @@ "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", "dev": true }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "1.0.0", - "css-what": "2.1.0", - "domutils": "1.5.1", - "nth-check": "1.0.1" - } - }, "css-selector-tokenizer": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", - "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", + "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", "dev": true, "requires": { "cssesc": "0.1.0", - "fastparse": "1.1.1", + "fastparse": "1.1.2", "regexpu-core": "1.0.0" } }, - "css-what": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", - "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", - "dev": true - }, "cssauron": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", @@ -3574,27 +4045,152 @@ "es5-ext": "0.10.44" } }, + "d3": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-4.13.0.tgz", + "integrity": "sha512-l8c4+0SldjVKLaE2WG++EQlqD7mh/dmQjvi2L2lKPadAVC+TbJC4ci7Uk9bRi+To0+ansgsS0iWfPjD7DBy+FQ==", + "requires": { + "d3-array": "1.2.1", + "d3-axis": "1.0.8", + "d3-brush": "1.0.4", + "d3-chord": "1.0.4", + "d3-collection": "1.0.4", + "d3-color": "1.0.3", + "d3-dispatch": "1.0.3", + "d3-drag": "1.2.1", + "d3-dsv": "1.0.8", + "d3-ease": "1.0.3", + "d3-force": "1.1.0", + "d3-format": "1.2.2", + "d3-geo": "1.9.1", + "d3-hierarchy": "1.1.5", + "d3-interpolate": "1.1.6", + "d3-path": "1.0.5", + "d3-polygon": "1.0.3", + "d3-quadtree": "1.0.3", + "d3-queue": "3.0.7", + "d3-random": "1.1.0", + "d3-request": "1.0.6", + "d3-scale": "1.0.7", + "d3-selection": "1.3.0", + "d3-shape": "1.2.0", + "d3-time": "1.0.8", + "d3-time-format": "2.1.1", + "d3-timer": "1.0.7", + "d3-transition": "1.1.1", + "d3-voronoi": "1.1.2", + "d3-zoom": "1.7.1" + }, + "dependencies": { + "d3-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.1.tgz", + "integrity": "sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==" + }, + "d3-brush": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz", + "integrity": "sha1-AMLyOAGfJPbAoZSibUGhUw/+e8Q=", + "requires": { + "d3-dispatch": "1.0.3", + "d3-drag": "1.2.1", + "d3-interpolate": "1.1.6", + "d3-selection": "1.3.0", + "d3-transition": "1.1.1" + } + }, + "d3-color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.0.3.tgz", + "integrity": "sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=" + }, + "d3-force": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.0.tgz", + "integrity": "sha512-2HVQz3/VCQs0QeRNZTYb7GxoUCeb6bOzMp/cGcLa87awY9ZsPvXOGeZm0iaGBjXic6I1ysKwMn+g+5jSAdzwcg==", + "requires": { + "d3-collection": "1.0.4", + "d3-dispatch": "1.0.3", + "d3-quadtree": "1.0.3", + "d3-timer": "1.0.7" + } + }, + "d3-format": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.2.2.tgz", + "integrity": "sha512-zH9CfF/3C8zUI47nsiKfD0+AGDEuM8LwBIP7pBVpyR4l/sKkZqITmMtxRp04rwBrlshIZ17XeFAaovN3++wzkw==" + }, + "d3-hierarchy": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz", + "integrity": "sha1-ochFxC+Eoga88cAcAQmOpN2qeiY=" + }, + "d3-interpolate": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.1.6.tgz", + "integrity": "sha512-mOnv5a+pZzkNIHtw/V6I+w9Lqm9L5bG3OTXPM5A+QO0yyVMQ4W1uZhR+VOJmazaOZXri2ppbiZ5BUNWT0pFM9A==", + "requires": { + "d3-color": "1.0.3" + } + }, + "d3-selection": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.0.tgz", + "integrity": "sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==" + }, + "d3-shape": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.0.tgz", + "integrity": "sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=", + "requires": { + "d3-path": "1.0.5" + } + }, + "d3-time-format": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.1.tgz", + "integrity": "sha512-8kAkymq2WMfzW7e+s/IUNAtN/y3gZXGRrdGfo6R8NKPAA85UBTxZg5E61bR6nLwjPjj4d3zywSQe1CkYLPFyrw==", + "requires": { + "d3-time": "1.0.8" + } + } + } + }, "d3-array": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" }, + "d3-axis": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.8.tgz", + "integrity": "sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=" + }, "d3-brush": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.6.tgz", "integrity": "sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w==", "requires": { - "d3-dispatch": "1.0.5", - "d3-drag": "1.2.3", + "d3-dispatch": "1.0.3", + "d3-drag": "1.2.1", "d3-interpolate": "1.3.2", - "d3-selection": "1.3.2", - "d3-transition": "1.1.3" + "d3-selection": "1.4.0", + "d3-transition": "1.1.1" + } + }, + "d3-chord": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.4.tgz", + "integrity": "sha1-fexPC6iG9xP+ERxF92NBT290yiw=", + "requires": { + "d3-array": "1.2.4", + "d3-path": "1.0.5" } }, "d3-collection": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", - "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", + "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=" }, "d3-color": { "version": "1.2.3", @@ -3602,33 +4198,43 @@ "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==" }, "d3-dispatch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.5.tgz", - "integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", + "integrity": "sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=" }, "d3-drag": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz", - "integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.1.tgz", + "integrity": "sha512-Cg8/K2rTtzxzrb0fmnYOUeZHvwa4PHzwXOLZZPwtEs2SKLLKLXeYwZKBB+DlOxUvFmarOnmt//cU4+3US2lyyQ==", + "requires": { + "d3-dispatch": "1.0.3", + "d3-selection": "1.4.0" + } + }, + "d3-dsv": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.8.tgz", + "integrity": "sha512-IVCJpQ+YGe3qu6odkPQI0KPqfxkhbP/oM1XhhE/DFiYmcXKfCRub4KXyiuehV1d4drjWVXHUWx4gHqhdZb6n/A==", "requires": { - "d3-dispatch": "1.0.5", - "d3-selection": "1.3.2" + "commander": "2.15.1", + "iconv-lite": "0.4.19", + "rw": "1.3.3" } }, "d3-ease": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz", - "integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.3.tgz", + "integrity": "sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=" }, "d3-force": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.2.tgz", - "integrity": "sha512-p1vcHAUF1qH7yR+e8ip7Bs61AHjLeKkIn8Z2gzwU2lwEf2wkSpWdjXG0axudTHsVFnYGlMkFaEsVy2l8tAg1Gw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.0.tgz", + "integrity": "sha512-PFLcDnRVANHMudbQlIB87gcfQorEsDIAvRpZ2bNddfM/WxdsEkyrEaOIPoydhH1I1V4HPjNLGOMLXCA0AuGQ9w==", "requires": { - "d3-collection": "1.0.7", - "d3-dispatch": "1.0.5", - "d3-quadtree": "1.0.5", - "d3-timer": "1.0.9" + "d3-collection": "1.0.4", + "d3-dispatch": "1.0.3", + "d3-quadtree": "1.0.3", + "d3-timer": "1.0.7" } }, "d3-format": { @@ -3636,6 +4242,14 @@ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.2.tgz", "integrity": "sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ==" }, + "d3-geo": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.9.1.tgz", + "integrity": "sha512-l9wL/cEQkyZQYXw3xbmLsH3eQ5ij+icNfo4r0GrLa5rOCZR/e/3am45IQ0FvQ5uMsv+77zBRunLc9ufTWSQYFA==", + "requires": { + "d3-array": "1.2.4" + } + }, "d3-hierarchy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz", @@ -3650,14 +4264,40 @@ } }, "d3-path": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz", - "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", + "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" + }, + "d3-polygon": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.3.tgz", + "integrity": "sha1-FoiOkCZGCTPysXllKtN4Ik04LGI=" }, "d3-quadtree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.5.tgz", - "integrity": "sha512-U2tjwDFbZ75JRAg8A+cqMvqPg1G3BE7UTJn3h8DHjY/pnsAfWdbJKgyfcy7zKjqGtLAmI0q8aDSeG1TVIKRaHQ==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.3.tgz", + "integrity": "sha1-rHmH4+I/6AWpkPKOG1DTj8uCJDg=" + }, + "d3-queue": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/d3-queue/-/d3-queue-3.0.7.tgz", + "integrity": "sha1-yTouVLQXwJWRKdfXP2z31Ckudhg=" + }, + "d3-random": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.0.tgz", + "integrity": "sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=" + }, + "d3-request": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-request/-/d3-request-1.0.6.tgz", + "integrity": "sha512-FJj8ySY6GYuAJHZMaCQ83xEYE4KbkPkmxZ3Hu6zA1xxG2GD+z6P+Lyp+zjdsHf0xEbp2xcluDI50rCS855EQ6w==", + "requires": { + "d3-collection": "1.0.4", + "d3-dispatch": "1.0.3", + "d3-dsv": "1.0.8", + "xmlhttprequest": "1.8.0" + } }, "d3-scale": { "version": "1.0.7", @@ -3665,56 +4305,73 @@ "integrity": "sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw==", "requires": { "d3-array": "1.2.4", - "d3-collection": "1.0.7", + "d3-collection": "1.0.4", "d3-color": "1.2.3", "d3-format": "1.3.2", "d3-interpolate": "1.3.2", - "d3-time": "1.0.10", + "d3-time": "1.0.8", "d3-time-format": "2.1.3" } }, "d3-selection": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.2.tgz", - "integrity": "sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.0.tgz", + "integrity": "sha512-EYVwBxQGEjLCKF2pJ4+yrErskDnz5v403qvAid96cNdCMr8rmCYfY5RGzWz24mdIbxmDf6/4EAH+K9xperD5jg==" }, "d3-shape": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.2.tgz", - "integrity": "sha512-hUGEozlKecFZ2bOSNt7ENex+4Tk9uc/m0TtTEHBvitCBxUNjhzm5hS2GrrVRD/ae4IylSmxGeqX5tWC2rASMlQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.4.tgz", + "integrity": "sha512-izaz4fOpOnY3CD17hkZWNxbaN70sIGagLR/5jb6RS96Y+6VqX+q1BQf1av6QSBRdfULi3Gb8Js4CzG4+KAPjMg==", "requires": { - "d3-path": "1.0.7" + "d3-path": "1.0.5" } }, "d3-time": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.10.tgz", - "integrity": "sha512-hF+NTLCaJHF/JqHN5hE8HVGAXPStEq6/omumPE/SxyHVrR7/qQxusFDo0t0c/44+sCGHthC7yNGFZIEgju0P8g==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.8.tgz", + "integrity": "sha512-YRZkNhphZh3KcnBfitvF3c6E0JOFGikHZ4YqD+Lzv83ZHn1/u6yGenRU1m+KAk9J1GnZMnKcrtfvSktlA1DXNQ==" }, "d3-time-format": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.3.tgz", "integrity": "sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA==", "requires": { - "d3-time": "1.0.10" + "d3-time": "1.0.8" } }, "d3-timer": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz", - "integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.7.tgz", + "integrity": "sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==" }, "d3-transition": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.3.tgz", - "integrity": "sha512-tEvo3qOXL6pZ1EzcXxFcPNxC/Ygivu5NoBY6mbzidATAeML86da+JfVIUzon3dNM6UX6zjDx+xbYDmMVtTSjuA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.1.tgz", + "integrity": "sha512-xeg8oggyQ+y5eb4J13iDgKIjUcEfIOZs2BqV/eEmXm2twx80wTzJ4tB4vaZ5BKfz7XsI/DFmQL5me6O27/5ykQ==", "requires": { "d3-color": "1.2.3", - "d3-dispatch": "1.0.5", - "d3-ease": "1.0.5", + "d3-dispatch": "1.0.3", + "d3-ease": "1.0.3", + "d3-interpolate": "1.3.2", + "d3-selection": "1.4.0", + "d3-timer": "1.0.7" + } + }, + "d3-voronoi": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", + "integrity": "sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=" + }, + "d3-zoom": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.1.tgz", + "integrity": "sha512-sZHQ55DGq5BZBFGnRshUT8tm2sfhPHFnOlmPbbwTkAoPeVdRTkB4Xsf9GCY0TSHrTD8PeJPZGmP/TpGicwJDJQ==", + "requires": { + "d3-dispatch": "1.0.3", + "d3-drag": "1.2.1", "d3-interpolate": "1.3.2", - "d3-selection": "1.3.2", - "d3-timer": "1.0.9" + "d3-selection": "1.4.0", + "d3-transition": "1.1.1" } }, "dashdash": { @@ -3742,7 +4399,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -3756,8 +4412,7 @@ "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { "version": "1.0.1", @@ -3877,7 +4532,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, "requires": { "is-descriptor": "1.0.2", "isobject": "3.0.1" @@ -3887,7 +4541,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -3896,7 +4549,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -3905,7 +4557,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "1.0.0", "is-data-descriptor": "1.0.0", @@ -3994,6 +4645,12 @@ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true }, + "dependency-graph": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", + "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", + "dev": true + }, "des.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", @@ -4051,7 +4708,7 @@ "requires": { "bn.js": "4.11.8", "miller-rabin": "4.0.1", - "randombytes": "2.0.6" + "randombytes": "2.1.0" } }, "dir-glob": { @@ -4099,51 +4756,16 @@ "isarray": "1.0.0" } }, - "dom-converter": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", - "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", - "dev": true, - "requires": { - "utila": "0.3.3" - }, - "dependencies": { - "utila": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", - "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", - "dev": true - } - } - }, "dom-serialize": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", "dev": true, "requires": { - "custom-event": "1.0.1", - "ent": "2.2.0", - "extend": "3.0.1", - "void-elements": "2.0.1" - } - }, - "dom-serializer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", - "dev": true, - "requires": { - "domelementtype": "1.1.3", - "entities": "1.1.1" - }, - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", - "dev": true - } + "custom-event": "1.0.1", + "ent": "2.2.0", + "extend": "3.0.1", + "void-elements": "2.0.1" } }, "domain-browser": { @@ -4152,35 +4774,10 @@ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, - "domelementtype": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", - "dev": true - }, - "domhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", - "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, "domino": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/domino/-/domino-2.0.2.tgz", - "integrity": "sha512-vzykUakUw5s1p0RrN/vI2sShYo3pLRy/z7PM1PuOIZIlMOJ0XfOnrckGE5f4MxIQVe5XcrH7yG9mR+l77mgLVA==" - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.3.0" - } + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.2.tgz", + "integrity": "sha512-nzg76s4Smji9teyLwOnqqUCdFVOho+OQFqUwp+42Wo+SEZ1FGw7uhemv6OKk2qp8YIgnGB3jVt0sJWU96wbPgA==" }, "dot-prop": { "version": "4.2.0", @@ -4241,16 +4838,10 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "ejs": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", - "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", - "dev": true - }, "electron-to-chromium": { - "version": "1.3.58", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.58.tgz", - "integrity": "sha512-AGJxlBEn2wOohxqWZkISVsOjZueKTQljfEODTDSEiMqSpH0S+xzV+/5oEM9AGaqhu7DzrpKOgU7ocQRjj0nJmg==", + "version": "1.3.113", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz", + "integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==", "dev": true }, "elliptic": { @@ -4261,7 +4852,7 @@ "requires": { "bn.js": "4.11.8", "brorand": "1.1.0", - "hash.js": "1.1.5", + "hash.js": "1.1.7", "hmac-drbg": "1.0.1", "inherits": "2.0.3", "minimalistic-assert": "1.0.1", @@ -4280,6 +4871,15 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, + "requires": { + "iconv-lite": "0.4.19" + } + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -4290,16 +4890,16 @@ } }, "engine.io": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", - "integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", "dev": true, "requires": { "accepts": "1.3.5", "base64id": "1.0.0", "cookie": "0.3.1", "debug": "3.1.0", - "engine.io-parser": "2.1.2", + "engine.io-parser": "2.1.3", "ws": "3.3.3" }, "dependencies": { @@ -4323,7 +4923,7 @@ "component-emitter": "1.2.1", "component-inherit": "0.0.3", "debug": "3.1.0", - "engine.io-parser": "2.1.2", + "engine.io-parser": "2.1.3", "has-cors": "1.1.0", "indexof": "0.0.1", "parseqs": "0.0.5", @@ -4345,15 +4945,15 @@ } }, "engine.io-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", "dev": true, "requires": { "after": "0.8.2", "arraybuffer.slice": "0.0.7", "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", + "blob": "0.0.5", "has-binary2": "1.0.3" } }, @@ -4365,7 +4965,7 @@ "requires": { "graceful-fs": "4.1.11", "memory-fs": "0.4.1", - "tapable": "1.0.0" + "tapable": "1.1.1" } }, "ent": { @@ -4374,10 +4974,10 @@ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, - "entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", "dev": true }, "errno": { @@ -4547,6 +5147,12 @@ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, "source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", @@ -4569,14 +5175,6 @@ "es6-weak-map": "2.0.2", "esrecurse": "4.2.1", "estraverse": "4.2.0" - }, - "dependencies": { - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - } } }, "eslint": { @@ -4639,12 +5237,6 @@ "supports-color": "2.0.0" } }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -4654,21 +5246,13 @@ } }, "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { "esrecurse": "4.2.1", "estraverse": "4.2.0" - }, - "dependencies": { - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - } } }, "espree": { @@ -4677,14 +5261,23 @@ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "acorn": "5.5.3", + "acorn": "5.7.3", "acorn-jsx": "3.0.1" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + } } }, "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true }, "esrecurse": { "version": "4.2.1", @@ -4693,20 +5286,12 @@ "dev": true, "requires": { "estraverse": "4.2.0" - }, - "dependencies": { - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - } } }, "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", "dev": true }, "estree-walker": { @@ -4759,9 +5344,9 @@ "dev": true }, "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", "dev": true }, "eventsource": { @@ -4779,7 +5364,7 @@ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "md5.js": "1.3.4", + "md5.js": "1.3.5", "safe-buffer": "5.1.2" } }, @@ -4854,28 +5439,6 @@ "requires": { "expand-range": "0.1.1" } - }, - "expand-range": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "dev": true, - "requires": { - "is-number": "0.1.1", - "repeat-string": "0.2.2" - } - }, - "is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", - "dev": true - }, - "repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", - "dev": true } } }, @@ -4883,7 +5446,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, "requires": { "debug": "2.6.9", "define-property": "0.2.5", @@ -4898,7 +5460,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "0.1.6" } @@ -4907,7 +5468,6 @@ "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.1" } @@ -4915,53 +5475,26 @@ } }, "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", "dev": true, "requires": { - "fill-range": "2.2.4" + "is-number": "0.1.1", + "repeat-string": "0.2.2" }, "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "3.0.0", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", + "dev": true }, - "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.6" - } + "repeat-string": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", + "dev": true } } }, @@ -5018,44 +5551,13 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", - "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "1.6.16" - } - }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, "requires": { "safer-buffer": "2.1.2" } - }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "dev": true, - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - } } } }, @@ -5069,7 +5571,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, "requires": { "assign-symbols": "1.0.0", "is-extendable": "1.0.1" @@ -5079,18 +5580,38 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "2.0.4" } } } }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "0.7.0", + "iconv-lite": "0.4.24", + "tmp": "0.0.33" + }, + "dependencies": { + "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, + "requires": { + "safer-buffer": "2.1.2" + } + } + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, "requires": { "array-unique": "0.3.2", "define-property": "1.0.0", @@ -5106,7 +5627,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "1.0.2" } @@ -5115,7 +5635,6 @@ "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.1" } @@ -5124,7 +5643,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -5133,7 +5651,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -5142,7 +5659,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "1.0.0", "is-data-descriptor": "1.0.0", @@ -5191,8 +5707,7 @@ "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=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fast-levenshtein": { "version": "2.0.6", @@ -5201,9 +5716,9 @@ "dev": true }, "fastparse": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", - "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", "dev": true }, "faye-websocket": { @@ -5215,6 +5730,12 @@ "websocket-driver": "0.7.0" } }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true + }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -5236,21 +5757,15 @@ } }, "file-loader": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", - "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", + "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", "dev": true, "requires": { - "loader-utils": "1.1.0", - "schema-utils": "0.4.7" + "loader-utils": "1.2.3", + "schema-utils": "1.0.0" } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, "fileset": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", @@ -5265,7 +5780,6 @@ "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", @@ -5277,7 +5791,6 @@ "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.1" } @@ -5476,6 +5989,12 @@ } } }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -5509,8 +6028,7 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, "for-own": { "version": "1.0.0", @@ -5563,7 +6081,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, "requires": { "map-cache": "0.2.2" } @@ -5625,6 +6142,15 @@ "universalify": "0.1.1" } }, + "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, + "requires": { + "minipass": "2.3.5" + } + }, "fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -5650,44 +6176,36 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "optional": true, "requires": { "nan": "2.10.0", - "node-pre-gyp": "0.10.0" + "node-pre-gyp": "0.10.3" }, "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, + "bundled": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": false, - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "bundled": true }, "aproba": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, + "bundled": true, "optional": true }, "are-we-there-yet": { - "version": "1.1.4", - "resolved": false, - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", - "dev": true, + "version": "1.1.5", + "bundled": true, "optional": true, "requires": { "delegates": "1.0.0", @@ -5696,105 +6214,77 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", - "resolved": false, - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "bundled": true, "requires": { "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true, + "version": "1.1.1", + "bundled": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "bundled": true }, "core-util-is": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, + "bundled": true, "optional": true }, "debug": { "version": "2.6.9", - "resolved": false, - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, + "bundled": true, "optional": true, "requires": { "ms": "2.0.0" } }, "deep-extend": { - "version": "0.5.1", - "resolved": false, - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", - "dev": true, + "version": "0.6.0", + "bundled": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, + "bundled": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": false, - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, + "bundled": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": false, - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, + "bundled": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "2.3.5" } }, "fs.realpath": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, + "bundled": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": false, - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, + "bundled": true, "optional": true, "requires": { "aproba": "1.2.0", @@ -5804,14 +6294,12 @@ "signal-exit": "3.0.2", "string-width": "1.0.2", "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "wide-align": "1.1.3" } }, "glob": { - "version": "7.1.2", - "resolved": false, - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, + "version": "7.1.3", + "bundled": true, "optional": true, "requires": { "fs.realpath": "1.0.0", @@ -5824,16 +6312,12 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, + "bundled": true, "optional": true }, "iconv-lite": { - "version": "0.4.21", - "resolved": false, - "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", - "dev": true, + "version": "0.4.24", + "bundled": true, "optional": true, "requires": { "safer-buffer": "2.1.2" @@ -5841,9 +6325,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": false, - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, + "bundled": true, "optional": true, "requires": { "minimatch": "3.0.4" @@ -5851,9 +6333,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": false, - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, + "bundled": true, "optional": true, "requires": { "once": "1.4.0", @@ -5862,120 +6342,94 @@ }, "inherits": { "version": "2.0.3", - "resolved": false, - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "bundled": true }, "ini": { "version": "1.3.5", - "resolved": false, - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, + "bundled": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, + "bundled": true, "requires": { "number-is-nan": "1.0.1" } }, "isarray": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, + "bundled": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": false, - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, + "bundled": true, "requires": { "brace-expansion": "1.1.11" } }, "minimist": { "version": "0.0.8", - "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "bundled": true }, "minipass": { - "version": "2.2.4", - "resolved": false, - "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", - "dev": true, + "version": "2.3.5", + "bundled": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "5.1.2", + "yallist": "3.0.3" } }, "minizlib": { - "version": "1.1.0", - "resolved": false, - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", - "dev": true, + "version": "1.2.1", + "bundled": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "2.3.5" } }, "mkdirp": { "version": "0.5.1", - "resolved": false, - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, + "bundled": true, "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, + "bundled": true, "optional": true }, "needle": { - "version": "2.2.0", - "resolved": false, - "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", - "dev": true, + "version": "2.2.4", + "bundled": true, "optional": true, "requires": { "debug": "2.6.9", - "iconv-lite": "0.4.21", + "iconv-lite": "0.4.24", "sax": "1.2.4" } }, "node-pre-gyp": { - "version": "0.10.0", - "resolved": false, - "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", - "dev": true, + "version": "0.10.3", + "bundled": true, "optional": true, "requires": { "detect-libc": "1.0.3", "mkdirp": "0.5.1", - "needle": "2.2.0", + "needle": "2.2.4", "nopt": "4.0.1", - "npm-packlist": "1.1.10", + "npm-packlist": "1.2.0", "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "rc": "1.2.8", + "rimraf": "2.6.3", + "semver": "5.6.0", + "tar": "4.4.8" } }, "nopt": { "version": "4.0.1", - "resolved": false, - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, + "bundled": true, "optional": true, "requires": { "abbrev": "1.1.1", @@ -5983,31 +6437,25 @@ } }, "npm-bundled": { - "version": "1.0.3", - "resolved": false, - "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", - "dev": true, + "version": "1.0.5", + "bundled": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", - "resolved": false, - "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", - "dev": true, + "version": "1.2.0", + "bundled": true, "optional": true, "requires": { "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "npm-bundled": "1.0.5" } }, "npmlog": { "version": "4.1.2", - "resolved": false, - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, + "bundled": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", + "are-we-there-yet": "1.1.5", "console-control-strings": "1.1.0", "gauge": "2.7.4", "set-blocking": "2.0.0" @@ -6015,45 +6463,33 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "bundled": true }, "object-assign": { "version": "4.1.1", - "resolved": false, - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, + "bundled": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": false, - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, + "bundled": true, "requires": { "wrappy": "1.0.2" } }, "os-homedir": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, + "bundled": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, + "bundled": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": false, - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, + "bundled": true, "optional": true, "requires": { "os-homedir": "1.0.2", @@ -6062,26 +6498,20 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, + "bundled": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true, + "bundled": true, "optional": true }, "rc": { - "version": "1.2.7", - "resolved": false, - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", - "dev": true, + "version": "1.2.8", + "bundled": true, "optional": true, "requires": { - "deep-extend": "0.5.1", + "deep-extend": "0.6.0", "ini": "1.3.5", "minimist": "1.2.0", "strip-json-comments": "2.0.1" @@ -6089,85 +6519,65 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, + "bundled": true, "optional": true } } }, "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, + "bundled": true, "optional": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", + "safe-buffer": "5.1.2", "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "rimraf": { - "version": "2.6.2", - "resolved": false, - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, + "version": "2.6.3", + "bundled": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "7.1.3" } }, "safe-buffer": { - "version": "5.1.1", - "resolved": false, - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "version": "5.1.2", + "bundled": true }, "safer-buffer": { "version": "2.1.2", - "resolved": false, - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, + "bundled": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": false, - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, + "bundled": true, "optional": true }, "semver": { - "version": "5.5.0", - "resolved": false, - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true, + "version": "5.6.0", + "bundled": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, + "bundled": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": false, - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, + "bundled": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, + "bundled": true, "requires": { "code-point-at": "1.1.0", "is-fullwidth-code-point": "1.0.0", @@ -6176,58 +6586,46 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, + "bundled": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "strip-ansi": { "version": "3.0.1", - "resolved": false, - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, + "bundled": true, "requires": { "ansi-regex": "2.1.1" } }, "strip-json-comments": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, + "bundled": true, "optional": true }, "tar": { - "version": "4.4.1", - "resolved": false, - "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", - "dev": true, + "version": "4.4.8", + "bundled": true, "optional": true, "requires": { - "chownr": "1.0.1", + "chownr": "1.1.1", "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", + "minipass": "2.3.5", + "minizlib": "1.2.1", "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "5.1.2", + "yallist": "3.0.3" } }, "util-deprecate": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, + "bundled": true, "optional": true }, "wide-align": { - "version": "1.1.2", - "resolved": false, - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", - "dev": true, + "version": "1.1.3", + "bundled": true, "optional": true, "requires": { "string-width": "1.0.2" @@ -6235,15 +6633,11 @@ }, "wrappy": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "bundled": true }, "yallist": { - "version": "3.0.2", - "resolved": false, - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true + "version": "3.0.3", + "bundled": true } } }, @@ -6305,6 +6699,12 @@ "is-property": "1.0.2" } }, + "genfun": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", + "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "dev": true + }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", @@ -6326,8 +6726,7 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, "getpass": { "version": "0.1.7", @@ -6342,6 +6741,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -6351,47 +6751,10 @@ "path-is-absolute": "1.0.1" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "2.0.1" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "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, "requires": { "is-glob": "3.1.0", "path-dirname": "1.0.2" @@ -6401,7 +6764,6 @@ "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.1" } @@ -6571,8 +6933,7 @@ "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "graphviz": { "version": "0.0.8", @@ -6695,9 +7056,9 @@ "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=" }, "handle-thing": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", - "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", "dev": true }, "handlebars": { @@ -6751,25 +7112,46 @@ "dev": true }, "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "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": "5.5.2", + "ajv": "6.9.1", "har-schema": "2.0.0" }, "dependencies": { "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "dev": true, "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", + "fast-deep-equal": "2.0.1", "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "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=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "2.1.1" } } } @@ -6863,7 +7245,6 @@ "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", @@ -6874,7 +7255,6 @@ "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" @@ -6884,7 +7264,6 @@ "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.6" } @@ -6902,28 +7281,22 @@ } }, "hash.js": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", - "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", + "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" } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "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.1.5", + "hash.js": "1.1.7", "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } @@ -6961,113 +7334,11 @@ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", "dev": true }, - "html-minifier": { - "version": "3.5.19", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.19.tgz", - "integrity": "sha512-Qr2JC9nsjK8oCrEmuB430ZIA8YWbF3D5LSjywD75FTuXmeqacwHgIM8wp3vHYzzPbklSjp53RdmDuzR4ub2HzA==", - "dev": true, - "requires": { - "camel-case": "3.0.0", - "clean-css": "4.1.11", - "commander": "2.16.0", - "he": "1.1.1", - "param-case": "2.1.1", - "relateurl": "0.2.7", - "uglify-js": "3.4.7" - }, - "dependencies": { - "clean-css": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz", - "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=", - "dev": true, - "requires": { - "source-map": "0.5.6" - } - }, - "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", - "dev": true - } - } - }, - "html-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", - "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", - "dev": true, - "requires": { - "html-minifier": "3.5.19", - "loader-utils": "0.2.17", - "lodash": "4.17.10", - "pretty-error": "2.1.1", - "tapable": "1.0.0", - "toposort": "1.0.7", - "util.promisify": "1.0.0" - }, - "dependencies": { - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" - } - } - } - }, - "htmlparser2": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", - "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", - "dev": true, - "requires": { - "domelementtype": "1.3.0", - "domhandler": "2.1.0", - "domutils": "1.1.6", - "readable-stream": "1.0.34" - }, - "dependencies": { - "domutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", - "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true }, "http-deceiver": { "version": "1.2.7", @@ -7104,6 +7375,27 @@ "requires-port": "1.0.0" } }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "requires": { + "agent-base": "4.2.0", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "http-proxy-middleware": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", @@ -7154,11 +7446,19 @@ } } }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, "ieee754": { "version": "1.1.12", @@ -7178,6 +7478,15 @@ "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", "dev": true }, + "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, + "requires": { + "minimatch": "3.0.4" + } + }, "image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", @@ -7310,6 +7619,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "1.4.0", "wrappy": "1.0.2" @@ -7443,7 +7753,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -7452,7 +7761,6 @@ "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.6" } @@ -7469,7 +7777,6 @@ "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.11.0" } @@ -7477,8 +7784,7 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-builtin-module": { "version": "1.0.0", @@ -7508,7 +7814,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -7517,7 +7822,6 @@ "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.6" } @@ -7534,7 +7838,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", "is-data-descriptor": "0.1.4", @@ -7544,8 +7847,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" } } }, @@ -7555,32 +7857,15 @@ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, "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-finite": { "version": "1.0.2", @@ -7604,7 +7889,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, "requires": { "is-extglob": "2.1.1" } @@ -7660,7 +7944,6 @@ "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.2.2" }, @@ -7669,7 +7952,6 @@ "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.6" } @@ -7686,7 +7968,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", - "dev": true, "requires": { "is-number": "4.0.0" }, @@ -7694,8 +7975,7 @@ "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" } } }, @@ -7727,21 +8007,14 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "requires": { "isobject": "3.0.1" } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, "is-property": { @@ -7834,8 +8107,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, "is-wsl": { "version": "1.1.0", @@ -7846,8 +8118,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isbinaryfile": { "version": "3.0.3", @@ -7867,8 +8138,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "isstream": { "version": "0.1.2", @@ -7979,7 +8249,7 @@ "requires": { "convert-source-map": "1.5.1", "istanbul-lib-instrument": "1.10.1", - "loader-utils": "1.1.0", + "loader-utils": "1.2.3", "schema-utils": "0.3.0" }, "dependencies": { @@ -8118,20 +8388,11 @@ } }, "jasmine-core": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.1.0.tgz", - "integrity": "sha1-pHheE11d9lAk38kiSVPfWFvSdmw=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.3.0.tgz", + "integrity": "sha512-3/xSmG/d35hf80BEN66Y6g9Ca5l/Isdeg/j6zvbTYlTzeKinzmaTM4p9am5kYqOmE05D7s1t8FGjzdSnbUbceA==", "dev": true }, - "jasmine-diff": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/jasmine-diff/-/jasmine-diff-0.1.3.tgz", - "integrity": "sha1-k8zC3MQQKMXd1GBlWAdIOfLe6qg=", - "dev": true, - "requires": { - "diff": "3.5.0" - } - }, "jasmine-spec-reporter": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", @@ -8163,6 +8424,7 @@ "version": "3.11.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "dev": true, "requires": { "argparse": "1.0.10", "esprima": "4.0.0" @@ -8221,10 +8483,21 @@ "dev": true }, "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } }, "jsonfile": { "version": "3.0.1", @@ -8241,6 +8514,12 @@ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, "jsonpointer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", @@ -8319,28 +8598,29 @@ "dev": true }, "karma": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-3.0.0.tgz", - "integrity": "sha512-ZTjyuDXVXhXsvJ1E4CnZzbCjSxD6sEdzEsFYogLuZM0yqvg/mgz+O+R1jb0J7uAQeuzdY8kJgx6hSNXLwFuHIQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/karma/-/karma-4.0.0.tgz", + "integrity": "sha512-EFoFs3F6G0BcUGPNOn/YloGOb3h09hzTguyXlg6loHlKY76qbJikkcyPk43m2kfRF65TUGda/mig29QQtyhm1g==", "dev": true, "requires": { "bluebird": "3.5.1", - "body-parser": "1.18.2", + "body-parser": "1.18.3", "chokidar": "2.0.3", "colors": "1.1.2", "combine-lists": "1.0.1", "connect": "3.6.6", - "core-js": "2.5.7", + "core-js": "2.6.5", "di": "0.0.1", "dom-serialize": "2.2.1", "expand-braces": "0.1.2", + "flatted": "2.0.0", "glob": "7.1.2", "graceful-fs": "4.1.11", "http-proxy": "1.17.0", "isbinaryfile": "3.0.3", "lodash": "4.17.10", - "log4js": "3.0.5", - "mime": "2.3.1", + "log4js": "3.0.6", + "mime": "2.4.0", "minimatch": "3.0.4", "optimist": "0.6.1", "qjobs": "1.2.0", @@ -8350,13 +8630,13 @@ "socket.io": "2.1.1", "source-map": "0.6.1", "tmp": "0.0.33", - "useragent": "2.2.1" + "useragent": "2.3.0" }, "dependencies": { "mime": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "dev": true }, "source-map": { @@ -8397,15 +8677,18 @@ } }, "karma-jasmine": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.2.tgz", - "integrity": "sha1-OU8rJf+0pkS5rabyLUQ+L9CIhsM=", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-2.0.1.tgz", + "integrity": "sha512-iuC0hmr9b+SNn1DaUD2QEYtUxkS1J+bSJSn7ejdEexs7P8EYvA1CWkEdrDQ+8jVH3AgWlCNwjYsT1chjcNW9lA==", + "dev": true, + "requires": { + "jasmine-core": "3.3.0" + } }, "karma-jasmine-html-reporter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.1.0.tgz", - "integrity": "sha512-uhNED+4B1axgptXkM8cCa3kztpQqsPrOxhfbjr4FdunNexnU6+cF2bfiIeGfsFMhphVyOMKy/S9LFaOFj8VXRA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.4.0.tgz", + "integrity": "sha512-0wxhwA8PLPpICZ4o2GRnPi67hf3JhfQm5WCB8nElh4qsE6wRNOTtrqooyBPNqI087Xr2SBhxLg5fU+BJ/qxRrw==", "dev": true }, "karma-source-map-support": { @@ -8414,7 +8697,7 @@ "integrity": "sha512-HcPqdAusNez/ywa+biN4EphGz62MmQyPggUsDfsHqa7tSe4jdsxgvTKuDfIazjL+IOxpVWyT7Pr4dhAV+sxX5Q==", "dev": true, "requires": { - "source-map-support": "0.5.6" + "source-map-support": "0.5.10" } }, "karma-spec-reporter": { @@ -8435,8 +8718,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" }, "klaw-sync": { "version": "2.1.0", @@ -8505,16 +8787,10 @@ "flush-write-stream": "1.0.3" } }, - "leb": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/leb/-/leb-0.3.0.tgz", - "integrity": "sha1-Mr7p+tFoMo1q6oUi2DP0GA7tHaM=", - "dev": true - }, "less": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/less/-/less-3.8.1.tgz", - "integrity": "sha512-8HFGuWmL3FhQR0aH89escFNBQH/nEiYPP2ltDFdQw2chE28Yx2E3lhAIq9Y2saYwLSwa699s4dBVEfCY8Drf7Q==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", + "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", "dev": true, "requires": { "clone": "2.1.2", @@ -8524,7 +8800,7 @@ "mime": "1.6.0", "mkdirp": "0.5.1", "promise": "7.3.1", - "request": "2.87.0", + "request": "2.88.0", "source-map": "0.6.1" }, "dependencies": { @@ -8550,7 +8826,7 @@ "dev": true, "requires": { "clone": "2.1.1", - "loader-utils": "1.1.0", + "loader-utils": "1.2.3", "pify": "3.0.0" } }, @@ -8592,12 +8868,13 @@ } }, "license-webpack-plugin": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.4.0.tgz", - "integrity": "sha512-iwuNFMWbXS76WiQXJBTs8/7Tby4NQnY8AIkBMuJG5El79UT8zWrJQMfpW+KRXt4Y2Bs5uk+Myg/MO7ROSF8jzA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.1.0.tgz", + "integrity": "sha512-vDiBeMWxjE9n6TabQ9J4FH8urFdsRK0Nvxn1cit9biCiR9aq1zBR0X2BlAkEiIG6qPamLeU0GzvIgLkrFc398A==", "dev": true, "requires": { - "ejs": "2.6.1" + "@types/webpack-sources": "0.1.5", + "webpack-sources": "1.3.0" } }, "lie": { @@ -8647,20 +8924,20 @@ } }, "loader-runner": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", - "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", "dev": true }, "loader-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "3.2.0", + "big.js": "5.2.2", "emojis-list": "2.1.0", - "json5": "0.5.1" + "json5": "1.0.1" } }, "locate-path": { @@ -8679,6 +8956,11 @@ "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", "dev": true }, + "lodash-es": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz", + "integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q==" + }, "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", @@ -8700,8 +8982,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, "lodash.kebabcase": { "version": "4.1.1", @@ -8719,40 +9000,31 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "2.2.2" - } + "dev": true }, "log4js": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.5.tgz", - "integrity": "sha512-IX5c3G/7fuTtdr0JjOT2OIR12aTESVhsH6cEsijloYwKgcPRlO6DgOU72v0UFhWcoV1HN6+M3dwT89qVPLXm0w==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz", + "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", "dev": true, "requires": { - "circular-json": "0.5.5", + "circular-json": "0.5.9", "date-format": "1.2.0", - "debug": "3.2.5", + "debug": "3.2.6", "rfdc": "1.1.2", "streamroller": "0.7.0" }, "dependencies": { "circular-json": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.5.tgz", - "integrity": "sha512-13YaR6kiz0kBNmIVM87Io8Hp7bWOo4r61vkEANy8iH9R9bc6avud/1FT0SBpqR1RpIQADOh/Q+yHZDA1iL6ysA==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", "dev": true }, "debug": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", - "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { "ms": "2.1.1" @@ -8772,28 +9044,12 @@ "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", "dev": true }, - "loglevelnext": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", - "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", - "dev": true, - "requires": { - "es6-symbol": "3.1.1", - "object.assign": "4.1.0" - } - }, "lolex": { "version": "1.3.2", "resolved": "http://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", "dev": true }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -8819,12 +9075,6 @@ "signal-exit": "3.0.2" } }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -8865,6 +9115,129 @@ "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", "dev": true }, + "make-fetch-happen": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz", + "integrity": "sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==", + "dev": true, + "requires": { + "agentkeepalive": "3.5.2", + "cacache": "11.3.2", + "http-cache-semantics": "3.8.1", + "http-proxy-agent": "2.1.0", + "https-proxy-agent": "2.2.1", + "lru-cache": "4.1.3", + "mississippi": "3.0.0", + "node-fetch-npm": "2.0.2", + "promise-retry": "1.1.1", + "socks-proxy-agent": "4.0.1", + "ssri": "6.0.1" + }, + "dependencies": { + "bluebird": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", + "dev": true + }, + "cacache": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", + "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "dev": true, + "requires": { + "bluebird": "3.5.3", + "chownr": "1.1.1", + "figgy-pudding": "3.5.1", + "glob": "7.1.3", + "graceful-fs": "4.1.15", + "lru-cache": "5.1.1", + "mississippi": "3.0.0", + "mkdirp": "0.5.1", + "move-concurrently": "1.0.1", + "promise-inflight": "1.0.1", + "rimraf": "2.6.2", + "ssri": "6.0.1", + "unique-filename": "1.1.1", + "y18n": "4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "3.0.3" + } + } + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "1.6.2", + "duplexify": "3.6.0", + "end-of-stream": "1.4.1", + "flush-write-stream": "1.0.3", + "from2": "2.3.0", + "parallel-transform": "1.1.0", + "pump": "3.0.0", + "pumpify": "1.5.1", + "stream-each": "1.2.3", + "through2": "2.0.3" + } + }, + "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.4.1", + "once": "1.4.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "3.5.1" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } + } + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -8886,8 +9259,7 @@ "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, "map-obj": { "version": "1.0.1", @@ -8905,7 +9277,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, "requires": { "object-visit": "1.0.1" } @@ -8959,20 +9330,15 @@ } } }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", - "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "requires": { "hash-base": "3.0.4", - "inherits": "2.0.3" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "media-typer": { @@ -9062,7 +9428,6 @@ "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", @@ -9093,7 +9458,8 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true + "dev": true, + "optional": true }, "mime-db": { "version": "1.33.0", @@ -9117,14 +9483,14 @@ "dev": true }, "mini-css-extract-plugin": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.1.tgz", - "integrity": "sha512-XWuB3G61Rtasq/gLe7cp5cuozehE6hN+E4sxCamRR/WDiHTg+f7ZIAS024r8UJQffY+e2gGELXQZgQoFDfNDCg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz", + "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==", "dev": true, "requires": { - "@webpack-contrib/schema-utils": "1.0.0-beta.0", - "loader-utils": "1.1.0", - "webpack-sources": "1.1.0" + "loader-utils": "1.2.3", + "schema-utils": "1.0.0", + "webpack-sources": "1.3.0" } }, "minimalistic-assert": { @@ -9153,6 +9519,33 @@ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, + "minipass": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2", + "yallist": "3.0.3" + }, + "dependencies": { + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } + } + }, + "minizlib": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "dev": true, + "requires": { + "minipass": "2.3.5" + } + }, "mississippi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", @@ -9175,7 +9568,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, "requires": { "for-in": "1.0.2", "is-extendable": "1.0.1" @@ -9185,7 +9577,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "2.0.4" } @@ -9226,9 +9617,9 @@ "dev": true }, "moment": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", - "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, "move-concurrently": { "version": "1.0.1", @@ -9247,8 +9638,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "multicast-dns": { "version": "6.2.3", @@ -9281,14 +9671,12 @@ "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "nanomatch": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", - "dev": true, "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", @@ -9311,9 +9699,9 @@ "dev": true }, "neo-async": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.2.tgz", - "integrity": "sha512-vdqTKI9GBIYcAEbFAcpKPErKINfPF5zIuz3/niBfq8WUZjpT2tytLlFVrBgWdOtqI4uaA/Rb6No0hux39XXDuw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", + "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", "dev": true }, "next-tick": { @@ -9323,88 +9711,52 @@ "dev": true }, "ng-packagr": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-4.4.0.tgz", - "integrity": "sha512-dLpC/kmQsdbkL96ZclGjNRhq/J4MwpPKwPYNom74lvXqFC2jbbT/fnwmxX9WKXjvE8MEGsg2D2x8MsRURiNscg==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-4.7.1.tgz", + "integrity": "sha512-MIPKxyrnV22fS3wSfst2XjwWOonFKujVVEnIehYJhiu8GOg37bCdbbr9plsE1jRDmDAUz6M1MvdKibUrJyRp6Q==", "dev": true, "requires": { "@ngtools/json-schema": "1.1.0", - "autoprefixer": "9.3.0", - "browserslist": "4.3.2", - "chalk": "2.4.1", + "autoprefixer": "9.4.6", + "browserslist": "4.4.1", + "chalk": "2.4.2", "chokidar": "2.0.3", "clean-css": "4.2.1", "commander": "2.15.1", - "fs-extra": "7.0.0", + "fs-extra": "7.0.1", "glob": "7.1.2", "injection-js": "2.2.1", - "less": "3.8.1", + "less": "3.9.0", "less-plugin-npm-import": "2.1.0", - "node-sass": "4.9.3", + "node-sass": "4.11.0", "node-sass-tilde-importer": "1.0.2", - "postcss": "7.0.5", + "opencollective-postinstall": "2.0.2", + "postcss": "7.0.14", "postcss-url": "8.0.0", "read-pkg-up": "4.0.0", "rimraf": "2.6.2", - "rollup": "0.66.6", + "rollup": "0.67.4", "rollup-plugin-commonjs": "9.2.0", "rollup-plugin-json": "3.1.0", - "rollup-plugin-node-resolve": "3.4.0", + "rollup-plugin-node-resolve": "4.0.0", "rollup-plugin-sourcemaps": "0.4.2", - "rxjs": "6.2.0", + "rxjs": "6.4.0", "stylus": "0.54.5", - "uglify-js": "3.4.7", + "uglify-js": "3.4.9", "update-notifier": "2.5.0" }, "dependencies": { - "autoprefixer": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.3.0.tgz", - "integrity": "sha512-rpp+REfk0Ii3lCoiXhU4+CGYn8FbYckmvj6JJbJGSdzaxYCGJ7EvpHncDqgfAn/P6XhWig4u9BBNnsFAfAd5wg==", - "dev": true, - "requires": { - "browserslist": "4.3.2", - "caniuse-lite": "1.0.30000898", - "normalize-range": "0.1.2", - "num2fraction": "1.2.2", - "postcss": "7.0.5", - "postcss-value-parser": "3.3.1" - } - }, - "browserslist": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.3.2.tgz", - "integrity": "sha512-wgZJWlYcDvsjRtf8socmAHf1nXq88KrQLB/gMYHGPUc2bzPWsgltSXwPWYHx4Sw0G9E/XGNW5wJDaWlpHRMpjA==", - "dev": true, - "requires": { - "caniuse-lite": "1.0.30000898", - "electron-to-chromium": "1.3.81", - "node-releases": "1.0.0-alpha.14" - } - }, - "caniuse-lite": { - "version": "1.0.30000898", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000898.tgz", - "integrity": "sha512-ytlTZqO4hYe4rNAJhMynUAIUI33jsP2Bb1two/9OVC39wZjPZ8exIO0eCLw5mqAtegOGiGF0kkTWTn3B02L+mw==", - "dev": true - }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "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.5.0" + "supports-color": "5.4.0" } }, - "electron-to-chromium": { - "version": "1.3.81", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.81.tgz", - "integrity": "sha512-+rym2xtzwPWmoi8AYRrCdW65QOT0vfUHjZb5mjgh0VLyj31pGM3CpP3znKhQNBzQaWujR/KEl/mfC2lnKYgADA==", - "dev": true - }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -9415,9 +9767,9 @@ } }, "fs-extra": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.0.tgz", - "integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "requires": { "graceful-fs": "4.1.11", @@ -9456,16 +9808,10 @@ "path-exists": "3.0.0" } }, - "mime": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", - "dev": true - }, "p-limit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", - "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", "dev": true, "requires": { "p-try": "2.0.0" @@ -9477,7 +9823,7 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.0.0" + "p-limit": "2.1.0" } }, "p-try": { @@ -9496,36 +9842,6 @@ "json-parse-better-errors": "1.0.2" } }, - "postcss": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.5.tgz", - "integrity": "sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ==", - "dev": true, - "requires": { - "chalk": "2.4.1", - "source-map": "0.6.1", - "supports-color": "5.5.0" - } - }, - "postcss-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-8.0.0.tgz", - "integrity": "sha512-E2cbOQ5aii2zNHh8F6fk1cxls7QVFZjLPSrqvmiza8OuXLzIpErij8BDS5Y3STPfJgpIMNCPEr8JlKQWEoozUw==", - "dev": true, - "requires": { - "mime": "2.3.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "postcss": "7.0.5", - "xxhashjs": "0.2.2" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -9547,26 +9863,11 @@ "read-pkg": "3.0.0" } }, - "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 - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true - }, - "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" - } } } }, @@ -9579,17 +9880,12 @@ "deep-freeze-strict": "1.1.1" } }, - "ngrx-store-logger": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ngrx-store-logger/-/ngrx-store-logger-0.2.1.tgz", - "integrity": "sha1-IW6ZyVJ888UIYu4rJ/6T++jChnE=" - }, "ngx-moment": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ngx-moment/-/ngx-moment-3.1.0.tgz", - "integrity": "sha512-liX6iTfOY0XyI3rUuWNgGpgxoeD+DFaAl7UJ/ejl9Ama5cXzw8L1Eft6UQLUo1d80kjNMc6AL+L19CPMvUQ/BA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ngx-moment/-/ngx-moment-3.3.0.tgz", + "integrity": "sha512-6fpllpJqLfjRWboOhphgeEYt+rzIA9O29rG5QWCebRt2X0uNk4P93sLEb0S8lbDF0dEp2NOC3UOD+xoCVlJQhA==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "nice-try": { @@ -9598,13 +9894,15 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "node-fetch-npm": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz", + "integrity": "sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==", "dev": true, "requires": { - "lower-case": "1.1.4" + "encoding": "0.1.12", + "json-parse-better-errors": "1.0.2", + "safe-buffer": "5.1.2" } }, "node-forge": { @@ -9632,7 +9930,7 @@ "nopt": "3.0.6", "npmlog": "4.1.2", "osenv": "0.1.5", - "request": "2.87.0", + "request": "2.88.0", "rimraf": "2.6.2", "semver": "5.3.0", "tar": "2.2.1", @@ -9648,9 +9946,9 @@ } }, "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", + "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", "dev": true, "requires": { "assert": "1.4.1", @@ -9660,7 +9958,7 @@ "constants-browserify": "1.0.0", "crypto-browserify": "3.12.0", "domain-browser": "1.2.0", - "events": "1.1.1", + "events": "3.0.0", "https-browserify": "1.0.0", "os-browserify": "0.3.0", "path-browserify": "0.0.0", @@ -9668,13 +9966,13 @@ "punycode": "1.4.1", "querystring-es3": "0.2.1", "readable-stream": "2.3.6", - "stream-browserify": "2.0.1", + "stream-browserify": "2.0.2", "stream-http": "2.8.3", "string_decoder": "1.1.1", "timers-browserify": "2.0.10", "tty-browserify": "0.0.0", "url": "0.11.0", - "util": "0.10.3", + "util": "0.11.1", "vm-browserify": "0.0.4" }, "dependencies": { @@ -9683,22 +9981,31 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } } } }, "node-releases": { - "version": "1.0.0-alpha.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.0.0-alpha.14.tgz", - "integrity": "sha512-G8nnF9cP9QPP/jUmYWw/uUUhumHmkm+X/EarCugYFjYm2uXRMFeOD6CVT3RLdoyCvDUNy51nirGfUItKWs/S1g==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.8.tgz", + "integrity": "sha512-gQm+K9mGCiT/NXHy+V/ZZS1N/LOaGGqRAAJJs3X9Ah1g+CIbRcBgNyoNYQ+SEtcyAtB9KqDruu+fF7nWjsqRaA==", "dev": true, "requires": { "semver": "5.5.0" } }, "node-sass": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.3.tgz", - "integrity": "sha512-XzXyGjO+84wxyH7fV6IwBOTrEBe2f0a6SBze9QWWYR/cL74AcQUks2AsqcCZenl/Fp/JVbuEaLpgrLtocwBUww==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.11.0.tgz", + "integrity": "sha512-bHUdHTphgQJZaF1LASx0kAviPH7sGlcyNhWade4eVIpFp6tsn7SV8xNMTbsQFpEV9VXpnwTTnNYlfsZXgGgmkA==", "dev": true, "requires": { "async-foreach": "0.1.3", @@ -9716,7 +10023,7 @@ "nan": "2.10.0", "node-gyp": "3.8.0", "npmlog": "4.1.2", - "request": "2.87.0", + "request": "2.88.0", "sass-graph": "2.2.4", "stdout-stream": "1.4.0", "true-case-path": "1.0.2" @@ -9783,7 +10090,6 @@ "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.1.0" } @@ -9808,6 +10114,12 @@ "once": "1.4.0" } }, + "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 + }, "npm-package-arg": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", @@ -9820,24 +10132,39 @@ "validate-npm-package-name": "3.0.0" } }, - "npm-registry-client": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-8.6.0.tgz", - "integrity": "sha512-Qs6P6nnopig+Y8gbzpeN/dkt+n7IyVd8f45NTMotGk6Qo7GfBmzwYx6jRLoOOgKiMnaQfYxsuyQlD8Mc3guBhg==", + "npm-packlist": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", + "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", "dev": true, "requires": { - "concat-stream": "1.6.2", - "graceful-fs": "4.1.11", - "normalize-package-data": "2.4.0", + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.6" + } + }, + "npm-pick-manifest": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz", + "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==", + "dev": true, + "requires": { + "figgy-pudding": "3.5.1", "npm-package-arg": "6.1.0", - "npmlog": "4.1.2", - "once": "1.4.0", - "request": "2.87.0", - "retry": "0.10.1", - "safe-buffer": "5.1.2", - "semver": "5.5.0", - "slide": "1.1.6", - "ssri": "5.3.0" + "semver": "5.5.0" + } + }, + "npm-registry-fetch": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz", + "integrity": "sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw==", + "dev": true, + "requires": { + "JSONStream": "1.3.5", + "bluebird": "3.5.1", + "figgy-pudding": "3.5.1", + "lru-cache": "4.1.3", + "make-fetch-happen": "4.0.1", + "npm-package-arg": "6.1.0" } }, "npm-run-all": { @@ -9943,15 +10270,6 @@ "set-blocking": "2.0.0" } }, - "nth-check": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", - "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", - "dev": true, - "requires": { - "boolbase": "1.0.0" - } - }, "null-check": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", @@ -9971,9 +10289,9 @@ "dev": true }, "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { @@ -9992,7 +10310,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, "requires": { "copy-descriptor": "0.1.1", "define-property": "0.2.5", @@ -10003,7 +10320,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "0.1.6" } @@ -10012,7 +10328,6 @@ "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.6" } @@ -10029,7 +10344,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, "requires": { "isobject": "3.0.1" } @@ -10058,16 +10372,6 @@ "isobject": "3.0.1" } }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.12.0" - } - }, "object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", @@ -10078,32 +10382,10 @@ "make-iterator": "1.0.1" } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - }, - "dependencies": { - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - } - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, "requires": { "isobject": "3.0.1" } @@ -10143,6 +10425,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1.0.2" } @@ -10153,6 +10436,12 @@ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true + }, "opn": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", @@ -10309,6 +10598,173 @@ "semver": "5.5.0" } }, + "pacote": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.0.tgz", + "integrity": "sha512-WQ1KL/phGMkedYEQx9ODsjj7xvwLSpdFJJdEXrLyw5SILMxcTNt5DTxT2Z93fXuLFYJBlZJdnwdalrQdB/rX5w==", + "dev": true, + "requires": { + "bluebird": "3.5.3", + "cacache": "11.3.2", + "figgy-pudding": "3.5.1", + "get-stream": "4.1.0", + "glob": "7.1.3", + "lru-cache": "5.1.1", + "make-fetch-happen": "4.0.1", + "minimatch": "3.0.4", + "minipass": "2.3.5", + "mississippi": "3.0.0", + "mkdirp": "0.5.1", + "normalize-package-data": "2.4.0", + "npm-package-arg": "6.1.0", + "npm-packlist": "1.4.1", + "npm-pick-manifest": "2.2.3", + "npm-registry-fetch": "3.9.0", + "osenv": "0.1.5", + "promise-inflight": "1.0.1", + "promise-retry": "1.1.1", + "protoduck": "5.0.1", + "rimraf": "2.6.2", + "safe-buffer": "5.1.2", + "semver": "5.6.0", + "ssri": "6.0.1", + "tar": "4.4.8", + "unique-filename": "1.1.1", + "which": "1.3.1" + }, + "dependencies": { + "bluebird": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", + "dev": true + }, + "cacache": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", + "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "dev": true, + "requires": { + "bluebird": "3.5.3", + "chownr": "1.1.1", + "figgy-pudding": "3.5.1", + "glob": "7.1.3", + "graceful-fs": "4.1.15", + "lru-cache": "5.1.1", + "mississippi": "3.0.0", + "mkdirp": "0.5.1", + "move-concurrently": "1.0.1", + "promise-inflight": "1.0.1", + "rimraf": "2.6.2", + "ssri": "6.0.1", + "unique-filename": "1.1.1", + "y18n": "4.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "3.0.3" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "1.6.2", + "duplexify": "3.6.0", + "end-of-stream": "1.4.1", + "flush-write-stream": "1.0.3", + "from2": "2.3.0", + "parallel-transform": "1.1.0", + "pump": "3.0.0", + "pumpify": "1.5.1", + "stream-each": "1.2.3", + "through2": "2.0.3" + } + }, + "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.4.1", + "once": "1.4.0" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "3.5.1" + } + }, + "tar": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "dev": true, + "requires": { + "chownr": "1.1.1", + "fs-minipass": "1.2.5", + "minipass": "2.3.5", + "minizlib": "1.2.1", + "mkdirp": "0.5.1", + "safe-buffer": "5.1.2", + "yallist": "3.0.3" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } + } + }, "pako": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", @@ -10326,26 +10782,18 @@ "readable-stream": "2.3.6" } }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, - "requires": { - "no-case": "2.3.2" - } - }, "parse-asn1": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", "dev": true, "requires": { "asn1.js": "4.10.1", "browserify-aes": "1.2.0", "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.16" + "pbkdf2": "3.0.17", + "safe-buffer": "5.1.2" } }, "parse-filepath": { @@ -10359,35 +10807,6 @@ "path-root": "0.1.1" } }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - } - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -10436,8 +10855,7 @@ "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "path": { "version": "0.12.7", @@ -10458,8 +10876,7 @@ "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, "path-exists": { "version": "3.0.0", @@ -10530,9 +10947,9 @@ } }, "pbkdf2": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", - "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", "dev": true, "requires": { "create-hash": "1.2.0", @@ -10643,9 +11060,9 @@ "dev": true }, "portfinder": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.16.tgz", - "integrity": "sha512-icBXCFQxzlK2PMepOM0QeEdPPFSLAaXXeuKOv5AClJlMy1oVCBrkDGJ12IZYesI/BF8mpeVco3vRCmgeBb4+hw==", + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", "dev": true, "requires": { "async": "1.5.2", @@ -10656,29 +11073,39 @@ "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { - "chalk": "2.4.1", + "chalk": "2.4.2", "source-map": "0.6.1", - "supports-color": "5.4.0" + "supports-color": "6.1.0" }, "dependencies": { "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "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.4.0" + "supports-color": "5.5.0" + }, + "dependencies": { + "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" + } + } } }, "source-map": { @@ -10686,17 +11113,26 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "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" + } } } }, "postcss-import": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz", - "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", + "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", "dev": true, "requires": { - "postcss": "6.0.23", - "postcss-value-parser": "3.3.0", + "postcss": "7.0.14", + "postcss-value-parser": "3.3.1", "read-cache": "1.0.0", "resolve": "1.7.1" } @@ -10712,34 +11148,42 @@ } }, "postcss-loader": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.6.tgz", - "integrity": "sha512-hgiWSc13xVQAq25cVw80CH0l49ZKlAnU1hKPOdRrNj89bokRr/bZF2nT+hebPPF9c9xs8c3gw3Fr2nxtmXYnNg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", "dev": true, "requires": { - "loader-utils": "1.1.0", - "postcss": "6.0.23", + "loader-utils": "1.2.3", + "postcss": "7.0.14", "postcss-load-config": "2.0.0", - "schema-utils": "0.4.7" + "schema-utils": "1.0.0" } }, "postcss-url": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.2.tgz", - "integrity": "sha512-QMV5mA+pCYZQcUEPQkmor9vcPQ2MT+Ipuu8qdi1gVxbNiIiErEGft+eny1ak19qALoBkccS5AHaCaCDzh7b9MA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-8.0.0.tgz", + "integrity": "sha512-E2cbOQ5aii2zNHh8F6fk1cxls7QVFZjLPSrqvmiza8OuXLzIpErij8BDS5Y3STPfJgpIMNCPEr8JlKQWEoozUw==", "dev": true, "requires": { - "mime": "1.6.0", + "mime": "2.4.0", "minimatch": "3.0.4", "mkdirp": "0.5.1", - "postcss": "6.0.23", + "postcss": "7.0.14", "xxhashjs": "0.2.2" + }, + "dependencies": { + "mime": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "dev": true + } } }, "postcss-value-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", - "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, "prelude-ls": { @@ -10754,22 +11198,6 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", - "dev": true, - "requires": { - "renderkid": "2.0.1", - "utila": "0.4.0" - } - }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -10785,8 +11213,7 @@ "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 + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "progress": { "version": "1.1.8", @@ -10810,13 +11237,32 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "promise-retry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "dev": true, + "requires": { + "err-code": "1.1.2", + "retry": "0.10.1" + } + }, + "protoduck": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", + "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", + "dev": true, + "requires": { + "genfun": "5.0.0" + } + }, "protractor": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.0.tgz", "integrity": "sha512-6TSYqMhUUzxr4/wN0ttSISqPMKvcVRXF4k8jOEpGWD8OioLak4KLgfzHK9FJ49IrjzRrZ+Mx1q2Op8Rk0zEcnQ==", "dev": true, "requires": { - "@types/node": "6.0.111", + "@types/node": "6.14.3", "@types/q": "0.0.32", "@types/selenium-webdriver": "3.0.10", "blocking-proxy": "1.0.1", @@ -10834,6 +11280,12 @@ "webdriver-manager": "12.1.0" }, "dependencies": { + "@types/node": { + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.3.tgz", + "integrity": "sha512-V2VrQBCKo4U0rni6tW4AASRDqIO5ZTLDN/Xzrm4mNBr9SGQYZ+7zZJn+hMs89Q8ZCIHzp4aWQPyCpK+rux1YGA==", + "dev": true + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -10928,7 +11380,7 @@ "ini": "1.3.5", "minimist": "1.2.0", "q": "1.4.1", - "request": "2.87.0", + "request": "2.88.0", "rimraf": "2.6.2", "semver": "5.5.0", "xml2js": "0.4.19" @@ -10961,32 +11413,30 @@ "table-parser": "0.1.3" } }, - "ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "dev": true, - "requires": { - "event-stream": "3.3.4" - } - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, "public-encrypt": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", - "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, "requires": { "bn.js": "4.11.8", "browserify-rsa": "4.0.1", "create-hash": "1.2.0", - "parse-asn1": "5.1.1", - "randombytes": "2.0.6" + "parse-asn1": "5.1.4", + "randombytes": "2.1.0", + "safe-buffer": "5.1.2" } }, "pump": { @@ -11013,8 +11463,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "q": { "version": "1.5.1", @@ -11052,29 +11501,10 @@ "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==", "dev": true }, - "randomatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", - "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", - "dev": true, - "requires": { - "is-number": "4.0.0", - "kind-of": "6.0.2", - "math-random": "1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "5.1.2" @@ -11086,7 +11516,7 @@ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { - "randombytes": "2.0.6", + "randombytes": "2.1.0", "safe-buffer": "5.1.2" } }, @@ -11097,48 +11527,37 @@ "dev": true }, "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "dev": true, "requires": { "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", "unpipe": "1.0.0" }, "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.4.0" + "safer-buffer": "2.1.2" } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true } } }, "raw-loader": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", - "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-1.0.0.tgz", + "integrity": "sha512-Uqy5AqELpytJTRxYT4fhltcKPj0TyaEpzJDcGz7DFJi+pQOOi3GjR/DOdxTkTsF+NzhnldIoG6TORaBlInUuqA==", + "dev": true, + "requires": { + "loader-utils": "1.2.3", + "schema-utils": "1.0.0" + } }, "rc": { "version": "1.2.8", @@ -11248,7 +11667,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", @@ -11263,7 +11681,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, "requires": { "graceful-fs": "4.1.11", "minimatch": "3.0.4", @@ -11302,9 +11719,9 @@ } }, "reflect-metadata": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.12.tgz", - "integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", "dev": true }, "regenerate": { @@ -11319,20 +11736,10 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" - } - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, "requires": { "extend-shallow": "3.0.2", "safe-regex": "1.1.0" @@ -11391,12 +11798,6 @@ } } }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, "remove-bom-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", @@ -11421,41 +11822,17 @@ "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "renderkid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", - "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", - "dev": true, - "requires": { - "css-select": "1.2.0", - "dom-converter": "0.1.4", - "htmlparser2": "3.3.0", - "strip-ansi": "3.0.1", - "utila": "0.3.3" - }, - "dependencies": { - "utila": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", - "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", - "dev": true - } - } + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "repeating": { "version": "2.0.1", @@ -11619,51 +11996,88 @@ } }, "request": { - "version": "2.87.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, "requires": { "aws-sign2": "0.7.0", - "aws4": "1.7.0", + "aws4": "1.8.0", "caseless": "0.12.0", "combined-stream": "1.0.6", - "extend": "3.0.1", + "extend": "3.0.2", "forever-agent": "0.6.1", "form-data": "2.3.2", - "har-validator": "5.0.3", + "har-validator": "5.1.3", "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", + "mime-types": "2.1.22", + "oauth-sign": "0.9.0", "performance-now": "2.1.0", "qs": "6.5.2", "safe-buffer": "5.1.2", - "tough-cookie": "2.3.4", + "tough-cookie": "2.4.3", "tunnel-agent": "0.6.0", - "uuid": "3.2.1" + "uuid": "3.3.2" + }, + "dependencies": { + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "requires": { + "mime-db": "1.38.0" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } } }, "request-promise-core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", - "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", "dev": true, "requires": { - "lodash": "4.17.10" + "lodash": "4.17.11" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + } } }, "request-promise-native": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", - "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", "dev": true, "requires": { - "request-promise-core": "1.1.1", + "request-promise-core": "1.1.2", "stealthy-require": "1.1.1", - "tough-cookie": "2.3.4" + "tough-cookie": "2.4.3" } }, "require-directory": { @@ -11759,8 +12173,7 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "restore-cursor": { "version": "1.0.1", @@ -11775,8 +12188,7 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, "retry": { "version": "0.10.1", @@ -11820,13 +12232,13 @@ } }, "rollup": { - "version": "0.66.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.66.6.tgz", - "integrity": "sha512-J7/SWanrcb83vfIHqa8+aVVGzy457GcjA6GVZEnD0x2u4OnOd0Q1pCrEoNe8yLwM6z6LZP02zBT2uW0yh5TqOw==", + "version": "0.67.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.67.4.tgz", + "integrity": "sha512-AVuP73mkb4BBMUmksQ3Jw0jTrBTU1i7rLiUYjFxLZGb3xiFmtVEg40oByphkZAsiL0bJC3hRAJUQos/e5EBd+w==", "dev": true, "requires": { "@types/estree": "0.0.39", - "@types/node": "6.0.111" + "@types/node": "11.9.4" } }, "rollup-plugin-commonjs": { @@ -11868,21 +12280,36 @@ } }, "rollup-plugin-node-resolve": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.4.0.tgz", - "integrity": "sha512-PJcd85dxfSBWih84ozRtBkB731OjXk0KnzN0oGp7WOWcarAFkVa71cV5hTJg2qpVsV2U8EUwrzHP3tvy9vS3qg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-4.0.0.tgz", + "integrity": "sha512-7Ni+/M5RPSUBfUaP9alwYQiIKnKeXCOHiqBpKUl9kwp3jX5ZJtgXAait1cne6pGEVUUztPD6skIKH9Kq9sNtfw==", "dev": true, "requires": { - "builtin-modules": "2.0.0", + "builtin-modules": "3.0.0", "is-module": "1.0.0", - "resolve": "1.7.1" + "resolve": "1.10.0" }, "dependencies": { "builtin-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-2.0.0.tgz", - "integrity": "sha512-3U5kUA5VPsRUA3nofm/BXX7GVHKfxz0hOBAPxXrIvHzlDRkQVqEn6yi8QJegxl4LzOHLdvb7XF5dVawa/VVYBg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz", + "integrity": "sha512-hMIeU4K2ilbXV6Uv93ZZ0Avg/M91RaKXucQ+4me2Do1txxBDyDZWCBa5bJSLqoNTRpXTLwEzIk1KmloenDDjhg==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "1.0.6" + } } } }, @@ -11932,6 +12359,11 @@ "aproba": "1.2.0" } }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + }, "rx-lite": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", @@ -11939,11 +12371,11 @@ "dev": true }, "rxjs": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.0.tgz", - "integrity": "sha512-qBzf5uu6eOKiCZuAE0SgZ0/Qp+l54oeVxFfC2t+mJ2SFI6IB8gmMdJHs5DUMu5kqifqcCtsKS2XHjhZu6RKvAw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "rxjs-spy": { @@ -11966,7 +12398,7 @@ "requires": { "chalk": "2.4.1", "optimist": "0.6.1", - "tslint": "5.10.0", + "tslint": "5.13.0", "tsutils": "2.27.1" }, "dependencies": { @@ -11991,14 +12423,12 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, "requires": { "ret": "0.1.15" } @@ -12006,8 +12436,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "samsam": { "version": "1.1.2", @@ -12096,16 +12525,17 @@ } }, "sass-loader": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.7.tgz", - "integrity": "sha512-JoiyD00Yo1o61OJsoP2s2kb19L1/Y2p3QFcCdWdF6oomBGKVYuZyqHWemRBfQ2uGYsk+CH3eCguXNfpjzlcpaA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz", + "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==", "dev": true, "requires": { "clone-deep": "2.0.2", - "loader-utils": "1.1.0", + "loader-utils": "1.2.3", "lodash.tail": "4.1.1", - "neo-async": "2.5.2", - "pify": "3.0.0" + "neo-async": "2.6.0", + "pify": "3.0.0", + "semver": "5.5.0" } }, "saucelabs": { @@ -12124,13 +12554,14 @@ "dev": true }, "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.4.0", - "ajv-keywords": "3.2.0" + "ajv": "6.9.1", + "ajv-errors": "1.0.1", + "ajv-keywords": "3.4.0" } }, "scss-tokenizer": { @@ -12264,9 +12695,9 @@ } }, "serialize-javascript": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", - "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", + "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", "dev": true }, "serve-index": { @@ -12314,14 +12745,12 @@ "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, "requires": { "extend-shallow": "2.0.1", "is-extendable": "0.1.1", @@ -12333,7 +12762,6 @@ "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.1" } @@ -12444,17 +12872,16 @@ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "smart-buffer": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", + "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", "dev": true }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, "requires": { "base": "0.11.2", "debug": "2.6.9", @@ -12470,7 +12897,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "0.1.6" } @@ -12479,7 +12905,6 @@ "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.1" } @@ -12490,7 +12915,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, "requires": { "define-property": "1.0.0", "isobject": "3.0.1", @@ -12501,7 +12925,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "1.0.2" } @@ -12510,7 +12933,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -12519,7 +12941,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -12528,7 +12949,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "1.0.0", "is-data-descriptor": "1.0.0", @@ -12541,7 +12961,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -12550,7 +12969,6 @@ "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.6" } @@ -12564,7 +12982,7 @@ "dev": true, "requires": { "debug": "3.1.0", - "engine.io": "3.2.0", + "engine.io": "3.2.1", "has-binary2": "1.0.3", "socket.io-adapter": "1.1.1", "socket.io-client": "2.1.1", @@ -12699,10 +13117,30 @@ } } }, + "socks": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.3.tgz", + "integrity": "sha512-+2r83WaRT3PXYoO/1z+RDEBE7Z2f9YcdQnJ0K/ncXXbV5gJ6wYfNAebYFYiiUjM6E4JyXnPY8cimwyvFYHVUUA==", + "dev": true, + "requires": { + "ip": "1.1.5", + "smart-buffer": "4.0.2" + } + }, + "socks-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", + "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", + "dev": true, + "requires": { + "agent-base": "4.2.0", + "socks": "2.2.3" + } + }, "source-list-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", "dev": true }, "source-map": { @@ -12716,18 +13154,24 @@ "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==", "dev": true, "requires": { - "async": "2.6.1", - "loader-utils": "1.1.0" + "async": "2.6.2", + "loader-utils": "1.2.3" }, "dependencies": { "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "dev": true, "requires": { - "lodash": "4.17.10" + "lodash": "4.17.11" } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true } } }, @@ -12735,7 +13179,6 @@ "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==", - "dev": true, "requires": { "atob": "2.1.1", "decode-uri-component": "0.2.0", @@ -12745,9 +13188,9 @@ } }, "source-map-support": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", - "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", "dev": true, "requires": { "buffer-from": "1.1.0", @@ -12765,8 +13208,7 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "sourcemap-codec": { "version": "1.4.4", @@ -12813,32 +13255,84 @@ "dev": true }, "spdy": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", - "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", + "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", "dev": true, "requires": { - "debug": "2.6.9", - "handle-thing": "1.2.5", + "debug": "4.1.1", + "handle-thing": "2.0.0", "http-deceiver": "1.2.7", - "safe-buffer": "5.1.2", "select-hose": "2.0.0", - "spdy-transport": "2.1.1" + "spdy-transport": "3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } } }, "spdy-transport": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.1.tgz", - "integrity": "sha512-q7D8c148escoB3Z7ySCASadkegMmUZW8Wb/Q1u0/XBgDKMO880rLQDj8Twiew/tYi7ghemKUi/whSYOwE17f5Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, "requires": { - "debug": "2.6.9", + "debug": "4.1.1", "detect-node": "2.0.4", "hpack.js": "2.1.6", "obuf": "1.1.2", - "readable-stream": "2.3.6", - "safe-buffer": "5.1.2", + "readable-stream": "3.1.1", "wbuf": "1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "readable-stream": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", + "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + } + } + }, + "speed-measure-webpack-plugin": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.0.tgz", + "integrity": "sha512-b9Yd0TrzceMVYSbuamM1sFsGM1oVfyFTM22gOoyLhymNvBVApuYpkdFOgYkKJpN/KhTpcCYcTGHg7X+FJ33Vvw==", + "dev": true, + "requires": { + "chalk": "2.2.2" } }, "split": { @@ -12854,7 +13348,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, "requires": { "extend-shallow": "3.0.2" } @@ -12862,7 +13355,8 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true }, "sshpk": { "version": "1.14.1", @@ -12913,7 +13407,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, "requires": { "define-property": "0.2.5", "object-copy": "0.1.0" @@ -12923,7 +13416,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "0.1.6" } @@ -12931,9 +13423,9 @@ } }, "stats-webpack-plugin": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/stats-webpack-plugin/-/stats-webpack-plugin-0.6.2.tgz", - "integrity": "sha1-LFlJtTHgf4eojm6k3PrFOqjHWis=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/stats-webpack-plugin/-/stats-webpack-plugin-0.7.0.tgz", + "integrity": "sha512-NT0YGhwuQ0EOX+uPhhUcI6/+1Sq/pMzNuSCBVT4GbFl/ac6I/JZefBcjlECNfAb1t3GOx5dEj1Z7x0cAxeeVLQ==", "dev": true, "requires": { "lodash": "4.17.10" @@ -12961,11 +13453,11 @@ "dev": true }, "stratos-angular6-json-schema-form": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stratos-angular6-json-schema-form/-/stratos-angular6-json-schema-form-1.0.3.tgz", - "integrity": "sha512-4CZm6hWqIlJQ7T4Bg3SM4YB4F+6KsswmC5Bm6yNMF6OfNPRo7sQuWw5wuAQMw6X3BRUJnxTkJGnG9vH2BpbPPw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/stratos-angular6-json-schema-form/-/stratos-angular6-json-schema-form-7.0.6.tgz", + "integrity": "sha512-S/yasSZ+1YNPsiTARCqaPOW8+5ob+9jfOO0XxJ/myDlSTtgoNb4nGnl3LWlEFwMUWiOjkOUVyyVlBsiK5vIBTg==", "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "stratos-merge-dirs": { @@ -13070,19 +13562,13 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", "dev": true - }, - "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", - "dev": true } } }, "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", "dev": true, "requires": { "inherits": "2.0.3", @@ -13140,15 +13626,15 @@ "dev": true, "requires": { "date-format": "1.2.0", - "debug": "3.2.5", + "debug": "3.2.6", "mkdirp": "0.5.1", "readable-stream": "2.3.6" }, "dependencies": { "debug": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", - "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { "ms": "2.1.1" @@ -13188,7 +13674,6 @@ "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, "requires": { "safe-buffer": "5.1.2" } @@ -13233,13 +13718,13 @@ "dev": true }, "style-loader": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", - "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", + "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", "dev": true, "requires": { - "loader-utils": "1.1.0", - "schema-utils": "0.4.7" + "loader-utils": "1.2.3", + "schema-utils": "1.0.0" } }, "stylus": { @@ -13287,7 +13772,7 @@ "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", "dev": true, "requires": { - "loader-utils": "1.1.0", + "loader-utils": "1.2.3", "lodash.clonedeep": "4.5.0", "when": "3.6.4" } @@ -13417,9 +13902,9 @@ } }, "tapable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", - "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", + "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", "dev": true }, "tar": { @@ -13454,27 +13939,229 @@ "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", "dev": true, "requires": { - "glob": "7.1.2" + "glob": "7.1.2" + } + } + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "0.7.0" + } + }, + "terser": { + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz", + "integrity": "sha512-JDJjgleBROeek2iBcSNzOHLKsB/MdDf+E/BOAJ0Tk9r7p9/fVobfv7LMJ/g/k3v9SXdmjZnIlFd5nfn/Rt0Xow==", + "dev": true, + "requires": { + "commander": "2.17.1", + "source-map": "0.6.1", + "source-map-support": "0.5.10" + }, + "dependencies": { + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "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 + } + } + }, + "terser-webpack-plugin": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.2.tgz", + "integrity": "sha512-1DMkTk286BzmfylAvLXwpJrI7dWa5BnFmscV/2dCr8+c56egFcbaeFAl7+sujAjdmpLam21XRdhA4oifLyiWWg==", + "dev": true, + "requires": { + "cacache": "11.3.2", + "find-cache-dir": "2.0.0", + "schema-utils": "1.0.0", + "serialize-javascript": "1.6.1", + "source-map": "0.6.1", + "terser": "3.16.1", + "webpack-sources": "1.3.0", + "worker-farm": "1.6.0" + }, + "dependencies": { + "bluebird": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", + "dev": true + }, + "cacache": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", + "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "dev": true, + "requires": { + "bluebird": "3.5.3", + "chownr": "1.1.1", + "figgy-pudding": "3.5.1", + "glob": "7.1.3", + "graceful-fs": "4.1.15", + "lru-cache": "5.1.1", + "mississippi": "3.0.0", + "mkdirp": "0.5.1", + "move-concurrently": "1.0.1", + "promise-inflight": "1.0.1", + "rimraf": "2.6.2", + "ssri": "6.0.1", + "unique-filename": "1.1.1", + "y18n": "4.0.0" + } + }, + "find-cache-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz", + "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", + "dev": true, + "requires": { + "commondir": "1.0.1", + "make-dir": "1.3.0", + "pkg-dir": "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "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" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "3.0.3" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "1.6.2", + "duplexify": "3.6.0", + "end-of-stream": "1.4.1", + "flush-write-stream": "1.0.3", + "from2": "2.3.0", + "parallel-transform": "1.1.0", + "pump": "3.0.0", + "pumpify": "1.5.1", + "stream-each": "1.2.3", + "through2": "2.0.3" + } + }, + "p-limit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "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.1.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "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" } - } - } - }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", - "dev": true, - "requires": { - "execa": "0.7.0" - }, - "dependencies": { - "rimraf": { - "version": "2.5.4", - "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + }, + "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": { - "glob": "7.1.2" + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + }, + "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 + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "3.5.1" } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true } } }, @@ -13578,7 +14265,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -13587,7 +14273,6 @@ "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.6" } @@ -13598,7 +14283,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, "requires": { "define-property": "2.0.2", "extend-shallow": "3.0.2", @@ -13610,7 +14294,6 @@ "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" @@ -13625,18 +14308,13 @@ "through2": "2.0.3" } }, - "toposort": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", - "dev": true - }, "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { + "psl": "1.1.31", "punycode": "1.4.1" }, "dependencies": { @@ -13649,9 +14327,9 @@ } }, "tree-kill": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", - "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", + "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", "dev": true }, "trim-newlines": { @@ -13754,66 +14432,51 @@ } } }, - "tsickle": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.33.0.tgz", - "integrity": "sha512-ww4jhOaKhHHjZzs+dm381hffl1GOHhfA3LgbSoHMogWKm5mazpglVhMl1zJrSzOdhYHlZvrT7hRWCbGptzIpSA==", - "dev": true, - "requires": { - "minimist": "1.2.0", - "mkdirp": "0.5.1", - "source-map": "0.7.3" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, "tslib": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.2.tgz", - "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==" + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" }, "tslint": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.10.0.tgz", - "integrity": "sha1-EeJrzLiK+gLdDZlWyuPUVAtfVMM=", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.13.0.tgz", + "integrity": "sha512-ECOOQRxXCYnUUePG5h/+Z1Zouobk3KFpIHA9aKBB/nnMxs97S1JJPDGt5J4cGm1y9U9VmVlfboOxA8n1kSNzGw==", "dev": true, "requires": { "babel-code-frame": "6.26.0", "builtin-modules": "1.1.1", - "chalk": "2.4.1", + "chalk": "2.4.2", "commander": "2.15.1", "diff": "3.5.0", "glob": "7.1.2", "js-yaml": "3.11.0", "minimatch": "3.0.4", + "mkdirp": "0.5.1", "resolve": "1.7.1", "semver": "5.5.0", - "tslib": "1.9.2", - "tsutils": "2.27.1" + "tslib": "1.9.3", + "tsutils": "2.29.0" }, "dependencies": { "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "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.4.0" } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } } } }, @@ -13823,7 +14486,7 @@ "integrity": "sha512-AE/7uzp32MmaHvNNFES85hhUDHFdFZp6OAiZcd6y4ZKKIg6orJTm8keYWBhIhrJQH3a4LzNKat7ZPXZt5aTf6w==", "dev": true, "requires": { - "tslib": "1.9.2" + "tslib": "1.9.3" } }, "tty-browserify": { @@ -13874,25 +14537,25 @@ "dev": true }, "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", + "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", "dev": true }, "uglify-js": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.7.tgz", - "integrity": "sha512-J0M2i1mQA+ze3EdN9SBi751DNdAXmeFLfJrd/MDIkRc3G3Gbb9OPVSx7GIQvVwfWxQARcYV2DTxIkMyDAk3o9Q==", + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", "dev": true, "requires": { - "commander": "2.16.0", + "commander": "2.17.1", "source-map": "0.6.1" }, "dependencies": { "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", "dev": true }, "source-map": { @@ -13910,46 +14573,6 @@ "dev": true, "optional": true }, - "uglifyjs-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw==", - "dev": true, - "requires": { - "cacache": "10.0.4", - "find-cache-dir": "1.0.0", - "schema-utils": "0.4.7", - "serialize-javascript": "1.5.0", - "source-map": "0.6.1", - "uglify-es": "3.3.9", - "webpack-sources": "1.1.0", - "worker-farm": "1.6.0" - }, - "dependencies": { - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, - "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 - }, - "uglify-es": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "dev": true, - "requires": { - "commander": "2.13.0", - "source-map": "0.6.1" - } - } - } - }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -13962,6 +14585,12 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "dev": true + }, "undertaker": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz", @@ -13989,7 +14618,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, "requires": { "arr-union": "3.1.0", "get-value": "2.0.6", @@ -14001,7 +14629,6 @@ "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.1" } @@ -14010,7 +14637,6 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, "requires": { "extend-shallow": "2.0.1", "is-extendable": "0.1.1", @@ -14021,18 +14647,18 @@ } }, "unique-filename": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz", - "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "dev": true, "requires": { - "unique-slug": "2.0.0" + "unique-slug": "2.0.1" } }, "unique-slug": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", - "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", "dev": true, "requires": { "imurmurhash": "0.1.4" @@ -14073,7 +14699,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, "requires": { "has-value": "0.3.1", "isobject": "3.0.1" @@ -14083,7 +14708,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, "requires": { "get-value": "2.0.6", "has-values": "0.1.4", @@ -14094,7 +14718,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, "requires": { "isarray": "1.0.0" } @@ -14104,8 +14727,7 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" } } }, @@ -14118,8 +14740,7 @@ "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==" }, "update-notifier": { "version": "2.5.0", @@ -14139,16 +14760,10 @@ "xdg-basedir": "3.0.0" } }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, "uri-js": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz", - "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { "punycode": "2.1.1" @@ -14157,8 +14772,7 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, "url": { "version": "0.11.0", @@ -14178,42 +14792,6 @@ } } }, - "url-join": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", - "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=", - "dev": true - }, - "url-loader": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.1.tgz", - "integrity": "sha512-vugEeXjyYFBCUOpX+ZuaunbK3QXMKaQ3zUnRfIpRBlGkY7QizCnzyyn2ASfcxsvyU3ef+CJppVywnl3Kgf13Gg==", - "dev": true, - "requires": { - "loader-utils": "1.1.0", - "mime": "2.3.1", - "schema-utils": "1.0.0" - }, - "dependencies": { - "mime": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "ajv": "6.4.0", - "ajv-errors": "1.0.0", - "ajv-keywords": "3.2.0" - } - } - } - }, "url-parse": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", @@ -14243,7 +14821,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", - "dev": true, "requires": { "kind-of": "6.0.2" } @@ -14258,21 +14835,13 @@ } }, "useragent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz", - "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", "dev": true, "requires": { - "lru-cache": "2.2.4", + "lru-cache": "4.1.3", "tmp": "0.0.33" - }, - "dependencies": { - "lru-cache": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.2.4.tgz", - "integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=", - "dev": true - } } }, "util": { @@ -14295,24 +14864,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "1.1.2", - "object.getownpropertydescriptors": "2.0.3" - } - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utils-merge": { "version": "1.0.1", @@ -14468,7 +15020,7 @@ "requires": { "chokidar": "2.0.3", "graceful-fs": "4.1.11", - "neo-async": "2.5.2" + "neo-async": "2.6.0" } }, "wbuf": { @@ -14485,19 +15037,6 @@ "resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.1.tgz", "integrity": "sha1-Om2bwVGWN3qQ+OKAP6UmIWWwRRA=" }, - "webassemblyjs": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webassemblyjs/-/webassemblyjs-1.4.3.tgz", - "integrity": "sha512-4lOV1Lv6olz0PJkDGQEp82HempAn147e6BXijWDzz9g7/2nSebVP9GVg62Fz5ZAs55mxq13GA0XLyvY8XkyDjg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/validation": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "@webassemblyjs/wast-parser": "1.4.3", - "long": "3.2.0" - } - }, "webdriver-js-extender": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.0.0.tgz", @@ -14509,34 +15048,53 @@ } }, "webpack": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.9.2.tgz", - "integrity": "sha512-jlWrCrJDU3sdWFprel6jHH8esN2C++Q8ehedRo74u7MWLTUJn9SD7RSgsCTEZCSRpVpMascDylAqPoldauOMfA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/wasm-edit": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "acorn": "5.5.3", - "acorn-dynamic-import": "3.0.0", - "ajv": "6.4.0", - "ajv-keywords": "3.2.0", - "chrome-trace-event": "0.1.3", + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.0.tgz", + "integrity": "sha512-pxdGG0keDBtamE1mNvT5zyBdx+7wkh6mh7uzMOo/uRQ/fhsdj5FXkh/j5mapzs060forql1oXqXN9HJGju+y7w==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/wasm-edit": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "acorn": "6.1.0", + "acorn-dynamic-import": "4.0.0", + "ajv": "6.9.1", + "ajv-keywords": "3.4.0", + "chrome-trace-event": "1.0.0", "enhanced-resolve": "4.1.0", - "eslint-scope": "3.7.3", + "eslint-scope": "4.0.0", "json-parse-better-errors": "1.0.2", - "loader-runner": "2.3.0", - "loader-utils": "1.1.0", + "loader-runner": "2.4.0", + "loader-utils": "1.2.3", "memory-fs": "0.4.1", "micromatch": "3.1.10", "mkdirp": "0.5.1", - "neo-async": "2.5.2", - "node-libs-browser": "2.1.0", + "neo-async": "2.6.0", + "node-libs-browser": "2.2.0", "schema-utils": "0.4.7", - "tapable": "1.0.0", - "uglifyjs-webpack-plugin": "1.3.0", + "tapable": "1.1.1", + "terser-webpack-plugin": "1.2.2", "watchpack": "1.6.0", - "webpack-sources": "1.1.0" + "webpack-sources": "1.3.0" + }, + "dependencies": { + "acorn": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", + "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==", + "dev": true + }, + "schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dev": true, + "requires": { + "ajv": "6.9.1", + "ajv-keywords": "3.4.0" + } + } } }, "webpack-core": { @@ -14567,39 +15125,36 @@ } }, "webpack-dev-middleware": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.1.3.tgz", - "integrity": "sha512-I6Mmy/QjWU/kXwCSFGaiOoL5YEQIVmbb0o45xMoCyQAg/mClqZVTcsX327sPfekDyJWpCxb+04whNyLOIxpJdQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.5.1.tgz", + "integrity": "sha512-4dwCh/AyMOYAybggUr8fiCkRnjVDp+Cqlr9c+aaNB3GJYgRGYQWJ1YX/WAKUNA9dPNHZ6QSN2lYDKqjKSI8Vqw==", "dev": true, "requires": { - "loud-rejection": "1.6.0", "memory-fs": "0.4.1", - "mime": "2.3.1", - "path-is-absolute": "1.0.1", + "mime": "2.4.0", "range-parser": "1.2.0", - "url-join": "4.0.0", - "webpack-log": "1.2.0" + "webpack-log": "2.0.0" }, "dependencies": { "mime": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "dev": true } } }, "webpack-dev-server": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.10.tgz", - "integrity": "sha512-RqOAVjfqZJtQcB0LmrzJ5y4Jp78lv9CK0MZ1YJDTaTmedMZ9PU9FLMQNrMCfVu8hHzaVLVOJKBlGEHMN10z+ww==", + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz", + "integrity": "sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==", "dev": true, "requires": { "ansi-html": "0.0.7", "bonjour": "3.5.0", "chokidar": "2.0.3", "compression": "1.7.3", - "connect-history-api-fallback": "1.5.0", + "connect-history-api-fallback": "1.6.0", "debug": "3.2.6", "del": "3.0.0", "express": "4.16.4", @@ -14611,15 +15166,17 @@ "killable": "1.0.1", "loglevel": "1.6.1", "opn": "5.3.0", - "portfinder": "1.0.16", + "portfinder": "1.0.20", "schema-utils": "1.0.0", "selfsigned": "1.10.4", + "semver": "5.6.0", "serve-index": "1.9.1", "sockjs": "0.3.19", "sockjs-client": "1.3.0", - "spdy": "3.4.7", + "spdy": "4.0.0", "strip-ansi": "3.0.1", "supports-color": "5.4.0", + "url": "0.11.0", "webpack-dev-middleware": "3.4.0", "webpack-log": "2.0.0", "yargs": "12.0.2" @@ -14628,8 +15185,7 @@ "ansi-colors": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.1.tgz", - "integrity": "sha512-Xt+zb6nqgvV9SWAVp0EG3lRsHcbq5DDgqjPPz6pwgtj6RKz65zGXMNa82oJfOSBA/to6GmRP7Dr+6o+kbApTzQ==", - "dev": true + "integrity": "sha512-Xt+zb6nqgvV9SWAVp0EG3lRsHcbq5DDgqjPPz6pwgtj6RKz65zGXMNa82oJfOSBA/to6GmRP7Dr+6o+kbApTzQ==" }, "ansi-regex": { "version": "3.0.0", @@ -14673,7 +15229,7 @@ "requires": { "nice-try": "1.0.5", "path-key": "2.0.1", - "semver": "5.5.0", + "semver": "5.6.0", "shebang-command": "1.2.0", "which": "1.3.1" } @@ -14697,13 +15253,13 @@ } }, "execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "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.5", - "get-stream": "3.0.0", + "get-stream": "4.1.0", "is-stream": "1.1.0", "npm-run-path": "2.0.2", "p-finally": "1.0.0", @@ -14720,6 +15276,15 @@ "locate-path": "3.0.0" } }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "3.0.0" + } + }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", @@ -14752,9 +15317,9 @@ } }, "mime": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "dev": true }, "ms": { @@ -14764,20 +15329,20 @@ "dev": true }, "os-locale": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz", - "integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==", + "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": "0.10.0", + "execa": "1.0.0", "lcid": "2.0.0", "mem": "4.0.0" } }, "p-limit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", - "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", "dev": true, "requires": { "p-try": "2.0.0" @@ -14789,7 +15354,7 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.0.0" + "p-limit": "2.1.0" } }, "p-try": { @@ -14798,17 +15363,22 @@ "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", "dev": true }, - "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==", + "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": { - "ajv": "6.4.0", - "ajv-errors": "1.0.0", - "ajv-keywords": "3.2.0" + "end-of-stream": "1.4.1", + "once": "1.4.0" } }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -14830,12 +15400,6 @@ } } }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, "webpack-dev-middleware": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz", @@ -14843,21 +15407,11 @@ "dev": true, "requires": { "memory-fs": "0.4.1", - "mime": "2.3.1", + "mime": "2.4.0", "range-parser": "1.2.0", "webpack-log": "2.0.0" } }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "3.2.1", - "uuid": "3.3.2" - } - }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -14874,7 +15428,7 @@ "decamelize": "2.0.0", "find-up": "3.0.0", "get-caller-file": "1.0.2", - "os-locale": "3.0.1", + "os-locale": "3.1.0", "require-directory": "2.1.1", "require-main-filename": "1.0.1", "set-blocking": "2.0.0", @@ -14896,33 +15450,45 @@ } }, "webpack-log": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", - "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", "dev": true, "requires": { - "chalk": "2.2.2", - "log-symbols": "2.2.0", - "loglevelnext": "1.0.5", - "uuid": "3.2.1" + "ansi-colors": "3.2.3", + "uuid": "3.3.2" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } } }, "webpack-merge": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.4.tgz", - "integrity": "sha512-TmSe1HZKeOPey3oy1Ov2iS3guIZjWvMT2BBJDzzT5jScHTjVC3mpjJofgueEzaEd6ibhxRDD6MIblDr8tzh8iQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", + "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", "dev": true, "requires": { "lodash": "4.17.10" } }, "webpack-sources": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", - "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", + "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", "dev": true, "requires": { - "source-list-map": "2.0.0", + "source-list-map": "2.0.1", "source-map": "0.6.1" }, "dependencies": { @@ -14935,9 +15501,9 @@ } }, "webpack-subresource-integrity": { - "version": "1.1.0-rc.4", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.4.tgz", - "integrity": "sha1-xcTj1pD50vZKlVDgeodn+Xlqpdg=", + "version": "1.1.0-rc.6", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.6.tgz", + "integrity": "sha512-Az7y8xTniNhaA0620AV1KPwWOqawurVVDzQSpPAeR5RwNbL91GoBSJAAo9cfd+GiFHwsS5bbHepBw1e6Hzxy4w==", "dev": true, "requires": { "webpack-core": "0.6.9" @@ -15066,7 +15632,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "write": { "version": "0.2.1", @@ -15134,6 +15701,11 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, "xmlhttprequest-ssl": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", @@ -15230,9 +15802,9 @@ "dev": true }, "zone.js": { - "version": "0.8.26", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.26.tgz", - "integrity": "sha512-W9Nj+UmBJG251wkCacIkETgra4QgBo/vgoEkb4a2uoLzpQG7qF9nzwoLXWU5xj3Fg2mxGvEDh47mg24vXccYjA==" + "version": "0.8.29", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.29.tgz", + "integrity": "sha512-mla2acNCMkWXBD+c+yeUrBUrzOxYMNFdQ6FGfigGGtEVBPJx07BQeJekjt9DmH1FtZek4E9rE1eRR9qQpxACOQ==" } } } diff --git a/package.json b/package.json index b0e199dcd5..f9d93a56c6 100644 --- a/package.json +++ b/package.json @@ -19,12 +19,13 @@ "start-high-mem": "npm run customize && node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve", "start-prod-high-mem": "npm run customize && node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve --prod", "start-dev": "ng serve --aot=false", - "test": "run-s test-frontend:*", + "test": "run-s test-frontend:* --continue-on-error", "test-frontend:core": "ng test core --code-coverage --watch=false", "test-frontend:store": "ng test store --code-coverage --watch=false", + "test-frontend:cloud-foundry": "ng test cloud-foundry --code-coverage --watch=false", "posttest": "istanbul report json && node build/combine-coverage.js", "codecov": "codecov -f coverage/coverage-final.json", - "lint": "ng lint", + "lint": "ng lint --format stylish", "sass-lint": "sass-lint -v", "e2e": "ng e2e", "e2e-dev": "ng e2e --dev-server-target= --base-url=https://127.0.0.1:4200", @@ -41,96 +42,97 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@angular/animations": "^6.1.1", - "@angular/cdk": "^6.4.0", - "@angular/common": "^6.1.1", - "@angular/compiler": "^6.1.1", - "@angular/core": "^6.1.1", - "@angular/flex-layout": "^6.0.0-beta.16", - "@angular/forms": "^6.1.1", - "@angular/http": "^6.1.1", - "@angular/material": "^6.1.0", - "@angular/material-moment-adapter": "^6.4.7", - "@angular/platform-browser": "^6.1.1", - "@angular/platform-browser-dynamic": "^6.1.1", - "@angular/platform-server": "^6.1.1", - "@angular/router": "^6.1.1", - "@ngrx/effects": "^6.0.1", - "@ngrx/router-store": "^6.0.1", - "@ngrx/store": "^6.0.1", - "@ngrx/store-devtools": "^6.0.1", - "@swimlane/ngx-charts": "^9.0.0", + "@angular/animations": "^7.2.6", + "@angular/cdk": "^7.3.3", + "@angular/common": "^7.2.6", + "@angular/compiler": "^7.2.6", + "@angular/core": "^7.2.6", + "@angular/flex-layout": "^7.0.0-beta.23", + "@angular/forms": "^7.2.6", + "@angular/http": "^7.2.6", + "@angular/material": "^7.3.3", + "@angular/material-moment-adapter": "^7.3.3", + "@angular/platform-browser": "^7.2.6", + "@angular/platform-browser-dynamic": "^7.2.6", + "@angular/platform-server": "^7.2.6", + "@angular/router": "^7.2.6", + "@ngrx/effects": "^7.2.0", + "@ngrx/router-store": "^7.2.0", + "@ngrx/store": "^7.2.0", + "@ngrx/store-devtools": "^7.2.0", + "@swimlane/ngx-charts": "^10.1.0", "angular2-virtual-scroll": "^0.3.1", - "core-js": "^2.5.7", + "core-js": "^2.6.5", "hammerjs": "^2.0.8", - "js-yaml": "^3.11.0", - "moment": "^2.22.2", - "ngrx-store-logger": "^0.2.1", - "ngx-moment": "^3.1.0", + "moment": "^2.24.0", + "ngx-moment": "^3.3.0", "normalizr": "^3.2.3", "reselect": "^3.0.1", "rxjs": "^6.2.0", "rxjs-spy": "^7.0.2", "rxjs-websockets": "~6.0.0", - "stratos-angular6-json-schema-form": "1.0.3", + "stratos-angular6-json-schema-form": "^7.0.6", "ts-md5": "^1.2.4", "web-animations-js": "^2.3.1", "xterm": "^3.5.0", - "zone.js": "~0.8.26" + "zone.js": "~0.8.26", + "lodash-es": "^4.17.11" }, "engines": { "node": "8.11.2" }, "devDependencies": { - "@angular-devkit/build-angular": "^0.7.4", - "@angular-devkit/build-ng-packagr": "~0.8.0", - "@angular-devkit/schematics": "^0.8.7", - "@angular/cli": "^6.1.5", - "@angular/compiler-cli": "^6.1.1", - "@angular/language-service": "^6.1.1", - "@nrwl/schematics": "^6.4.0", + "@angular-devkit/build-angular": "~0.13.0", + "@angular-devkit/build-ng-packagr": "~0.13.0", + "@angular-devkit/schematics": "^7.3.2", + "@angular/cli": "^7.3.2", + "@angular/compiler-cli": "^7.2.6", + "@angular/language-service": "^7.2.6", + "@nrwl/schematics": "^7.6.0", "@types/jasmine": "^2.8.7", "@types/jasminewd2": "~2.0.3", - "@types/karma": "^1.7.1", - "@types/node": "^6.0.111", - "@types/request": "^2.47.0", + "@types/karma": "^3.0.2", + "@types/node": "^11.9.4", + "@types/request": "^2.48.1", + "acorn": "^6.0.0", "browserstack-local": "^1.3.4", "codecov": "^3.0.2", - "codelyzer": "^4.4.4", + "codelyzer": "^4.5.0", "delete": "^0.3.2", "fs-extra": "^3.0.1", "globby": "^8.0.1", "gulp": "^4.0.0", "gulp-zip": "^4.2.0", - "jasmine-core": "~3.1.0", + "istanbul": "^0.4.5", + "jasmine-core": "~3.3.0", "jasmine-spec-reporter": "~4.2.1", "js-yaml": "~3.11.0", - "karma": "~3.0.0", + "karma": "~4.0.0", "karma-chrome-launcher": "~2.1.1", "karma-cli": "~1.0.1", "karma-coverage-istanbul-reporter": "^2.0.1", - "karma-jasmine": "~1.1.2", - "karma-jasmine-html-reporter": "^1.1.0", + "karma-jasmine": "~2.0.1", + "karma-jasmine-html-reporter": "^1.4.0", "karma-spec-reporter": "0.0.31", "lodash": "^4.17.10", "mem": "4.0.0", "mktemp": "^0.4.0", - "ng-packagr": "^4.1.0", + "ng-packagr": "^4.7.1", "ngrx-store-freeze": "^0.2.3", "npm-run-all": "^4.1.5", "protractor": "^5.4.0", "ps-node": "^0.1.6", "q": "^1.4.1", "replace-in-file": "^3.4.0", - "request-promise-native": "^1.0.5", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", "rxjs-tslint": "^0.1.5", "sass-lint": "^1.12.1", "stratos-merge-dirs": "^0.2.3", "stratos-protractor-reporter": "^1.2.3", "ts-node": "~3.2.0", - "tsickle": ">=0.29.0", "tslib": "^1.9.0", - "tslint": "~5.10.0", - "typescript": "~2.9.0" + "tslint": "~5.13.0", + "typescript": "~3.1.6" } } diff --git a/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts b/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts new file mode 100644 index 0000000000..e8429cf42d --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; + +import { StratosExtension } from '../../core/src/core/extension/extension-service'; +import { EndpointTypeConfig } from '../../core/src/core/extension/extension-types'; +import { urlValidationExpression } from '../../core/src/core/utils.service'; +import { CfEndpointDetailsComponent } from './shared/components/cf-endpoint-details/cf-endpoint-details.component'; +import { CloudFoundryComponentsModule } from './shared/components/components.module'; + +const cloudFoundryEndpointTypes: EndpointTypeConfig[] = [{ + value: 'cf', + label: 'Cloud Foundry', + urlValidation: urlValidationExpression, + icon: 'cloud_foundry', + iconFont: 'stratos-icons', + imagePath: '/core/assets/endpoint-icons/cloudfoundry.png', + homeLink: (guid) => ['/cloud-foundry', guid], + listDetailsComponent: CfEndpointDetailsComponent +}]; + +@StratosExtension({ + endpointTypes: cloudFoundryEndpointTypes, +}) +@NgModule({ + imports: [ + CloudFoundryComponentsModule + ], +}) +export class CloudFoundryModule { } diff --git a/src/frontend/packages/cloud-foundry/src/public_api.ts b/src/frontend/packages/cloud-foundry/src/public_api.ts index ef11c82c31..eef53f2d79 100644 --- a/src/frontend/packages/cloud-foundry/src/public_api.ts +++ b/src/frontend/packages/cloud-foundry/src/public_api.ts @@ -2,6 +2,6 @@ * Public API Surface of cloud-foundry */ -export * from './lib/cloud-foundry.service'; +// export * from './lib/cloud-foundry.service'; export * from './lib/cloud-foundry.component'; export * from './lib/cloud-foundry.module'; diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.html b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.html new file mode 100644 index 0000000000..52465960a6 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.html @@ -0,0 +1,9 @@ +
+
+ + person + + {{ user.name}} (Administrator) +
+
+- \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.scss b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.scss new file mode 100644 index 0000000000..5b7707aa0e --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.scss @@ -0,0 +1,16 @@ +.cf-details { + display: flex; + flex-direction: column; + + &__line { + align-items: center; + display: flex; + } + + &__icon { + align-items: center; + display: flex; + justify-content: center; + width: 32px; + } +} diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.spec.ts new file mode 100644 index 0000000000..c6cf04c3a1 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.spec.ts @@ -0,0 +1,31 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CoreModule } from '../../../../../core/src/core/core.module'; +import { SharedModule } from '../../../../../core/src/shared/shared.module'; +import { CfEndpointDetailsComponent } from './cf-endpoint-details.component'; + +describe('CfEndpointDetailsComponent', () => { + let component: CfEndpointDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [CfEndpointDetailsComponent], + imports: [ + CoreModule, + SharedModule + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CfEndpointDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.ts new file mode 100644 index 0000000000..0012fef5d0 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; + +import { + EndpointListDetailsComponent, +} from '../../../../../core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers'; + + +@Component({ + selector: 'lib-cf-endpoint-details', + templateUrl: './cf-endpoint-details.component.html', + styleUrls: ['./cf-endpoint-details.component.scss'] +}) +export class CfEndpointDetailsComponent extends EndpointListDetailsComponent { } diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/components.module.ts b/src/frontend/packages/cloud-foundry/src/shared/components/components.module.ts new file mode 100644 index 0000000000..3ec2e28d4e --- /dev/null +++ b/src/frontend/packages/cloud-foundry/src/shared/components/components.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; + +import { CoreModule } from '../../../../core/src/core/core.module'; +import { CfEndpointDetailsComponent } from './cf-endpoint-details/cf-endpoint-details.component'; + +@NgModule({ + imports: [ + CoreModule + ], + declarations: [ + CfEndpointDetailsComponent + ], + exports: [ + CfEndpointDetailsComponent + ], + entryComponents: [ + CfEndpointDetailsComponent + ] +}) +export class CloudFoundryComponentsModule { } diff --git a/src/frontend/packages/cloud-foundry/src/test.ts b/src/frontend/packages/cloud-foundry/src/test.ts index e11ff1c97b..18653a67a2 100644 --- a/src/frontend/packages/cloud-foundry/src/test.ts +++ b/src/frontend/packages/cloud-foundry/src/test.ts @@ -1,21 +1,35 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files - import 'core-js/es7/reflect'; import 'zone.js/dist/zone'; import 'zone.js/dist/zone-testing'; + +import { APP_BASE_HREF } from '@angular/common'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; + declare const require: any; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( +const testBed = getTestBed(); +testBed.initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting() ); + +beforeEach(() => { + testBed.configureTestingModule({ + providers: [{ provide: APP_BASE_HREF, useValue: '/' }] + }); +}); + +/** + * Bump up the Jasmine timeout from 5 seconds + */ +beforeAll(() => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; +}); + // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/src/frontend/packages/cloud-foundry/tsconfig.spec.json b/src/frontend/packages/cloud-foundry/tsconfig.spec.json index 1fe1c34b80..cb4a7be918 100644 --- a/src/frontend/packages/cloud-foundry/tsconfig.spec.json +++ b/src/frontend/packages/cloud-foundry/tsconfig.spec.json @@ -2,6 +2,10 @@ "extends": "../../../tsconfig.spec.json", "compilerOptions": { "outDir": "../../../../out-tsc/spec", + "types": [ + "jasmine", + "node" + ] }, "files": [ "src/test.ts" @@ -9,8 +13,5 @@ "include": [ "**/*.spec.ts", "**/*.d.ts" - ], - "exclude": [ - "**/node_modules/**" ] } diff --git a/src/frontend/packages/core/assets/endpoint-icons/cloudfoundry.png b/src/frontend/packages/core/assets/endpoint-icons/cloudfoundry.png new file mode 100644 index 0000000000..cc022705d5 Binary files /dev/null and b/src/frontend/packages/core/assets/endpoint-icons/cloudfoundry.png differ diff --git a/src/frontend/packages/core/assets/endpoint-icons/metrics.svg b/src/frontend/packages/core/assets/endpoint-icons/metrics.svg new file mode 100644 index 0000000000..5c51f66d90 --- /dev/null +++ b/src/frontend/packages/core/assets/endpoint-icons/metrics.svg @@ -0,0 +1,50 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/src/frontend/packages/core/src/app.module.ts b/src/frontend/packages/core/src/app.module.ts index 4ad01493c1..b2ddb80e3b 100644 --- a/src/frontend/packages/core/src/app.module.ts +++ b/src/frontend/packages/core/src/app.module.ts @@ -6,6 +6,7 @@ import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router import { Store } from '@ngrx/store'; import { debounceTime, withLatestFrom } from 'rxjs/operators'; +import { CloudFoundryModule } from '../../cloud-foundry/src/cloud-foundry.module'; import { GetAllEndpoints } from '../../store/src/actions/endpoint.actions'; import { GetOrganization } from '../../store/src/actions/organization.actions'; import { SetRecentlyVisitedEntityAction } from '../../store/src/actions/recently-visited.actions'; @@ -38,6 +39,7 @@ import { CurrentUserPermissionsService } from './core/current-user-permissions.s 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 { LoggerService } from './core/logger.service'; import { UserFavoriteManager } from './core/user-favorite-manager'; import { CustomImportModule } from './custom-import.module'; import { AboutModule } from './features/about/about.module'; @@ -112,6 +114,7 @@ export class CustomRouterStateSerializer AboutModule, CustomImportModule, XSRFModule, + CloudFoundryModule ], providers: [ LoggedInService, @@ -130,13 +133,14 @@ export class AppModule { private permissionService: CurrentUserPermissionsService, private appStateService: ApplicationStateService, private store: Store, + private logger: LoggerService ) { ext.init(); // Init Auth Types and Endpoint Types provided by extensions initEndpointExtensions(ext); // Once the CF modules become an extension point, these should be moved to a CF specific module this.registerCfFavoriteMappers(); - this.userFavoriteManager = new UserFavoriteManager(store); + this.userFavoriteManager = new UserFavoriteManager(store, logger); const allFavs$ = this.userFavoriteManager.getAllFavorites(); const recents$ = this.store.select(recentlyVisitedSelector); const debouncedApiRequestData$ = this.store.select(getAPIRequestDataState).pipe(debounceTime(2000)); diff --git a/src/frontend/packages/core/src/core/auth-guard.service.ts b/src/frontend/packages/core/src/core/auth-guard.service.ts index 8dc7a4d5dd..246dd2b3a0 100644 --- a/src/frontend/packages/core/src/core/auth-guard.service.ts +++ b/src/frontend/packages/core/src/core/auth-guard.service.ts @@ -1,26 +1,23 @@ - -import { first, map } from 'rxjs/operators'; - - import { Injectable } from '@angular/core'; import { ActivatedRoute, CanActivate, Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; +import { first, map } from 'rxjs/operators'; import { RouterNav } from '../../../store/src/actions/router.actions'; import { AppState } from '../../../store/src/app-state'; import { AuthState } from '../../../store/src/reducers/auth.reducer'; -export function queryParamMap() { +export function queryParamMap(): { [key: string]: string } { const paramMap = {}; const query = window.location.search.substring(1); if (query.length === 0) { return paramMap; } const vars = query.split('&'); - for (let i = 0; i < vars.length; i++) { - const pair = vars[i].split('='); - paramMap[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); + for (const pair of vars) { + const vals = pair.split('='); + paramMap[decodeURIComponent(vals[0])] = decodeURIComponent(vals[1]); } return paramMap; } diff --git a/src/frontend/packages/core/src/core/cf-api.types.ts b/src/frontend/packages/core/src/core/cf-api.types.ts index ecb3edcdf0..da51083a15 100644 --- a/src/frontend/packages/core/src/core/cf-api.types.ts +++ b/src/frontend/packages/core/src/core/cf-api.types.ts @@ -1,7 +1,6 @@ -import { IRoute } from './cf-api.types'; import { APIResource } from '../../../store/src/types/api.types'; -import { IServiceBinding, IService } from './cf-api-svc.types'; import { CfUser } from '../../../store/src/types/user.types'; +import { IService, IServiceBinding } from './cf-api-svc.types'; export interface IRoute { host: string; @@ -138,7 +137,7 @@ export interface IDockercredentials { } export interface IEnvironmentjson { - [any: string]: string; + [key: string]: string; } export interface IDeveloper { diff --git a/src/frontend/packages/core/src/core/core.module.ts b/src/frontend/packages/core/src/core/core.module.ts index 63958dc505..0a3757a28d 100644 --- a/src/frontend/packages/core/src/core/core.module.ts +++ b/src/frontend/packages/core/src/core/core.module.ts @@ -10,6 +10,7 @@ import { BytesToHumanSize, MegaBytesToHumanSize } from './byte-formatters.pipe'; import { ClickStopPropagationDirective } from './click-stop-propagation.directive'; import { CurrentUserPermissionsService } from './current-user-permissions.service'; import { Customizations } from './customizations.types'; +import { DisableRouterLinkDirective } from './disable-router-link.directive'; import { DotContentComponent } from './dot-content/dot-content.component'; import { EndpointsService } from './endpoints.service'; import { EntityFavoriteStarComponent } from './entity-favorite-star/entity-favorite-star.component'; @@ -51,7 +52,8 @@ import { WindowRef } from './window-ref/window-ref.service'; ButtonBlurOnClickDirective, PageNotFoundComponentComponent, EntityFavoriteStarComponent, - RecentEntitiesComponent + RecentEntitiesComponent, + DisableRouterLinkDirective ], providers: [ AuthGuardService, @@ -78,7 +80,8 @@ import { WindowRef } from './window-ref/window-ref.service'; ButtonBlurOnClickDirective, PageNotFoundComponentComponent, EntityFavoriteStarComponent, - RecentEntitiesComponent + RecentEntitiesComponent, + DisableRouterLinkDirective ], entryComponents: [ LogOutDialogComponent 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 e68918b558..3c462a0114 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 @@ -2,11 +2,6 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; -import { CFFeatureFlagTypes } from '../shared/components/cf-auth/cf-auth.types'; -import { - createCFFeatureFlagPaginationKey, -} from '../shared/components/list/list-types/cf-feature-flags/cf-feature-flags-data-source.helpers'; -import { PaginationMonitor } from '../shared/monitors/pagination-monitor'; import { AppState } from '../../../store/src/app-state'; import { entityFactory, featureFlagSchemaKey } from '../../../store/src/helpers/entity-factory'; import { @@ -19,6 +14,11 @@ import { import { endpointsRegisteredEntitiesSelector } from '../../../store/src/selectors/endpoint.selectors'; import { APIResource } from '../../../store/src/types/api.types'; import { IOrgRoleState, ISpaceRoleState, ISpacesRoleState } from '../../../store/src/types/current-user-roles.types'; +import { CFFeatureFlagTypes } from '../shared/components/cf-auth/cf-auth.types'; +import { + createCFFeatureFlagPaginationKey, +} from '../shared/components/list/list-types/cf-feature-flags/cf-feature-flags-data-source.helpers'; +import { PaginationMonitor } from '../shared/monitors/pagination-monitor'; import { IFeatureFlag } from './cf-api.types'; import { PermissionConfig, @@ -78,11 +78,7 @@ export class CurrentUserPermissionsChecker { ); } /** - * * @param permissionConfig Single permission to be checked - * @param endpointGuid - * @param orgOrSpaceGuid - * @param spaceGuid */ public getSimpleCheck(permissionConfig: PermissionConfig, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string) { switch (permissionConfig.type) { @@ -208,7 +204,7 @@ export class CurrentUserPermissionsChecker { } public checkFeatureFlag(featureFlags: APIResource[], permission: CFFeatureFlagTypes) { - const flag = featureFlags.find(_flag => _flag.entity.name === permission.toString()); + const flag = featureFlags.find(ff => ff.entity.name === permission.toString()); if (!flag) { return false; } @@ -231,8 +227,8 @@ export class CurrentUserPermissionsChecker { } /** - * Includes read only admins, global auditors and users that don't have the cloud_controller.write scope - */ + * 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( diff --git a/src/frontend/packages/core/src/core/current-user-permissions.service.spec.ts b/src/frontend/packages/core/src/core/current-user-permissions.service.spec.ts index a67e284007..8062513a3d 100644 --- a/src/frontend/packages/core/src/core/current-user-permissions.service.spec.ts +++ b/src/frontend/packages/core/src/core/current-user-permissions.service.spec.ts @@ -24,13 +24,13 @@ const initialState = { currentPage: 1, totalResults: 2, ids: { - '1': [ + 1: [ '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb', 'c80420ca-204b-4879-bf69-b6b7a202ad87' ] }, pageRequests: { - '1': { + 1: { busy: false, error: false, message: '' @@ -73,7 +73,7 @@ const initialState = { currentPage: 1, totalResults: 13, ids: { - '1': [ + 1: [ '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-0', '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-1', '0e934dc8-7ad4-40ff-b85c-53c1b61d2abb-2', @@ -90,7 +90,7 @@ const initialState = { ] }, pageRequests: { - '1': { + 1: { busy: false, error: false, message: '' @@ -112,7 +112,7 @@ const initialState = { currentPage: 1, totalResults: 13, ids: { - '1': [ + 1: [ 'c80420ca-204b-4879-bf69-b6b7a202ad87-0', 'c80420ca-204b-4879-bf69-b6b7a202ad87-1', 'c80420ca-204b-4879-bf69-b6b7a202ad87-2', @@ -129,7 +129,7 @@ const initialState = { ] }, pageRequests: { - '1': { + 1: { busy: false, error: false, message: '' @@ -695,7 +695,7 @@ const initialState = { } } }, - 'READ_ONLY_ADMIN': { + READ_ONLY_ADMIN: { global: { isAdmin: false, isReadOnlyAdmin: true, @@ -759,7 +759,7 @@ const initialState = { } } }, - 'READ_ONLY_USER': { + READ_ONLY_USER: { global: { isAdmin: false, isReadOnlyAdmin: false, 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 fd7a1aaedf..b441ef814c 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 @@ -119,21 +119,21 @@ export class CurrentUserPermissionsService { } } - private getConfig(config: PermissionConfigType, _tries = 0): PermissionConfig[] | PermissionConfig { + private getConfig(config: PermissionConfigType, tries = 0): PermissionConfig[] | PermissionConfig { const linkConfig = config as PermissionConfigLink; if (linkConfig.link) { - if (_tries >= 20) { + if (tries >= 20) { // Tried too many times to get permission config, circular reference very likely. return; } - ++_tries; - return this.getLinkedPermissionConfig(linkConfig, _tries); + ++tries; + return this.getLinkedPermissionConfig(linkConfig, tries); } else { return config as PermissionConfig[] | PermissionConfig; } } - private getLinkedPermissionConfig(linkConfig: PermissionConfigLink, _tries = 0) { + private getLinkedPermissionConfig(linkConfig: PermissionConfigLink, tries = 0) { return this.getConfig(permissionConfigs[linkConfig.link]); } diff --git a/src/frontend/packages/core/src/core/disable-router-link.directive.ts b/src/frontend/packages/core/src/core/disable-router-link.directive.ts new file mode 100644 index 0000000000..3a24c8ecfc --- /dev/null +++ b/src/frontend/packages/core/src/core/disable-router-link.directive.ts @@ -0,0 +1,32 @@ +import { Directive, Input, Optional } from '@angular/core'; +import { RouterLink, RouterLinkWithHref } from '@angular/router'; + +@Directive({ + selector: '[routerLink][appDisableRouterLink]' +}) +export class DisableRouterLinkDirective { + + @Input() appDisableRouterLink: boolean; + + constructor( + // Inject routerLink + @Optional() routerLink: RouterLink, + @Optional() routerLinkWithHref: RouterLinkWithHref + ) { + + const link = routerLink || routerLinkWithHref; + + // Save original method + const onClick = link.onClick; + + // Replace method + link.onClick = (...args) => { + if (this.appDisableRouterLink) { + return routerLinkWithHref ? false : true; + } else { + return onClick.apply(link, args); + } + }; + } + +} diff --git a/src/frontend/packages/core/src/core/dispatch-sequencer.ts b/src/frontend/packages/core/src/core/dispatch-sequencer.ts index df861386f9..9af1571ead 100644 --- a/src/frontend/packages/core/src/core/dispatch-sequencer.ts +++ b/src/frontend/packages/core/src/core/dispatch-sequencer.ts @@ -1,6 +1,7 @@ import { Action, Store } from '@ngrx/store'; import { from, Observable, of as observableOf } from 'rxjs'; import { bufferTime, concatMap, delay, filter, map, mergeMap, switchMap, tap } from 'rxjs/operators'; + import { AppState } from '../../../store/src/app-state'; @@ -16,20 +17,18 @@ export class DispatchSequencer { } = {}; /** - * @param {Store} store - * @param {number} [batchSize=5] + * @param [batchSize=5] * Multiple requests will be split up into batches of this size - * @param {number} [batchDelayInMs=5000] + * @param [batchDelayInMs=5000] * Delay to apply between each batch - * @param {number} [debounceInMs=5000] + * @param [debounceInMs=5000] * Ignore repeat request made within this time period - * @memberof DispatchSequencer */ constructor(private store: Store, private batchSize = 5, private batchDelayInMs = 5000, private debounceInMs = 5000) { } /** - * Filter out recently dispatched actions - */ + * Filter out recently dispatched actions + */ private filter(actions: DispatchSequencerAction[]): DispatchSequencerAction[] { if (this.debounceInMs) { const now = new Date().getTime(); @@ -49,9 +48,9 @@ export class DispatchSequencer { } /** - * Dispatch actions in groups of `batchSize` such that there are no duplicate actions dispatched within `debounceInMs`. Each batch dispatch - * will be separated by `batchDelayInMs`. - */ + * Dispatch actions in groups of `batchSize` such that there are no duplicate actions dispatched within `debounceInMs`. Each batch + * dispatch will be separated by `batchDelayInMs`. + */ public sequence(obs: Observable): Observable { return obs.pipe(switchMap(actions => this.innerSequence(actions))); } diff --git a/src/frontend/packages/core/src/core/endpoints.service.ts b/src/frontend/packages/core/src/core/endpoints.service.ts index 9af41000bd..eae3d2ec5e 100644 --- a/src/frontend/packages/core/src/core/endpoints.service.ts +++ b/src/frontend/packages/core/src/core/endpoints.service.ts @@ -16,6 +16,7 @@ import { UserService } from './user.service'; import { AuthState } from '../../../store/src/reducers/auth.reducer'; import { RouterNav } from '../../../store/src/actions/router.actions'; import { endpointHealthChecks, EndpointHealthCheck } from '../../endpoints-health-checks'; +import { getEndpointTypes } from '../features/endpoints/endpoint-helpers'; @Injectable() @@ -25,6 +26,17 @@ export class EndpointsService implements CanActivate { haveRegistered$: Observable; haveConnected$: Observable; + static getLinkForEndpoint(endpoint: EndpointModel): string { + if (!endpoint) { + return ''; + } + const ext = getEndpointTypes().find(ep => ep.value === endpoint.cnsi_type); + if (ext && ext.homeLink) { + return ext.homeLink(endpoint.guid).join('/'); + } + return ''; + } + constructor( private store: Store, private userService: UserService @@ -101,5 +113,4 @@ export class EndpointsService implements CanActivate { ); } - } 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 ea503a89aa..a45a27dcb7 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 @@ -9,6 +9,7 @@ import { ConfirmationDialogConfig } from '../../shared/components/confirmation-d import { ConfirmationDialogService } from '../../shared/components/confirmation-dialog.service'; import { favoritesConfigMapper } from '../../shared/components/favorites-meta-card/favorite-config-mapper'; import { UserFavoriteManager } from '../user-favorite-manager'; +import { LoggerService } from '../logger.service'; @Component({ selector: 'app-entity-favorite-star', @@ -23,9 +24,9 @@ export class EntityFavoriteStarComponent { this.confirmationDialogConfig.message = `Are you sure you would you like to unfavorite this ${name ? name.toLocaleLowerCase() : 'favorite'}?`; this.isFavorite$ = this.userFavoriteManager.getIsFavoriteObservable(favorite); - this._favorite = favorite; + this.pFavourite = favorite; } - private _favorite: UserFavorite; + private pFavourite: UserFavorite; @Input() private confirmRemoval = false; @@ -36,8 +37,11 @@ export class EntityFavoriteStarComponent { private confirmationDialogConfig = new ConfirmationDialogConfig('Unfavorite?', '', 'Yes', true); - constructor(store: Store, private confirmDialog: ConfirmationDialogService) { - this.userFavoriteManager = new UserFavoriteManager(store); + constructor( + store: Store, + private confirmDialog: ConfirmationDialogService, + logger: LoggerService) { + this.userFavoriteManager = new UserFavoriteManager(store, logger); } public toggleFavorite(event: Event) { @@ -48,18 +52,18 @@ export class EntityFavoriteStarComponent { first(), tap(is => { if (is) { - this.confirmDialog.open(this.confirmationDialogConfig, this._toggleFavorite); + this.confirmDialog.open(this.confirmationDialogConfig, this.pToggleFavorite); } else { - this._toggleFavorite(); + this.pToggleFavorite(); } }) ).subscribe(); } else { - this._toggleFavorite(); + this.pToggleFavorite(); } } - private _toggleFavorite = () => { - this.userFavoriteManager.toggleFavorite(this._favorite); + private pToggleFavorite = (res?: any) => { + this.userFavoriteManager.toggleFavorite(this.pFavourite); } } diff --git a/src/frontend/packages/core/src/core/entity-service.spec.ts b/src/frontend/packages/core/src/core/entity-service.spec.ts index 9611fe9a45..576ea210c4 100644 --- a/src/frontend/packages/core/src/core/entity-service.spec.ts +++ b/src/frontend/packages/core/src/core/entity-service.spec.ts @@ -3,22 +3,27 @@ import { HttpModule, XHRBackend } from '@angular/http'; import { MockBackend } from '@angular/http/testing'; import { Store } from '@ngrx/store'; import { schema as normalizrSchema } from 'normalizr'; -import { filter, first, tap, pairwise, map } from 'rxjs/operators'; -import { ENTITY_SERVICE } from '../shared/entity.tokens'; -import { EntityMonitor } from '../shared/monitors/entity-monitor'; -import { EntityMonitorFactory } from '../shared/monitors/entity-monitor.factory.service'; +import { filter, first, map, pairwise, tap } from 'rxjs/operators'; + import { GetApplication } from '../../../store/src/actions/application.actions'; import { APIResponse } from '../../../store/src/actions/request.actions'; import { AppState } from '../../../store/src/app-state'; import { applicationSchemaKey, entityFactory } from '../../../store/src/helpers/entity-factory'; -import { completeApiRequest, startApiRequest, failApiRequest } from '../../../store/src/reducers/api-request-reducer/request-helpers'; +import { + completeApiRequest, + failApiRequest, + startApiRequest, +} from '../../../store/src/reducers/api-request-reducer/request-helpers'; import { RequestSectionKeys } from '../../../store/src/reducers/api-request-reducer/types'; import { NormalizedResponse } from '../../../store/src/types/api.types'; import { ICFAction, IRequestAction } from '../../../store/src/types/request.types'; -import { EntityService } from './entity-service'; -import { EntityServiceFactory } from './entity-service-factory.service'; import { generateTestEntityServiceProvider } from '../../test-framework/entity-service.helper'; import { createBasicStoreModule } from '../../test-framework/store-test-helper'; +import { ENTITY_SERVICE } from '../shared/entity.tokens'; +import { EntityMonitor } from '../shared/monitors/entity-monitor'; +import { EntityMonitorFactory } from '../shared/monitors/entity-monitor.factory.service'; +import { EntityService } from './entity-service'; +import { EntityServiceFactory } from './entity-service-factory.service'; const appId = '4e4858c4-24ab-4caf-87a8-7703d1da58a0'; diff --git a/src/frontend/packages/core/src/core/entity-service.ts b/src/frontend/packages/core/src/core/entity-service.ts index b859a2a21c..af81987c98 100644 --- a/src/frontend/packages/core/src/core/entity-service.ts +++ b/src/frontend/packages/core/src/core/entity-service.ts @@ -2,7 +2,6 @@ import { compose, Store } from '@ngrx/store'; import { combineLatest, Observable } from 'rxjs'; import { filter, first, map, publishReplay, refCount, switchMap, tap, withLatestFrom } from 'rxjs/operators'; -import { EntityMonitor } from '../shared/monitors/entity-monitor'; import { ValidateEntitiesStart } from '../../../store/src/actions/request.actions'; import { AppState } from '../../../store/src/app-state'; import { @@ -14,6 +13,7 @@ import { import { getEntityUpdateSections, getUpdateSectionById } from '../../../store/src/selectors/api.selectors'; import { EntityInfo } from '../../../store/src/types/api.types'; import { ICFAction, IRequestAction } from '../../../store/src/types/request.types'; +import { EntityMonitor } from '../shared/monitors/entity-monitor'; export function isEntityBlocked(entityRequestInfo: RequestInfoState) { if (!entityRequestInfo) { @@ -38,7 +38,7 @@ export class EntityService { public validateRelations = true, public entitySection: TRequestTypeKeys = RequestSectionKeys.CF, ) { - this.actionDispatch = (updatingKey) => { + this.actionDispatch = (updatingKey?: string) => { if (updatingKey) { action.updatingKey = updatingKey; } @@ -87,9 +87,9 @@ export class EntityService { refreshKey = 'updating'; - private actionDispatch: Function; + private actionDispatch: (key: string) => void; - updateEntity: Function; + updateEntity: () => void; entityObs$: Observable>; @@ -102,7 +102,7 @@ export class EntityService { updatingSection$: Observable; private getEntityObservable = ( entityMonitor: EntityMonitor, - actionDispatch: Function + actionDispatch: (key?: string) => void ): Observable => { const cleanEntityInfo$ = this.getCleanEntityInfoObs(entityMonitor); return entityMonitor.entityRequest$.pipe( 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 f42e623869..60febeabbf 100644 --- a/src/frontend/packages/core/src/core/extension/extension-service.ts +++ b/src/frontend/packages/core/src/core/extension/extension-service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Route, Router } from '@angular/router'; -import { EndpointTypeConfig, EndpointAuthTypeConfig, ExtensionEntitySchema } from './extension-types'; +import { EndpointAuthTypeConfig, EndpointTypeConfig, ExtensionEntitySchema } from './extension-types'; export const extensionsActionRouteKey = 'extensionsActionsKey'; @@ -80,25 +80,21 @@ const extensionMetadata = { * Decortator for a Tab extension */ export function StratosTab(props: StratosTabMetadata) { - return function (target) { - addExtensionTab(props.type, target, props); - }; + return target => addExtensionTab(props.type, target, props); } /** * Decortator for an Action extension */ export function StratosAction(props: StratosActionMetadata) { - return function (target) { - addExtensionAction(props.type, target, props); - }; + return target => addExtensionAction(props.type, target, props); } /** * Decorator for an Extension module */ export function StratosExtension(config: StratosExtensionConfig) { - return (_target) => { + return target => { if (config.endpointTypes) { extensionMetadata.endpointTypes.push(...config.endpointTypes); } @@ -112,9 +108,7 @@ export function StratosExtension(config: StratosExtensionConfig) { } export function StratosLoginComponent() { - return (target) => { - extensionMetadata.loginComponent = target; - }; + return target => extensionMetadata.loginComponent = target; } function addExtensionTab(tab: StratosTabType, target: any, props: any) { diff --git a/src/frontend/packages/core/src/core/extension/extension-types.ts b/src/frontend/packages/core/src/core/extension/extension-types.ts index 8fb372c0ac..74f30c9d52 100644 --- a/src/frontend/packages/core/src/core/extension/extension-types.ts +++ b/src/frontend/packages/core/src/core/extension/extension-types.ts @@ -12,11 +12,20 @@ export interface EndpointTypeConfig { allowTokenSharing?: boolean; icon?: string; iconFont?: string; + imagePath?: string; authTypes?: string[]; - // Get the link to the home page for the given endpoint GUID - homeLink?: (string) => string[]; - // Schema keys associated with this endpoint type (used when clearing pagination) + /** + * Get the link to the home page for the given endpoint GUID + */ + homeLink?: (s) => string[]; + /** + * Schema keys associated with this endpoint type (used when clearing pagination) + */ entitySchemaKeys?: string[]; + /** + * Show custom content in the endpoints list. Should be Type + */ + listDetailsComponent?: any; } export interface EndpointAuthTypeConfig { @@ -42,7 +51,7 @@ export interface EndpointAuthValues { [key: string]: string; } * Optional interface that an Endpoint Auth Form Component can implement * if it needs to supply content in the request body when connecting an endppoint * e.g. if it needs to send a config file - **/ + */ export interface IEndpointAuthComponent extends IAuthForm { // Allows auth type to override which values are sent to the backend when connecting getValues(values: EndpointAuthValues): EndpointAuthValues; // Map of values to send diff --git a/src/frontend/packages/core/src/core/log-out-dialog/log-out-dialog.component.ts b/src/frontend/packages/core/src/core/log-out-dialog/log-out-dialog.component.ts index bac57a7c2d..a0a24a2aab 100644 --- a/src/frontend/packages/core/src/core/log-out-dialog/log-out-dialog.component.ts +++ b/src/frontend/packages/core/src/core/log-out-dialog/log-out-dialog.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, Inject, OnDestroy, Optional } from '@angular/core'; -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { Component, Inject, OnDestroy, OnInit, Optional } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; import { Store } from '@ngrx/store'; import { interval, Subscription } from 'rxjs'; import { tap } from 'rxjs/operators'; -import { AppState } from '../../../../store/src/app-state'; + import { Logout } from '../../../../store/src/actions/auth.actions'; +import { AppState } from '../../../../store/src/app-state'; @Component({ selector: 'app-log-out-dialog', @@ -17,7 +18,7 @@ export class LogOutDialogComponent implements OnInit, OnDestroy { @Optional() @Inject(MAT_DIALOG_DATA) public data: any, private store: Store) { } - private _autoLogout: Subscription; + private autoLogout: Subscription; public countDown: number; public countdownTotal: number; public percentage = 0; @@ -25,11 +26,11 @@ export class LogOutDialogComponent implements OnInit, OnDestroy { ngOnInit() { const updateInterval = 500; this.countdownTotal = this.countDown = this.data.expiryDate - Date.now(); - this._autoLogout = interval(updateInterval) + this.autoLogout = interval(updateInterval) .pipe( tap(() => { if (this.countDown <= 0) { - this._autoLogout.unsubscribe(); + this.autoLogout.unsubscribe(); this.store.dispatch(new Logout()); } else { this.countDown -= updateInterval; @@ -41,7 +42,7 @@ export class LogOutDialogComponent implements OnInit, OnDestroy { ngOnDestroy() { this.percentage = 0; - this._autoLogout.unsubscribe(); + this.autoLogout.unsubscribe(); } } diff --git a/src/frontend/packages/core/src/core/logger.service.ts b/src/frontend/packages/core/src/core/logger.service.ts index 53a51b481e..410958f0c7 100644 --- a/src/frontend/packages/core/src/core/logger.service.ts +++ b/src/frontend/packages/core/src/core/logger.service.ts @@ -1,7 +1,14 @@ import { Injectable } from '@angular/core'; -import { Store, Action } from '@ngrx/store'; +import { Store } from '@ngrx/store'; + +import { + LoggerDebugAction, + LoggerErrorAction, + LoggerInfoAction, + LoggerWarnAction, + LogLevel, +} from '../../../store/src/actions/log.actions'; import { AppState } from '../../../store/src/app-state'; -import { LoggerInfoAction, LoggerDebugAction, LoggerWarnAction, LoggerErrorAction, LogLevel } from '../../../store/src/actions/log.actions'; import { environment } from '../environments/environment.prod'; export enum LogLevelStringToNumber { @@ -34,6 +41,7 @@ export class LoggerService { this.store.dispatch(new LoggerWarnAction(message)); break; case LogLevel.INFO: + // tslint:disable-next-line:no-console func = console.info; this.store.dispatch(new LoggerInfoAction(message)); break; diff --git a/src/frontend/packages/core/src/core/user-favorite-manager.ts b/src/frontend/packages/core/src/core/user-favorite-manager.ts index e57d8946b7..565afef0d4 100644 --- a/src/frontend/packages/core/src/core/user-favorite-manager.ts +++ b/src/frontend/packages/core/src/core/user-favorite-manager.ts @@ -23,6 +23,7 @@ import { favoritesConfigMapper, TFavoriteMapperFunction, } from '../shared/components/favorites-meta-card/favorite-config-mapper'; +import { LoggerService } from './logger.service'; export interface IFavoriteEntity { type: string; @@ -51,7 +52,10 @@ export interface IHydrationResults) { } + constructor( + private store: Store, + private logger: LoggerService + ) { } private getTypeAndID(favorite: UserFavorite) { const type = favorite.entityType; @@ -122,7 +126,7 @@ export class UserFavoriteManager { if (!endpointFav) { return this.store.select(endpointEntitiesSelector).pipe( map(endpoints => { - const endpointGuid = UserFavorite.getEntityGuidFromFavoriteGuid(endpointFavoriteGuid); + const endpointGuid = UserFavorite.getEntityGuidFromFavoriteGuid(endpointFavoriteGuid, this.logger); const endpointEntity = endpoints[endpointGuid]; return new UserFavoriteEndpoint( endpointGuid, diff --git a/src/frontend/packages/core/src/core/utils.service.ts b/src/frontend/packages/core/src/core/utils.service.ts index b7ffda14e5..c4a273acba 100644 --- a/src/frontend/packages/core/src/core/utils.service.ts +++ b/src/frontend/packages/core/src/core/utils.service.ts @@ -112,8 +112,8 @@ export class UtilsService { return Math.floor(Math.log(value) / Math.log(1024)); } - getReducedValue(value, number, precision): number { - return (value / Math.pow(1024, Math.floor(number))); + getReducedValue(value: number, multiplier: number): number { + return (value / Math.pow(1024, Math.floor(multiplier))); } usageBytes(usage, usedPrecision?, totalPrecision?): string { @@ -131,29 +131,28 @@ export class UtilsService { totalPrecision = this.getDefaultPrecision(totalPrecision); // Units - const number = this.getNumber(total); + const value = this.getNumber(total); let usedNumber = null; // Values to display - const totalDisplay = this.getReducedValue(total, number, totalPrecision).toFixed(totalPrecision); - const usedValue = this.getReducedValue(used, number, usedPrecision); + const totalDisplay = this.getReducedValue(total, value).toFixed(totalPrecision); + const usedValue = this.getReducedValue(used, value); let usedDisplay = usedValue.toFixed(totalPrecision); // Is the used value too small to be accurate (for instance 20M consumed of 1GB would show as 0 of 1GB)? if (used !== 0 && usedPrecision === 0 && usedValue < 1) { // Use the units relative to the used value instead of total (20MB of 1GB instead of 0 of 1GB) usedNumber = this.getNumber(used); - usedDisplay = this.getReducedValue(used, usedNumber, usedPrecision).toFixed(totalPrecision); + usedDisplay = this.getReducedValue(used, usedNumber).toFixed(totalPrecision); } - return usedDisplay + (usedNumber ? ' ' + this.units[usedNumber] : '') + ' / ' + totalDisplay + ' ' + this.units[number]; + return usedDisplay + (usedNumber ? ' ' + this.units[usedNumber] : '') + ' / ' + totalDisplay + ' ' + this.units[value]; } /** - * @function formatUptime * @description format an uptime in seconds into a days, hours, minutes, seconds string - * @param {number} uptime in seconds - * @returns {string} formatted uptime string + * @param uptime in seconds + * @returns formatted uptime string */ formatUptime(uptime): string { if (uptime === undefined || uptime === null) { @@ -206,8 +205,8 @@ export class UtilsService { } /** -* Return the value in the object for the given dot separated param path -*/ + * Return the value in the object for the given dot separated param path + */ export function pathGet(path: string, object: any): any { const params = path.split('.'); @@ -234,7 +233,7 @@ export function pathSet(path: string, object: any, value: any) { } } -export function parseHttpPipeError(res): {} { +export function parseHttpPipeError(res): { message?: string } { if (!res.status) { return res; } diff --git a/src/frontend/packages/core/src/features/applications/app-name-unique.directive/app-name-unique.directive.ts b/src/frontend/packages/core/src/features/applications/app-name-unique.directive/app-name-unique.directive.ts index 78b5224dac..e78b9c7e3a 100644 --- a/src/frontend/packages/core/src/features/applications/app-name-unique.directive/app-name-unique.directive.ts +++ b/src/frontend/packages/core/src/features/applications/app-name-unique.directive/app-name-unique.directive.ts @@ -1,14 +1,14 @@ - -import { throwError as observableThrowError, timer as observableTimer, of as observableOf, Observable } from 'rxjs'; - -import { take, combineLatest, switchMap, map, catchError } from 'rxjs/operators'; import { Directive, forwardRef, Input, OnInit } from '@angular/core'; import { AbstractControl, AsyncValidator, NG_ASYNC_VALIDATORS } from '@angular/forms'; import { Headers, Http, Request, RequestOptions, URLSearchParams } from '@angular/http'; import { Store } from '@ngrx/store'; +import { Observable, of as observableOf, throwError as observableThrowError, timer as observableTimer } from 'rxjs'; +import { catchError, combineLatest, map, switchMap, take } from 'rxjs/operators'; + +import { AppState } from '../../../../../store/src/app-state'; import { selectNewAppState } from '../../../../../store/src/effects/create-app-effects'; import { environment } from '../../../environments/environment.prod'; -import { AppState } from '../../../../../store/src/app-state'; + /* tslint:disable:no-use-before-declare */ const APP_UNIQUE_NAME_PROVIDER = { diff --git a/src/frontend/packages/core/src/features/applications/application-delete/delete-app-instances/app-delete-instances-routes-list-config.service.ts b/src/frontend/packages/core/src/features/applications/application-delete/delete-app-instances/app-delete-instances-routes-list-config.service.ts index 2e0a9a31e5..986b462669 100644 --- a/src/frontend/packages/core/src/features/applications/application-delete/delete-app-instances/app-delete-instances-routes-list-config.service.ts +++ b/src/frontend/packages/core/src/features/applications/application-delete/delete-app-instances/app-delete-instances-routes-list-config.service.ts @@ -4,6 +4,15 @@ import { Store } from '@ngrx/store'; import { Observable, of as observableOf } from 'rxjs'; import { first, map } from 'rxjs/operators'; +import { FetchAllServiceBindings } from '../../../../../../store/src/actions/service-bindings.actions'; +import { AppState } from '../../../../../../store/src/app-state'; +import { entityFactory, serviceSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; +import { + createEntityRelationPaginationKey, +} from '../../../../../../store/src/helpers/entity-relations/entity-relations.types'; +import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { APIResource } from '../../../../../../store/src/types/api.types'; +import { QParam } from '../../../../../../store/src/types/pagination.types'; import { IServiceBinding } from '../../../../core/cf-api-svc.types'; import { CurrentUserPermissionsService } from '../../../../core/current-user-permissions.service'; import { RowState } from '../../../../shared/components/list/data-sources-controllers/list-data-source-types'; @@ -13,13 +22,6 @@ import { import { ListViewTypes } from '../../../../shared/components/list/list.component.types'; import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; import { ApplicationService } from '../../application.service'; -import { FetchAllServiceBindings } from '../../../../../../store/src/actions/service-bindings.actions'; -import { createEntityRelationPaginationKey } from '../../../../../../store/src/helpers/entity-relations/entity-relations.types'; -import { serviceSchemaKey, entityFactory } from '../../../../../../store/src/helpers/entity-factory'; -import { QParam } from '../../../../../../store/src/types/pagination.types'; -import { AppState } from '../../../../../../store/src/app-state'; -import { APIResource } from '../../../../../../store/src/types/api.types'; -import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; @Injectable() export class AppDeleteServiceInstancesListConfigService extends AppServiceBindingListConfigService { @@ -40,12 +42,12 @@ export class AppDeleteServiceInstancesListConfigService extends AppServiceBindin } constructor(store: Store, - appService: ApplicationService, - _datePipe: DatePipe, - currentUserPermissionService: CurrentUserPermissionsService, - private paginationMonitorFactory: PaginationMonitorFactory + appService: ApplicationService, + datePipe: DatePipe, + currentUserPermissionService: CurrentUserPermissionsService, + private paginationMonitorFactory: PaginationMonitorFactory ) { - super(store, appService, _datePipe, currentUserPermissionService); + super(store, appService, datePipe, currentUserPermissionService); this.getGlobalActions = () => null; this.getMultiActions = () => null; diff --git a/src/frontend/packages/core/src/features/applications/application.service.ts b/src/frontend/packages/core/src/features/applications/application.service.ts index a28d461f9e..0bcf6cd910 100644 --- a/src/frontend/packages/core/src/features/applications/application.service.ts +++ b/src/frontend/packages/core/src/features/applications/application.service.ts @@ -147,15 +147,6 @@ export class ApplicationService { /** * Fetch the current state of the app (given it's instances) as an object ready - * - * @static - * @param {Store} store - * @param {ApplicationStateService} appStateService - * @param {any} app - * @param {string} appGuid - * @param {string} cfGuid - * @returns {Observable} - * @memberof ApplicationService */ static getApplicationState( store: Store, diff --git a/src/frontend/packages/core/src/features/applications/application/application-base.component.ts b/src/frontend/packages/core/src/features/applications/application/application-base.component.ts index f622959604..3c7b78067d 100644 --- a/src/frontend/packages/core/src/features/applications/application/application-base.component.ts +++ b/src/frontend/packages/core/src/features/applications/application/application-base.component.ts @@ -1,14 +1,15 @@ import { Component } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; + +import { AppState } from '../../../../../store/src/app-state'; +import { applicationSchemaKey, entityFactory } from '../../../../../store/src/helpers/entity-factory'; import { EntityServiceFactory } from '../../../core/entity-service-factory.service'; import { ApplicationStateService } from '../../../shared/components/application-state/application-state.service'; import { APP_GUID, CF_GUID, ENTITY_SERVICE } from '../../../shared/entity.tokens'; import { PaginationMonitorFactory } from '../../../shared/monitors/pagination-monitor.factory'; import { ApplicationService, createGetApplicationAction } from '../application.service'; import { ApplicationEnvVarsHelper } from './application-tabs-base/tabs/build-tab/application-env-vars.service'; -import { AppState } from '../../../../../store/src/app-state'; -import { applicationSchemaKey, entityFactory } from '../../../../../store/src/helpers/entity-factory'; @@ -35,9 +36,9 @@ export function applicationServiceFactory( export function entityServiceFactory( cfId: string, id: string, - _entityServiceFactory: EntityServiceFactory, + esf: EntityServiceFactory, ) { - return _entityServiceFactory.create( + return esf.create( applicationSchemaKey, entityFactory(applicationSchemaKey), id, diff --git a/src/frontend/packages/core/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts b/src/frontend/packages/core/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts index e0c0151fa5..5f0e87b954 100644 --- a/src/frontend/packages/core/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts +++ b/src/frontend/packages/core/src/features/applications/application/application-tabs-base/application-tabs-base.component.ts @@ -346,7 +346,10 @@ export class ApplicationTabsBaseComponent implements OnInit, OnDestroy { this.applicationService.updateApplication({ state: 'STARTED' }, [], appData.app.entity); return this.pollEntityService('starting', 'STARTED').pipe(first()); }), - ).subscribe(null, this.dispatchAppStats, this.dispatchAppStats); + ).subscribe({ + error: this.dispatchAppStats, + complete: this.dispatchAppStats + }); }); } @@ -385,7 +388,7 @@ export class ApplicationTabsBaseComponent implements OnInit, OnDestroy { this.isBusyUpdating$ = this.entityService.updatingSection$.pipe( map(updatingSection => { - const updating = this.updatingSectionBusy(updatingSection['restaging']) || + const updating = this.updatingSectionBusy(updatingSection.restaging) || this.updatingSectionBusy(updatingSection['Updating-Existing-Application']); return { updating }; }), diff --git a/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts b/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts index 57ff4c91a2..35f0847389 100644 --- a/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts +++ b/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.ts @@ -2,12 +2,12 @@ import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { combineLatest, distinct, map, startWith } from 'rxjs/operators'; +import { APIResource, EntityInfo } from '../../../../../../../../store/src/types/api.types'; +import { IAppSummary } from '../../../../../../core/cf-api.types'; +import { GitSCMService, GitSCMType } from '../../../../../../shared/data-services/scm/scm.service'; import { getFullEndpointApiUrl } from '../../../../../endpoints/endpoint-helpers'; import { ApplicationMonitorService } from '../../../../application-monitor.service'; import { ApplicationData, ApplicationService } from '../../../../application.service'; -import { EntityInfo, APIResource } from '../../../../../../../../store/src/types/api.types'; -import { IAppSummary } from '../../../../../../core/cf-api.types'; -import { GitSCMService, GitSCMType } from '../../../../../../shared/data-services/scm/scm.service'; const isDockerHubRegEx = /^([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+):([a-zA-Z0-9_.-]+)/g; diff --git a/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/log-stream-tab/log-stream-tab.component.ts b/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/log-stream-tab/log-stream-tab.component.ts index 90faa522b7..c0a856220a 100644 --- a/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/log-stream-tab/log-stream-tab.component.ts +++ b/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/log-stream-tab/log-stream-tab.component.ts @@ -1,17 +1,16 @@ - -import { never as observableNever, Observable, Subject } from 'rxjs'; - -import { filter, share, catchError } from 'rxjs/operators'; import { Component, OnInit, ViewChild } from '@angular/core'; import { NgModel } from '@angular/forms'; import { Store } from '@ngrx/store'; import * as moment from 'moment'; +import { NEVER, Observable, Subject } from 'rxjs'; import websocketConnect from 'rxjs-websockets'; +import { catchError, filter, share } from 'rxjs/operators'; +import { AppState } from '../../../../../../../../store/src/app-state'; import { LoggerService } from '../../../../../../core/logger.service'; import { AnsiColorizer } from '../../../../../../shared/components/log-viewer/ansi-colorizer'; import { ApplicationService } from '../../../../application.service'; -import { AppState } from '../../../../../../../../store/src/app-state'; + export interface LogItem { message: string; @@ -47,7 +46,7 @@ export class LogStreamTabComponent implements OnInit { ngOnInit() { if (!this.applicationService.cfGuid || !this.applicationService.appGuid) { - this.messages = observableNever(); + this.messages = NEVER; } else { const host = window.location.host; const streamUrl = `wss://${host}/pp/v1/${ @@ -76,7 +75,9 @@ export class LogStreamTabComponent implements OnInit { return; } - let msgColour, sourceColour, bold; + let msgColour; + let sourceColour; + let bold; // CF timestamps are in nanoseconds const msStamp = Math.round(messageObj.timestamp / 1000000); diff --git a/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/variables-tab/variables-tab.component.ts b/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/variables-tab/variables-tab.component.ts index cd3d75dffd..bd0e4f1b00 100644 --- a/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/variables-tab/variables-tab.component.ts +++ b/src/frontend/packages/core/src/features/applications/application/application-tabs-base/tabs/variables-tab/variables-tab.component.ts @@ -3,6 +3,7 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { AppState } from '../../../../../../../../store/src/app-state'; import { LoggerService } from '../../../../../../core/logger.service'; import { ListDataSource } from '../../../../../../shared/components/list/data-sources-controllers/list-data-source'; import { @@ -13,7 +14,6 @@ import { } from '../../../../../../shared/components/list/list-types/app-variables/cf-app-variables-list-config.service'; import { ListConfig } from '../../../../../../shared/components/list/list.component.types'; import { ApplicationService } from '../../../../application.service'; -import { AppState } from '../../../../../../../../store/src/app-state'; export interface VariableTabAllEnvVarType { @@ -43,7 +43,7 @@ export class VariablesTabComponent implements OnInit { } envVars$: Observable<{ - names: String[], + names: string[], values: {} }>; @@ -90,7 +90,7 @@ export class VariablesTabComponent implements OnInit { return result; } - private parseStratosProject(value: string): Object | string { + private parseStratosProject(value: string): object | string { try { return JSON.parse(value); } catch (err) { diff --git a/src/frontend/packages/core/src/features/applications/cli-info-application/cli-info-application.component.ts b/src/frontend/packages/core/src/features/applications/cli-info-application/cli-info-application.component.ts index c5f9d08650..ef791aabe7 100644 --- a/src/frontend/packages/core/src/features/applications/cli-info-application/cli-info-application.component.ts +++ b/src/frontend/packages/core/src/features/applications/cli-info-application/cli-info-application.component.ts @@ -1,13 +1,16 @@ import { Component, OnInit } from '@angular/core'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { filter, first, map } from 'rxjs/operators'; + +import { GetAllEndpoints } from '../../../../../store/src/actions/endpoint.actions'; +import { endpointSchemaKey, entityFactory } from '../../../../../store/src/helpers/entity-factory'; +import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; +import { EntityService } from '../../../core/entity-service'; import { EntityServiceFactory } from '../../../core/entity-service-factory.service'; import { CFAppCLIInfoContext } from '../../../shared/components/cli-info/cli-info.component'; import { IHeaderBreadcrumb } from '../../../shared/components/page-header/page-header.types'; import { getFullEndpointApiUrl } from '../../endpoints/endpoint-helpers'; import { ApplicationService } from '../application.service'; -import { endpointSchemaKey, entityFactory } from '../../../../../store/src/helpers/entity-factory'; -import { GetAllEndpoints } from '../../../../../store/src/actions/endpoint.actions'; @Component({ selector: 'app-cli-info-application', @@ -16,7 +19,7 @@ import { GetAllEndpoints } from '../../../../../store/src/actions/endpoint.actio }) export class CliInfoApplicationComponent implements OnInit { - cfEndpointEntityService: any; + cfEndpointEntityService: EntityService; public previousUrl: string; public previousQueryParams: { [key: string]: string; @@ -39,7 +42,7 @@ export class CliInfoApplicationComponent implements OnInit { } private setupObservables(cfGuid: string) { - this.cfEndpointEntityService = this.entityServiceFactory.create( + this.cfEndpointEntityService = this.entityServiceFactory.create( endpointSchemaKey, entityFactory(endpointSchemaKey), cfGuid, @@ -53,10 +56,11 @@ export class CliInfoApplicationComponent implements OnInit { ).pipe( filter(([app, ep]) => !!app && !!ep), map(([app, ep]) => { + const space = app.app.entity.space; return { appName: app.app.entity.name, - spaceName: app.app.entity.space.entity.name, - orgName: app.app.entity.space.entity.organization.entity.name, + spaceName: typeof space !== 'string' ? space.entity.name : space, + orgName: typeof space !== 'string' ? space.entity.organization.entity.name : '', apiEndpoint: getFullEndpointApiUrl(ep.entity), username: ep.entity.user ? ep.entity.user.name : '' }; diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-deployer.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-deployer.ts index 40e331c5fb..2fb80c10f7 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-deployer.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-deployer.ts @@ -3,21 +3,20 @@ import { BehaviorSubject, Observable, of as observableOf, Subject, Subscription import websocketConnect from 'rxjs-websockets'; import { catchError, combineLatest, filter, first, map, mergeMap, share, tap } from 'rxjs/operators'; -import { CfOrgSpaceDataService } from '../../../shared/data-services/cf-org-space-service.service'; - -import { FileScannerInfo } from './deploy-application-step2/deploy-application-fs/deploy-application-fs-scanner'; +import { AppState } from '../../../../../store/src/app-state'; +import { organizationSchemaKey, spaceSchemaKey } from '../../../../../store/src/helpers/entity-factory'; +import { selectEntity } from '../../../../../store/src/selectors/api.selectors'; +import { selectDeployAppState } from '../../../../../store/src/selectors/deploy-application.selector'; import { AppData, - OverrideAppDetails, + DeployApplicationSource, DeployApplicationState, + OverrideAppDetails, SocketEventTypes, - DeployApplicationSource } from '../../../../../store/src/types/deploy-application.types'; import { environment } from '../../../environments/environment.prod'; -import { AppState } from '../../../../../store/src/app-state'; -import { selectDeployAppState } from '../../../../../store/src/selectors/deploy-application.selector'; -import { selectEntity } from '../../../../../store/src/selectors/api.selectors'; -import { organizationSchemaKey, spaceSchemaKey } from '../../../../../store/src/helpers/entity-factory'; +import { CfOrgSpaceDataService } from '../../../shared/data-services/cf-org-space-service.service'; +import { FileScannerInfo } from './deploy-application-step2/deploy-application-fs/deploy-application-fs-scanner'; export interface DeployApplicationDeployerStatus { @@ -82,8 +81,8 @@ export class DeployApplicationDeployer { updateStatus(error = false, errorMsg?: string) { this.status$.next({ - error: error, - errorMsg: errorMsg, + error, + errorMsg, deploying: this.deploying }); } diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-ignorefiles.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-ignorefiles.ts index cbb6356fcd..eb9a542816 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-ignorefiles.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-ignorefiles.ts @@ -42,20 +42,20 @@ export class GitIgnoreFilter { * Each of these two arrays in turn contains two regexps, one * strict and one for 'maybe'. * - * @param {String} content The content to parse, - * @returns {Array[]} The parsed positive and negatives definitions. + * @param content The content to parse, + * @returns The parsed positive and negatives definitions. */ parse(content) { const prepareRegexes = this.prepareRegexes.bind(this); return content.split('\n') - .map(function (line) { + .map(line => { line = line.trim(); return line; }) - .filter(function (line) { + .filter(line => { return line && line[0] !== '#'; }) - .reduce(function (lists, line) { + .reduce((lists, line) => { const isNegative = line[0] === '!'; if (isNegative) { line = line.slice(1); @@ -74,13 +74,13 @@ export class GitIgnoreFilter { return list .sort() .map(pattern => prepareRegexes(pattern)) - .reduce(function (ls, prepared) { + .reduce((ls, prepared) => { ls[0].push(prepared[0]); ls[1].push(prepared[1]); return ls; }, [[], [], []]); }) - .map(function (item) { + .map(item => { return [ item[0].length > 0 ? new RegExp('^((' + item[0].join(')|(') + '))') : new RegExp('$^'), item[1].length > 0 ? new RegExp('^((' + item[1].join(')|(') + '))') : new RegExp('$^') @@ -105,7 +105,7 @@ export class GitIgnoreFilter { const prepareRegexPattern = this.prepareRegexPattern.bind(this); return pattern .split('/') - .map(function (item, index) { + .map((item, index) => { if (index) { return '([\\/]?(' + prepareRegexPattern(item) + '\\b|$))'; } else { diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-options-step/deploy-application-options-step.component.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-options-step/deploy-application-options-step.component.ts index 4a629ce597..bbd5b21d4b 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-options-step/deploy-application-options-step.component.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-options-step/deploy-application-options-step.component.ts @@ -6,19 +6,21 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import { filter, first, map, share, startWith, switchMap } from 'rxjs/operators'; -import { IDomain } from '../../../../core/cf-api.types'; -import { StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; -import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; -import { APIResource } from '../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../store/src/app-state'; -import { ApplicationEnvVarsHelper } from '../../application/application-tabs-base/tabs/build-tab/application-env-vars.service'; -import { selectCfDetails } from '../../../../../../store/src/selectors/deploy-application.selector'; +import { SaveAppOverrides } from '../../../../../../store/src/actions/deploy-applications.actions'; import { FetchAllDomains } from '../../../../../../store/src/actions/domains.actions'; -import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; -import { entityFactory } from '../../../../../../store/src/helpers/entity-factory'; import { GetAllStacks } from '../../../../../../store/src/actions/stack.action'; +import { AppState } from '../../../../../../store/src/app-state'; +import { entityFactory } from '../../../../../../store/src/helpers/entity-factory'; +import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { selectCfDetails } from '../../../../../../store/src/selectors/deploy-application.selector'; +import { APIResource } from '../../../../../../store/src/types/api.types'; import { OverrideAppDetails } from '../../../../../../store/src/types/deploy-application.types'; -import { SaveAppOverrides } from '../../../../../../store/src/actions/deploy-applications.actions'; +import { IDomain } from '../../../../core/cf-api.types'; +import { StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; +import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; +import { + ApplicationEnvVarsHelper, +} from '../../application/application-tabs-base/tabs/build-tab/application-env-vars.service'; @Component({ selector: 'app-deploy-application-options-step', @@ -164,7 +166,7 @@ export class DeployApplicationOptionsStepComponent implements OnInit, OnDestroy })); // Extract any existing values from the app's env var and assign to form - this.appGuid = this.activatedRoute.snapshot.queryParams['appGuid']; + this.appGuid = this.activatedRoute.snapshot.queryParams.appGuid; if (this.appGuid) { combineLatest(this.domains$, cfDetails$).pipe( switchMap(([domains, cfDetails]) => this.appEnvVarsService.createEnvVarsObs(this.appGuid, cfDetails.cloudFoundry).entities$), diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step-source-upload/deploy-application-step-source-upload.component.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step-source-upload/deploy-application-step-source-upload.component.ts index f0f7207fcb..ec470908ab 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step-source-upload/deploy-application-step-source-upload.component.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step-source-upload/deploy-application-step-source-upload.component.ts @@ -21,7 +21,7 @@ export class DeployApplicationStepSourceUploadComponent implements OnDestroy { public valid$: Observable; constructor(store: Store, - public cfOrgSpaceService: CfOrgSpaceDataService, + public cfOrgSpaceService: CfOrgSpaceDataService, ) { this.deployer = new DeployApplicationDeployer(store, cfOrgSpaceService); this.valid$ = this.deployer.fileTransferStatus$.pipe( diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2-1/deploy-application-step2-1.component.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2-1/deploy-application-step2-1.component.ts index f081aea716..841c8c34c2 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2-1/deploy-application-step2-1.component.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2-1/deploy-application-step2-1.component.ts @@ -52,7 +52,7 @@ export class DeployApplicationStep21Component { onEnter = () => { // Wrap the list component in another component. This means it's recreated every time to include changes in the github repo this.wrapperRef = this.target.createComponent(this.wrapperFactory); - const wrapper = this.wrapperRef.instance; + const wrapper = this.wrapperRef.instance as CommitListWrapperComponent; this.selectedCommit$ = wrapper.selectedCommit$; this.validate = this.selectedCommit$.pipe( map(selectedCommit => !!selectedCommit) diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs-scanner.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs-scanner.ts index 33ceaa053d..f9bd96f1fc 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs-scanner.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs-scanner.ts @@ -44,7 +44,7 @@ export class DeployApplicationFSScanner implements FileScannerInfo { if (fileExcludes) { this.filter = new GitIgnoreFilter(fileExcludes); } - } + } isArchiveFile(fileName: string): boolean { return archiveRegex.test(name); @@ -132,10 +132,10 @@ export class DeployApplicationFSScanner implements FileScannerInfo { readItemContents(item): Promise { const scanner = this; return new Promise((resolve, reject) => { - item.file(function (file) { - scanner.readFileContents(file).then(function (data: string) { + item.file(file => { + scanner.readFileContents(file).then((data: string) => { resolve(data); - }).catch(function () { + }).catch(() => { reject(); }); }); @@ -145,15 +145,9 @@ export class DeployApplicationFSScanner implements FileScannerInfo { readFileContents(file): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); - reader.onload = function () { - resolve(reader.result); - }; - reader.onerror = function () { - reject(); - }; - reader.onabort = function () { - reject(); - }; + reader.onload = () => resolve(reader.result as string); + reader.onerror = () => reject(); + reader.onabort = () => reject(); reader.readAsText(file); }); } diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs-utils.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs-utils.ts index 84fc6c66be..dcacea01b6 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs-utils.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs-utils.ts @@ -1,11 +1,12 @@ +import { BehaviorSubject, Observable } from 'rxjs'; + import { DeployApplicationFSScanner, FileScannerInfo } from './deploy-application-fs-scanner'; -import { Observable , BehaviorSubject } from 'rxjs'; export const CF_IGNORE_FILE = '.cfignore'; export const CF_DEFAULT_IGNORES = '.cfignore\n_darcs\n.DS_Store\n.git\n.gitignore\n.hg\n.svn\n'; export const CF_MANIFEST_FILE = 'manifest.yml'; -export class DeployApplicatioNFsUtils { +export class DeployApplicationFsUtils { constructor() { } @@ -25,8 +26,8 @@ export class DeployApplicatioNFsUtils { } } else { // See if we can find the .cfignore file and/or the manifest file - for (let j = 0; j < items.length; j++) { - const filePath = items[j].webkitRelativePath.split('/'); + for (const item of items) { + const filePath = item.webkitRelativePath.split('/'); // First part is the root folder name if (filePath.length === 2 && !rootFolderName) { rootFolderName = filePath[0]; @@ -36,10 +37,10 @@ export class DeployApplicatioNFsUtils { break; } if (!cfIgnoreFile && filePath.length === 2 && filePath[1] === CF_IGNORE_FILE) { - cfIgnoreFile = items[j]; + cfIgnoreFile = item; } if (filePath.length === 2 && filePath[1] === CF_MANIFEST_FILE) { - manifestFile = items[j]; + manifestFile = item; } } } diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs.component.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs.component.ts index c394e0ee20..4259b0a3de 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs.component.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs.component.ts @@ -1,9 +1,10 @@ -import { Component, OnInit, Input, forwardRef, ViewChild } from '@angular/core'; -import { DeployApplicatioNFsUtils } from './deploy-application-fs-utils'; -import { filter, first, map } from 'rxjs/operators'; -import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { Component, forwardRef, Input } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { BehaviorSubject } from 'rxjs'; +import { filter, first } from 'rxjs/operators'; + import { FileScannerInfo } from './deploy-application-fs-scanner'; +import { DeployApplicationFsUtils } from './deploy-application-fs-utils'; @Component({ selector: 'app-deploy-application-fs', @@ -19,7 +20,7 @@ import { FileScannerInfo } from './deploy-application-fs-scanner'; }) export class DeployApplicationFsComponent implements ControlValueAccessor { - private propagateChange: Function; + private propagateChange: (fsi: FileScannerInfo) => void; constructor() { } @Input() sourceType: string; @@ -29,7 +30,7 @@ export class DeployApplicationFsComponent implements ControlValueAccessor { // Handle result of a file input form field selection onFileChange(event) { const files = event.srcElement.files; - const utils = new DeployApplicatioNFsUtils(); + const utils = new DeployApplicationFsUtils(); utils.handleFileInputSelection(files).pipe( filter(res => !!res), first() diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-step2.component.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-step2.component.ts index 9385d80c40..66c5ebc771 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-step2.component.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application-step2/deploy-application-step2.component.ts @@ -309,7 +309,7 @@ export class DeployApplicationStep2Component return observableTimer(500).pipe( take(1), switchMap(() => this.scm.getMatchingRepositories(name)), - catchError(_e => observableOf(null)), + catchError(e => observableOf(null)), tap(suggestions => this.cachedSuggestions[cacheName] = suggestions) ); } diff --git a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application.component.ts b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application.component.ts index b2c5f690f5..2754b12772 100644 --- a/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application.component.ts +++ b/src/frontend/packages/core/src/features/applications/deploy-application/deploy-application.component.ts @@ -1,21 +1,21 @@ - -import { of as observableOf, Observable, Subscription } from 'rxjs'; -import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { ErrorStateMatcher, ShowOnDirtyErrorStateMatcher } from '@angular/material'; import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; +import { Observable, of as observableOf, Subscription } from 'rxjs'; import { filter, map, tap } from 'rxjs/operators'; -import { CfAppsDataSource } from '../../../shared/components/list/list-types/app/cf-apps-data-source'; -import { CfOrgSpaceDataService } from '../../../shared/data-services/cf-org-space-service.service'; -import { StepOnNextFunction } from '../../../shared/components/stepper/step/step.component'; -import { ErrorStateMatcher, ShowOnDirtyErrorStateMatcher } from '@angular/material'; +import { DeleteDeployAppSection, StoreCFSettings } from '../../../../../store/src/actions/deploy-applications.actions'; +import { RouterNav } from '../../../../../store/src/actions/router.actions'; import { AppState } from '../../../../../store/src/app-state'; -import { DeployApplicationSource } from '../../../../../store/src/types/deploy-application.types'; +import { applicationSchemaKey } from '../../../../../store/src/helpers/entity-factory'; import { selectApplicationSource, selectCfDetails } from '../../../../../store/src/selectors/deploy-application.selector'; -import { StoreCFSettings, DeleteDeployAppSection } from '../../../../../store/src/actions/deploy-applications.actions'; -import { RouterNav } from '../../../../../store/src/actions/router.actions'; import { selectPaginationState } from '../../../../../store/src/selectors/pagination.selectors'; -import { applicationSchemaKey } from '../../../../../store/src/helpers/entity-factory'; +import { DeployApplicationSource } from '../../../../../store/src/types/deploy-application.types'; +import { CfAppsDataSource } from '../../../shared/components/list/list-types/app/cf-apps-data-source'; +import { StepOnNextFunction } from '../../../shared/components/stepper/step/step.component'; +import { CfOrgSpaceDataService } from '../../../shared/data-services/cf-org-space-service.service'; + @Component({ selector: 'app-deploy-application', @@ -39,7 +39,7 @@ export class DeployApplicationComponent implements OnInit, OnDestroy { private cfOrgSpaceService: CfOrgSpaceDataService, private activatedRoute: ActivatedRoute ) { - this.appGuid = this.activatedRoute.snapshot.queryParams['appGuid']; + this.appGuid = this.activatedRoute.snapshot.queryParams.appGuid; this.isRedeploy = !!this.appGuid; this.skipConfig$ = this.store.select(selectApplicationSource).pipe( diff --git a/src/frontend/packages/core/src/features/applications/routes/add-routes/add-routes.component.ts b/src/frontend/packages/core/src/features/applications/routes/add-routes/add-routes.component.ts index 396c3a9776..0e19f961d2 100644 --- a/src/frontend/packages/core/src/features/applications/routes/add-routes/add-routes.component.ts +++ b/src/frontend/packages/core/src/features/applications/routes/add-routes/add-routes.component.ts @@ -5,17 +5,15 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, Observable, of as observableOf, Subscription } from 'rxjs'; import { filter, map, mergeMap, pairwise, switchMap, take, tap } from 'rxjs/operators'; -import { IDomain, ISpace } from '../../../../core/cf-api.types'; -import { EntityServiceFactory } from '../../../../core/entity-service-factory.service'; -import { pathGet } from '../../../../core/utils.service'; -import { StepOnNextFunction, StepOnNextResult } from '../../../../shared/components/stepper/step/step.component'; -import { APIResource } from '../../../../../../store/src/types/api.types'; -import { RouteMode, Route } from '../../../../../../store/src/types/route.types'; -import { ApplicationService } from '../../application.service'; -import { AppState } from '../../../../../../store/src/app-state'; -import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; +import { + AssociateRouteWithAppApplication, + GetAppRoutes, +} from '../../../../../../store/src/actions/application-service-routes.actions'; import { FetchAllDomains } from '../../../../../../store/src/actions/domains.actions'; -import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { CreateRoute } from '../../../../../../store/src/actions/route.actions'; +import { RouterNav } from '../../../../../../store/src/actions/router.actions'; +import { GetSpace } from '../../../../../../store/src/actions/space.actions'; +import { AppState } from '../../../../../../store/src/app-state'; import { applicationSchemaKey, domainSchemaKey, @@ -23,13 +21,18 @@ import { routeSchemaKey, spaceSchemaKey, } from '../../../../../../store/src/helpers/entity-factory'; -import { GetSpace } from '../../../../../../store/src/actions/space.actions'; import { createEntityRelationKey } from '../../../../../../store/src/helpers/entity-relations/entity-relations.types'; -import { CreateRoute } from '../../../../../../store/src/actions/route.actions'; -import { selectRequestInfo } from '../../../../../../store/src/selectors/api.selectors'; -import { AssociateRouteWithAppApplication, GetAppRoutes } from '../../../../../../store/src/actions/application-service-routes.actions'; import { RequestInfoState } from '../../../../../../store/src/reducers/api-request-reducer/types'; -import { RouterNav } from '../../../../../../store/src/actions/router.actions'; +import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { selectRequestInfo } from '../../../../../../store/src/selectors/api.selectors'; +import { APIResource } from '../../../../../../store/src/types/api.types'; +import { Route, RouteMode } from '../../../../../../store/src/types/route.types'; +import { IDomain, ISpace } from '../../../../core/cf-api.types'; +import { EntityServiceFactory } from '../../../../core/entity-service-factory.service'; +import { pathGet } from '../../../../core/utils.service'; +import { StepOnNextFunction, StepOnNextResult } from '../../../../shared/components/stepper/step/step.component'; +import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; +import { ApplicationService } from '../../application.service'; const hostPattern = '^([\\w\\-\\.]*)$'; const pathPattern = `^([\\w\\-\\/\\!\\#\\[\\]\\@\\&\\$\\'\\(\\)\\*\\+\\;\\=\\,]*)$`; @@ -74,11 +77,11 @@ export class AddRoutesComponent implements OnInit, OnDestroy { this.appUrl = `/applications/${this.cfGuid}/${this.appGuid}/routes`; this.addRouteMode = this.addRouteModes[0]; this.domainFormGroup = new FormGroup({ - domain: new FormControl('', [Validators.required]) + domain: new FormControl('', [Validators.required as any]) }); this.addHTTPRoute = new FormGroup({ - host: new FormControl('', [Validators.required, Validators.pattern(hostPattern), Validators.maxLength(63)]), + host: new FormControl('', [Validators.required as any, Validators.pattern(hostPattern), Validators.maxLength(63)]), path: new FormControl('', [Validators.pattern(pathPattern), Validators.maxLength(128)]) }); @@ -95,18 +98,18 @@ export class AddRoutesComponent implements OnInit, OnDestroy { ngOnInit() { this.subscriptions.push(this.addTCPRoute.valueChanges.subscribe(val => { - const useRandomPort = val['useRandomPort']; + const useRandomPort = val.useRandomPort; if (useRandomPort !== this.useRandomPort) { this.useRandomPort = useRandomPort; const validators = [ Validators.required, Validators.pattern('[0-9]*'), ]; - this.addTCPRoute.controls['port'].setValidators(useRandomPort ? [] : validators); + this.addTCPRoute.controls.port.setValidators(useRandomPort ? [] : validators); if (useRandomPort) { - this.addTCPRoute.controls['port'].disable(); + this.addTCPRoute.controls.port.disable(); } else { - this.addTCPRoute.controls['port'].enable(); + this.addTCPRoute.controls.port.enable(); } } })); @@ -183,7 +186,7 @@ export class AddRoutesComponent implements OnInit, OnDestroy { } isTCPRouteCreation(): boolean { - return this.domainFormGroup.value['domain'] && this.domainFormGroup.value['domain'].entity.router_group_type === 'tcp'; + return this.domainFormGroup.value.domain && this.domainFormGroup.value.domain.entity.router_group_type === 'tcp'; } submit: StepOnNextFunction = () => { @@ -196,13 +199,13 @@ export class AddRoutesComponent implements OnInit, OnDestroy { } onSubmit(): Observable { - const domainGuid = this.domainFormGroup.value['domain'].metadata.guid; + const domainGuid = this.domainFormGroup.value.domain.metadata.guid; const isTcpRoute = this.isTCPRouteCreation(); const formGroup = isTcpRoute ? this.addTCPRoute : this.addHTTPRoute; // Set port to -1 to indicate that we should generate a random port number let port = this._getValue('port', formGroup); - if (isTcpRoute && formGroup.value['useRandomPort']) { + if (isTcpRoute && formGroup.value.useRandomPort) { port = -1; } diff --git a/src/frontend/packages/core/src/features/applications/ssh-application/ssh-application.component.ts b/src/frontend/packages/core/src/features/applications/ssh-application/ssh-application.component.ts index a43643dcf5..d57266f8ad 100644 --- a/src/frontend/packages/core/src/features/applications/ssh-application/ssh-application.component.ts +++ b/src/frontend/packages/core/src/features/applications/ssh-application/ssh-application.component.ts @@ -1,17 +1,16 @@ - -import { never as observableNever, Observable, Subject, Subscription } from 'rxjs'; - -import { catchError, first, map } from 'rxjs/operators'; import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; +import { NEVER, Observable, Subject, Subscription } from 'rxjs'; import websocketConnect from 'rxjs-websockets'; +import { catchError, first, map } from 'rxjs/operators'; +import { AppState } from '../../../../../store/src/app-state'; import { IApp } from '../../../core/cf-api.types'; import { IHeaderBreadcrumb } from '../../../shared/components/page-header/page-header.types'; import { SshViewerComponent } from '../../../shared/components/ssh-viewer/ssh-viewer.component'; import { ApplicationService } from '../application.service'; -import { AppState } from '../../../../../store/src/app-state'; + @Component({ selector: 'app-ssh-application', @@ -72,8 +71,8 @@ export class SshApplicationComponent implements OnInit { ); if (!cfGuid || !appGuid || !this.instanceId) { - this.messages = observableNever(); - this.connectionStatus = observableNever(); + this.messages = NEVER; + this.connectionStatus = NEVER; } else { const host = window.location.host; const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; diff --git a/src/frontend/packages/core/src/features/cloud-foundry/add-edit-space-step-base.ts b/src/frontend/packages/core/src/features/cloud-foundry/add-edit-space-step-base.ts index 800f53d2cb..50d24677a1 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/add-edit-space-step-base.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/add-edit-space-step-base.ts @@ -59,7 +59,7 @@ export class AddEditSpaceStepBase { spaceNameTakenValidator = (): ValidatorFn => { return (formField: AbstractControl): { [key: string]: any } => { const nameValid = this.validate(formField.value); - return !nameValid ? { 'spaceNameTaken': { value: formField.value } } : null; + return !nameValid ? { spaceNameTaken: { value: formField.value } } : null; }; } diff --git a/src/frontend/packages/core/src/features/cloud-foundry/add-organization/create-organization-step/create-organization-step.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/add-organization/create-organization-step/create-organization-step.component.ts index fc118ea81c..f2b66d9987 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/add-organization/create-organization-step/create-organization-step.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/add-organization/create-organization-step/create-organization-step.component.ts @@ -5,16 +5,16 @@ import { Store } from '@ngrx/store'; import { Observable, Subscription } from 'rxjs'; import { filter, map, tap } from 'rxjs/operators'; +import { CreateOrganization } from '../../../../../../store/src/actions/organization.actions'; +import { AppState } from '../../../../../../store/src/app-state'; +import { entityFactory, organizationSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; +import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { selectRequestInfo } from '../../../../../../store/src/selectors/api.selectors'; +import { APIResource } from '../../../../../../store/src/types/api.types'; import { IOrganization } from '../../../../core/cf-api.types'; import { StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; import { CloudFoundryEndpointService } from '../../services/cloud-foundry-endpoint.service'; -import { APIResource } from '../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../store/src/app-state'; -import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; -import { entityFactory, organizationSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; -import { CreateOrganization } from '../../../../../../store/src/actions/organization.actions'; -import { selectRequestInfo } from '../../../../../../store/src/selectors/api.selectors'; @Component({ @@ -44,7 +44,7 @@ export class CreateOrganizationStepComponent implements OnInit, OnDestroy { ngOnInit() { this.addOrg = new FormGroup({ - orgName: new FormControl('', [Validators.required, this.nameTakenValidator()]), + orgName: new FormControl('', [Validators.required as any, this.nameTakenValidator()]), }); const action = CloudFoundryEndpointService.createGetAllOrganizations(this.cfGuid); this.orgs$ = getPaginationObservables( @@ -68,7 +68,7 @@ export class CreateOrganizationStepComponent implements OnInit, OnDestroy { nameTakenValidator = (): ValidatorFn => { return (formField: AbstractControl): { [key: string]: any } => - !this.validateNameTaken(formField.value) ? { 'nameTaken': { value: formField.value } } : null; + !this.validateNameTaken(formField.value) ? { nameTaken: { value: formField.value } } : null; } validateNameTaken = (value: string = null) => this.allOrgs ? this.allOrgs.indexOf(value || this.orgName.value) === -1 : true; @@ -76,7 +76,7 @@ export class CreateOrganizationStepComponent implements OnInit, OnDestroy { validate = () => !!this.addOrg && this.addOrg.valid; submit: StepOnNextFunction = () => { - const orgName = this.addOrg.value['orgName']; + const orgName = this.addOrg.value.orgName; this.store.dispatch(new CreateOrganization(orgName, this.cfGuid)); return this.store.select(selectRequestInfo(organizationSchemaKey, orgName)).pipe( diff --git a/src/frontend/packages/core/src/features/cloud-foundry/add-space/create-space-step/create-space-step.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/add-space/create-space-step/create-space-step.component.ts index 713ccbfaf0..3cec8c6b25 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/add-space/create-space-step/create-space-step.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/add-space/create-space-step/create-space-step.component.ts @@ -4,14 +4,14 @@ import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; import { filter } from 'rxjs/operators'; +import { CreateSpace } from '../../../../../../store/src/actions/space.actions'; +import { AppState } from '../../../../../../store/src/app-state'; +import { spaceSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; +import { selectRequestInfo } from '../../../../../../store/src/selectors/api.selectors'; import { StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; import { AddEditSpaceStepBase } from '../../add-edit-space-step-base'; import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; -import { AppState } from '../../../../../../store/src/app-state'; -import { CreateSpace } from '../../../../../../store/src/actions/space.actions'; -import { selectRequestInfo } from '../../../../../../store/src/selectors/api.selectors'; -import { spaceSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; @Component({ @@ -36,7 +36,7 @@ export class CreateSpaceStepComponent extends AddEditSpaceStepBase implements On ngOnInit() { this.createSpaceForm = new FormGroup({ - spaceName: new FormControl('', [Validators.required, this.spaceNameTakenValidator()]), + spaceName: new FormControl('', [Validators.required as any, this.spaceNameTakenValidator()]), }); } @@ -47,11 +47,11 @@ export class CreateSpaceStepComponent extends AddEditSpaceStepBase implements On spaceNameTakenValidator = (): ValidatorFn => { return (formField: AbstractControl): { [key: string]: any } => - !this.validateNameTaken(formField.value) ? { 'spaceNameTaken': { value: formField.value } } : null; + !this.validateNameTaken(formField.value) ? { spaceNameTaken: { value: formField.value } } : null; } submit: StepOnNextFunction = () => { - const spaceName = this.createSpaceForm.value['spaceName']; + const spaceName = this.createSpaceForm.value.spaceName; this.store.dispatch(new CreateSpace(spaceName, this.orgGuid, this.cfGuid)); return this.store.select(selectRequestInfo(spaceSchemaKey, `${this.orgGuid}-${spaceName}`)).pipe( diff --git a/src/frontend/packages/core/src/features/cloud-foundry/cf.helpers.ts b/src/frontend/packages/core/src/features/cloud-foundry/cf.helpers.ts index 14ba792317..4087ef50ac 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/cf.helpers.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/cf.helpers.ts @@ -278,18 +278,20 @@ export function fetchTotalResults( store: Store, paginationMonitorFactory: PaginationMonitorFactory ): Observable { - - action.paginationKey = createFetchTotalResultsPagKey(action.paginationKey); - action.initialParams['results-per-page'] = 1; - action.flattenPagination = false; - action['includeRelations'] = []; + const newAction = { + ...action, + paginationKey: createFetchTotalResultsPagKey(action.paginationKey), + flattenPagination: false, + includeRelations: [] + }; + newAction.initialParams['results-per-page'] = 1; const pagObs = getPaginationObservables({ store, - action, + action: newAction, paginationMonitor: paginationMonitorFactory.create( - action.paginationKey, - entityFactory(action.entityKey) + newAction.paginationKey, + entityFactory(newAction.entityKey) ) }); // Ensure the request is made by sub'ing to the entities observable @@ -311,9 +313,9 @@ export const cfOrgSpaceFilter = (entities: APIResource[], paginationState: Pagin } // Filter by cf/org/space - const cfGuid = paginationState.clientPagination.filter.items['cf']; - const orgGuid = paginationState.clientPagination.filter.items['org']; - const spaceGuid = paginationState.clientPagination.filter.items['space']; + const cfGuid = paginationState.clientPagination.filter.items.cf; + const orgGuid = paginationState.clientPagination.filter.items.org; + const spaceGuid = paginationState.clientPagination.filter.items.space; return !cfGuid && !orgGuid && !spaceGuid ? entities : entities.filter(e => { const validCF = !(cfGuid && cfGuid !== e.entity.cfGuid); const validOrg = !(orgGuid && orgGuid !== e.entity.space.entity.organization_guid); diff --git a/src/frontend/packages/core/src/features/cloud-foundry/cloud-foundry.module.ts b/src/frontend/packages/core/src/features/cloud-foundry/cloud-foundry.module.ts index da0a0d0416..5ac649661b 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/cloud-foundry.module.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/cloud-foundry.module.ts @@ -8,6 +8,7 @@ import { CustomImportModule } from '../../custom-import.module'; import { CFEndpointsListConfigService, } from '../../shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service'; +import { EndpointListHelper } from '../../shared/components/list/list-types/endpoint/endpoint-list.helpers'; import { EndpointsListConfigService } from '../../shared/components/list/list-types/endpoint/endpoints-list-config.service'; import { SharedModule } from '../../shared/shared.module'; import { AddOrganizationComponent } from './add-organization/add-organization.component'; @@ -162,6 +163,7 @@ import { UsersRolesComponent } from './users/manage-users/manage-users.component CfAdminAddUserWarningComponent, ], providers: [ + EndpointListHelper, CFEndpointsListConfigService, EndpointsListConfigService, { @@ -176,7 +178,7 @@ import { UsersRolesComponent } from './users/manage-users/manage-users.component CloudFoundryEndpointService, CfRolesService, CloudFoundryCellService, - UserInviteService, + UserInviteService ], entryComponents: [ UserInviteConfigurationDialogComponent diff --git a/src/frontend/packages/core/src/features/cloud-foundry/edit-organization/edit-organization-step/edit-organization-step.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/edit-organization/edit-organization-step/edit-organization-step.component.ts index b8b23cfb8d..2d52742131 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/edit-organization/edit-organization-step/edit-organization-step.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/edit-organization/edit-organization-step/edit-organization-step.component.ts @@ -55,7 +55,7 @@ export class EditOrganizationStepComponent implements OnInit, OnDestroy { this.cfGuid = cfOrgService.cfGuid; this.status = false; this.editOrgName = new FormGroup({ - orgName: new FormControl('', [Validators.required, this.nameTakenValidator()]) + orgName: new FormControl('', [Validators.required as any, this.nameTakenValidator()]) // toggleStatus: new FormControl(false), }); this.org$ = this.cfOrgService.org$.pipe( @@ -75,7 +75,7 @@ export class EditOrganizationStepComponent implements OnInit, OnDestroy { nameTakenValidator = (): ValidatorFn => { return (formField: AbstractControl): { [key: string]: any } => { const nameValid = this.validate(formField.value); - return !nameValid ? { 'nameTaken': { value: formField.value } } : null; + return !nameValid ? { nameTaken: { value: formField.value } } : null; }; } diff --git a/src/frontend/packages/core/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/core/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.spec.ts index 1f352d466b..3726acf6e9 100644 --- a/src/frontend/packages/core/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/core/src/features/cloud-foundry/tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-summary/cloud-foundry-cell-summary.component.spec.ts @@ -49,7 +49,7 @@ class MockCloudFoundryCellService { buildChartConfig = (yAxisLabel: string): MetricsLineChartConfig => ({ chartType: MetricsChartTypes.LINE, xAxisLabel: 'Time', - yAxisLabel: yAxisLabel, + yAxisLabel, autoScale: true }) diff --git a/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose-formatter.ts b/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose-formatter.ts index 2f3c270453..08e5917053 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose-formatter.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose-formatter.ts @@ -1,12 +1,13 @@ /** * Formats log messages from the Cloud Foundry firehose */ +import * as moment from 'moment'; -import { AnsiColorizer } from '../../../../shared/components/log-viewer/ansi-colorizer'; import { LoggerService } from '../../../../core/logger.service'; import { UtilsService } from '../../../../core/utils.service'; -import * as moment from 'moment'; -import { HTTP_METHODS, FireHoseItem } from './cloud-foundry-firehose.types'; +import { AnsiColorizer } from '../../../../shared/components/log-viewer/ansi-colorizer'; +import { FireHoseItem, HTTP_METHODS } from './cloud-foundry-firehose.types'; + /* eslint-disable no-control-regex */ const ANSI_ESCAPE_MATCHER = new RegExp('\x1B\\[([0-9;]*)m', 'g'); @@ -145,7 +146,8 @@ export class CloudFoundryFirehoseFormatter { return ''; } const counterEvent = cfEvent.counterEvent; - let delta, total; + let delta; + let total; if (counterEvent.name.indexOf('ByteCount') !== -1) { delta = this.utils.bytesToHumanSize(counterEvent.delta); total = this.utils.bytesToHumanSize(counterEvent.total); @@ -195,17 +197,18 @@ export class CloudFoundryFirehoseFormatter { // Map each character index in the sanitized version of originalString to its original index in originalString mapSanitizedIndices(originalString) { - let escapeMatch; + let escapeMatch = ANSI_ESCAPE_MATCHER.exec(originalString); const mappedIndices = {}; let mappedUpTo = 0; let offset = 0; ANSI_ESCAPE_MATCHER.lastIndex = 0; - while ((escapeMatch = ANSI_ESCAPE_MATCHER.exec(originalString)) !== null) { + while (escapeMatch !== null) { while (mappedUpTo + offset < escapeMatch.index) { mappedIndices[mappedUpTo] = offset + mappedUpTo++; } offset += escapeMatch[0].length; + escapeMatch = ANSI_ESCAPE_MATCHER.exec(originalString); } while (mappedUpTo + offset < originalString.length) { mappedIndices[mappedUpTo] = offset + mappedUpTo++; @@ -215,14 +218,15 @@ export class CloudFoundryFirehoseFormatter { // Determine which colour and bold modes are active where the highlight ends getPreviousModes(toEndOfMatch) { - let escapeMatch; + let escapeMatch = ANSI_ESCAPE_MATCHER.exec(toEndOfMatch); let boldOn = null; let prevColour = null; let lastColourMatches = null; ANSI_ESCAPE_MATCHER.lastIndex = 0; - while ((escapeMatch = ANSI_ESCAPE_MATCHER.exec(toEndOfMatch)) !== null) { + while (escapeMatch !== null) { lastColourMatches = escapeMatch; + escapeMatch = ANSI_ESCAPE_MATCHER.exec(toEndOfMatch); } if (lastColourMatches !== null) { boldOn = lastColourMatches[1].indexOf('1') === 0; diff --git a/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose.component.ts index a7ebd90e9f..e4b297cf99 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose.component.ts @@ -5,9 +5,9 @@ import { catchError, filter, share } from 'rxjs/operators'; import { LoggerService } from '../../../../core/logger.service'; import { UtilsService } from '../../../../core/utils.service'; +import { environment } from '../../../../environments/environment.prod'; import { CloudFoundryEndpointService } from '../../services/cloud-foundry-endpoint.service'; import { CloudFoundryFirehoseFormatter } from './cloud-foundry-firehose-formatter'; -import { environment } from '../../../../environments/environment.prod'; @Component({ selector: 'app-cloud-foundry-firehose', @@ -18,7 +18,7 @@ export class CloudFoundryFirehoseComponent implements OnInit { messages: Observable; connectionStatus: Observable; - filter: Function; + filter: (jsonString: string) => string; // Formatter for fire hose log messages formatter: CloudFoundryFirehoseFormatter; diff --git a/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.ts index a5c2580069..6ea5709037 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-summary/cloud-foundry-organization-summary.component.ts @@ -15,7 +15,7 @@ import { CloudFoundryOrganizationService } from '../../../services/cloud-foundry }) export class CloudFoundryOrganizationSummaryComponent { - appLink: Function; + appLink: () => void; detailsLoading$: Observable; constructor( diff --git a/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-summary-tab/cloud-foundry-summary-tab.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-summary-tab/cloud-foundry-summary-tab.component.ts index 88376a5842..67bd126734 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-summary-tab/cloud-foundry-summary-tab.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/tabs/cloud-foundry-summary-tab/cloud-foundry-summary-tab.component.ts @@ -13,7 +13,7 @@ import { CloudFoundryEndpointService } from '../../services/cloud-foundry-endpoi styleUrls: ['./cloud-foundry-summary-tab.component.scss'] }) export class CloudFoundrySummaryTabComponent { - appLink: Function; + appLink: () => void; detailsLoading$: Observable; constructor(store: Store, public cfEndpointService: CloudFoundryEndpointService) { diff --git a/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts b/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts index 746dcab3e6..1125b8aa30 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/cf-roles.service.ts @@ -13,37 +13,37 @@ import { switchMap, } from 'rxjs/operators'; -import { IOrganization } from '../../../../core/cf-api.types'; -import { CurrentUserPermissionsChecker } from '../../../../core/current-user-permissions.checker'; -import { CurrentUserPermissionsService } from '../../../../core/current-user-permissions.service'; -import { EntityServiceFactory } from '../../../../core/entity-service-factory.service'; -import { CfUserService } from '../../../../shared/data-services/cf-user.service'; -import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; -import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; -import { canUpdateOrgSpaceRoles } from '../../cf.helpers'; -import { CfUserRolesSelected, CfRoleChange } from '../../../../../../store/src/types/users-roles.types'; -import { IUserPermissionInOrg, CfUser, UserRoleInOrg, UserRoleInSpace } from '../../../../../../store/src/types/user.types'; -import { APIResource, EntityInfo } from '../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../store/src/app-state'; -import { - selectUsersRolesPicked, - selectUsersRolesCf, - selectUsersRolesRoles -} from '../../../../../../store/src/selectors/users-roles.selector'; -import { createDefaultOrgRoles, createDefaultSpaceRoles } from '../../../../../../store/src/reducers/users-roles.reducer'; +import { GetAllOrganizations, GetOrganization } from '../../../../../../store/src/actions/organization.actions'; import { UsersRolesSetChanges } from '../../../../../../store/src/actions/users-roles.actions'; +import { AppState } from '../../../../../../store/src/app-state'; import { - organizationSchemaKey, + endpointSchemaKey, entityFactory, + organizationSchemaKey, spaceSchemaKey, - endpointSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; -import { GetOrganization, GetAllOrganizations } from '../../../../../../store/src/actions/organization.actions'; import { createEntityRelationKey, - createEntityRelationPaginationKey + createEntityRelationPaginationKey, } from '../../../../../../store/src/helpers/entity-relations/entity-relations.types'; import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { createDefaultOrgRoles, createDefaultSpaceRoles } from '../../../../../../store/src/reducers/users-roles.reducer'; +import { + selectUsersRolesCf, + selectUsersRolesPicked, + selectUsersRolesRoles, +} from '../../../../../../store/src/selectors/users-roles.selector'; +import { APIResource, EntityInfo } from '../../../../../../store/src/types/api.types'; +import { CfUser, IUserPermissionInOrg, UserRoleInOrg, UserRoleInSpace } from '../../../../../../store/src/types/user.types'; +import { CfRoleChange, CfUserRolesSelected } from '../../../../../../store/src/types/users-roles.types'; +import { IOrganization, ISpace } from '../../../../core/cf-api.types'; +import { CurrentUserPermissionsChecker } from '../../../../core/current-user-permissions.checker'; +import { CurrentUserPermissionsService } from '../../../../core/current-user-permissions.service'; +import { EntityServiceFactory } from '../../../../core/entity-service-factory.service'; +import { CfUserService } from '../../../../shared/data-services/cf-user.service'; +import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory'; +import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; +import { canUpdateOrgSpaceRoles } from '../../cf.helpers'; @Injectable() @@ -57,7 +57,7 @@ export class CfRolesService { /** * Given a list of orgs or spaces remove those that the connected user cannot edit roles in. */ - static filterEditableOrgOrSpace( + static filterEditableOrgOrSpace( userPerms: CurrentUserPermissionsService, isOrg: boolean, orgOrSpaces$: Observable[]> @@ -71,7 +71,7 @@ export class CfRolesService { userPerms, orgOrSpace.metadata.guid, orgOrSpace.entity.cfGuid, - isOrg ? orgOrSpace.metadata.guid : orgOrSpace.entity['organization_guid'], + isOrg ? orgOrSpace.metadata.guid : (orgOrSpace as APIResource).entity.organization_guid, isOrg ? CurrentUserPermissionsChecker.ALL_SPACES : orgOrSpace.metadata.guid, )))); }), @@ -129,11 +129,6 @@ export class CfRolesService { /** * Take the structure that cf stores user roles in (per user and flat) and convert into a format that's easier to use and compare with * (easier to access at specific levels, easier to parse pieces around) - * - * @param {string} cfGuid - * @param {CfUser[]} selectedUsers - * @returns {Observable} - * @memberof CfRolesService */ populateRoles(cfGuid: string, selectedUsers: CfUser[]): Observable { if (!cfGuid || !selectedUsers || selectedUsers.length === 0) { @@ -180,10 +175,6 @@ export class CfRolesService { /** * Create a collection of role `change` items representing the diff between existing roles and newly selected roles. - * - * @param {string} orgGuid - * @returns {Observable} - * @memberof CfRolesService */ createRolesDiff(orgGuid: string): Observable { return this.existingRoles$.pipe( @@ -273,13 +264,6 @@ export class CfRolesService { /** * Compare a set of org or space permissions and return the differences - * - * @private - * @param {CfRoleChange} template - * @param {(UserRoleInOrg | UserRoleInSpace)} oldPerms - * @param {(UserRoleInOrg | UserRoleInSpace)} newPerms - * @returns {CfRoleChange[]} - * @memberof CfRolesService */ private comparePermissions( template: CfRoleChange, diff --git a/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts index 2a7aee287c..9e32adf685 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users-confirm/manage-users-confirm.component.ts @@ -98,7 +98,7 @@ export class UsersRolesConfirmComponent implements OnInit, AfterContentInit { const guid = isSpace ? row.spaceGuid : row.orgGuid; return { entityKey: schema.key, - schema: schema, + schema, monitorState: AppMonitorComponentTypes.UPDATE, updateKey: ChangeUserRole.generateUpdatingKey(row.role, row.userGuid), getId: () => guid diff --git a/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts index 507167f53b..8d2cb04b1f 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users-modify/manage-users-modify.component.ts @@ -242,12 +242,14 @@ export class UsersRolesModifyComponent implements OnInit, OnDestroy { // Wait for the store to have the correct org filter(newRoles => newRoles && newRoles.orgGuid === orgGuid), first() - ).subscribe(null, null, () => { - // The org has changed, completely recreate the roles table - this.destroySpacesList(); + ).subscribe({ + complete: () => { + // The org has changed, completely recreate the roles table + this.destroySpacesList(); - this.wrapperRef = this.spaceRolesTable.createComponent(this.wrapperFactory); - this.cd.detectChanges(); + this.wrapperRef = this.spaceRolesTable.createComponent(this.wrapperFactory); + this.cd.detectChanges(); + } }); } diff --git a/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users.component.ts b/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users.component.ts index 7aa7e554d7..55c4451a8a 100644 --- a/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users.component.ts +++ b/src/frontend/packages/core/src/features/cloud-foundry/users/manage-users/manage-users.component.ts @@ -1,19 +1,22 @@ import { Component, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; +import { Observable, of as observableOf } from 'rxjs'; import { combineLatest, filter, first, map } from 'rxjs/operators'; +import { + UsersRolesClear, + UsersRolesExecuteChanges, + UsersRolesSetUsers, +} from '../../../../../../store/src/actions/users-roles.actions'; +import { AppState } from '../../../../../../store/src/app-state'; +import { selectUsersRoles, selectUsersRolesPicked } from '../../../../../../store/src/selectors/users-roles.selector'; +import { CfUser } from '../../../../../../store/src/types/user.types'; import { StepOnNextFunction } from '../../../../shared/components/stepper/step/step.component'; import { CfUserService } from '../../../../shared/data-services/cf-user.service'; - import { ActiveRouteCfOrgSpace } from '../../cf-page.types'; import { getActiveRouteCfOrgSpaceProvider } from '../../cf.helpers'; import { CfRolesService } from './cf-roles.service'; -import { CfUser } from '../../../../../../store/src/types/user.types'; -import { AppState } from '../../../../../../store/src/app-state'; -import { selectUsersRolesPicked, selectUsersRoles } from '../../../../../../store/src/selectors/users-roles.selector'; -import { UsersRolesSetUsers, UsersRolesClear, UsersRolesExecuteChanges } from '../../../../../../store/src/actions/users-roles.actions'; -import { Observable, of as observableOf } from 'rxjs'; @Component({ @@ -75,10 +78,6 @@ export class UsersRolesComponent implements OnDestroy { /** * Determine where the return url should be. This will only apply when user visits modal directly (otherwise stepper uses previous state) - * - * @param {ActiveRouteCfOrgSpace} activeRouteCfOrgSpace - * @returns {Observable} - * @memberof UsersRolesComponent */ createReturnUrl(activeRouteCfOrgSpace: ActiveRouteCfOrgSpace): string { let route = `/cloud-foundry/${activeRouteCfOrgSpace.cfGuid}`; 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 d7e8b5c54d..35f6f9a867 100644 --- a/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts +++ b/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts @@ -1,19 +1,19 @@ +import { Type } from '@angular/core'; +import { Validators } from '@angular/forms'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { first, map } from 'rxjs/operators'; -import { Validators } from '@angular/forms'; - -import { urlValidationExpression } from '../../core/utils.service'; -import { EndpointModel } from '../../../../store/src/types/endpoint.types'; -import { EndpointTypeConfig, EndpointAuthTypeConfig, EndpointType } from '../../core/extension/extension-types'; import { AppState } from '../../../../store/src/app-state'; -import { selectEntities } from '../../../../store/src/selectors/api.selectors'; import { endpointSchemaKey } from '../../../../store/src/helpers/entity-factory'; +import { selectEntities } from '../../../../store/src/selectors/api.selectors'; +import { EndpointModel } from '../../../../store/src/types/endpoint.types'; import { ExtensionService } from '../../core/extension/extension-service'; +import { EndpointAuthTypeConfig, EndpointType, EndpointTypeConfig } from '../../core/extension/extension-types'; +import { EndpointListDetailsComponent } from '../../shared/components/list/list-types/endpoint/endpoint-list.helpers'; 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'; export function getFullEndpointApiUrl(endpoint: EndpointModel) { return endpoint && endpoint.api_endpoint ? `${endpoint.api_endpoint.Scheme}://${endpoint.api_endpoint.Host}` : 'Unknown'; @@ -31,18 +31,11 @@ export interface EndpointIcon { } const endpointTypes: EndpointTypeConfig[] = [ - { - value: 'cf', - label: 'Cloud Foundry', - urlValidation: urlValidationExpression, - icon: 'cloud_foundry', - iconFont: 'stratos-icons', - homeLink: (guid) => ['/cloud-foundry', guid] - }, { value: 'metrics', label: 'Metrics', allowTokenSharing: true, + imagePath: '/core/assets/endpoint-icons/metrics.svg', homeLink: (guid) => ['/endpoints/metrics', guid] }, ]; @@ -76,6 +69,9 @@ let endpointAuthTypes: EndpointAuthTypeConfig[] = [ const endpointTypesMap = {}; +// Any initial endpointTypes listDetailsComponent should be added here +export const coreEndpointListDetailsComponents: Type[] = []; + export function initEndpointTypes(epTypes: EndpointTypeConfig[]) { epTypes.forEach(epType => { endpointTypes.push(epType); @@ -114,6 +110,10 @@ export function getEndpointTypes() { return endpointTypes; } +export function getEndpointType(type: string): EndpointTypeConfig { + return getEndpointTypes().find(ep => ep.value === type); +} + export function getIconForEndpoint(type: string): EndpointIcon { const icon = { name: 'settings_ethernet', 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 de54b5231a..e3084deb45 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 @@ -1,18 +1,23 @@ -import { Component, OnDestroy, OnInit, NgZone } from '@angular/core'; +import { Component, NgZone, OnDestroy, OnInit } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { Subscription } from 'rxjs'; +import { delay, filter, first, map } from 'rxjs/operators'; +import { ShowSnackBar } from '../../../../../store/src/actions/snackBar.actions'; +import { AppState } from '../../../../../store/src/app-state'; +import { queryParamMap } from '../../../core/auth-guard.service'; +import { CurrentUserPermissions } from '../../../core/current-user-permissions.config'; import { EndpointsService } from '../../../core/endpoints.service'; +import { + getActionsFromExtensions, + StratosActionMetadata, + StratosActionType, +} from '../../../core/extension/extension-service'; import { EndpointsListConfigService, } from '../../../shared/components/list/list-types/endpoint/endpoints-list-config.service'; import { ListConfig } from '../../../shared/components/list/list.component.types'; -import { CurrentUserPermissions } from '../../../core/current-user-permissions.config'; -import { Subscription, } from 'rxjs'; -import { queryParamMap } from '../../../core/auth-guard.service'; -import { delay, first, map, filter } from 'rxjs/operators'; -import { Store } from '@ngrx/store'; -import { StratosActionType, getActionsFromExtensions, StratosActionMetadata } from '../../../core/extension/extension-service'; -import { AppState } from '../../../../../store/src/app-state'; -import { ShowSnackBar } from '../../../../../store/src/actions/snackBar.actions'; +import { EndpointListHelper } from '../../../shared/components/list/list-types/endpoint/endpoint-list.helpers'; @Component({ selector: 'app-endpoints-page', @@ -21,7 +26,7 @@ import { ShowSnackBar } from '../../../../../store/src/actions/snackBar.actions' providers: [{ provide: ListConfig, useClass: EndpointsListConfigService, - }] + }, EndpointListHelper] }) export class EndpointsPageComponent implements OnDestroy, OnInit { @@ -51,8 +56,8 @@ export class EndpointsPageComponent implements OnDestroy, OnInit { ngOnInit() { this.startEndpointHealthCheckPulse(); const params = queryParamMap(); - if (params['cnsi_guid']) { - const guid = params['cnsi_guid']; + if (params.cnsi_guid) { + const guid = params.cnsi_guid; window.history.pushState({}, '', '/endpoints'); this.sub = this.endpointsService.endpoints$.pipe( delay(0), diff --git a/src/frontend/packages/core/src/features/login/login-page/login-page.component.ts b/src/frontend/packages/core/src/features/login/login-page/login-page.component.ts index 19779265ba..cf78159f25 100644 --- a/src/frontend/packages/core/src/features/login/login-page/login-page.component.ts +++ b/src/frontend/packages/core/src/features/login/login-page/login-page.component.ts @@ -4,12 +4,12 @@ import { Store } from '@ngrx/store'; import { Observable, Subscription } from 'rxjs'; import { map, startWith, takeWhile, tap } from 'rxjs/operators'; -import { queryParamMap } from '../../../core/auth-guard.service'; -import { AppState } from '../../../../../store/src/app-state'; -import { RouterRedirect } from '../../../../../store/src/reducers/routing.reducer'; -import { VerifySession, Login } from '../../../../../store/src/actions/auth.actions'; +import { Login, VerifySession } from '../../../../../store/src/actions/auth.actions'; import { RouterNav } from '../../../../../store/src/actions/router.actions'; +import { AppState } from '../../../../../store/src/app-state'; import { AuthState } from '../../../../../store/src/reducers/auth.reducer'; +import { RouterRedirect } from '../../../../../store/src/reducers/routing.reducer'; +import { queryParamMap } from '../../../core/auth-guard.service'; @Component({ selector: 'app-login-page', @@ -67,7 +67,9 @@ export class LoginPageComponent implements OnInit, OnDestroy { return !(loggedIn && validSession); }), ) - .subscribe(null, null, () => this.handleSuccess()); + .subscribe({ + complete: () => this.handleSuccess() + }); } ngOnDestroy() { @@ -110,7 +112,7 @@ export class LoginPageComponent implements OnInit, OnDestroy { this.ssoLogin = !!this.ssoOptions; const params = queryParamMap(); - const ssoMessage = params['SSO_Message']; + const ssoMessage = params.SSO_Message; // Upgrade in progress if (auth.sessionData && auth.sessionData.upgradeInProgress) { diff --git a/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.ts b/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.ts index 852b300cb6..fbcd5a6749 100644 --- a/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.ts +++ b/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.ts @@ -68,7 +68,7 @@ export class MetricsComponent { }); return { entity: ep, - metadata: metadata + metadata }; } )); diff --git a/src/frontend/packages/core/src/features/service-catalog/services-helper.ts b/src/frontend/packages/core/src/features/service-catalog/services-helper.ts index a9291418ab..ccffc915ee 100644 --- a/src/frontend/packages/core/src/features/service-catalog/services-helper.ts +++ b/src/frontend/packages/core/src/features/service-catalog/services-helper.ts @@ -3,40 +3,40 @@ import { Store } from '@ngrx/store'; import { Observable, of as observableOf } from 'rxjs'; import { combineLatest, filter, first, map, share, switchMap } from 'rxjs/operators'; +import { GetServiceBroker } from '../../../../store/src/actions/service-broker.actions'; +import { GetServiceInstances } from '../../../../store/src/actions/service-instances.actions'; +import { GetService, GetServicePlansForService } from '../../../../store/src/actions/service.actions'; +import { AppState } from '../../../../store/src/app-state'; +import { + entityFactory, + serviceBrokerSchemaKey, + serviceInstancesSchemaKey, + servicePlanSchemaKey, + serviceSchemaKey, +} from '../../../../store/src/helpers/entity-factory'; +import { createEntityRelationPaginationKey } from '../../../../store/src/helpers/entity-relations/entity-relations.types'; +import { getPaginationObservables } from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { APIResource } from '../../../../store/src/types/api.types'; import { IService, IServiceBroker, IServiceInstance, IServicePlan, - IServicePlanVisibility, IServicePlanExtra, + IServicePlanVisibility, } from '../../core/cf-api-svc.types'; +import { EntityService } from '../../core/entity-service'; +import { EntityServiceFactory } from '../../core/entity-service-factory.service'; +import { safeStringToObj } from '../../core/utils.service'; import { PaginationMonitorFactory } from '../../shared/monitors/pagination-monitor.factory'; +import { CardStatus } from '../../shared/shared.types'; import { getIdFromRoute } from '../cloud-foundry/cf.helpers'; -import { APIResource } from '../../../../store/src/types/api.types'; -import { AppState } from '../../../../store/src/app-state'; -import { createEntityRelationPaginationKey } from '../../../../store/src/helpers/entity-relations/entity-relations.types'; -import { - serviceInstancesSchemaKey, - entityFactory, - servicePlanSchemaKey, - serviceBrokerSchemaKey, - serviceSchemaKey -} from '../../../../store/src/helpers/entity-factory'; -import { getPaginationObservables } from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; -import { GetServiceInstances } from '../../../../store/src/actions/service-instances.actions'; -import { GetServicePlansForService, GetService } from '../../../../store/src/actions/service.actions'; import { ServicePlanAccessibility } from './services.service'; -import { CardStatus } from '../../shared/shared.types'; -import { safeStringToObj } from '../../core/utils.service'; -import { EntityServiceFactory } from '../../core/entity-service-factory.service'; -import { EntityService } from '../../core/entity-service'; -import { GetServiceBroker } from '../../../../store/src/actions/service-broker.actions'; export const getSvcAvailability = (servicePlan: APIResource, - serviceBroker: APIResource, - allServicePlanVisibilities: APIResource[]) => { + serviceBroker: APIResource, + allServicePlanVisibilities: APIResource[]) => { const svcAvailability = { isPublic: false, spaceScoped: false, hasVisibilities: false, guid: servicePlan.metadata.guid, spaceGuid: null }; @@ -79,7 +79,7 @@ export const isEditServiceInstanceMode = (activatedRoute: ActivatedRoute) => { export const getServiceInstancesInCf = (cfGuid: string, store: Store, paginationMonitorFactory: PaginationMonitorFactory) => { const paginationKey = createEntityRelationPaginationKey(serviceInstancesSchemaKey, cfGuid); return getPaginationObservables>({ - store: store, + store, action: new GetServiceInstances(cfGuid, paginationKey), paginationMonitor: paginationMonitorFactory.create(paginationKey, entityFactory(serviceInstancesSchemaKey)) }, true).entities$; @@ -102,7 +102,7 @@ export const getServicePlans = ( const getServicePlansAction = new GetServicePlansForService(guid, cfGuid, paginationKey); // Could be a space-scoped service, make a request to fetch the plan return getPaginationObservables>({ - store: store, + store, action: getServicePlansAction, paginationMonitor: paginationMonitorFactory.create(getServicePlansAction.paginationKey, entityFactory(servicePlanSchemaKey)) }, true) diff --git a/src/frontend/packages/core/src/features/service-catalog/services.service.mock.ts b/src/frontend/packages/core/src/features/service-catalog/services.service.mock.ts index 270f23ebdc..064002862c 100644 --- a/src/frontend/packages/core/src/features/service-catalog/services.service.mock.ts +++ b/src/frontend/packages/core/src/features/service-catalog/services.service.mock.ts @@ -48,7 +48,7 @@ export class ServicesServiceMock { service_guid: 'f88cdd0e-82e1-429c-be8b-7ab43644c3f4', extra: null, unique_id: '826fcda4-80e1-11e7-aead-9372473ff564-plan-shared', - 'public': true, + public: true, bindable: true, active: true, service_url: '/v2/services/f88cdd0e-82e1-429c-be8b-7ab43644c3f4', diff --git a/src/frontend/packages/core/src/features/service-catalog/services.service.ts b/src/frontend/packages/core/src/features/service-catalog/services.service.ts index a92c5df0a8..28f4ac815b 100644 --- a/src/frontend/packages/core/src/features/service-catalog/services.service.ts +++ b/src/frontend/packages/core/src/features/service-catalog/services.service.ts @@ -225,7 +225,7 @@ export class ServicesService { filter(o => !!o && !!o.entity), map(o => ({ isSpaceScoped: true, - spaceGuid: spaceGuid, + spaceGuid, orgGuid: o.entity.entity.organization_guid })), ); diff --git a/src/frontend/packages/core/src/features/services/detach-service-instance/detach-apps/detach-apps.component.spec.ts b/src/frontend/packages/core/src/features/services/detach-service-instance/detach-apps/detach-apps.component.spec.ts index f90ca89f2d..da897c437f 100644 --- a/src/frontend/packages/core/src/features/services/detach-service-instance/detach-apps/detach-apps.component.spec.ts +++ b/src/frontend/packages/core/src/features/services/detach-service-instance/detach-apps/detach-apps.component.spec.ts @@ -1,8 +1,8 @@ +import { DatePipe } from '@angular/common'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { DetachAppsComponent } from './detach-apps.component'; import { BaseTestModules } from '../../../../../test-framework/cloud-foundry-endpoint-service.helper'; -import { DatePipe } from '@angular/common'; +import { DetachAppsComponent } from './detach-apps.component'; describe('DetachAppsComponent', () => { let component: DetachAppsComponent; @@ -10,11 +10,11 @@ describe('DetachAppsComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ DetachAppsComponent ], + declarations: [DetachAppsComponent], imports: [BaseTestModules], providers: [DatePipe] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { diff --git a/src/frontend/packages/core/src/features/services/detach-service-instance/detach-service-instance.component.spec.ts b/src/frontend/packages/core/src/features/services/detach-service-instance/detach-service-instance.component.spec.ts index 055c0bd48f..6451d16efd 100644 --- a/src/frontend/packages/core/src/features/services/detach-service-instance/detach-service-instance.component.spec.ts +++ b/src/frontend/packages/core/src/features/services/detach-service-instance/detach-service-instance.component.spec.ts @@ -1,9 +1,9 @@ +import { DatePipe } from '@angular/common'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { DetachServiceInstanceComponent } from './detach-service-instance.component'; import { BaseTestModules } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; import { DetachAppsComponent } from './detach-apps/detach-apps.component'; -import { DatePipe } from '@angular/common'; +import { DetachServiceInstanceComponent } from './detach-service-instance.component'; describe('DetachServiceInstanceComponent', () => { let component: DetachServiceInstanceComponent; @@ -11,11 +11,11 @@ describe('DetachServiceInstanceComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ DetachServiceInstanceComponent, DetachAppsComponent ], + declarations: [DetachServiceInstanceComponent, DetachAppsComponent], imports: [BaseTestModules], providers: [DatePipe] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { diff --git a/src/frontend/packages/core/src/features/services/services-wall/services-wall.component.spec.ts b/src/frontend/packages/core/src/features/services/services-wall/services-wall.component.spec.ts index bfd97c50a8..7d18997a1d 100644 --- a/src/frontend/packages/core/src/features/services/services-wall/services-wall.component.spec.ts +++ b/src/frontend/packages/core/src/features/services/services-wall/services-wall.component.spec.ts @@ -1,9 +1,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { ServicesWallComponent } from './services-wall.component'; import { BaseTestModules } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; -import { CloudFoundryService } from '../../../shared/data-services/cloud-foundry.service'; import { CfOrgSpaceDataService } from '../../../shared/data-services/cf-org-space-service.service'; +import { CloudFoundryService } from '../../../shared/data-services/cloud-foundry.service'; +import { ServicesWallComponent } from './services-wall.component'; describe('ServicesWallComponent', () => { let component: ServicesWallComponent; diff --git a/src/frontend/packages/core/src/features/services/services-wall/services-wall.component.ts b/src/frontend/packages/core/src/features/services/services-wall/services-wall.component.ts index dea396ea9c..ee1986e786 100644 --- a/src/frontend/packages/core/src/features/services/services-wall/services-wall.component.ts +++ b/src/frontend/packages/core/src/features/services/services-wall/services-wall.component.ts @@ -34,8 +34,8 @@ export class ServicesWallComponent implements OnDestroy { cfIds$: Observable; constructor(public cloudFoundryService: CloudFoundryService, - public store: Store, - private cfOrgSpaceService: CfOrgSpaceDataService) { + public store: Store, + private cfOrgSpaceService: CfOrgSpaceDataService) { this.canCreateServiceInstance = CurrentUserPermissions.SERVICE_INSTANCE_CREATE; this.cfIds$ = cloudFoundryService.cFEndpoints$.pipe( diff --git a/src/frontend/packages/core/src/features/services/services/services-wall.service.spec.ts b/src/frontend/packages/core/src/features/services/services/services-wall.service.spec.ts index 3651790dad..928edc4643 100644 --- a/src/frontend/packages/core/src/features/services/services/services-wall.service.spec.ts +++ b/src/frontend/packages/core/src/features/services/services/services-wall.service.spec.ts @@ -1,9 +1,9 @@ import { inject, TestBed } from '@angular/core/testing'; +import { BaseTestModules } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; import { EntityServiceFactory } from '../../../core/entity-service-factory.service'; import { PaginationMonitorFactory } from '../../../shared/monitors/pagination-monitor.factory'; import { ServicesWallService } from './services-wall.service'; -import { BaseTestModules } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; describe('ServicesWallService', () => { beforeEach(() => { diff --git a/src/frontend/packages/core/src/features/setup/uaa-wizard/console-uaa-wizard.component.ts b/src/frontend/packages/core/src/features/setup/uaa-wizard/console-uaa-wizard.component.ts index 7103130d40..54853fe366 100644 --- a/src/frontend/packages/core/src/features/setup/uaa-wizard/console-uaa-wizard.component.ts +++ b/src/frontend/packages/core/src/features/setup/uaa-wizard/console-uaa-wizard.component.ts @@ -5,12 +5,12 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, Observable } from 'rxjs'; import { delay, filter, map, skipWhile, take } from 'rxjs/operators'; -import { StepOnNextFunction } from '../../../shared/components/stepper/step/step.component'; +import { VerifySession } from '../../../../../store/src/actions/auth.actions'; +import { SetUAAScope, SetupUAA } from '../../../../../store/src/actions/setup.actions'; import { AppState } from '../../../../../store/src/app-state'; -import { SetupUAA, SetUAAScope } from '../../../../../store/src/actions/setup.actions'; -import { UAASetupState } from '../../../../../store/src/types/uaa-setup.types'; import { AuthState } from '../../../../../store/src/reducers/auth.reducer'; -import { VerifySession } from '../../../../../store/src/actions/auth.actions'; +import { UAASetupState } from '../../../../../store/src/types/uaa-setup.types'; +import { StepOnNextFunction } from '../../../shared/components/stepper/step/step.component'; @Component({ selector: 'app-console-uaa-wizard', @@ -98,18 +98,18 @@ export class ConsoleUaaWizardComponent implements OnInit { } ngOnInit() { this.uaaForm = new FormGroup({ - apiUrl: new FormControl('', [Validators.required]), + apiUrl: new FormControl('', [Validators.required as any]), skipSll: new FormControl(false), - clientId: new FormControl('', [Validators.required]), + clientId: new FormControl('', [Validators.required as any]), clientSecret: new FormControl(''), - adminUsername: new FormControl('', [Validators.required]), - adminPassword: new FormControl('', [Validators.required]), + adminUsername: new FormControl('', [Validators.required as any]), + adminPassword: new FormControl('', [Validators.required as any]), useSSO: new FormControl(false), }); let observer; - this.validateUAAForm = Observable.create((_observer) => { - observer = _observer; + this.validateUAAForm = new Observable(o => { + observer = o; observer.next(false); }); 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 80f8ac761e..c05f60543f 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 @@ -1,17 +1,14 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms'; -import { - ErrorStateMatcher, - ShowOnDirtyErrorStateMatcher, -} from '@angular/material'; +import { ErrorStateMatcher, ShowOnDirtyErrorStateMatcher } from '@angular/material'; import { Subscription } from 'rxjs'; import { first, map, take } from 'rxjs/operators'; +import { UserProfileInfo, UserProfileInfoUpdates } from '../../../../../store/src/types/user-profile.types'; import { CurrentUserPermissions } from '../../../core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../core/current-user-permissions.service'; import { StepOnNextFunction } from '../../../shared/components/stepper/step/step.component'; import { UserProfileService } from '../user-profile.service'; -import { UserProfileInfo, UserProfileInfoUpdates } from '../../../../../store/src/types/user-profile.types'; @Component({ @@ -84,15 +81,15 @@ export class EditProfileInfoComponent implements OnInit, OnDestroy { if (required !== this.lastRequired) { this.lastRequired = required; const validators = required ? [Validators.required] : []; - this.editProfileForm.controls['currentPassword'].setValidators(validators); - this.editProfileForm.controls['currentPassword'].updateValueAndValidity(); + this.editProfileForm.controls.currentPassword.setValidators(validators); + this.editProfileForm.controls.currentPassword.updateValueAndValidity(); } const havePassword = !!values.newPassword.length; if (havePassword !== this.lastHavePassword) { this.lastHavePassword = havePassword; const confirmValidator = havePassword ? [Validators.required, this.confirmPasswordValidator()] : []; - this.editProfileForm.controls['confirmPassword'].setValidators(confirmValidator); - this.editProfileForm.controls['confirmPassword'].updateValueAndValidity(); + this.editProfileForm.controls.confirmPassword.setValidators(confirmValidator); + this.editProfileForm.controls.confirmPassword.updateValueAndValidity(); } }); } @@ -100,7 +97,7 @@ export class EditProfileInfoComponent implements OnInit, OnDestroy { confirmPasswordValidator(): ValidatorFn { return (control: AbstractControl): { [key: string]: any } => { const same = control.value === this.editProfileForm.value.newPassword; - return same ? null : { 'passwordMatch': { value: control.value } }; + return same ? null : { passwordMatch: { value: control.value } }; }; } diff --git a/src/frontend/packages/core/src/logged-in.service.spec.ts b/src/frontend/packages/core/src/logged-in.service.spec.ts index 4368faea23..3f661311a6 100644 --- a/src/frontend/packages/core/src/logged-in.service.spec.ts +++ b/src/frontend/packages/core/src/logged-in.service.spec.ts @@ -1,9 +1,9 @@ import { inject, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { createBasicStoreModule } from '../test-framework/store-test-helper'; import { CoreModule } from './core/core.module'; import { LoggedInService } from './logged-in.service'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { createBasicStoreModule } from '../test-framework/store-test-helper'; describe('LoggedInService', () => { diff --git a/src/frontend/packages/core/src/logged-in.service.ts b/src/frontend/packages/core/src/logged-in.service.ts index 99166c14c2..558cec38fb 100644 --- a/src/frontend/packages/core/src/logged-in.service.ts +++ b/src/frontend/packages/core/src/logged-in.service.ts @@ -1,45 +1,45 @@ -import { HostListener, Inject, Injectable, NgZone } from '@angular/core'; import { DOCUMENT } from '@angular/common'; +import { Inject, Injectable, NgZone } from '@angular/core'; +import { MatDialog } from '@angular/material'; import { Store } from '@ngrx/store'; +import { fromEvent, interval, merge, Subscription } from 'rxjs'; +import { tap } from 'rxjs/operators'; + +import { VerifySession } from '../../store/src/actions/auth.actions'; import { AppState } from '../../store/src/app-state'; import { AuthState } from '../../store/src/reducers/auth.reducer'; -import { VerifySession } from '../../store/src/actions/auth.actions'; -import { MatDialog } from '@angular/material'; -import { LogOutDialogComponent } from './core/log-out-dialog/log-out-dialog.component'; -import { Observable, interval, Subscription, fromEvent, merge } from 'rxjs'; import { SessionData } from '../../store/src/types/auth.types'; - -import { tap } from 'rxjs/operators'; +import { LogOutDialogComponent } from './core/log-out-dialog/log-out-dialog.component'; @Injectable() export class LoggedInService { - private _sessionData: SessionData; - private _userInteractionChecker: Subscription; + private sessionData: SessionData; + private userInteractionChecker: Subscription; - private _lastUserInteraction = Date.now(); - private _sessionChecker: Subscription; + private lastUserInteraction = Date.now(); + private sessionChecker: Subscription; // Check the session every 5 seconds (Note: this is vey cheap to do unless the session is about to expire) - private _checkSessionInterval = 5 * 1000; + private checkSessionInterval = 5 * 1000; // Warn inactive users 2 minutes before logging them out - private _warnBeforeLogout = 2 * 60 * 1000; + private warnBeforeLogout = 2 * 60 * 1000; // User considered idle if no interaction for 5 minutes - private _userIdlePeriod = 5 * 60 * 1000; + private userIdlePeriod = 5 * 60 * 1000; // Avoid a race condition where the cookie is deleted if the user presses ok just before expiration - private _autoLogoutDelta = 5 * 1000; + private autoLogoutDelta = 5 * 1000; // When we see the following events, we consider the user as active - private _userActiveEvents = ['keydown', 'DOMMouseScroll', 'mousewheel', 'mousedown', 'touchstart', 'touchmove', 'scroll', 'wheel']; + private userActiveEvents = ['keydown', 'DOMMouseScroll', 'mousewheel', 'mousedown', 'touchstart', 'touchmove', 'scroll', 'wheel']; - private _activityPromptShown = false; + private activityPromptShown = false; - private _sub: Subscription; + private sub: Subscription; - private _destroying = false; + private destroying = false; constructor( @Inject(DOCUMENT) private document: Document, @@ -50,39 +50,39 @@ export class LoggedInService { } init() { - const eventStreams = this._userActiveEvents.map((eventName) => { + const eventStreams = this.userActiveEvents.map((eventName) => { return fromEvent(document, eventName); }); - this._sub = this.store.select(s => s.auth) + this.sub = this.store.select(s => s.auth) .subscribe((auth: AuthState) => { - this._sessionData = auth.sessionData; + this.sessionData = auth.sessionData; if (auth.loggedIn && auth.sessionData && auth.sessionData.valid) { - if (!this._sessionChecker || this._sessionChecker.closed) { + if (!this.sessionChecker || this.sessionChecker.closed) { this.openSessionCheckerPoll(); } - if (!this._userInteractionChecker) { - this._userInteractionChecker = merge(...eventStreams).subscribe(() => { - this._lastUserInteraction = Date.now(); + if (!this.userInteractionChecker) { + this.userInteractionChecker = merge(...eventStreams).subscribe(() => { + this.lastUserInteraction = Date.now(); }); } } else { this.closeSessionCheckerPoll(); - if (this._userInteractionChecker) { - this._userInteractionChecker.unsubscribe(); + if (this.userInteractionChecker) { + this.userInteractionChecker.unsubscribe(); } } }); } destroy() { - this._destroying = true; - if (this._sub) { - this._sub.unsubscribe(); + this.destroying = true; + if (this.sub) { + this.sub.unsubscribe(); } this.closeSessionCheckerPoll(); - if (this._userInteractionChecker) { - this._userInteractionChecker.unsubscribe(); + if (this.userInteractionChecker) { + this.userInteractionChecker.unsubscribe(); } } @@ -91,7 +91,7 @@ export class LoggedInService { private openSessionCheckerPoll() { this.closeSessionCheckerPoll(); this.ngZone.runOutsideAngular(() => { - this._sessionChecker = interval(this._checkSessionInterval) + this.sessionChecker = interval(this.checkSessionInterval) .pipe( tap(() => { this.ngZone.run(() => { @@ -103,14 +103,14 @@ export class LoggedInService { } private closeSessionCheckerPoll() { - if (this._sessionChecker && !this._sessionChecker.closed) { - this._sessionChecker.unsubscribe(); + if (this.sessionChecker && !this.sessionChecker.closed) { + this.sessionChecker.unsubscribe(); } } private _promptInactiveUser(expiryDate) { - this._activityPromptShown = true; + this.activityPromptShown = true; const dialogRef = this.dialog.open(LogOutDialogComponent, { data: { expiryDate }, @@ -122,23 +122,23 @@ export class LoggedInService { this.store.dispatch(new VerifySession(false, false)); this.openSessionCheckerPoll(); } - this._activityPromptShown = false; + this.activityPromptShown = false; }); } private _checkSession() { - if (this._activityPromptShown || this._destroying) { + if (this.activityPromptShown || this.destroying) { return; } const now = Date.now(); - const sessionExpiresOn = this._sessionData.sessionExpiresOn; - const safeExpire = sessionExpiresOn - this._autoLogoutDelta; + const sessionExpiresOn = this.sessionData.sessionExpiresOn; + const safeExpire = sessionExpiresOn - this.autoLogoutDelta; const delta = safeExpire - now; - const aboutToExpire = delta < this._warnBeforeLogout; + const aboutToExpire = delta < this.warnBeforeLogout; if (aboutToExpire) { - const idleDelta = now - this._lastUserInteraction; - const userIsActive = idleDelta < this._userIdlePeriod; + const idleDelta = now - this.lastUserInteraction; + const userIsActive = idleDelta < this.userIdlePeriod; if (userIsActive) { this.store.dispatch(new VerifySession(false, false)); } else { diff --git a/src/frontend/packages/core/src/polyfills.ts b/src/frontend/packages/core/src/polyfills.ts index 2fbb9c9c57..2b9bc2226c 100644 --- a/src/frontend/packages/core/src/polyfills.ts +++ b/src/frontend/packages/core/src/polyfills.ts @@ -18,7 +18,9 @@ * BROWSER POLYFILLS */ -/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +/** + * IE9, IE10 and IE11 requires all of the following polyfills. + */ // import 'core-js/es6/symbol'; // import 'core-js/es6/object'; // import 'core-js/es6/function'; @@ -34,18 +36,21 @@ // import 'core-js/es6/weak-map'; // import 'core-js/es6/set'; -/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +/** + * IE10 and IE11 requires the following for NgClass support on SVG elements + */ // import 'classlist.js'; // Run `npm install --save classlist.js`. -/** Evergreen browsers require these. **/ +/** + * Evergreen browsers require these. + */ import 'core-js/es6/reflect'; -import 'core-js/es7/reflect'; /** * Required to support Web Animations `@angular/animation`. * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation - **/ + */ import 'web-animations-js'; // Run `npm install --save web-animations-js`. diff --git a/src/frontend/packages/core/src/shared/components/add-service-instance/bind-apps-step/bind-apps-step.component.ts b/src/frontend/packages/core/src/shared/components/add-service-instance/bind-apps-step/bind-apps-step.component.ts index 4b10332de2..346ac91dc1 100644 --- a/src/frontend/packages/core/src/shared/components/add-service-instance/bind-apps-step/bind-apps-step.component.ts +++ b/src/frontend/packages/core/src/shared/components/add-service-instance/bind-apps-step/bind-apps-step.component.ts @@ -4,20 +4,22 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, Observable, of as observableOf, Subscription } from 'rxjs'; import { filter, switchMap } from 'rxjs/operators'; -import { IServicePlan } from '../../../../core/cf-api-svc.types'; -import { IApp } from '../../../../core/cf-api.types'; -import { PaginationMonitorFactory } from '../../../monitors/pagination-monitor.factory'; -import { StepOnNextResult } from '../../stepper/step/step.component'; -import { APIResource } from '../../../../../../store/src/types/api.types'; +import { SetCreateServiceInstanceApp } from '../../../../../../store/src/actions/create-service-instance.actions'; +import { GetAllAppsInSpace } from '../../../../../../store/src/actions/space.actions'; import { AppState } from '../../../../../../store/src/app-state'; -import { selectCreateServiceInstance } from '../../../../../../store/src/selectors/create-service-instance.selectors'; -import { createEntityRelationPaginationKey } from '../../../../../../store/src/helpers/entity-relations/entity-relations.types'; -import { spaceSchemaKey, entityFactory, applicationSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; +import { applicationSchemaKey, entityFactory, spaceSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; +import { + createEntityRelationPaginationKey, +} from '../../../../../../store/src/helpers/entity-relations/entity-relations.types'; import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; -import { GetAllAppsInSpace } from '../../../../../../store/src/actions/space.actions'; -import { SetCreateServiceInstanceApp } from '../../../../../../store/src/actions/create-service-instance.actions'; +import { selectCreateServiceInstance } from '../../../../../../store/src/selectors/create-service-instance.selectors'; +import { APIResource } from '../../../../../../store/src/types/api.types'; +import { IServicePlan } from '../../../../core/cf-api-svc.types'; +import { IApp } from '../../../../core/cf-api.types'; import { pathGet, safeUnsubscribe } from '../../../../core/utils.service'; +import { PaginationMonitorFactory } from '../../../monitors/pagination-monitor.factory'; import { SchemaFormConfig } from '../../schema-form/schema-form.component'; +import { StepOnNextResult } from '../../stepper/step/step.component'; @Component({ selector: 'app-bind-apps-step', @@ -80,7 +82,7 @@ export class BindAppsStepComponent implements OnDestroy, AfterContentInit { } // Start - this.validateSubscription = this.stepperForm.controls['apps'].valueChanges.subscribe(app => { + this.validateSubscription = this.stepperForm.controls.apps.valueChanges.subscribe(app => { if (!app) { // If there's no app selected the step will always be valid this.validate.next(true); diff --git a/src/frontend/packages/core/src/shared/components/add-service-instance/create-service-instance-helper.service.ts b/src/frontend/packages/core/src/shared/components/add-service-instance/create-service-instance-helper.service.ts index b9e15f3955..0fbdad52f7 100644 --- a/src/frontend/packages/core/src/shared/components/add-service-instance/create-service-instance-helper.service.ts +++ b/src/frontend/packages/core/src/shared/components/add-service-instance/create-service-instance-helper.service.ts @@ -1,8 +1,22 @@ import { Inject } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { filter, map, publishReplay, refCount, share, switchMap, first } from 'rxjs/operators'; +import { filter, map, publishReplay, refCount, share, switchMap } from 'rxjs/operators'; +import { GetServiceInstances } from '../../../../../store/src/actions/service-instances.actions'; +import { GetServicePlanVisibilities } from '../../../../../store/src/actions/service-plan-visibility.actions'; +import { GetServicePlanServiceInstances } from '../../../../../store/src/actions/service-plan.actions'; +import { GetServiceInstancesForSpace } from '../../../../../store/src/actions/space.actions'; +import { AppState } from '../../../../../store/src/app-state'; +import { + entityFactory, + serviceInstancesSchemaKey, + servicePlanVisibilitySchemaKey, +} from '../../../../../store/src/helpers/entity-factory'; +import { createEntityRelationPaginationKey } from '../../../../../store/src/helpers/entity-relations/entity-relations.types'; +import { getPaginationObservables } from '../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; +import { APIResource } from '../../../../../store/src/types/api.types'; +import { QParam } from '../../../../../store/src/types/pagination.types'; import { IService, IServiceBroker, @@ -11,35 +25,9 @@ import { IServicePlanVisibility, } from '../../../core/cf-api-svc.types'; import { EntityServiceFactory } from '../../../core/entity-service-factory.service'; -import { pathGet } from '../../../core/utils.service'; -import { CloudFoundryEndpointService } from '../../../features/cloud-foundry/services/cloud-foundry-endpoint.service'; -import { getServicePlans, getSvcAvailability, getCfService, getServiceBroker } from '../../../features/service-catalog/services-helper'; -import { ServicePlanAccessibility } from '../../../features/service-catalog/services.service'; - +import { getCfService, getServiceBroker, getServicePlans } from '../../../features/service-catalog/services-helper'; import { CF_GUID } from '../../entity.tokens'; import { PaginationMonitorFactory } from '../../monitors/pagination-monitor.factory'; -import { APIResource } from '../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../store/src/app-state'; -import { - entityFactory, - servicePlanVisibilitySchemaKey, - organizationSchemaKey, - spaceSchemaKey, - spaceWithOrgKey, - serviceInstancesSchemaKey -} from '../../../../../store/src/helpers/entity-factory'; -import { - createEntityRelationPaginationKey, - createEntityRelationKey -} from '../../../../../store/src/helpers/entity-relations/entity-relations.types'; -import { getPaginationObservables } from '../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; -import { GetServicePlanVisibilities } from '../../../../../store/src/actions/service-plan-visibility.actions'; -import { selectCreateServiceInstanceServicePlan } from '../../../../../store/src/selectors/create-service-instance.selectors'; -import { GetSpace, GetServiceInstancesForSpace } from '../../../../../store/src/actions/space.actions'; -import { QParam } from '../../../../../store/src/types/pagination.types'; -import { GetServicePlanServiceInstances } from '../../../../../store/src/actions/service-plan.actions'; -import { GetServiceInstances } from '../../../../../store/src/actions/service-instances.actions'; -import { IOrganization, ISpace } from '../../../core/cf-api.types'; export class CreateServiceInstanceHelper { servicePlanVisibilities$: Observable[]>; @@ -194,7 +182,8 @@ export class CreateServiceInstanceHelper { // } getServiceInstancesForService = (servicePlanGuid: string = null, spaceGuid: string = null, cfGuid: string = null) => { - let action, paginationKey; + let action; + let paginationKey; if (spaceGuid) { paginationKey = createEntityRelationPaginationKey(serviceInstancesSchemaKey, `${spaceGuid}-${servicePlanGuid}`); const q = [new QParam('service_plan_guid', servicePlanGuid, ':')]; diff --git a/src/frontend/packages/core/src/shared/components/add-service-instance/csi-mode.service.ts b/src/frontend/packages/core/src/shared/components/add-service-instance/csi-mode.service.ts index 6e15139a3c..c863325be3 100644 --- a/src/frontend/packages/core/src/shared/components/add-service-instance/csi-mode.service.ts +++ b/src/frontend/packages/core/src/shared/components/add-service-instance/csi-mode.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; + import { getIdFromRoute } from '../../../features/cloud-foundry/cf.helpers'; import { SpaceScopedService } from '../../../features/service-catalog/services.service'; @@ -51,9 +52,9 @@ export class CsiModeService { showSelectService: false, }; this.spaceScopedDetails = { - isSpaceScoped: activatedRoute.snapshot.queryParams['isSpaceScoped'] === 'true' ? true : false, - spaceGuid: activatedRoute.snapshot.queryParams['spaceGuid'], - orgGuid: activatedRoute.snapshot.queryParams['orgGuid'], + isSpaceScoped: activatedRoute.snapshot.queryParams.isSpaceScoped === 'true' ? true : false, + spaceGuid: activatedRoute.snapshot.queryParams.spaceGuid, + orgGuid: activatedRoute.snapshot.queryParams.orgGuid, }; } diff --git a/src/frontend/packages/core/src/shared/components/add-service-instance/select-service/select-service.component.ts b/src/frontend/packages/core/src/shared/components/add-service-instance/select-service/select-service.component.ts index d4ec6a5e2a..5b69e1f404 100644 --- a/src/frontend/packages/core/src/shared/components/add-service-instance/select-service/select-service.component.ts +++ b/src/frontend/packages/core/src/shared/components/add-service-instance/select-service/select-service.component.ts @@ -42,7 +42,7 @@ export class SelectServiceComponent implements OnDestroy, AfterContentInit { private servicesWallService: ServicesWallService ) { this.stepperForm = new FormGroup({ - service: new FormControl('', [Validators.required]), + service: new FormControl('', [Validators.required as any]), }); const cfSpaceGuid$ = combineLatest( diff --git a/src/frontend/packages/core/src/shared/components/add-service-instance/specify-details-step/specify-details-step.component.ts b/src/frontend/packages/core/src/shared/components/add-service-instance/specify-details-step/specify-details-step.component.ts index de846a9524..e7ad644758 100644 --- a/src/frontend/packages/core/src/shared/components/add-service-instance/specify-details-step/specify-details-step.component.ts +++ b/src/frontend/packages/core/src/shared/components/add-service-instance/specify-details-step/specify-details-step.component.ts @@ -24,33 +24,37 @@ import { take, tap, } from 'rxjs/operators'; -import { IServiceInstance, IServicePlan } from '../../../../core/cf-api-svc.types'; -import { StepOnNextResult } from '../../stepper/step/step.component'; -import { CreateServiceInstanceHelperServiceFactory } from '../create-service-instance-helper-service-factory.service'; -import { CreateServiceInstanceHelper } from '../create-service-instance-helper.service'; -import { CsiGuidsService } from '../csi-guids.service'; -import { CsiModeService } from '../csi-mode.service'; -import { CreateServiceInstanceState } from '../../../../../../store/src/types/create-service-instance.types'; -import { APIResource, NormalizedResponse } from '../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../store/src/app-state'; + +import { GetAppEnvVarsAction } from '../../../../../../store/src/actions/app-metadata.actions'; import { - selectCreateServiceInstance, - selectCreateServiceInstanceSpaceGuid -} from '../../../../../../store/src/selectors/create-service-instance.selectors'; -import { SetCreateServiceInstanceOrg, SetServiceInstanceGuid } from '../../../../../../store/src/actions/create-service-instance.actions'; + SetCreateServiceInstanceOrg, + SetServiceInstanceGuid, +} from '../../../../../../store/src/actions/create-service-instance.actions'; +import { RouterNav } from '../../../../../../store/src/actions/router.actions'; +import { CreateServiceBinding } from '../../../../../../store/src/actions/service-bindings.actions'; import { - UpdateServiceInstance, CreateServiceInstance, - GetServiceInstance + GetServiceInstance, + UpdateServiceInstance, } from '../../../../../../store/src/actions/service-instances.actions'; -import { GetAppEnvVarsAction } from '../../../../../../store/src/actions/app-metadata.actions'; -import { RouterNav } from '../../../../../../store/src/actions/router.actions'; -import { selectUpdateInfo, selectRequestInfo } from '../../../../../../store/src/selectors/api.selectors'; -import { serviceInstancesSchemaKey, serviceBindingSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; -import { RequestInfoState } from '../../../../../../store/src/reducers/api-request-reducer/types'; -import { CreateServiceBinding } from '../../../../../../store/src/actions/service-bindings.actions'; +import { AppState } from '../../../../../../store/src/app-state'; +import { serviceBindingSchemaKey, serviceInstancesSchemaKey } from '../../../../../../store/src/helpers/entity-factory'; +import { getDefaultRequestState, RequestInfoState } from '../../../../../../store/src/reducers/api-request-reducer/types'; +import { selectRequestInfo, selectUpdateInfo } from '../../../../../../store/src/selectors/api.selectors'; +import { + selectCreateServiceInstance, + selectCreateServiceInstanceSpaceGuid, +} from '../../../../../../store/src/selectors/create-service-instance.selectors'; +import { APIResource, NormalizedResponse } from '../../../../../../store/src/types/api.types'; +import { CreateServiceInstanceState } from '../../../../../../store/src/types/create-service-instance.types'; +import { IServiceInstance, IServicePlan } from '../../../../core/cf-api-svc.types'; import { pathGet, safeStringToObj } from '../../../../core/utils.service'; import { SchemaFormConfig } from '../../schema-form/schema-form.component'; +import { StepOnNextResult } from '../../stepper/step/step.component'; +import { CreateServiceInstanceHelperServiceFactory } from '../create-service-instance-helper-service-factory.service'; +import { CreateServiceInstanceHelper } from '../create-service-instance-helper.service'; +import { CsiGuidsService } from '../csi-guids.service'; +import { CsiModeService } from '../csi-mode.service'; const enum FormMode { @@ -110,7 +114,7 @@ export class SpecifyDetailsStepComponent implements OnDestroy, AfterContentInit nameTakenValidator = (): ValidatorFn => { return (formField: AbstractControl): { [key: string]: any } => - !this.checkName(formField.value) ? { 'nameTaken': { value: formField.value } } : null; + !this.checkName(formField.value) ? { nameTaken: { value: formField.value } } : null; } constructor( @@ -284,14 +288,7 @@ export class SpecifyDetailsStepComponent implements OnDestroy, AfterContentInit switchMap(p => { if (this.bindExistingInstance) { // Binding an existing instance, therefore, skip creation by returning a dummy response - return observableOf({ - creating: false, - error: false, - fetching: false, - response: { - result: [] - } - }); + return observableOf(getDefaultRequestState()); } else { return this.createServiceInstance(p); } diff --git a/src/frontend/packages/core/src/shared/components/app-action-monitor/app-action-monitor.component.ts b/src/frontend/packages/core/src/shared/components/app-action-monitor/app-action-monitor.component.ts index c6b2ee202d..1d6474ca9c 100644 --- a/src/frontend/packages/core/src/shared/components/app-action-monitor/app-action-monitor.component.ts +++ b/src/frontend/packages/core/src/shared/components/app-action-monitor/app-action-monitor.component.ts @@ -1,16 +1,20 @@ - import { DataSource } from '@angular/cdk/table'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { schema } from 'normalizr'; import { never as observableNever, Observable, of as observableOf } from 'rxjs'; -import { AppMonitorComponentTypes, IApplicationMonitorComponentState } from '../app-action-monitor-icon/app-action-monitor-icon.component'; + +import { rootUpdatingKey } from '../../../../../store/src/reducers/api-request-reducer/types'; +import { + AppMonitorComponentTypes, + IApplicationMonitorComponentState, +} from '../app-action-monitor-icon/app-action-monitor-icon.component'; import { ITableListDataSource } from '../list/data-sources-controllers/list-data-source-types'; import { ITableCellRequestMonitorIconConfig, - TableCellRequestMonitorIconComponent + TableCellRequestMonitorIconComponent, } from '../list/list-table/table-cell-request-monitor-icon/table-cell-request-monitor-icon.component'; import { ITableColumn } from '../list/list-table/table.types'; -import { rootUpdatingKey } from '../../../../../store/src/reducers/api-request-reducer/types'; + @Component({ selector: 'app-action-monitor', @@ -56,7 +60,7 @@ export class AppActionMonitorComponent implements OnInit { constructor() { } ngOnInit() { - const _getCellConfig = () => ({ + const getCellConfig = () => ({ entityKey: this.entityKey, schema: this.schema, monitorState: this.monitorState, @@ -66,7 +70,7 @@ export class AppActionMonitorComponent implements OnInit { const monitorColumn = { columnId: 'monitorState', cellComponent: TableCellRequestMonitorIconComponent, - cellConfig: this.getCellConfig || _getCellConfig, + cellConfig: this.getCellConfig || getCellConfig, cellFlex: '0 0 40px' }; diff --git a/src/frontend/packages/core/src/shared/components/application-state/application-state.service.spec.ts b/src/frontend/packages/core/src/shared/components/application-state/application-state.service.spec.ts index ab09b36e29..aa9cb6d5ca 100644 --- a/src/frontend/packages/core/src/shared/components/application-state/application-state.service.spec.ts +++ b/src/frontend/packages/core/src/shared/components/application-state/application-state.service.spec.ts @@ -22,7 +22,7 @@ describe('ApplicationStateService', () => { expect(cfAppStateService).toBeTruthy(); }); - describe('check friendly names and indicators', function () { + describe('check friendly names and indicators', () => { function makeTestData(appState, packageState, instanceStates?) { const summary = { @@ -35,7 +35,7 @@ describe('ApplicationStateService', () => { let instances = []; let running = 0; if (instanceStates) { - instanceStates.forEach(function (s) { + instanceStates.forEach(s => { instances.push({ state: s }); if (s === 'RUNNING') { running++; } }); @@ -44,12 +44,12 @@ describe('ApplicationStateService', () => { } summary.running_instances = running; return { - summary: summary, - instances: instances + summary, + instances }; } - it('Busted push', function () { + it('Busted push', () => { const testData = makeTestData('ANY', 'FAILED', ['RUNNING']); const res = cfAppStateService.get(testData.summary, testData.instances); @@ -59,7 +59,7 @@ describe('ApplicationStateService', () => { expect(res.actions.delete).toBe(true); }); - it('Updating app', function () { + it('Updating app', () => { const testData = makeTestData('STOPPED', 'PENDING', ['RUNNING', 'CRASHED']); testData.summary.package_updated_at = 'some date'; const res = cfAppStateService.get(testData.summary, testData.instances); @@ -70,7 +70,7 @@ describe('ApplicationStateService', () => { expect(res.actions.start).toBe(true); }); - it('Incomplete app', function () { + it('Incomplete app', () => { const testData = makeTestData('STOPPED', 'PENDING', ['RUNNING', 'CRASHED']); const res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('incomplete'); @@ -80,7 +80,7 @@ describe('ApplicationStateService', () => { expect(res.actions.cli).toBe(true); }); - it('User stopped app', function () { + it('User stopped app', () => { const testData = makeTestData('STOPPED', 'STAGED', ['RUNNING', 'CRASHED']); const res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('warning'); @@ -90,7 +90,7 @@ describe('ApplicationStateService', () => { expect(res.actions.delete).toBe(true); }); - it('Incomplete', function () { + it('Incomplete', () => { const testData = makeTestData('STOPPED', undefined, ['RUNNING', 'CRASHED']); const res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('incomplete'); @@ -100,7 +100,7 @@ describe('ApplicationStateService', () => { expect(res.actions.cli).toBe(true); }); - it('During push', function () { + it('During push', () => { const testData = makeTestData('STARTED', 'PENDING', ['RUNNING', 'CRASHED']); const res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('busy'); @@ -109,7 +109,7 @@ describe('ApplicationStateService', () => { expect(res.actions.delete).toBe(true); }); - it('After successful push', function () { + it('After successful push', () => { const testData = makeTestData('STARTED', 'STAGED', ['STARTING']); const res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('busy'); @@ -120,7 +120,7 @@ describe('ApplicationStateService', () => { expect(res.actions.restart).toBe(true); }); - it('Starting', function () { + it('Starting', () => { const testData = makeTestData('STARTED', 'STAGED', ['STARTING', 'RUNNING']); const res = cfAppStateService.get(testData.summary, testData.instances); @@ -132,7 +132,7 @@ describe('ApplicationStateService', () => { expect(res.actions.restart).toBe(true); }); - it('Running!', function () { + it('Running!', () => { let testData = makeTestData('STARTED', 'STAGED', ['RUNNING']); let res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('ok'); @@ -150,7 +150,7 @@ describe('ApplicationStateService', () => { expect(res.actions.launch).toBe(true); }); - it('Borked, usually due to app code', function () { + it('Borked, usually due to app code', () => { let testData = makeTestData('STARTED', 'STAGED', ['CRASHED']); let res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('error'); @@ -167,7 +167,7 @@ describe('ApplicationStateService', () => { expect(res.actions.stop).toBe(true); }); - it('Borked, usually due to starting timeouts', function () { + it('Borked, usually due to starting timeouts', () => { let testData = makeTestData('STARTED', 'STAGED', ['TIMEOUT']); let res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('warning'); @@ -184,7 +184,7 @@ describe('ApplicationStateService', () => { expect(res.actions.stop).toBe(true); }); - it('Borked, usually due to starting timeouts (1)', function () { + it('Borked, usually due to starting timeouts (1)', () => { let testData = makeTestData('STARTED', 'STAGED', ['TIMEOUT', 'CRASHED']); let res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('error'); @@ -201,7 +201,7 @@ describe('ApplicationStateService', () => { expect(res.actions.stop).toBe(true); }); - it('Borked, usually due to platform issues', function () { + it('Borked, usually due to platform issues', () => { let testData = makeTestData('STARTED', 'STAGED', ['RUNNING', 'CRASHED']); let res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('warning'); @@ -219,7 +219,7 @@ describe('ApplicationStateService', () => { expect(res.actions.launch).toBe(true); }); - it('Borked, usually due to platform issues (2)', function () { + it('Borked, usually due to platform issues (2)', () => { let testData = makeTestData('STARTED', 'STAGED', ['RUNNING', 'UNKNOWN']); let res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('warning'); @@ -237,7 +237,7 @@ describe('ApplicationStateService', () => { expect(res.actions.launch).toBe(true); }); - it('Borked, one crashed, one running, one stating', function () { + it('Borked, one crashed, one running, one stating', () => { const testData = makeTestData('STARTED', 'STAGED', ['RUNNING', 'CRASHED', 'STARTING']); const res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('warning'); @@ -245,7 +245,7 @@ describe('ApplicationStateService', () => { expect($translate.instant(res.subLabel)).toBe('Crashing'); }); - it('Started, but no stats available', function () { + it('Started, but no stats available', () => { const testData = makeTestData('STARTED', 'STAGED'); const res = cfAppStateService.get(testData.summary, undefined); expect(res.indicator).toBe('tentative'); @@ -253,7 +253,7 @@ describe('ApplicationStateService', () => { expect(res.subLabel).not.toBeDefined(); }); - it('Started, but have instance counf set to 0', function () { + it('Started, but have instance counf set to 0', () => { const testData = makeTestData('STARTED', 'STAGED'); const res = cfAppStateService.get(testData.summary, testData.instances); expect(res.indicator).toBe('tentative'); diff --git a/src/frontend/packages/core/src/shared/components/application-state/application-state.service.ts b/src/frontend/packages/core/src/shared/components/application-state/application-state.service.ts index 252a404438..9ffe123677 100644 --- a/src/frontend/packages/core/src/shared/components/application-state/application-state.service.ts +++ b/src/frontend/packages/core/src/shared/components/application-state/application-state.service.ts @@ -17,18 +17,18 @@ export interface ApplicationStateData { export class ApplicationStateService { /** - * @description: State metadata - * - * First level keys match the APP_STATE with a '?' for a wildcard match for any APP_STATE - * Second level keys match PACKAGE_STATE directly OR on a combination of #running #crashed, #flapping - * which we presentation in the name as (X,X,X) - where X can be: - * - 0 - must be 0 - * - N - must be >0 - * - ? - matches when the value is not known - * - * To determine the incomplete state, we also need to look at the package_updated_at field - * - */ + * @description: State metadata + * + * First level keys match the APP_STATE with a '?' for a wildcard match for any APP_STATE + * Second level keys match PACKAGE_STATE directly OR on a combination of #running #crashed, #flapping + * which we presentation in the name as (X,X,X) - where X can be: + * - 0 - must be 0 + * - N - must be >0 + * - ? - matches when the value is not known + * + * To determine the incomplete state, we also need to look at the package_updated_at field + * + */ private stateMetadata = { '?': { FAILED: { @@ -132,7 +132,7 @@ export class ApplicationStateService { indicator: CardStatus.ERROR, actions: 'stop,restart,cli,restage' }, - 'CRASHING': { + CRASHING: { label: 'Deployed', subLabel: 'Crashing', indicator: CardStatus.WARNING, @@ -160,9 +160,9 @@ export class ApplicationStateService { }; /** - * @description Translates string list of action names into a map for easier checking if an action is supported - * @param {any} obj - object to traverse to replace 'actions' keys with maps - */ + * @description Translates string list of action names into a map for easier checking if an action is supported + * @param obj - object to traverse to replace 'actions' keys with maps + */ private mapActions(obj: any) { for (const k of Object.keys(obj)) { const v = obj[k]; @@ -187,11 +187,11 @@ export class ApplicationStateService { } /** - * @description Get the application state metadata for an application based on its summary and - * optionally its instance metadata. - * @param {object} summary - the application summary metadata (either from summary or entity) - * @param {object} appInstances - the application instances metadata (from the app stats API call) - */ + * @description Get the application state metadata for an application based on its summary and + * optionally its instance metadata. + * @param summary - the application summary metadata (either from summary or entity) + * @param appInstances - the application instances metadata (from the app stats API call) + */ get(summary: any, appInstances: any): ApplicationStateData { const appState: string = summary ? summary.state : 'UNKNOWN'; const pkgState = this.getPackageState(appState, summary); @@ -261,10 +261,10 @@ export class ApplicationStateService { } /** - * @description Gets the package state based on the application summary metadata - * @param {string} appState - the application state - * @param {object} summary - the application summary - */ + * @description Gets the package state based on the application summary metadata + * @param appState - the application state + * @param summary - the application summary + */ private getPackageState(appState: string, summary: any): string { let pkgState = (summary ? summary.package_state : '') || '*NONE*'; // Tweak package state based on extra info in package_updated_at if needed (for now, only if stopped) @@ -275,11 +275,11 @@ export class ApplicationStateService { } /** - * @description Get an object with the instance counts for running, crashed and failing - * @param {object} summary - the application summary - * @param {object} appInstances - the application instances metadata (from the app stats API call) - * @returns {object} Object with instance count metadata - */ + * @description Get an object with the instance counts for running, crashed and failing + * @param summary - the application summary + * @param appInstances - the application instances metadata (from the app stats API call) + * @returns Object with instance count metadata + */ private getCounts(summary, appInstances) { const counts: any = {}; // Need to check based on additional state @@ -310,11 +310,11 @@ export class ApplicationStateService { } /** -* @description Get a count either from a value if supplied or by filterine app instance metadata -* @param {number} value - the value to use directly or undefined if not available -* @param {object} appInstances - the application instances metadata (from the app stats API call) -* @param {string} instanceState - the instance state to use when filtering the app instance metadata -*/ + * @description Get a count either from a value if supplied or by filterine app instance metadata + * @param value - the value to use directly or undefined if not available + * @param appInstances - the application instances metadata (from the app stats API call) + * @param instanceState - the instance state to use when filtering the app instance metadata + */ private getCount(value: number, appInstances: any, instanceState: string): number { // Use a value if one available if (value) { @@ -329,9 +329,9 @@ export class ApplicationStateService { } /** - * @description Format a numeric count into a string to be used for state matching - * @param {number} value - the value to use directly or undefined if not available - */ + * @description Format a numeric count into a string to be used for state matching + * @param value - the value to use directly or undefined if not available + */ private formatCount(value: number): string { if (value === 0) { return '0'; @@ -343,10 +343,10 @@ export class ApplicationStateService { } /** - * @description Get the instance state - single state to summarize the state of the application's instances - * @param {object} summary - the application summary metadata (either from summary or entity) - * @param {object} appInstances - the application instances metadata (from the app stats API call) - */ + * @description Get the instance state - single state to summarize the state of the application's instances + * @param summary - the application summary metadata (either from summary or entity) + * @param appInstances - the application instances metadata (from the app stats API call) + */ getInstanceState(summary: any, appInstances: any): ApplicationStateData { const appState: string = summary ? summary.state : 'UNKNOWN'; if (appState !== 'STARTED') { @@ -365,7 +365,7 @@ export class ApplicationStateService { private getStateForIndicator(indicator: CardStatus): ApplicationStateData { return { - indicator: indicator, + indicator, label: '-', actions: {} }; diff --git a/src/frontend/packages/core/src/shared/components/boolean-indicator/boolean-indicator.component.ts b/src/frontend/packages/core/src/shared/components/boolean-indicator/boolean-indicator.component.ts index b0960cad9f..f1b45f1c1b 100644 --- a/src/frontend/packages/core/src/shared/components/boolean-indicator/boolean-indicator.component.ts +++ b/src/frontend/packages/core/src/shared/components/boolean-indicator/boolean-indicator.component.ts @@ -57,5 +57,5 @@ export class BooleanIndicatorComponent { getTypeText = (s: string) => s.split('-'); - capitalizeFirstLetter = (string) => string.charAt(0).toUpperCase() + string.slice(1); + capitalizeFirstLetter = (s: string) => s.charAt(0).toUpperCase() + s.slice(1); } diff --git a/src/frontend/packages/core/src/shared/components/cards/card-app-usage/card-app-usage.component.ts b/src/frontend/packages/core/src/shared/components/cards/card-app-usage/card-app-usage.component.ts index 40bc287e7d..b9664f9be4 100644 --- a/src/frontend/packages/core/src/shared/components/cards/card-app-usage/card-app-usage.component.ts +++ b/src/frontend/packages/core/src/shared/components/cards/card-app-usage/card-app-usage.component.ts @@ -25,8 +25,8 @@ export class CardAppUsageComponent implements OnInit { this.appService.applicationRunning$, ).pipe( map(([monitor, isRunning]) => ({ - monitor: monitor, - isRunning: isRunning, + monitor, + isRunning, status: !isRunning ? 'tentative' : pathGet('status.usage', monitor) })), share() 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 b1e994db4b..e8c712c961 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 @@ -2,9 +2,9 @@ import { Component, Input, OnChanges, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { BehaviorSubject } from 'rxjs'; -import { UtilsService } from '../../../../core/utils.service'; -import { AppState } from '../../../../../../store/src/app-state'; import { RouterNav } from '../../../../../../store/src/actions/router.actions'; +import { AppState } from '../../../../../../store/src/app-state'; +import { UtilsService } from '../../../../core/utils.service'; import { CardStatus } from '../../../shared.types'; import { determineCardStatus } from '../card-status/card-status.component'; @@ -23,7 +23,7 @@ export class CardNumberMetricComponent implements OnInit, OnChanges { @Input() units: string; @Input() value: string; @Input() showUsage = false; - @Input() link: string | Function; + @Input() link: () => void | string; formattedValue: string; formattedLimit: string; diff --git a/src/frontend/packages/core/src/shared/components/cf-auth/cf-auth.service.ts b/src/frontend/packages/core/src/shared/components/cf-auth/cf-auth.service.ts index 39c67ac494..7a7fd8a5f0 100644 --- a/src/frontend/packages/core/src/shared/components/cf-auth/cf-auth.service.ts +++ b/src/frontend/packages/core/src/shared/components/cf-auth/cf-auth.service.ts @@ -1,16 +1,16 @@ - -import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; - -import { take } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { CfAuthPrinciple } from './principal'; -import { CFAuthAction, CFAuthResource, CfAuthUserSummary, CfAuthUserSummaryMapped, CFFeatureFlags } from './cf-auth.types'; -import { IRequestEntityTypeState, AppState } from '../../../../../store/src/app-state'; -import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; -import { SessionData } from '../../../../../store/src/types/auth.types'; -import { endpointEntitiesSelector } from '../../../../../store/src/selectors/endpoint.selectors'; +import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; +import { take } from 'rxjs/operators'; + +import { AppState, IRequestEntityTypeState } from '../../../../../store/src/app-state'; import { selectSessionData } from '../../../../../store/src/reducers/auth.reducer'; +import { endpointEntitiesSelector } from '../../../../../store/src/selectors/endpoint.selectors'; +import { SessionData } from '../../../../../store/src/types/auth.types'; +import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; +import { CFAuthAction, CFAuthResource, CfAuthUserSummary, CfAuthUserSummaryMapped, CFFeatureFlags } from './cf-auth.types'; +import { CfAuthPrinciple } from './principal'; + /** * NOTE - WIP @@ -19,8 +19,7 @@ import { selectSessionData } from '../../../../../store/src/reducers/auth.reduce * - Handling fetch wait and error * - Calculate read-only admin and group auditor values from user scope and intergrate with principals (new, not in V1) * - Determine org or space 'suspended' state and intergrate with principals -*/ - + */ @Injectable() export class CfAuthService { endpoints$: Observable>; @@ -71,8 +70,7 @@ export class CfAuthService { } /** - * @name isAllowed - * @description is user allowed the certain action + * is user allowed the certain action */ isAllowed(endpointGuid: string, resourceType: CFAuthResource, action: CFAuthAction, ...args: any[]): boolean { if (!this.isInitialized(endpointGuid)) { @@ -86,10 +84,9 @@ export class CfAuthService { } /** - * @name isOrgOrSpaceActionableByResource - * @description convenience method to determine if the user has rights to execute the action against the resource + * convenience method to determine if the user has rights to execute the action against the resource * in the organization or any of the organization's spaces - */ + */ isOrgOrSpaceActionableByResource(endpointGuid: string, orgGuid: string, spaceGuids: string[], action: CFAuthAction): boolean { // Is the organization valid? if (this.isAllowed(endpointGuid, CFAuthResource.organization, action, orgGuid)) { @@ -106,8 +103,7 @@ export class CfAuthService { } /** - * @name isAdmin - * @description Is User Admin in endpoint + * Is User Admin in endpoint */ isAdmin(endpointGuid: string): boolean { if (!this.isInitialized(endpointGuid)) { diff --git a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/application-access.ts b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/application-access.ts index 38e794c1a3..073fc5b114 100644 --- a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/application-access.ts +++ b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/application-access.ts @@ -1,6 +1,7 @@ +import { CFAuthChecker, CFAuthResource } from '../cf-auth.types'; import { CfAuthPrinciple } from '../principal'; import { CfAuthBaseAccess } from './base-access'; -import { CFAuthResource, CFAuthChecker } from '../cf-auth.types'; + export class CFAuthCheckerApplication extends CfAuthBaseAccess implements CFAuthChecker { /** @@ -12,12 +13,11 @@ export class CFAuthCheckerApplication extends CfAuthBaseAccess implements CFAuth } /** - * @name create - * @description User can deploy apps if: - * 1. User is an admin - * 2. User is a space developer - * @param {string} spaceGuid GUID of the space where the application resides - */ + * User can deploy apps if: + * 1. User is an admin + * 2. User is a space developer + * @param spaceGuid GUID of the space where the application resides + */ create(spaceGuid: string): boolean { // Admin @@ -30,11 +30,10 @@ export class CFAuthCheckerApplication extends CfAuthBaseAccess implements CFAuth } /** - * @name update - * @description User can manage apps if: + * User can manage apps if: * 1. User is an admin * 2. User is a space developer - * @param {string} spaceGuid GUID of the space where the application resides + * @param spaceGuid GUID of the space where the application resides */ update(spaceGuid: string): boolean { // Admin @@ -47,11 +46,10 @@ export class CFAuthCheckerApplication extends CfAuthBaseAccess implements CFAuth } /** - * @name delete - * @description User can delete apps if: + * User can delete apps if: * 1. User is an admin * 2. User is a space developer - * @param {string} spaceGuid GUID of the space where the application resides + * @param spaceGuid GUID of the space where the application resides */ delete(spaceGuid: string): boolean { // Admin @@ -64,10 +62,8 @@ export class CFAuthCheckerApplication extends CfAuthBaseAccess implements CFAuth } /** - * @name canHandle - * @description Specifies that this ACL checker can handle `application` permission - * @param {String} resource - String representing the resource - * @returns {boolean} + * Specifies that this ACL checker can handle `application` permission + * @param resource - String representing the resource */ canHandle(resource: CFAuthResource): boolean { return resource === CFAuthResource.application; diff --git a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/organization-access.ts b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/organization-access.ts index 9d2f0bb7ba..50231cc678 100644 --- a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/organization-access.ts +++ b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/organization-access.ts @@ -1,6 +1,7 @@ +import { CFAuthChecker, CFAuthResource, CFFeatureFlagTypes } from '../cf-auth.types'; import { CfAuthPrinciple } from '../principal'; import { CfAuthBaseAccess } from './base-access'; -import { CFAuthResource, CFAuthChecker, CFFeatureFlagTypes } from '../cf-auth.types'; + export class CFAuthCheckerOrganization extends CfAuthBaseAccess implements CFAuthChecker { /** @@ -11,11 +12,10 @@ export class CFAuthCheckerOrganization extends CfAuthBaseAccess implements CFAut } /** - * @name create - * @description Users can create an organization if: - * 1. User is and admin - * 2. the `user_org_creation` feature flag is enabled - */ + * Users can create an organization if: + * 1. User is and admin + * 2. the `user_org_creation` feature flag is enabled + */ create(orgGuid: string): boolean { // Admin @@ -28,8 +28,7 @@ export class CFAuthCheckerOrganization extends CfAuthBaseAccess implements CFAut } /** - * @name update - * @description Users can update an organization if: + * Users can update an organization if: * 1. User is and admin * 2. is Org Manager */ @@ -44,7 +43,6 @@ export class CFAuthCheckerOrganization extends CfAuthBaseAccess implements CFAut } /** - * @name delete * @description Users can delete an organization if: * 1. User is and admin * 2. is Org Manager @@ -60,10 +58,8 @@ export class CFAuthCheckerOrganization extends CfAuthBaseAccess implements CFAut } /** - * @name canHandle - * @description Specifies that this ACL checker can handle `application` permission - * @param {String} resource - String representing the resource - * @returns {boolean} + * Specifies that this ACL checker can handle `application` permission + * @param resource - String representing the resource */ canHandle(resource: CFAuthResource): boolean { return resource === CFAuthResource.organization; diff --git a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/route-access.ts b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/route-access.ts index cf5f504ee1..22d4de8403 100644 --- a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/route-access.ts +++ b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/route-access.ts @@ -1,6 +1,7 @@ +import { CFAuthChecker, CFAuthResource, CFFeatureFlagTypes } from '../cf-auth.types'; import { CfAuthPrinciple } from '../principal'; import { CfAuthBaseAccess } from './base-access'; -import { CFAuthResource, CFAuthChecker, CFFeatureFlagTypes } from '../cf-auth.types'; + export class CFAuthCheckerRoute extends CfAuthBaseAccess implements CFAuthChecker { /** @@ -12,11 +13,10 @@ export class CFAuthCheckerRoute extends CfAuthBaseAccess implements CFAuthChecke } /** - * @name create - * @description User can create a route if: - * 1. User is admin - * 2. User is a space developer AND route_creation feature flag is turned on - */ + * User can create a route if: + * 1. User is admin + * 2. User is a space developer AND route_creation feature flag is turned on + */ create(spaceGuid: string): boolean { // Admin @@ -30,8 +30,7 @@ export class CFAuthCheckerRoute extends CfAuthBaseAccess implements CFAuthChecke } /** - * @name update - * @description User can manage apps if: + * User can manage apps if: * 1. User is an admin * 2. User is a space developer */ @@ -45,8 +44,7 @@ export class CFAuthCheckerRoute extends CfAuthBaseAccess implements CFAuthChecke } /** - * @name delete - * @description User can delete apps if: + * User can delete apps if: * 1. User is an admin * 2. User is a space developer */ @@ -60,8 +58,7 @@ export class CFAuthCheckerRoute extends CfAuthBaseAccess implements CFAuthChecke } /** - * @name canHandle - * @description Specifies that this ACL checker can handle `application` permission + * Specifies that this ACL checker can handle `application` permission */ canHandle(resource: CFAuthResource): boolean { return resource === CFAuthResource.route; diff --git a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/service-instance-access.ts b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/service-instance-access.ts index 427b63bd8e..842e6086ac 100644 --- a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/service-instance-access.ts +++ b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/service-instance-access.ts @@ -1,6 +1,7 @@ +import { CFAuthChecker, CFAuthResource, CFFeatureFlagTypes } from '../cf-auth.types'; import { CfAuthPrinciple } from '../principal'; import { CfAuthBaseAccess } from './base-access'; -import { CFAuthResource, CFAuthChecker, CFFeatureFlagTypes } from '../cf-auth.types'; + export class CFAuthCheckerServiceInstance extends CfAuthBaseAccess implements CFAuthChecker { constructor(private principal: CfAuthPrinciple) { @@ -8,11 +9,10 @@ export class CFAuthCheckerServiceInstance extends CfAuthBaseAccess implements CF } /** - * @name create - * @description A User is can create a service if: - * 1. User is an admin - * 2. Is a space developer and the feature flag is enabled - */ + * A User is can create a service if: + * 1. User is an admin + * 2. Is a space developer and the feature flag is enabled + */ create(spaceGuid: string): boolean { // If user is developer in space the service instances will @@ -27,8 +27,7 @@ export class CFAuthCheckerServiceInstance extends CfAuthBaseAccess implements CF } /** - * @name update - * @description User can update a service instance if: + * User can update a service instance if: * 1. User is an admin * 2. or a space developer */ @@ -42,8 +41,7 @@ export class CFAuthCheckerServiceInstance extends CfAuthBaseAccess implements CF } /** - * @name delete - * @description User can delete a service instance if: + * User can delete a service instance if: * 1. They are an admin * 2. or they are a space developer */ @@ -57,8 +55,7 @@ export class CFAuthCheckerServiceInstance extends CfAuthBaseAccess implements CF } /** - * @name canHandle - * @description Specifies that this ACL checker can handle `application` permission + * Specifies that this ACL checker can handle `application` permission */ canHandle(resource: CFAuthResource): boolean { return resource === CFAuthResource.managed_service_instance; diff --git a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/space-access.ts b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/space-access.ts index 6a499e7abf..f1ceea8a6f 100644 --- a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/space-access.ts +++ b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/space-access.ts @@ -1,6 +1,7 @@ +import { CFAuthChecker, CFAuthResource } from '../cf-auth.types'; import { CfAuthPrinciple } from '../principal'; import { CfAuthBaseAccess } from './base-access'; -import { CFAuthResource, CFAuthChecker } from '../cf-auth.types'; + export class CFAuthCheckerSpace extends CfAuthBaseAccess implements CFAuthChecker { constructor(private principal: CfAuthPrinciple) { @@ -8,11 +9,10 @@ export class CFAuthCheckerSpace extends CfAuthBaseAccess implements CFAuthChecke } /** - * @name create - * @description User can create a space if: - * 1. User is an Admin - * 2. User is an Org Manager - */ + * User can create a space if: + * 1. User is an Admin + * 2. User is an Org Manager + */ create(spaceGuid: string): boolean { if (super.baseCreate()) { return true; @@ -22,8 +22,7 @@ export class CFAuthCheckerSpace extends CfAuthBaseAccess implements CFAuthChecke } /** - * @name update - * @description User can update a space if: + * User can update a space if: * 1. User is an admin * 2. User is org manager * 3. user is space manager @@ -39,8 +38,7 @@ export class CFAuthCheckerSpace extends CfAuthBaseAccess implements CFAuthChecke } /** - * @name delete - * @description User can delete space if: + * User can delete space if: * 1. user is an admin * 2. user is the org manager */ @@ -54,8 +52,7 @@ export class CFAuthCheckerSpace extends CfAuthBaseAccess implements CFAuthChecke } /** - * @name canHandle - * @description Specifies that this ACL checker can handle `application` permission + * Specifies that this ACL checker can handle `application` permission */ canHandle(resource: CFAuthResource): boolean { return resource === CFAuthResource.space; diff --git a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/users-assign-access.ts b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/users-assign-access.ts index b8cf3e2d64..306859b618 100644 --- a/src/frontend/packages/core/src/shared/components/cf-auth/checkers/users-assign-access.ts +++ b/src/frontend/packages/core/src/shared/components/cf-auth/checkers/users-assign-access.ts @@ -1,6 +1,7 @@ +import { CFAuthChecker, CFAuthResource } from '../cf-auth.types'; import { CfAuthPrinciple } from '../principal'; import { CfAuthBaseAccess } from './base-access'; -import { CFAuthResource, CFAuthChecker } from '../cf-auth.types'; + export class CFAuthCheckerUser extends CfAuthBaseAccess implements CFAuthChecker { constructor(private principal: CfAuthPrinciple) { @@ -12,11 +13,10 @@ export class CFAuthCheckerUser extends CfAuthBaseAccess implements CFAuthChecker } /** - * @name update - * @description User can update a space if: - * 1. User is an admin - * 2. User is org manager - * 3. user is space manager + * User can update a space if: + * 1. User is an admin + * 2. User is org manager + * 3. user is space manager */ update(spaceGuid: string, orgGuid: string, isSpace: boolean): boolean { // Admin @@ -37,8 +37,7 @@ export class CFAuthCheckerUser extends CfAuthBaseAccess implements CFAuthChecker } /** - * @name canHandle - * @description Specifies that this ACL checker can handle `application` permission + * Specifies that this ACL checker can handle `application` permission */ canHandle(resource: CFAuthResource): boolean { return resource === CFAuthResource.user; diff --git a/src/frontend/packages/core/src/shared/components/cf-auth/principal.ts b/src/frontend/packages/core/src/shared/components/cf-auth/principal.ts index 5361baf987..e1b6e615ef 100644 --- a/src/frontend/packages/core/src/shared/components/cf-auth/principal.ts +++ b/src/frontend/packages/core/src/shared/components/cf-auth/principal.ts @@ -1,11 +1,18 @@ -import { CFAuthCheckerUser } from './checkers/users-assign-access'; -import { CFAuthCheckerSpace } from './checkers/space-access'; -import { CFAuthCheckerServiceInstance } from './checkers/service-instance-access'; -import { CFAuthCheckerRoute } from './checkers/route-access'; -import { CFAuthCheckerOrganization } from './checkers/organization-access'; -import { CFAuthCheckerApplication } from './checkers/application-access'; -import { CfAuthUserSummaryMapped, CFFeatureFlags, CFAuthResource, CFAuthAction, CFAuthChecker, CFFeatureFlagTypes } from './cf-auth.types'; import { SessionData } from '../../../../../store/src/types/auth.types'; +import { + CFAuthAction, + CFAuthChecker, + CFAuthResource, + CfAuthUserSummaryMapped, + CFFeatureFlags, + CFFeatureFlagTypes, +} from './cf-auth.types'; +import { CFAuthCheckerApplication } from './checkers/application-access'; +import { CFAuthCheckerOrganization } from './checkers/organization-access'; +import { CFAuthCheckerRoute } from './checkers/route-access'; +import { CFAuthCheckerServiceInstance } from './checkers/service-instance-access'; +import { CFAuthCheckerSpace } from './checkers/space-access'; +import { CFAuthCheckerUser } from './checkers/users-assign-access'; export class CfAuthPrinciple { @@ -27,17 +34,15 @@ export class CfAuthPrinciple { } /** - * @name hasAccessTo - * @description Does user have access to operation based on feature flags - */ + * Does user have access to operation based on feature flags + */ hasAccessTo(operation: CFFeatureFlagTypes): boolean { return this.isAdmin || this.featureFlags[operation]; } /** - * @name isAllowed - * @description Is user permitted to do the action. - */ + * Is user permitted to do the action. + */ isAllowed(resourceType: CFAuthResource, action: CFAuthAction): boolean { let args = Array.prototype.slice.call(arguments); @@ -51,10 +56,8 @@ export class CfAuthPrinciple { } /** -* @name_createAccessCheckerList -* @description Internal method to create checker list -* @returns {Array} -*/ + * Internal method to create checker list + */ private _createAccessCheckerList(): CFAuthChecker[] { const checkers = []; @@ -69,9 +72,8 @@ export class CfAuthPrinciple { } /** -* @name _getAccessChecker -* @description Get Access checker for a given resource type -*/ + * Get Access checker for a given resource type + */ private getAccessChecker(resourceType: CFAuthResource): CFAuthChecker { if (!this.checkers || this.checkers.length === 0) { diff --git a/src/frontend/packages/core/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts b/src/frontend/packages/core/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts index 9edcab4ef0..16abd48e02 100644 --- a/src/frontend/packages/core/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts +++ b/src/frontend/packages/core/src/shared/components/cf-role-checkbox/cf-role-checkbox.component.ts @@ -3,21 +3,21 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, Subscription } from 'rxjs'; import { combineLatest, filter, first } from 'rxjs/operators'; -import { CurrentUserPermissions } from '../../../core/current-user-permissions.config'; -import { CurrentUserPermissionsService } from '../../../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 { CfUserRolesSelected } from '../../../../../store/src/types/users-roles.types'; +import { UsersRolesSetOrgRole, UsersRolesSetSpaceRole } from '../../../../../store/src/actions/users-roles.actions'; +import { AppState } from '../../../../../store/src/app-state'; +import { selectUsersRolesPicked } from '../../../../../store/src/selectors/users-roles.selector'; import { - IUserPermissionInOrg, CfUser, + IUserPermissionInOrg, IUserPermissionInSpace, + OrgUserRoleNames, SpaceUserRoleNames, - OrgUserRoleNames } from '../../../../../store/src/types/user.types'; -import { AppState } from '../../../../../store/src/app-state'; -import { selectUsersRolesPicked } from '../../../../../store/src/selectors/users-roles.selector'; -import { UsersRolesSetOrgRole, UsersRolesSetSpaceRole } from '../../../../../store/src/actions/users-roles.actions'; +import { CfUserRolesSelected } from '../../../../../store/src/types/users-roles.types'; +import { CurrentUserPermissions } from '../../../core/current-user-permissions.config'; +import { CurrentUserPermissionsService } from '../../../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'; /** * Component to manage the display and change of a specific org or space role. Will be checked if all users have role or user has selected @@ -25,9 +25,6 @@ import { UsersRolesSetOrgRole, UsersRolesSetSpaceRole } from '../../../../../sto * Special rules apply to an org user role. If there are any other roles set this will be disabled. * * @export - * @class CfRoleCheckboxComponent - * @implements {OnInit} - * @implements {OnDestroy} */ @Component({ selector: 'app-cf-role-checkbox', @@ -42,7 +39,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { @Input() role: string; @Output() changed = new BehaviorSubject(false); - checked: Boolean = false; + checked = false; tooltip = ''; sub: Subscription; isOrgRole = false; @@ -56,7 +53,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { return false; } - private static hasRole(role: string, orgRoles: IUserPermissionInOrg, spaceGuid: string): Boolean { + private static hasRole(role: string, orgRoles: IUserPermissionInOrg, spaceGuid: string): boolean { if (!orgRoles) { return undefined; } @@ -81,7 +78,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { newRoles: IUserPermissionInOrg, orgGuid: string, spaceGuid?: string): { - checked: Boolean; + checked: boolean; tooltip: string; } { let tooltip = ''; @@ -102,8 +99,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { let oneWithout = false; tooltip = ''; // Loop through users, determine who hasn't got the role and if there are any that don't - for (let i = 0; i < users.length; i++) { - const user = users[i]; + for (const user of users) { if (CfRoleCheckboxComponent.hasExistingRole(role, existingRoles, user.guid, orgGuid, spaceGuid)) { tooltip += `${user.username}, `; } else { @@ -140,8 +136,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { checkedSpaces: Set ): boolean { const spaceGuids = Object.keys(spaces || {}); - for (let y = 0; y < spaceGuids.length; y++) { - const spaceGuid = spaceGuids[y]; + for (const spaceGuid of spaceGuids) { if (checkedSpaces.has(spaceGuid)) { continue; } @@ -185,8 +180,8 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { // .. second check existing space roles const existingUserGuids = Object.keys(existingRoles); - for (let x = 0; x < existingUserGuids.length; x++) { - const orgs = existingRoles[existingUserGuids[x]]; + for (const existingUserGuid of existingUserGuids) { + const orgs = existingRoles[existingUserGuid]; const org = orgs[orgGuid]; if (!org) { continue; @@ -202,17 +197,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { * Determine if the checkbox should be disabled. This is only relevant to the Org User role which should be disabled if there are any * existing or new org or space roles set * - * @private - * @static - * @param {boolean} isOrgRole - * @param {string} role - * @param {CfUser[]} users - * @param {CfUserRolesSelected} existingRoles - * @param {IUserPermissionInOrg} newRoles - * @param {string} orgGuid - * @param {Boolean} checked - * @returns {boolean} True if the checkbox should be disabled - * @memberof CfRoleCheckboxComponent + * @returns True if the checkbox should be disabled */ private static isDisabled( isOrgRole: boolean, @@ -221,7 +206,7 @@ export class CfRoleCheckboxComponent implements OnInit, OnDestroy { existingRoles: CfUserRolesSelected, newRoles: IUserPermissionInOrg, orgGuid: string, - checked: Boolean): boolean { + checked: boolean): boolean { if (isOrgRole && role === OrgUserRoleNames.USER) { // Never disable the org user checkbox if it's not enabled/semi enabled (covers odd cases when cf creates orgs/spaces without the // permissions) diff --git a/src/frontend/packages/core/src/shared/components/code-block/code-block.component.html b/src/frontend/packages/core/src/shared/components/code-block/code-block.component.html index fde26a299f..683df4faf7 100644 --- a/src/frontend/packages/core/src/shared/components/code-block/code-block.component.html +++ b/src/frontend/packages/core/src/shared/components/code-block/code-block.component.html @@ -1,10 +1,10 @@ -
+
-
-
+
+
Copied to clipboard check_circle
- content_copy -
+ content_copy +
\ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/code-block/code-block.component.ts b/src/frontend/packages/core/src/shared/components/code-block/code-block.component.ts index 3c7417d38f..28bab818f6 100644 --- a/src/frontend/packages/core/src/shared/components/code-block/code-block.component.ts +++ b/src/frontend/packages/core/src/shared/components/code-block/code-block.component.ts @@ -1,6 +1,7 @@ -import { LoggerService } from '../../../core/logger.service'; -import { Component, OnInit, Input, Inject, ElementRef, ViewChild } from '@angular/core'; import { DOCUMENT } from '@angular/common'; +import { Component, ElementRef, Inject, Input, OnInit, ViewChild } from '@angular/core'; + +import { LoggerService } from '../../../core/logger.service'; @Component({ selector: 'app-code-block', @@ -8,30 +9,30 @@ import { DOCUMENT } from '@angular/common'; styleUrls: ['./code-block.component.scss'] }) export class CodeBlockComponent implements OnInit { - private _document: Document; + private document: Document; constructor(@Inject(DOCUMENT) document: Document, private logService: LoggerService) { - this._document = document; + this.document = document; } @Input() hideCopy: boolean; @Input() codeBlockStyle: string; - _canCopy = false; - _copySuccessfull = false; - _copySuccessWait = false; + canCopy = false; + copySuccessful = false; + copySuccessWait = false; @ViewChild('preBlock') code: ElementRef; ngOnInit() { try { - this._canCopy = this._document.queryCommandSupported('copy'); + this.canCopy = this.document.queryCommandSupported('copy'); } finally { } } copyToClipboard() { - const textArea = this._document.createElement('textarea'); + const textArea = this.document.createElement('textarea'); textArea.style.position = 'fixed'; textArea.style.top = '0'; @@ -51,14 +52,14 @@ export class CodeBlockComponent implements OnInit { textArea.select(); try { - this._copySuccessfull = document.execCommand('copy'); - this._copySuccessWait = true; - setTimeout(() => this._copySuccessWait = false, 2000); + this.copySuccessful = document.execCommand('copy'); + this.copySuccessWait = true; + setTimeout(() => this.copySuccessWait = false, 2000); } catch (err) { this.logService.warn('Failed to copy to clipboard'); } - this._document.body.removeChild(textArea); + this.document.body.removeChild(textArea); } } diff --git a/src/frontend/packages/core/src/shared/components/confirmation-dialog.service.ts b/src/frontend/packages/core/src/shared/components/confirmation-dialog.service.ts index 49d34f1717..2349286e86 100644 --- a/src/frontend/packages/core/src/shared/components/confirmation-dialog.service.ts +++ b/src/frontend/packages/core/src/shared/components/confirmation-dialog.service.ts @@ -1,9 +1,10 @@ - -import {take} from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material'; -import { DialogConfirmComponent } from './dialog-confirm/dialog-confirm.component'; +import { take } from 'rxjs/operators'; + import { ConfirmationDialogConfig } from './confirmation-dialog.config'; +import { DialogConfirmComponent } from './dialog-confirm/dialog-confirm.component'; + @Injectable() @@ -11,7 +12,7 @@ export class ConfirmationDialogService { constructor(private dialog: MatDialog) { } - open(dialog: ConfirmationDialogConfig, doFn: Function): void { + open(dialog: ConfirmationDialogConfig, doFn: (res?: any) => void): void { const dialogRef = this.dialog.open(DialogConfirmComponent, { maxWidth: '400px', diff --git a/src/frontend/packages/core/src/shared/components/endpoints-missing/endpoints-missing.component.ts b/src/frontend/packages/core/src/shared/components/endpoints-missing/endpoints-missing.component.ts index 7c7d12f857..cb294f9019 100644 --- a/src/frontend/packages/core/src/shared/components/endpoints-missing/endpoints-missing.component.ts +++ b/src/frontend/packages/core/src/shared/components/endpoints-missing/endpoints-missing.component.ts @@ -3,7 +3,6 @@ import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { delay, map, startWith, tap } from 'rxjs/operators'; -import { UserService } from '../../../core/user.service'; import { EndpointsService } from '../../../core/endpoints.service'; @Component({ @@ -36,7 +35,7 @@ export class EndpointsMissingComponent implements AfterViewInit, OnDestroy, OnIn }, }; - private _snackBar: MatSnackBarRef; + private snackBarRef: MatSnackBarRef; constructor(private snackBar: MatSnackBar, public endpointsService: EndpointsService) { } ngOnInit() { @@ -69,10 +68,10 @@ export class EndpointsMissingComponent implements AfterViewInit, OnDestroy, OnIn } private showSnackBar(show: boolean) { - if (!this._snackBar && show) { - this._snackBar = this.snackBar.open(this.snackBarText.message, this.snackBarText.action, {}); - } else if (this._snackBar && !show) { - this._snackBar.dismiss(); + if (!this.snackBarRef && show) { + this.snackBarRef = this.snackBar.open(this.snackBarText.message, this.snackBarText.action, {}); + } else if (this.snackBarRef && !show) { + this.snackBarRef.dismiss(); } } diff --git a/src/frontend/packages/core/src/shared/components/enumerate/enumerate.component.html b/src/frontend/packages/core/src/shared/components/enumerate/enumerate.component.html index 266f02340f..9a5bd2308a 100644 --- a/src/frontend/packages/core/src/shared/components/enumerate/enumerate.component.html +++ b/src/frontend/packages/core/src/shared/components/enumerate/enumerate.component.html @@ -1,10 +1,10 @@ -
-
- - {{labelPath ? item[labelPath] : item}}, +
+
+ + {{labelPath ? item[labelPath] : item}},
None
-
+ \ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/enumerate/enumerate.component.ts b/src/frontend/packages/core/src/shared/components/enumerate/enumerate.component.ts index 80b52e40a8..9da8e03036 100644 --- a/src/frontend/packages/core/src/shared/components/enumerate/enumerate.component.ts +++ b/src/frontend/packages/core/src/shared/components/enumerate/enumerate.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { Observable } from 'rxjs'; @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 35aefa482b..c4d0c092f4 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 @@ -15,9 +15,9 @@ export class FavoritesEntityListComponent implements AfterViewInit { @Input() set entities(favoriteEntities: IFavoriteEntity[]) { - this._entities = favoriteEntities ? [...favoriteEntities] : favoriteEntities; + this.pEntities = favoriteEntities ? [...favoriteEntities] : favoriteEntities; this.entitiesSubject.next(favoriteEntities); - this.hasEntities = this._entities && this._entities.length > 0; + this.hasEntities = this.pEntities && this.pEntities.length > 0; } @Input() public placeholder = false; @@ -60,7 +60,7 @@ export class FavoritesEntityListComponent implements AfterViewInit { public filterName: string; public filterType: string; - public _entities: IFavoriteEntity[] = []; + public pEntities: IFavoriteEntity[] = []; public limitedEntities: IFavoriteEntity[]; public minLimit = 3; 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 4f83150622..699b3a26bb 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 @@ -9,6 +9,7 @@ import { fetchingFavoritesSelector, } from '../../../../../store/src/selectors/favorite-groups.selectors'; import { IFavoriteEntity, IGroupedFavorites, UserFavoriteManager } from '../../../core/user-favorite-manager'; +import { LoggerService } from '../../../core/logger.service'; interface IFavoritesInfo { @@ -24,10 +25,10 @@ interface IFavoritesInfo { export class FavoritesGlobalListComponent implements OnInit { public favInfo$: Observable; public favoriteGroups$: Observable; - constructor(private store: Store) { } + constructor(private store: Store, private logger: LoggerService) { } ngOnInit() { - const manager = new UserFavoriteManager(this.store); + const manager = new UserFavoriteManager(this.store, this.logger); this.favoriteGroups$ = manager.hydrateAllFavorites().pipe( map(favs => this.sortFavoriteGroups(favs)) ); diff --git a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorite-config-mapper.ts b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorite-config-mapper.ts index 352fe38b8b..70d0478d97 100644 --- a/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorite-config-mapper.ts +++ b/src/frontend/packages/core/src/shared/components/favorites-meta-card/favorite-config-mapper.ts @@ -78,7 +78,6 @@ class FavoritesConfigMapper { } /** * For a given favorite, return the corresponding favorite meta card mapper - * @param favorite */ public getMapperFunction(favorite: IFavoriteTypeInfo) { const mapperKey = this.getMapperKeyFromFavoriteInfo(favorite); @@ -86,9 +85,8 @@ class FavoritesConfigMapper { } /** - * For a given favorite, return the corresponding human readable type name - * @param favorite - */ + * For a given favorite, return the corresponding human readable type name + */ public getPrettyTypeName(favorite: IFavoriteTypeInfo) { const mapperKey = this.getMapperKeyFromFavoriteInfo(favorite); return this.mappers[mapperKey] ? this.mappers[mapperKey].prettyName : null; @@ -96,7 +94,6 @@ class FavoritesConfigMapper { /** * For a given favorite, return the corresponding hydration action - * @param favorite */ public getActionFromFavorite(favorite: UserFavorite) { const mapperKey = this.getMapperKeyFromFavoriteInfo(favorite); @@ -105,7 +102,6 @@ class FavoritesConfigMapper { /** * For a given favorite, return the corresponding hydration action - * @param favorite */ public getEntityMetadata(favorite: IFavoriteTypeInfo, entity: T) { const mapperKey = this.getMapperKeyFromFavoriteInfo(favorite); @@ -114,7 +110,6 @@ class FavoritesConfigMapper { /** * For a given endpoint type, return the list of possible favorite types - * @param favorite */ public getAllTypesForEndpoint(endpointType: string): IFavoriteTypes[] { return Object.values(this.mappers).reduce((types: IFavoriteTypes[], mapper) => { diff --git a/src/frontend/packages/core/src/shared/components/file-input/file-input.component.ts b/src/frontend/packages/core/src/shared/components/file-input/file-input.component.ts index 8b481f387e..42c4e1587d 100644 --- a/src/frontend/packages/core/src/shared/components/file-input/file-input.component.ts +++ b/src/frontend/packages/core/src/shared/components/file-input/file-input.component.ts @@ -1,4 +1,15 @@ -import { Component, ElementRef, EventEmitter, Input, Output, ViewChild, OnInit, Optional, Host, SkipSelf } from '@angular/core'; +import { + Component, + ElementRef, + EventEmitter, + Host, + Input, + OnInit, + Optional, + Output, + SkipSelf, + ViewChild, +} from '@angular/core'; import { ControlContainer, FormGroupName } from '@angular/forms'; @Component({ @@ -13,7 +24,7 @@ export class FileInputComponent implements OnInit { @Output() onFileSelect: EventEmitter = new EventEmitter(); @Input() fileFormControlName; - private _files: File[]; + private files: File[]; public name = ''; @@ -21,27 +32,27 @@ export class FileInputComponent implements OnInit { constructor( @Optional() @Host() @SkipSelf() private parent: ControlContainer, - ) {} + ) { } ngOnInit(): void { - if (this.parent instanceof FormGroupName) { - this.formGroupControl = this.parent as FormGroupName; - } + if (this.parent instanceof FormGroupName) { + this.formGroupControl = this.parent as FormGroupName; + } } - get fileCount(): number { return this._files && this._files.length || 0; } + get fileCount(): number { return this.files && this.files.length || 0; } onNativeInputFileSelect($event) { - const _files = $event.srcElement.files; - if (_files.length > 0) { - this._files = _files; - this.onFileSelect.emit(this._files[0]); + const fs = $event.srcElement.files; + if (fs.length > 0) { + this.files = fs; + this.onFileSelect.emit(this.files[0]); if (!!this.formGroupControl) { - this.handleFormControl(this._files[0]); + this.handleFormControl(this.files[0]); } - if (this._files.length > 0) { - this.name = this._files[0].name; + if (this.files.length > 0) { + this.name = this.files[0].name; } } } diff --git a/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source-types.ts b/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source-types.ts index a06113839c..acea04c74f 100644 --- a/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source-types.ts +++ b/src/frontend/packages/core/src/shared/components/list/data-sources-controllers/list-data-source-types.ts @@ -1,10 +1,11 @@ import { DataSource } from '@angular/cdk/table'; import { Action } from '@ngrx/store'; import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs'; -import { IRequestEntityTypeState } from '../../../../../../store/src/app-state'; -import { PaginationEntityState, PaginatedAction, PaginationParam } from '../../../../../../store/src/types/pagination.types'; -import { MetricsAction } from '../../../../../../store/src/actions/metrics.actions'; + import { ListFilter, ListSort } from '../../../../../../store/src/actions/list.actions'; +import { MetricsAction } from '../../../../../../store/src/actions/metrics.actions'; +import { IRequestEntityTypeState } from '../../../../../../store/src/app-state'; +import { PaginatedAction, PaginationEntityState, PaginationParam } from '../../../../../../store/src/types/pagination.types'; export interface AppEvent { actee_name: string; @@ -13,7 +14,7 @@ export interface AppEvent { actor_name: string; actor_type: string; actor_username: string; - metadata: Object; + metadata: object; organization_guid: string; space_guid: string; timestamp: string; 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 d9d5c191ad..15b06f9108 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 @@ -39,7 +39,7 @@ export class DataFunctionDefinition { field: string; static is(obj) { if (obj) { - const typed = obj; + const typed = obj as DataFunctionDefinition; return typed.type && typed.orderKey && typed.field; } return false; diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/card/card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/card/card.component.ts index 4d2071fa2a..de0f98d1ab 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/card/card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/card/card.component.ts @@ -12,26 +12,26 @@ import { } from '@angular/core'; import { IListDataSource } from '../../data-sources-controllers/list-data-source-types'; - -import { CardCell } from '../../list.types'; +import { + AppServiceBindingCardComponent, +} from '../../list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component'; import { CardAppComponent } from '../../list-types/app/card/card-app.component'; -import { EndpointCardComponent } from '../../list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component'; -import { CfOrgCardComponent } from '../../list-types/cf-orgs/cf-org-card/cf-org-card.component'; -import { CfSpaceCardComponent } from '../../list-types/cf-spaces/cf-space-card/cf-space-card.component'; import { CfBuildpackCardComponent } from '../../list-types/cf-buildpacks/cf-buildpack-card/cf-buildpack-card.component'; +import { CfOrgCardComponent } from '../../list-types/cf-orgs/cf-org-card/cf-org-card.component'; import { - CfSecurityGroupsCardComponent + CfSecurityGroupsCardComponent, } from '../../list-types/cf-security-groups/cf-security-groups-card/cf-security-groups-card.component'; -import { CfStacksCardComponent } from '../../list-types/cf-stacks/cf-stacks-card/cf-stacks-card.component'; import { CfServiceCardComponent } from '../../list-types/cf-services/cf-service-card/cf-service-card.component'; +import { CfSpaceCardComponent } from '../../list-types/cf-spaces/cf-space-card/cf-space-card.component'; +import { CfStacksCardComponent } from '../../list-types/cf-stacks/cf-stacks-card/cf-stacks-card.component'; +import { EndpointCardComponent } from '../../list-types/endpoint/endpoint-card/endpoint-card.component'; import { - AppServiceBindingCardComponent -} from '../../list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component'; -import { ServiceInstanceCardComponent } from '../../list-types/services-wall/service-instance-card/service-instance-card.component'; + ServiceInstanceCardComponent, +} from '../../list-types/services-wall/service-instance-card/service-instance-card.component'; +import { CardCell } from '../../list.types'; export const listCards = [ CardAppComponent, - EndpointCardComponent, CfOrgCardComponent, CfSpaceCardComponent, CfBuildpackCardComponent, @@ -39,7 +39,8 @@ export const listCards = [ CfStacksCardComponent, CfServiceCardComponent, AppServiceBindingCardComponent, - ServiceInstanceCardComponent + ServiceInstanceCardComponent, + EndpointCardComponent ]; @Component({ selector: 'app-card', @@ -68,7 +69,7 @@ export class CardComponent implements OnInit, OnChanges { const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.component); // Add to target to ensure ngcontent is correct in new component const componentRef = this.target.createComponent(componentFactory); - this.cardComponent = >componentRef.instance; + this.cardComponent = componentRef.instance as CardCell; this.cardComponent.row = this.item; this.cardComponent.dataSource = this.dataSource; } diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/cards.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/cards.component.ts index 113607027f..1ea537a0f2 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/cards.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/cards.component.ts @@ -11,11 +11,12 @@ import { CardCell } from '../list.types'; export class CardsComponent { public columns = CardCell.columns; @Input() dataSource: IListDataSource; - private _component: CardCell; + private pComponent: CardCell; @Input() - get component() { return this._component; } + get component() { return this.pComponent; } set component(cardCell) { - this._component = cardCell; + this.pComponent = cardCell; + /* tslint:disable-next-line:no-string-literal */ this.columns = cardCell['columns']; } } diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.html b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.html index 1573840d12..573d962427 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.html +++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-base/meta-card.component.html @@ -19,13 +19,12 @@ -
+
- +
- + \ No newline at end of file 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 a37275c7a0..ec19984bbe 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 @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, ContentChild, OnInit, TemplateRef, ViewChild, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ContentChild, Input, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { MetaCardKeyComponent } from '../meta-card-key/meta-card-key.component'; import { MetaCardValueComponent } from '../meta-card-value/meta-card-value.component'; @@ -12,9 +12,9 @@ import { MetaCardValueComponent } from '../meta-card-value/meta-card-value.compo export class MetaCardItemComponent implements OnInit { styles = { - 'row': 'meta-card-item-row', + row: 'meta-card-item-row', 'row-top': 'meta-card-item-row-top', - 'column': 'meta-card-item-column', + column: 'meta-card-item-column', 'long-text': 'meta-card-item-long-text', 'long-text-fixed': 'meta-card-item-long-text-fixed', }; @@ -29,9 +29,6 @@ export class MetaCardItemComponent implements OnInit { @Input() customStyle = 'row'; - constructor() { - } - ngOnInit() { this.itemStyle = this.styles[this.customStyle]; } diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/app-table-cell-default/app-table-cell-default.component.ts b/src/frontend/packages/core/src/shared/components/list/list-table/app-table-cell-default/app-table-cell-default.component.ts index 0430bb7a21..a0912122fc 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/app-table-cell-default/app-table-cell-default.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/app-table-cell-default/app-table-cell-default.component.ts @@ -1,9 +1,9 @@ import { Component, Input, OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs'; +import { objectHelper } from '../../../../../core/helper-classes/object.helpers'; import { pathGet } from '../../../../../core/utils.service'; import { TableCellCustom } from '../../list.types'; -import { objectHelper } from '../../../../../core/helper-classes/object.helpers'; import { ICellDefinition } from '../table.types'; @Component({ @@ -16,11 +16,11 @@ export class TableCellDefaultComponent extends TableCellCustom implements public cellDefinition: ICellDefinition; - private _row: T; + private pRow: T; @Input('row') - get row() { return this._row; } + get row() { return this.pRow; } set row(row: T) { - this._row = row; + this.pRow = row; if (row) { this.setValue(row); } diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-actions/table-cell-actions.component.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-actions/table-cell-actions.component.ts index 79506b8fb3..858dba6ce4 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-actions/table-cell-actions.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-actions/table-cell-actions.component.ts @@ -1,13 +1,13 @@ - -import { of as observableOf, Observable, combineLatest, BehaviorSubject } from 'rxjs'; import { Component, Input, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; +import { BehaviorSubject, combineLatest, Observable, of as observableOf } from 'rxjs'; import { map } from 'rxjs/operators'; +import { AppState } from '../../../../../../../store/src/app-state'; import { RowState } from '../../data-sources-controllers/list-data-source-types'; import { IListAction, ListConfig } from '../../list.component.types'; import { TableCellCustom } from '../../list.types'; -import { AppState } from '../../../../../../../store/src/app-state'; + @Component({ selector: 'app-table-cell-actions', @@ -19,11 +19,11 @@ export class TableCellActionsComponent extends TableCellCustom implements @Input() rowState: Observable; - private _row: T; + private pRow: T; @Input('row') - get row() { return this._row; } + get row() { return this.pRow; } set row(row: T) { - this._row = row; + this.pRow = row; if (row) { this.initialise(row); } diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-boolean-indicator/table-cell-boolean-indicator.component.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-boolean-indicator/table-cell-boolean-indicator.component.ts index a65e9912c9..151b9620c4 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-boolean-indicator/table-cell-boolean-indicator.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-boolean-indicator/table-cell-boolean-indicator.component.ts @@ -16,21 +16,21 @@ export interface TableCellBooleanIndicatorComponentConfig { }) export class TableCellBooleanIndicatorComponent extends TableCellCustom { - private _row: T; + private pRow: T; @Input('row') - get row() { return this._row; } + get row() { return this.pRow; } set row(row: T) { - this._row = row; + this.pRow = row; if (this.config) { this.enabled = this.config.isEnabled(row); } } - private _config: TableCellBooleanIndicatorComponentConfig; + private pConfig: TableCellBooleanIndicatorComponentConfig; @Input('config') - get config() { return this._config; } + get config() { return this.pConfig; } set config(config: TableCellBooleanIndicatorComponentConfig) { - this._config = config; + this.pConfig = config; if (!config) { return; } 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 7fc04d2031..6d802e6c27 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 @@ -19,19 +19,19 @@ export class TableCellFavoriteComponent extends public favorite: UserFavorite; public canFavorite = false; - private _config: TableCellFavoriteComponentConfig; + private pC: TableCellFavoriteComponentConfig; @Input('config') - get config() { return this._config; } + get config() { return this.pC; } set config(config: TableCellFavoriteComponentConfig) { - this._config = config; + this.pC = config; this.createUserFavorite(); } - private _row: T; + private pRow: T; @Input('row') - get row() { return this._row; } + get row() { return this.pRow; } set row(row: T) { - this._row = row; + this.pRow = row; this.createUserFavorite(); } diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-radio/table-cell-radio.component.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-radio/table-cell-radio.component.ts index 664c74eb2c..96bcc53cde 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-radio/table-cell-radio.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell-radio/table-cell-radio.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { TableCellCustom } from '../../list.types'; @@ -10,11 +10,11 @@ import { TableCellCustom } from '../../list.types'; export class TableCellRadioComponent extends TableCellCustom implements OnInit { disable: boolean; - private _row: T; + private r: T; @Input('row') - get row() { return this._row; } + get row() { return this.r; } set row(row: T) { - this._row = row; + this.r = row; if (row) { this.updateDisabled(); } 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 5adb3debd4..2e0a6232bb 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 @@ -13,6 +13,7 @@ import { ViewEncapsulation, } from '@angular/core'; +import { coreEndpointListDetailsComponents } from '../../../../../features/endpoints/endpoint-helpers'; import { IListDataSource } from '../../data-sources-controllers/list-data-source-types'; import { TableCellEventActionComponent, @@ -84,8 +85,8 @@ import { CfSpacePermissionCellComponent, } from '../../list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component'; import { - TableCellEndpointIsAdminComponent, -} from '../../list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component'; + TableCellEndpointDetailsComponent, +} from '../../list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component'; import { TableCellEndpointNameComponent, } from '../../list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component'; @@ -118,7 +119,6 @@ import { TableCellSelectComponent } from '../table-cell-select/table-cell-select import { TableHeaderSelectComponent } from '../table-header-select/table-header-select.component'; import { ICellDefinition } from '../table.types'; - /* tslint:enable:max-line-length */ export const listTableCells = [ TableCellDefaultComponent, @@ -160,11 +160,12 @@ export const listTableCells = [ TableCellSpaceNameComponent, TableCellAppCfOrgSpaceHeaderComponent, TableCellAppCfOrgSpaceComponent, - TableCellEndpointIsAdminComponent, TableCellAServicePlanPublicComponent, TableCellAServicePlanPriceComponent, TableCellAServicePlanExtrasComponent, - TableCellFavoriteComponent + TableCellFavoriteComponent, + TableCellEndpointDetailsComponent, + ...coreEndpointListDetailsComponents ]; @Component({ @@ -215,7 +216,7 @@ export class TableCellComponent implements OnInit, OnChanges { if (component) { // Add to target to ensure ngcontent is correct in new component - this.cellComponent = >component.instance; + this.cellComponent = component.instance as TableCellCustom; this.cellComponent.row = this.row; this.cellComponent.dataSource = this.dataSource; diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-row/table-row-state-manager.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-row/table-row-state-manager.spec.ts index 60983b91ed..871d5896ef 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table-row/table-row-state-manager.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-row/table-row-state-manager.spec.ts @@ -11,7 +11,7 @@ describe('TableRowStateManager', () => { let obs: Observable; const checkState = (manager: TableRowStateManager, actualState: RowState, expectedState: RowState) => { const fake = { - 'FAKE': { + FAKE: { error: false } }; @@ -167,11 +167,11 @@ describe('TableRowStateManager', () => { it('should set the row state', async((done) => { const initState = { - '1': { + 1: { error: true, customProp: 'custom' }, - '2': { + 2: { error: false, blocked: true } @@ -182,12 +182,12 @@ describe('TableRowStateManager', () => { cusrtomProp2: 'test123' }; const expectedState = { - '1': { + 1: { error: false, blocked: true, cusrtomProp2: 'test123' }, - '2': { + 2: { error: false, blocked: true } diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-row/table-row-state-manager.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-row/table-row-state-manager.ts index 06d5fe1366..5dda3e4188 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table-row/table-row-state-manager.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-row/table-row-state-manager.ts @@ -1,6 +1,7 @@ -import { Subject, ReplaySubject } from 'rxjs'; -import { RowState, RowsState } from '../../data-sources-controllers/list-data-source-types'; -import { debounceTime } from 'rxjs/operators'; +import { ReplaySubject } from 'rxjs'; + +import { RowsState, RowState } from '../../data-sources-controllers/list-data-source-types'; + /** * A manager that helps manage list table row state. */ @@ -8,7 +9,7 @@ export class TableRowStateManager { private stateSubject: ReplaySubject; get rowState(): RowState { - return this._rowState; + return this.rs; } /** @@ -22,17 +23,17 @@ export class TableRowStateManager { private mergeRowState(id: string, state) { const mergeIdState = { - ...(this._rowState[id] || {}), + ...(this.rs[id] || {}), ...state }; - this._rowState[id] = mergeIdState; + this.rs[id] = mergeIdState; } /** * Set the state of a row and triggers the observable to emit the state. * This method will replace the row state with the provided values. */ setRowState(id: string, state: RowState) { - this._rowState[id] = state; + this.rs[id] = state; this.syncObservableState(); } @@ -41,7 +42,7 @@ export class TableRowStateManager { * This method will replace the whole state with provided values. */ setState(state: RowsState) { - this._rowState = state; + this.rs = state; this.syncObservableState(); } @@ -57,7 +58,7 @@ export class TableRowStateManager { } private syncObservableState() { - this.stateSubject.next(this._rowState); + this.stateSubject.next(this.rs); } /** * The observable that will emit the state. @@ -67,9 +68,9 @@ export class TableRowStateManager { } /** - * @param _rowState: Initial state. + * @param rs: Initial state. */ - constructor(private _rowState: RowsState = {}) { + constructor(private rs: RowsState = {}) { this.stateSubject = new ReplaySubject(1); this.syncObservableState(); } diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table.component.spec.ts index 99cba6a18c..f7e0e181d0 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table.component.spec.ts @@ -2,15 +2,15 @@ import { CdkTableModule } from '@angular/cdk/table'; import { Component, ViewChild } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { empty, of as observableOf } from 'rxjs'; +import { EMPTY, of as observableOf } from 'rxjs'; +import { ListSort } from '../../../../../../store/src/actions/list.actions'; +import { createBasicStoreModule } from '../../../../../test-framework/store-test-helper'; import { CoreModule } from '../../../../core/core.module'; import { UtilsService } from '../../../../core/utils.service'; -import { createBasicStoreModule } from '../../../../../test-framework/store-test-helper'; import { SharedModule } from '../../../shared.module'; import { IListPaginationController } from '../data-sources-controllers/list-pagination-controller'; import { TableComponent } from './table.component'; -import { ListSort } from '../../../../../../store/src/actions/list.actions'; describe('TableComponent', () => { @@ -80,7 +80,7 @@ describe('TableComponent', () => { } as IListPaginationController; public dataSource = { trackBy: () => '1', - connect: () => empty(), + connect: () => EMPTY, disconnect: () => null, isTableLoading$: observableOf(false) }; diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table.types.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table.types.ts index 7c3d49c504..9b67e6d6e6 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-table/table.types.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-table/table.types.ts @@ -57,5 +57,5 @@ export const listTableComponents = [ TableRowComponent, TableCellDefaultComponent, ...listTableCells, - TableCellStatusDirective, + TableCellStatusDirective ]; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/app-event/cf-app-events-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/app-event/cf-app-events-data-source.ts index 57be88b199..e8b39c951c 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/app-event/cf-app-events-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/app-event/cf-app-events-data-source.ts @@ -1,12 +1,12 @@ import { Store } from '@ngrx/store'; -import { ListDataSource } from '../../data-sources-controllers/list-data-source'; -import { EntityInfo } from '../../../../../../../store/src/types/api.types'; -import { PaginationEntityState, QParam } from '../../../../../../../store/src/types/pagination.types'; +import { GetAllAppEvents } from '../../../../../../../store/src/actions/app-event.actions'; import { AddParams, RemoveParams } from '../../../../../../../store/src/actions/pagination.actions'; import { AppState } from '../../../../../../../store/src/app-state'; -import { GetAllAppEvents } from '../../../../../../../store/src/actions/app-event.actions'; -import { entityFactory, appEventSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; +import { appEventSchemaKey, entityFactory } from '../../../../../../../store/src/helpers/entity-factory'; +import { EntityInfo } from '../../../../../../../store/src/types/api.types'; +import { PaginationEntityState, QParam } from '../../../../../../../store/src/types/pagination.types'; +import { ListDataSource } from '../../data-sources-controllers/list-data-source'; export class CfAppEventsDataSource extends ListDataSource { @@ -33,11 +33,11 @@ export class CfAppEventsDataSource extends ListDataSource { constructor( store: Store, - _cfGuid: string, - _appGuid: string, + cfGuid: string, + appGuid: string, ) { - const paginationKey = `app-events:${_cfGuid}${_appGuid}`; - const action = new GetAllAppEvents(paginationKey, _appGuid, _cfGuid); + const paginationKey = `app-events:${cfGuid}${appGuid}`; + const action = new GetAllAppEvents(paginationKey, appGuid, cfGuid); super( { diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/app-instance/cf-app-instances-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/app-instance/cf-app-instances-data-source.ts index cfd44661dc..60fb9203d3 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/app-instance/cf-app-instances-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/app-instance/cf-app-instances-data-source.ts @@ -1,26 +1,32 @@ import { Store } from '@ngrx/store'; import { map } from 'rxjs/operators'; +import { GetAppStatsAction } from '../../../../../../../store/src/actions/app-metadata.actions'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { + applicationSchemaKey, + appStatsSchemaKey, + entityFactory, +} from '../../../../../../../store/src/helpers/entity-factory'; +import { + createEntityRelationPaginationKey, +} from '../../../../../../../store/src/helpers/entity-relations/entity-relations.types'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; +import { AppStat } from '../../../../../../../store/src/types/app-metadata.types'; import { ListDataSource } from '../../data-sources-controllers/list-data-source'; import { IListConfig } from '../../list.component.types'; import { ListAppInstance, ListAppInstanceUsage } from './app-instance-types'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; -import { AppStat } from '../../../../../../../store/src/types/app-metadata.types'; -import { AppState } from '../../../../../../../store/src/app-state'; -import { createEntityRelationPaginationKey } from '../../../../../../../store/src/helpers/entity-relations/entity-relations.types'; -import { applicationSchemaKey, entityFactory, appStatsSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; -import { GetAppStatsAction } from '../../../../../../../store/src/actions/app-metadata.actions'; export class CfAppInstancesDataSource extends ListDataSource> { constructor( store: Store, - _cfGuid: string, - _appGuid: string, + cfGuid: string, + appGuid: string, listConfig: IListConfig ) { - const paginationKey = createEntityRelationPaginationKey(applicationSchemaKey, _appGuid); - const action = new GetAppStatsAction(_appGuid, _cfGuid); + const paginationKey = createEntityRelationPaginationKey(applicationSchemaKey, appGuid); + const action = new GetAppStatsAction(appGuid, cfGuid); super( { diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/app-route/cf-app-routes-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/app-route/cf-app-routes-data-source.ts index fed33909b9..a7287c107c 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/app-route/cf-app-routes-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/app-route/cf-app-routes-data-source.ts @@ -1,21 +1,20 @@ import { Store } from '@ngrx/store'; -import { IRoute } from '../../../../../core/cf-api.types'; -import { ApplicationService } from '../../../../../features/applications/application.service'; -import { IListConfig } from '../../list.component.types'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; import { AppState } from '../../../../../../../store/src/app-state'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; import { PaginatedAction } from '../../../../../../../store/src/types/pagination.types'; +import { IRoute } from '../../../../../core/cf-api.types'; +import { ApplicationService } from '../../../../../features/applications/application.service'; import { IListDataSource } from '../../data-sources-controllers/list-data-source-types'; +import { IListConfig } from '../../list.component.types'; import { CfRoutesDataSourceBase } from '../cf-routes/cf-routes-data-source-base'; export class CfAppRoutesDataSource extends CfRoutesDataSourceBase implements IListDataSource> { /** * Creates an instance of CfAppRoutesDataSource. - * @param {boolean} [genericRouteState] + * @param [genericRouteState] * Use the generic route state which enables the route busy ux - * @memberof CfAppRoutesDataSource */ constructor( store: Store, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts b/src/frontend/packages/core/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts index ed53d1dd87..04aac93878 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/app-route/cf-app-routes-list-config-base.ts @@ -3,17 +3,17 @@ import { Store } from '@ngrx/store'; import { of as observableOf } from 'rxjs'; import { publishReplay, refCount, switchMap } from 'rxjs/operators'; +import { GetAppRoutes } from '../../../../../../../store/src/actions/application-service-routes.actions'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; +import { PaginatedAction } from '../../../../../../../store/src/types/pagination.types'; import { CurrentUserPermissions } from '../../../../../core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; import { ApplicationService } from '../../../../../features/applications/application.service'; import { ConfirmationDialogService } from '../../../confirmation-dialog.service'; import { IListConfig } from '../../list.component.types'; -import { CfAppRoutesDataSource } from './cf-app-routes-data-source'; import { CfRoutesListConfigBase } from '../cf-routes/cf-routes-list-config-base'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../../store/src/app-state'; -import { GetAppRoutes } from '../../../../../../../store/src/actions/application-service-routes.actions'; -import { PaginatedAction } from '../../../../../../../store/src/types/pagination.types'; +import { CfAppRoutesDataSource } from './cf-app-routes-data-source'; export abstract class CfAppRoutesListConfigServiceBase extends CfRoutesListConfigBase implements IListConfig { @@ -23,12 +23,11 @@ export abstract class CfAppRoutesListConfigServiceBase extends CfRoutesListConfi protected dataSource: CfAppRoutesDataSource; /** - *Creates an instance of CfAppRoutesListConfigServiceBase. - * @param {boolean} [hasActions=false] + * Creates an instance of CfAppRoutesListConfigServiceBase. + * @param [hasActions=false] * Display the generic unmap/delete actions - * @param {boolean} [genericRouteState=true] + * @param [genericRouteState=true] * Use the generic route state which enables the route busy ux - * @memberof CfAppRoutesListConfigServiceBase */ constructor( store: Store, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts index c9c67e3b7d..4650e998fb 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component.ts @@ -4,26 +4,26 @@ import { MatDialog } from '@angular/material'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { filter, first, map, switchMap } from 'rxjs/operators'; +import { GetServiceInstance } from '../../../../../../../../store/src/actions/service-instances.actions'; +import { + entityFactory, + serviceBindingSchemaKey, + serviceInstancesSchemaKey, +} from '../../../../../../../../store/src/helpers/entity-factory'; +import { APIResource, EntityInfo } from '../../../../../../../../store/src/types/api.types'; +import { AppEnvVarsState } from '../../../../../../../../store/src/types/app-metadata.types'; import { IService, IServiceBinding, IServiceInstance } from '../../../../../../core/cf-api-svc.types'; import { CurrentUserPermissions } from '../../../../../../core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../core/current-user-permissions.service'; import { EntityServiceFactory } from '../../../../../../core/entity-service-factory.service'; import { ApplicationService } from '../../../../../../features/applications/application.service'; +import { getCfService } from '../../../../../../features/service-catalog/services-helper'; import { ServiceActionHelperService } from '../../../../../data-services/service-action-helper.service'; import { ComponentEntityMonitorConfig } from '../../../../../shared.types'; import { AppChip } from '../../../../chips/chips.component'; import { EnvVarViewComponent } from '../../../../env-var-view/env-var-view.component'; import { MetaCardMenuItem } from '../../../list-cards/meta-card/meta-card-base/meta-card.component'; import { CardCell, IListRowCell, IListRowCellData } from '../../../list.types'; -import { APIResource, EntityInfo } from '../../../../../../../../store/src/types/api.types'; -import { - entityFactory, - serviceBindingSchemaKey, - serviceInstancesSchemaKey, -} from '../../../../../../../../store/src/helpers/entity-factory'; -import { GetServiceInstance } from '../../../../../../../../store/src/actions/service-instances.actions'; -import { AppEnvVarsState } from '../../../../../../../../store/src/types/app-metadata.types'; -import { getCfService } from '../../../../../../features/service-catalog/services-helper'; @@ -125,10 +125,10 @@ export class AppServiceBindingCardComponent extends CardCell>).entity.entity.label; - if (systemEnvJson['VCAP_SERVICES'][serviceLabel]) { + if (systemEnvJson.VCAP_SERVICES[serviceLabel]) { return { key: serviceInstanceName, - value: systemEnvJson['VCAP_SERVICES'][serviceLabel].find(s => s.name === serviceInstanceName) + value: systemEnvJson.VCAP_SERVICES[serviceLabel].find(s => s.name === serviceInstanceName) }; } return null; @@ -155,7 +155,7 @@ export class AppServiceBindingCardComponent extends CardCell this.serviceActionHelperService.editServiceBinding( this.row.entity.service_instance_guid, this.appService.cfGuid, - { 'appId': this.appService.appGuid } + { appId: this.appService.appGuid } ) } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/app-variables/cf-app-variables-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/app-variables/cf-app-variables-data-source.ts index beda79fc1e..edbde87fa9 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/app-variables/cf-app-variables-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/app-variables/cf-app-variables-data-source.ts @@ -1,17 +1,22 @@ import { Store } from '@ngrx/store'; import { map } from 'rxjs/operators'; +import { GetAppEnvVarsAction } from '../../../../../../../store/src/actions/app-metadata.actions'; +import { AppVariablesAdd, AppVariablesEdit } from '../../../../../../../store/src/actions/app-variables.actions'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { + appEnvVarsSchemaKey, + applicationSchemaKey, + entityFactory, +} from '../../../../../../../store/src/helpers/entity-factory'; +import { + createEntityRelationPaginationKey, +} from '../../../../../../../store/src/helpers/entity-relations/entity-relations.types'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; +import { AppEnvVarsState } from '../../../../../../../store/src/types/app-metadata.types'; import { ApplicationService } from '../../../../../features/applications/application.service'; - import { ListDataSource } from '../../data-sources-controllers/list-data-source'; import { IListConfig } from '../../list.component.types'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; -import { AppEnvVarsState } from '../../../../../../../store/src/types/app-metadata.types'; -import { AppState } from '../../../../../../../store/src/app-state'; -import { GetAppEnvVarsAction } from '../../../../../../../store/src/actions/app-metadata.actions'; -import { entityFactory, appEnvVarsSchemaKey, applicationSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; -import { createEntityRelationPaginationKey } from '../../../../../../../store/src/helpers/entity-relations/entity-relations.types'; -import { AppVariablesAdd, AppVariablesEdit } from '../../../../../../../store/src/actions/app-variables.actions'; export interface ListAppEnvVar { name: string; @@ -25,16 +30,16 @@ export class CfAppVariablesDataSource extends ListDataSource, - _appService: ApplicationService, + appService: ApplicationService, listConfig: IListConfig ) { super({ store, - action: new GetAppEnvVarsAction(_appService.appGuid, _appService.cfGuid), + action: new GetAppEnvVarsAction(appService.appGuid, appService.cfGuid), schema: entityFactory(appEnvVarsSchemaKey), getRowUniqueId: object => object.name, getEmptyType: () => ({ name: '', value: '', }), - paginationKey: createEntityRelationPaginationKey(applicationSchemaKey, _appService.appGuid), + paginationKey: createEntityRelationPaginationKey(applicationSchemaKey, appService.appGuid), transformEntity: map(variables => { if (!variables || variables.length === 0) { return []; @@ -48,8 +53,8 @@ export class CfAppVariablesDataSource extends ListDataSource { getRowUniqueId: getRowMetadata, paginationKey, isLocal: true, - transformEntities: transformEntities, + transformEntities, listConfig, destroy: () => this.subs.forEach(sub => sub.unsubscribe()) }); diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/base-endpoints-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/base-endpoints-data-source.ts index c6827dcb8f..3925a7cd75 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/base-endpoints-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/base-endpoints-data-source.ts @@ -1,12 +1,13 @@ import { Store } from '@ngrx/store'; -import { AppState } from '../../../../../../../store/src/app-state'; + import { GetAllEndpoints } from '../../../../../../../store/src/actions/endpoint.actions'; import { CreatePagination } from '../../../../../../../store/src/actions/pagination.actions'; -import { ListDataSource } from '../../data-sources-controllers/list-data-source'; +import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { endpointSchemaKey, entityFactory } from '../../../../../../../store/src/helpers/entity-factory'; import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; +import { ListDataSource } from '../../data-sources-controllers/list-data-source'; import { IListConfig } from '../../list.component.types'; -import { entityFactory, endpointSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; -import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions'; function syncPaginationSection( @@ -22,6 +23,7 @@ function syncPaginationSection( } export class BaseEndpointsDataSource extends ListDataSource { store: Store; + endpointType: string; constructor( store: Store, @@ -54,5 +56,6 @@ export class BaseEndpointsDataSource extends ListDataSource { listConfig, refresh: () => this.store.dispatch(new GetSystemInfo(false, action)) }); + this.endpointType = endpointType; } } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.html deleted file mode 100644 index 6b87693173..0000000000 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.html +++ /dev/null @@ -1,17 +0,0 @@ - - {{ row.name }} - - Address - {{ getEndpointUrl(row) }} - - - Account Username - {{ row.user.name }} - - - Administrator - - - - - \ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.scss deleted file mode 100644 index ce7d1d2449..0000000000 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.scss +++ /dev/null @@ -1,6 +0,0 @@ -.endpoint-card { - cursor: pointer; - &:focus { - outline: 0; - } -} diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.spec.ts deleted file mode 100644 index 3b7851addf..0000000000 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { SharedModule } from '../../../../../shared.module'; -import { EntityMonitorFactory } from '../../../../../monitors/entity-monitor.factory.service'; -import { createBasicStoreModule } from '../../../../../../../test-framework/store-test-helper'; -import { BaseTestModules } from '../../../../../../../test-framework/cloud-foundry-endpoint-service.helper'; -import { ServiceActionHelperService } from '../../../../../data-services/service-action-helper.service'; -import { EndpointCardComponent } from './endpoint-card.component'; - -describe('EndpointCardComponent', () => { - let component: EndpointCardComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - createBasicStoreModule(), - SharedModule, - RouterTestingModule, - BaseTestModules, - ], - providers: [ - EntityMonitorFactory, - ServiceActionHelperService - ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(EndpointCardComponent); - component = fixture.componentInstance; - component.row = { - name: 'test', - user: { - admin: false, - name: '', - guid: '', - }, - metricsAvailable: false, - system_shared_token: false, - sso_allowed: false, - }; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.ts deleted file mode 100644 index e227b35d2a..0000000000 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; -import { ReplaySubject } from 'rxjs'; - -import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; -import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types'; -import { getFavoriteFromEndpointEntity } from '../../../../../../core/user-favorite-helpers'; -import { getEndpointTypes, getFullEndpointApiUrl } from '../../../../../../features/endpoints/endpoint-helpers'; -import { CardStatus } from '../../../../../shared.types'; -import { CardCell } from '../../../list.types'; - - -@Component({ - selector: 'app-endpoint-card', - templateUrl: './endpoint-card.component.html', - styleUrls: ['./endpoint-card.component.scss'] -}) -export class EndpointCardComponent extends CardCell implements OnInit, OnChanges { - - static columns = 2; - - public status$ = new ReplaySubject(); - - @Input() - public row: EndpointModel; - public favorite: UserFavoriteEndpoint; - - constructor() { - super(); - } - - ngOnInit() { - this.favorite = getFavoriteFromEndpointEntity(this.row); - this.status$.next(this.mapStatus(this.row)); - } - - ngOnChanges(changes: SimpleChanges) { - const row = changes['row'].currentValue; - this.status$.next(this.mapStatus(row)); - } - - public getEndpointUrl(row: EndpointModel) { - return getFullEndpointApiUrl(row); - } - - public getRouterPath(row: EndpointModel) { - const ext = getEndpointTypes().find(ep => ep.value === row.cnsi_type); - if (ext && ext.homeLink) { - return ext.homeLink(row.guid); - } - return ''; - } - - private mapStatus(endpoint: EndpointModel) { - const connectionStatus = endpoint ? endpoint.connectionStatus : ''; - switch (connectionStatus) { - case 'connected': - return CardStatus.OK; - case 'disconnected': - return CardStatus.INCOMPLETE; - default: - return CardStatus.TENTATIVE; - } - } - -} diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service.ts index 71caa96f1b..3289f66c4c 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service.ts @@ -1,18 +1,14 @@ - -import { pairwise } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; import { ITableColumn } from '../../list-table/table.types'; import { IListConfig, ListViewTypes } from '../../list.component.types'; +import { EndpointCardComponent } from '../endpoint/endpoint-card/endpoint-card.component'; import { endpointColumns } from '../endpoint/endpoints-list-config.service'; -import { EndpointModel, endpointStoreNames } from '../../../../../../../store/src/types/endpoint.types'; -import { selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors'; -import { AppState } from '../../../../../../../store/src/app-state'; -import { - BaseEndpointsDataSource -} from './base-endpoints-data-source'; -import { EndpointCardComponent } from './cf-endpoint-card/endpoint-card.component'; +import { BaseEndpointsDataSource } from './base-endpoints-data-source'; + @Injectable() export class CFEndpointsListConfigService implements IListConfig { @@ -29,21 +25,6 @@ export class CFEndpointsListConfigService implements IListConfig enableTextFilter = true; tableFixedRowHeight = true; - private handleAction(item, effectKey, handleChange) { - const disSub = this.store.select(selectUpdateInfo( - endpointStoreNames.type, - item.guid, - effectKey, - )).pipe( - pairwise()) - .subscribe(([oldVal, newVal]) => { - if (!newVal.error && (oldVal.busy && !newVal.busy)) { - handleChange([oldVal, newVal]); - disSub.unsubscribe(); - } - }); - } - constructor( private store: Store ) { diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-routes/cf-routes-data-source-base.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-routes/cf-routes-data-source-base.ts index db02c4a4c3..d759103da0 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-routes/cf-routes-data-source-base.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-routes/cf-routes-data-source-base.ts @@ -2,6 +2,10 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, Subscription } from 'rxjs'; import { map, switchMap, tap } from 'rxjs/operators'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { entityFactory, routeSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; +import { PaginatedAction, PaginationParam } from '../../../../../../../store/src/types/pagination.types'; import { IRoute } from '../../../../../core/cf-api.types'; import { safeUnsubscribe } from '../../../../../core/utils.service'; import { getRoute, isTCPRoute } from '../../../../../features/applications/routes/routes.helper'; @@ -13,10 +17,6 @@ import { ListDataSource } from '../../data-sources-controllers/list-data-source' import { ListPaginationMultiFilterChange, RowsState } from '../../data-sources-controllers/list-data-source-types'; import { TableRowStateManager } from '../../list-table/table-row/table-row-state-manager'; import { IListConfig } from '../../list.component.types'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../../store/src/app-state'; -import { PaginatedAction, PaginationParam } from '../../../../../../../store/src/types/pagination.types'; -import { entityFactory, routeSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; export interface ListCfRoute extends IRoute { url: string; @@ -25,18 +25,21 @@ export interface ListCfRoute extends IRoute { mappedAppsCountLabel?: string; } +function isListCfRoute(anything: any): boolean { + return !!anything.url && !!anything.isTCPRoute; +} + export abstract class CfRoutesDataSourceBase extends ListDataSource, APIResource> { cfGuid: string; appGuid: string; /** - *Creates an instance of CfRoutesDataSourceBase. - * @param {string} [appGuid] + * Creates an instance of CfRoutesDataSourceBase. + * @param [appGuid] * Are the routes specific to a single app? - * @param {boolean} [genericRouteState=true] + * @param [genericRouteState=true] * Use the generic route state which enables the route busy ux - * @memberof CfRoutesDataSourceBase */ constructor( store: Store, @@ -66,7 +69,7 @@ export abstract class CfRoutesDataSourceBase extends ListDataSource { - if (route.entity['url'] && route.entity['isTCPRoute']) { + if (isListCfRoute(route.entity)) { return route as APIResource; } const entity: ListCfRoute = { @@ -100,13 +103,6 @@ export abstract class CfRoutesDataSourceBase extends ListDataSource, sub: Subscription }} - * @memberof CfRoutesDataSourceBase */ private static createRowState(store, paginationKey, genericRouteState: boolean): { rowsState: Observable, sub: Subscription } { if (genericRouteState) { @@ -157,7 +153,7 @@ export abstract class CfRoutesDataSourceBase extends ListDataSource { - const unmapping = request.updating['unmapping'] || { busy: false }; + const unmapping = request.updating.unmapping || { busy: false }; const busy = unmapping.busy; rowStateManager.setRowState(route.metadata.guid, { deleting: request.deleting.busy, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-routes/cf-routes-list-config-base.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-routes/cf-routes-list-config-base.ts index db55b12f9b..1688cb5618 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-routes/cf-routes-list-config-base.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-routes/cf-routes-list-config-base.ts @@ -3,6 +3,9 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { DeleteRoute, UnmapRoute } from '../../../../../../../store/src/actions/route.actions'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; import { ConfirmationDialogConfig } from '../../../confirmation-dialog.config'; import { ConfirmationDialogService } from '../../../confirmation-dialog.service'; import { ITableColumn, ITableText } from '../../list-table/table.types'; @@ -20,9 +23,6 @@ import { import { TableCellRouteComponent } from '../cf-routes/table-cell-route/table-cell-route.component'; import { TableCellTCPRouteComponent } from '../cf-routes/table-cell-tcproute/table-cell-tcproute.component'; import { CfRoutesDataSourceBase, ListCfRoute } from './cf-routes-data-source-base'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; -import { DeleteRoute, UnmapRoute } from '../../../../../../../store/src/actions/route.actions'; -import { AppState } from '../../../../../../../store/src/app-state'; export abstract class CfRoutesListConfigBase implements IListConfig { @@ -204,13 +204,12 @@ export abstract class CfRoutesListConfigBase implements IListConfig getMultiFiltersConfigs = () => []; /** - *Creates an instance of CfRoutesListConfigBase. + * Creates an instance of CfRoutesListConfigBase. * @param isLocal Is the list all local or paginated via the cf api * @param [hasActions=true] Should actions such as unmap and delete be shown - * @param {(route: Observable>) => Observable} [canEditRoute] User can edit route? - * @param {Observable} [canEditSpace$] User can edit space? + * @param [canEditRoute] User can edit route? + * @param [canEditSpace$] User can edit space? * @param [removeEntityOnUnmap=false] On unmap remove the entity from the list - * @memberof CfRoutesListConfigBase */ constructor( private store: Store, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-select-users/cf-select-users-data-source.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-select-users/cf-select-users-data-source.service.ts index 2d20ab33b9..adf6c0e06e 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-select-users/cf-select-users-data-source.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-select-users/cf-select-users-data-source.service.ts @@ -11,11 +11,11 @@ import { entityFactory, cfUserSchemaKey } from '../../../../../../../store/src/h export class CfSelectUsersDataSourceService extends ListDataSource { constructor(cfGuid: string, - store: Store, - getAllUsersAction: PaginatedAction, - listConfig: IListConfig, - rowStateManager: TableRowStateManager, - destroy: () => void + store: Store, + getAllUsersAction: PaginatedAction, + listConfig: IListConfig, + rowStateManager: TableRowStateManager, + destroy: () => void ) { super({ store, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-services/cf-services-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-services/cf-services-data-source.ts index 2bd4b8b6bc..02a1a4b574 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-services/cf-services-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-services/cf-services-data-source.ts @@ -1,14 +1,16 @@ import { Store } from '@ngrx/store'; -import { getRowMetadata } from '../../../../../features/cloud-foundry/cf.helpers'; -import { ListDataSource } from '../../data-sources-controllers/list-data-source'; -import { IListConfig } from '../../list.component.types'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; +import { GetAllServices } from '../../../../../../../store/src/actions/service.actions'; import { AppState } from '../../../../../../../store/src/app-state'; -import { createEntityRelationPaginationKey } from '../../../../../../../store/src/helpers/entity-relations/entity-relations.types'; import { endpointSchemaKey, entityFactory, serviceSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; -import { GetAllServices } from '../../../../../../../store/src/actions/service.actions'; +import { + createEntityRelationPaginationKey, +} from '../../../../../../../store/src/helpers/entity-relations/entity-relations.types'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; import { PaginationEntityState } from '../../../../../../../store/src/types/pagination.types'; +import { getRowMetadata } from '../../../../../features/cloud-foundry/cf.helpers'; +import { ListDataSource } from '../../data-sources-controllers/list-data-source'; +import { IListConfig } from '../../list.component.types'; export class CfServicesDataSource extends ListDataSource { constructor(store: Store, endpointGuid: string, listConfig?: IListConfig) { @@ -27,7 +29,7 @@ export class CfServicesDataSource extends ListDataSource { field: 'entity.label' }, (entities: APIResource[], paginationState: PaginationEntityState) => { - const cfGuid = paginationState.clientPagination.filter.items['cf']; + const cfGuid = paginationState.clientPagination.filter.items.cf; return entities.filter(e => { const validCF = !(cfGuid && cfGuid !== e.entity.cfGuid); return validCF; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-space-routes/cf-space-route-row-state.helper.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-space-routes/cf-space-route-row-state.helper.ts index 31393e29e7..d8b2c88007 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-space-routes/cf-space-route-row-state.helper.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-space-routes/cf-space-route-row-state.helper.ts @@ -2,12 +2,12 @@ import { Store } from '@ngrx/store'; import { combineLatest } from 'rxjs'; import { map, switchMap, tap } from 'rxjs/operators'; -import { EntityMonitor } from '../../../../monitors/entity-monitor'; -import { PaginationMonitor } from '../../../../monitors/pagination-monitor'; -import { TableRowStateManager } from '../../list-table/table-row/table-row-state-manager'; import { AppState } from '../../../../../../../store/src/app-state'; import { entityFactory, routeSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; import { APIResource } from '../../../../../../../store/src/types/api.types'; +import { EntityMonitor } from '../../../../monitors/entity-monitor'; +import { PaginationMonitor } from '../../../../monitors/pagination-monitor'; +import { TableRowStateManager } from '../../list-table/table-row/table-row-state-manager'; export class SpaceRouteDataSourceHelper { static getRowStateManager( @@ -43,7 +43,7 @@ export class SpaceRouteDataSourceHelper { const entityMonitor = new EntityMonitor(store, route.metadata.guid, routeSchemaKey, entityFactory(routeSchemaKey)); const request$ = entityMonitor.entityRequest$.pipe( tap(request => { - const unmapping = request.updating['unmapping'] || { busy: false }; + const unmapping = request.updating.unmapping || { busy: false }; const busy = unmapping.busy; rowStateManager.setRowState(route.metadata.guid, { deleting: request.deleting.busy, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts index ef542afd7f..92dee8b9ce 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-spaces-service-instances/cf-spaces-service-instances-list-config.service.ts @@ -2,23 +2,21 @@ import { DatePipe } from '@angular/common'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; import { IServiceInstance } from '../../../../../core/cf-api-svc.types'; +import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; import { CloudFoundrySpaceService } from '../../../../../features/cloud-foundry/services/cloud-foundry-space.service'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; import { IListConfig } from '../../list.component.types'; import { CfServiceInstancesListConfigBase } from '../cf-services/cf-service-instances-list-config.base'; import { CfSpacesServiceInstancesDataSource } from './cf-spaces-service-instances-data-source'; -import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../../store/src/app-state'; /** * Service instance list shown for `cf / org / space / service instances` tab * * @export - * @class CfSpacesServiceInstancesListConfigService * @extends {CfServiceInstancesListConfigBase} - * @implements {IListConfig>} */ @Injectable() export class CfSpacesServiceInstancesListConfigService extends CfServiceInstancesListConfigBase diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-spaces-service-instances/table-cell-space-name/table-cell-space-name.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-spaces-service-instances/table-cell-space-name/table-cell-space-name.component.ts index 06e9a4f36d..e90a8a642b 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-spaces-service-instances/table-cell-space-name/table-cell-space-name.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-spaces-service-instances/table-cell-space-name/table-cell-space-name.component.ts @@ -29,6 +29,6 @@ export class TableCellSpaceNameComponent extends TableCellCustom { }, }]; - constructor(private store: Store, private activeRouteCfOrgSpace: ActiveRouteCfOrgSpace) { + constructor(private store: Store, activeRouteCfOrgSpace: ActiveRouteCfOrgSpace) { super(); this.dataSource = new CfStacksDataSource(this.store, activeRouteCfOrgSpace.cfGuid, this); } diff --git a/src/frontend/packages/core/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/core/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts index b6fa0bc506..79267921e0 100644 --- a/src/frontend/packages/core/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/core/src/shared/components/list/list-types/cf-users-org-space-roles/table-cell-select-org/table-cell-select-org.component.ts @@ -1,16 +1,16 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; -import { Observable, of as observableOf, Subscription } from 'rxjs'; +import { Observable, Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { UsersRolesSetOrg } from '../../../../../../../../store/src/actions/users-roles.actions'; +import { AppState } from '../../../../../../../../store/src/app-state'; +import { selectUsersRolesOrgGuid } from '../../../../../../../../store/src/selectors/users-roles.selector'; +import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { IOrganization } from '../../../../../../core/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 { TableCellCustom } from '../../../list.types'; -import { map } from 'rxjs/operators'; -import { APIResource } from '../../../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../../../store/src/app-state'; -import { selectUsersRolesOrgGuid } from '../../../../../../../../store/src/selectors/users-roles.selector'; -import { UsersRolesSetOrg } from '../../../../../../../../store/src/actions/users-roles.actions'; @Component({ selector: 'app-table-cell-select-org', @@ -20,8 +20,8 @@ import { UsersRolesSetOrg } from '../../../../../../../../store/src/actions/user export class TableCellSelectOrgComponent extends TableCellCustom> implements OnInit, OnDestroy { /** - * Observable which is populated if only a single org is to be used - */ + * Observable which is populated if only a single org is to be used + */ singleOrg$: Observable>; organizations$: Observable[]>; selectedOrgGuid: string; diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts index d320fc4ab9..29d396880a 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component.ts @@ -41,7 +41,9 @@ export class CfSpacePermissionCellComponent extends CfPermissionCell[]> = this.config$.pipe(switchMap(config => config.spaces$)); + const spaces$: Observable[]> = this.config$.pipe( + switchMap(config => config.spaces$ as Observable[]>) + ); const isOrgLevel$: Observable = this.config$.pipe(map(config => config.isOrgLevel)); this.chipsConfig$ = combineLatest( this.rowSubject.asObservable(), diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts index 032c857fe4..d21be9f163 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-users/cf-user-list-config.service.ts @@ -204,8 +204,6 @@ export class CfUserListConfigService extends ListConfig> { /** * Assign the org and/or spaces obs to the cell configs. These will be used to determine which org or space roles to show * - * @private - * @memberof CfUserListConfigService */ private assignColumnConfig = ( org$?: Observable>>, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.html new file mode 100644 index 0000000000..fba8e0bb1e --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.html @@ -0,0 +1,29 @@ + + +
+
+ +
+
+ {{ row?.name }} +
{{endpointConfig.label}}
+
+
+
+ + Status + + + + + + Address + {{ address }} + + + Details + +
+
+
+
\ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.scss new file mode 100644 index 0000000000..d9f81e670f --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.scss @@ -0,0 +1,31 @@ +.endpoint-card { + cursor: pointer; + &.no-link { + cursor: default; + } + &:focus { + outline: 0; + } + + &__image { + height: 48px; + margin-right: 10px; + + &--img { + height: 100%; + width: auto; + } + } + + &__title { + display: flex; + &__text { + display: flex; + flex-direction: column; + &--subtext { + font-size: 13px; + opacity: .6; + } + } + } +} diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.spec.ts new file mode 100644 index 0000000000..4fd4b60e59 --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.spec.ts @@ -0,0 +1,33 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { BaseTestModules } from '../../../../../../../test-framework/cloud-foundry-endpoint-service.helper'; +import { EndpointListHelper } from '../endpoint-list.helpers'; +import { EndpointCardComponent } from './endpoint-card.component'; + +describe('EndpointCardComponent', () => { + let component: EndpointCardComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [], + imports: [...BaseTestModules], + providers: [EndpointListHelper] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EndpointCardComponent); + component = fixture.componentInstance; + component.row = { + cnsi_type: 'metrics', + } as EndpointModel; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); 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 new file mode 100644 index 0000000000..44961170ae --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts @@ -0,0 +1,125 @@ +import { + Component, + ComponentFactoryResolver, + ComponentRef, + Input, + OnDestroy, + OnInit, + ViewChild, + ViewContainerRef, +} from '@angular/core'; +import { ReplaySubject } from 'rxjs'; + +import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types'; +import { EndpointsService } from '../../../../../../core/endpoints.service'; +import { EndpointTypeConfig } from '../../../../../../core/extension/extension-types'; +import { getFavoriteFromEndpointEntity } from '../../../../../../core/user-favorite-helpers'; +import { + coreEndpointListDetailsComponents, + getEndpointType, + getFullEndpointApiUrl, +} from '../../../../../../features/endpoints/endpoint-helpers'; +import { MetaCardMenuItem } from '../../../list-cards/meta-card/meta-card-base/meta-card.component'; +import { CardCell } from '../../../list.types'; +import { BaseEndpointsDataSource } from '../../cf-endpoints/base-endpoints-data-source'; +import { EndpointListDetailsComponent, EndpointListHelper } from '../endpoint-list.helpers'; + +@Component({ + selector: 'app-endpoint-card', + templateUrl: './endpoint-card.component.html', + styleUrls: ['./endpoint-card.component.scss'], + entryComponents: [...coreEndpointListDetailsComponents] +}) +export class EndpointCardComponent extends CardCell implements OnInit, OnDestroy { + + public rowObs = new ReplaySubject(); + public favorite: UserFavoriteEndpoint; + public address: string; + public cardMenu: MetaCardMenuItem[]; + public endpointConfig: EndpointTypeConfig; + public hasDetails = true; + public endpointLink: string = null; + + private componentRef: ComponentRef; + + @Input() component: EndpointListDetailsComponent; + private endpointDetails: ViewContainerRef; + @ViewChild('endpointDetails', { read: ViewContainerRef }) set content(content: ViewContainerRef) { + this.endpointDetails = content; + this.updateDetails(); + } + + private pRow: EndpointModel; + @Input('row') + set row(row: EndpointModel) { + if (!row) { + return; + } + this.pRow = row; + this.endpointConfig = getEndpointType(row.cnsi_type); + this.address = getFullEndpointApiUrl(row); + this.rowObs.next(row); + this.endpointLink = row.connectionStatus === 'connected' ? EndpointsService.getLinkForEndpoint(row) : null; + this.updateDetails(); + + } + get row(): EndpointModel { + return this.pRow; + } + + @Input('dataSource') + set dataSource(ds: BaseEndpointsDataSource) { + if (ds && ds.endpointType !== 'cf' && !this.cardMenu) { + this.cardMenu = this.endpointListHelper.endpointActions().map(endpointAction => ({ + label: endpointAction.label, + action: () => endpointAction.action(this.pRow), + can: endpointAction.createVisible(this.rowObs) + })); + } + } + + constructor( + private endpointListHelper: EndpointListHelper, + private componentFactoryResolver: ComponentFactoryResolver + ) { + super(); + } + + ngOnInit() { + this.favorite = this.pRow.cnsi_type === 'cf' ? getFavoriteFromEndpointEntity(this.row) : null; + const e = getEndpointType(this.pRow.cnsi_type); + this.hasDetails = !!e.listDetailsComponent; + } + + ngOnDestroy(): void { + this.endpointListHelper.destroyEndpointDetails({ + componentRef: this.componentRef, + component: this.component, + endpointDetails: this.endpointDetails + }); + } + + updateDetails() { + if (!this.endpointDetails || !this.pRow) { + return; + } + const e = getEndpointType(this.pRow.cnsi_type); + if (!e.listDetailsComponent) { + return; + } + + if (!this.component) { + const res = + this.endpointListHelper.createEndpointDetails(e.listDetailsComponent, this.endpointDetails, this.componentFactoryResolver); + this.componentRef = res.componentRef; + this.component = res.component; + } + + if (this.component) { + this.component.row = this.pRow; + this.component.isTable = false; + } + } + +} 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 new file mode 100644 index 0000000000..a2e5ce482f --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts @@ -0,0 +1,172 @@ +import { ComponentFactoryResolver, ComponentRef, Injectable, ViewContainerRef } from '@angular/core'; +import { MatDialog } from '@angular/material'; +import { Store } from '@ngrx/store'; +import { combineLatest, Observable } from 'rxjs'; +import { map, pairwise } from 'rxjs/operators'; + +import { DisconnectEndpoint, UnregisterEndpoint } from '../../../../../../../store/src/actions/endpoint.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 { EndpointsEffect } from '../../../../../../../store/src/effects/endpoint.effects'; +import { selectDeletionInfo, selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors'; +import { EndpointModel, endpointStoreNames } from '../../../../../../../store/src/types/endpoint.types'; +import { CurrentUserPermissions } from '../../../../../core/current-user-permissions.config'; +import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; +import { LoggerService } from '../../../../../core/logger.service'; +import { + ConnectEndpointDialogComponent, +} from '../../../../../features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component'; +import { ConfirmationDialogConfig } from '../../../confirmation-dialog.config'; +import { ConfirmationDialogService } from '../../../confirmation-dialog.service'; +import { IListAction } from '../../list.component.types'; +import { TableCellCustom } from '../../list.types'; + +interface EndpointDetailsContainerRefs { + componentRef: ComponentRef; + component: EndpointListDetailsComponent; + endpointDetails: ViewContainerRef; +} + +export abstract class EndpointListDetailsComponent extends TableCellCustom { + isEndpointListDetailsComponent = true; + isTable = true; +} + +function isEndpointListDetailsComponent(obj: any): EndpointListDetailsComponent { + return obj ? obj.isEndpointListDetailsComponent ? obj as EndpointListDetailsComponent : null : null; +} + +@Injectable() +export class EndpointListHelper { + + constructor( + private store: Store, + private dialog: MatDialog, + private currentUserPermissionsService: CurrentUserPermissionsService, + private confirmDialog: ConfirmationDialogService, + private log: LoggerService) { + + } + + endpointActions(): IListAction[] { + return [ + { + action: (item) => { + const confirmation = new ConfirmationDialogConfig( + 'Disconnect Endpoint', + `Are you sure you want to disconnect endpoint '${item.name}'?`, + 'Disconnect', + false + ); + 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.store.dispatch(new GetSystemInfo()); + }); + }); + }, + label: 'Disconnect', + description: ``, // Description depends on console user permission + createVisible: (row$: Observable) => combineLatest( + this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER), + row$ + ).pipe( + map(([isAdmin, row]) => { + const isConnected = row.connectionStatus === 'connected'; + return isConnected && (!row.system_shared_token || row.system_shared_token && isAdmin); + }) + ) + }, + { + action: (item) => { + this.dialog.open(ConnectEndpointDialogComponent, { + data: { + name: item.name, + guid: item.guid, + type: item.cnsi_type, + ssoAllowed: item.sso_allowed + }, + disableClose: true + }); + }, + label: 'Connect', + description: '', + createVisible: (row$: Observable) => row$.pipe(map(row => row.connectionStatus === 'disconnected')) + }, + { + action: (item) => { + const confirmation = new ConfirmationDialogConfig( + 'Unregister Endpoint', + `Are you sure you want to unregister endpoint '${item.name}'?`, + 'Unregister', + true + ); + 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}`)); + }); + }); + }, + label: 'Unregister', + description: 'Remove the endpoint', + createVisible: () => this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER) + } + ]; + } + + private handleUpdateAction(item, effectKey, handleChange) { + this.handleAction(selectUpdateInfo( + endpointStoreNames.type, + item.guid, + effectKey, + ), handleChange); + } + + private handleDeleteAction(item, handleChange) { + this.handleAction(selectDeletionInfo( + endpointStoreNames.type, + item.guid, + ), handleChange); + } + + private handleAction(storeSelect, handleChange) { + const disSub = this.store.select(storeSelect).pipe( + pairwise()) + .subscribe(([oldVal, newVal]) => { + // https://github.com/SUSE/stratos/issues/29 Generic way to handle errors ('Failed to disconnect X') + if (!newVal.error && (oldVal.busy && !newVal.busy)) { + handleChange([oldVal, newVal]); + disSub.unsubscribe(); + } + }); + } + + createEndpointDetails(listDetailsComponent: any, container: ViewContainerRef, componentFactoryResolver: ComponentFactoryResolver): + EndpointDetailsContainerRefs { + const componentFactory = componentFactoryResolver.resolveComponentFactory(listDetailsComponent); + const componentRef = container.createComponent(componentFactory); + const component = isEndpointListDetailsComponent(componentRef.instance); + const refs = { + componentRef, + component, + endpointDetails: container + }; + if (!component) { + this.log.warn(`Attempted to create a non-endpoint list details component "${listDetailsComponent}"`); + this.destroyEndpointDetails(refs); + } + return refs; + } + + destroyEndpointDetails(refs: EndpointDetailsContainerRefs) { + if (refs.componentRef) { + refs.componentRef.destroy(); + } + if (refs.endpointDetails) { + refs.endpointDetails.clear(); + } + } +} 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 6c3f9e6e02..9187046806 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 @@ -1,22 +1,22 @@ -import { createBasicStoreModule } from '../../../../../../test-framework/store-test-helper'; -import { StoreModule } from '@ngrx/store'; import { CommonModule } from '@angular/common'; +import { inject, TestBed } from '@angular/core/testing'; + +import { createBasicStoreModule } from '../../../../../../test-framework/store-test-helper'; import { CoreModule } from '../../../../../core/core.module'; import { SharedModule } from '../../../../shared.module'; -import { TestBed, inject } from '@angular/core/testing'; - +import { EndpointListHelper } from './endpoint-list.helpers'; import { EndpointsListConfigService } from './endpoints-list-config.service'; describe('EndpointsListConfigService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [EndpointsListConfigService], + providers: [EndpointsListConfigService, EndpointListHelper], imports: [ CommonModule, CoreModule, SharedModule, createBasicStoreModule() - ] + ], }); }); 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 d78dfb64a7..7b8b81b9ef 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 @@ -1,37 +1,21 @@ import { Injectable } from '@angular/core'; -import { MatDialog } from '@angular/material'; import { Store } from '@ngrx/store'; -import { combineLatest, Observable } from 'rxjs'; -import { map, pairwise } from 'rxjs/operators'; -import { DisconnectEndpoint, UnregisterEndpoint } from '../../../../../../../store/src/actions/endpoint.actions'; -import { ShowSnackBar } from '../../../../../../../store/src/actions/snackBar.actions'; -import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions'; +import { ListView } from '../../../../../../../store/src/actions/list.actions'; import { AppState } from '../../../../../../../store/src/app-state'; -import { EndpointsEffect } from '../../../../../../../store/src/effects/endpoint.effects'; -import { selectDeletionInfo, selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors'; -import { EndpointModel, endpointStoreNames } from '../../../../../../../store/src/types/endpoint.types'; +import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types'; import { UserFavoriteEndpoint } from '../../../../../../../store/src/types/user-favorites.types'; -import { CurrentUserPermissions } from '../../../../../core/current-user-permissions.config'; -import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; -import { - ConnectEndpointDialogComponent, -} from '../../../../../features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component'; -import { - getEndpointUsername, - getFullEndpointApiUrl, - getNameForEndpointType, -} from '../../../../../features/endpoints/endpoint-helpers'; +import { getFullEndpointApiUrl, getNameForEndpointType } from '../../../../../features/endpoints/endpoint-helpers'; import { EntityMonitorFactory } from '../../../../monitors/entity-monitor.factory.service'; import { InternalEventMonitorFactory } from '../../../../monitors/internal-event-monitor.factory'; import { PaginationMonitorFactory } from '../../../../monitors/pagination-monitor.factory'; -import { ConfirmationDialogConfig } from '../../../confirmation-dialog.config'; -import { ConfirmationDialogService } from '../../../confirmation-dialog.service'; 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'; +import { EndpointCardComponent } from './endpoint-card/endpoint-card.component'; +import { EndpointListHelper } from './endpoint-list.helpers'; import { EndpointsDataSource } from './endpoints-data-source'; -import { TableCellEndpointIsAdminComponent } from './table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.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'; @@ -75,30 +59,6 @@ export const endpointColumns: ITableColumn[] = [ }, cellFlex: '2' }, - { - columnId: 'username', - headerCell: () => 'Username', - cellDefinition: { - getValue: getEndpointUsername - }, - sort: { - type: 'sort', - orderKey: 'username', - field: 'user.name' - }, - cellFlex: '2' - }, - { - columnId: 'user-type', - headerCell: () => 'Admin', - cellComponent: TableCellEndpointIsAdminComponent, - sort: { - type: 'sort', - orderKey: 'user-type', - field: 'user.admin' - }, - cellFlex: '2' - }, { columnId: 'address', headerCell: () => 'Address', @@ -112,81 +72,19 @@ export const endpointColumns: ITableColumn[] = [ }, cellFlex: '5' }, + { + columnId: 'details', + headerCell: () => 'Details', + cellComponent: TableCellEndpointDetailsComponent, + cellFlex: '4' + } ]; @Injectable() export class EndpointsListConfigService implements IListConfig { - private listActionDelete: IListAction = { - action: (item) => { - const confirmation = new ConfirmationDialogConfig( - 'Unregister Endpoint', - `Are you sure you want to unregister endpoint '${item.name}'?`, - 'Unregister', - true - ); - 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}`)); - }); - }); - }, - label: 'Unregister', - description: 'Remove the endpoint', - createVisible: () => this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER) - }; - - private listActionDisconnect: IListAction = { - action: (item) => { - const confirmation = new ConfirmationDialogConfig( - 'Disconnect Endpoint', - `Are you sure you want to disconnect endpoint '${item.name}'?`, - 'Disconnect', - false - ); - 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.store.dispatch(new GetSystemInfo()); - }); - }); - }, - label: 'Disconnect', - description: ``, // Description depends on console user permission - createVisible: (row$: Observable) => combineLatest( - this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER), - row$ - ).pipe( - map(([isAdmin, row]) => { - const isConnected = row.connectionStatus === 'connected'; - return isConnected && (!row.system_shared_token || row.system_shared_token && isAdmin); - }) - ) - }; + cardComponent = EndpointCardComponent; - private listActionConnect: IListAction = { - action: (item) => { - this.dialog.open(ConnectEndpointDialogComponent, { - data: { - name: item.name, - guid: item.guid, - type: item.cnsi_type, - ssoAllowed: item.sso_allowed - }, - disableClose: true - }); - }, - label: 'Connect', - description: '', - createVisible: (row$: Observable) => row$.pipe(map(row => row.connectionStatus === 'disconnected')) - }; - - private singleActions = [ - this.listActionDisconnect, - this.listActionConnect, - this.listActionDelete - ]; + private singleActions: IListAction[]; private globalActions = []; @@ -195,7 +93,8 @@ export class EndpointsListConfigService implements IListConfig { ]; isLocal = true; dataSource: EndpointsDataSource; - viewType = ListViewTypes.TABLE_ONLY; + viewType = ListViewTypes.BOTH; + defaultView = 'cards' as ListView; text = { title: '', filter: 'Filter Endpoints' @@ -203,42 +102,14 @@ export class EndpointsListConfigService implements IListConfig { enableTextFilter = true; tableFixedRowHeight = true; - private handleUpdateAction(item, effectKey, handleChange) { - this.handleAction(selectUpdateInfo( - endpointStoreNames.type, - item.guid, - effectKey, - ), handleChange); - } - - private handleDeleteAction(item, handleChange) { - this.handleAction(selectDeletionInfo( - endpointStoreNames.type, - item.guid, - ), handleChange); - } - - private handleAction(storeSelect, handleChange) { - const disSub = this.store.select(storeSelect).pipe( - pairwise()) - .subscribe(([oldVal, newVal]) => { - // https://github.com/SUSE/stratos/issues/29 Generic way to handle errors ('Failed to disconnect X') - if (!newVal.error && (oldVal.busy && !newVal.busy)) { - handleChange([oldVal, newVal]); - disSub.unsubscribe(); - } - }); - } - constructor( private store: Store, - private dialog: MatDialog, paginationMonitorFactory: PaginationMonitorFactory, entityMonitorFactory: EntityMonitorFactory, internalEventMonitorFactory: InternalEventMonitorFactory, - private currentUserPermissionsService: CurrentUserPermissionsService, - private confirmDialog: ConfirmationDialogService + endpointListHelper: EndpointListHelper ) { + this.singleActions = endpointListHelper.endpointActions(); const favoriteCell = createTableColumnFavorite( (row: EndpointModel) => new UserFavoriteEndpoint( row.guid, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.html new file mode 100644 index 0000000000..6e81826a58 --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.spec.ts new file mode 100644 index 0000000000..338a1ce656 --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.spec.ts @@ -0,0 +1,29 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BaseTestModules } from '../../../../../../../test-framework/cloud-foundry-endpoint-service.helper'; +import { EndpointListHelper } from '../endpoint-list.helpers'; +import { TableCellEndpointDetailsComponent } from './table-cell-endpoint-details.component'; + +fdescribe('TableCellEndpointDetailsComponent', () => { + let component: TableCellEndpointDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [], + imports: [...BaseTestModules], + providers: [EndpointListHelper] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TableCellEndpointDetailsComponent); + 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-details/table-cell-endpoint-details.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.ts new file mode 100644 index 0000000000..cf6e771498 --- /dev/null +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.ts @@ -0,0 +1,71 @@ +import { + Component, + ComponentFactoryResolver, + ComponentRef, + Input, + OnDestroy, + Type, + ViewChild, + ViewContainerRef, +} from '@angular/core'; + +import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { getEndpointType } from '../../../../../../features/endpoints/endpoint-helpers'; +import { TableCellCustom } from '../../../list.types'; +import { EndpointListDetailsComponent, EndpointListHelper } from '../endpoint-list.helpers'; + +@Component({ + selector: 'app-table-cell-endpoint-details', + templateUrl: './table-cell-endpoint-details.component.html', + styleUrls: ['./table-cell-endpoint-details.component.scss'] +}) +export class TableCellEndpointDetailsComponent extends TableCellCustom implements OnDestroy { + + private componentRef: ComponentRef; + @Input() component: Type; + + private endpointDetails: ViewContainerRef; + @ViewChild('target', { read: ViewContainerRef }) set target(content: ViewContainerRef) { + this.endpointDetails = content; + } + + cell: EndpointListDetailsComponent; + + constructor(private componentFactoryResolver: ComponentFactoryResolver, private endpointListHelper: EndpointListHelper) { + super(); + } + + private pRow: EndpointModel; + @Input('row') + set row(row: EndpointModel) { + this.pRow = row; + + const e = getEndpointType(row.cnsi_type); + if (!e.listDetailsComponent) { + return; + } + if (!this.cell) { + const res = + this.endpointListHelper.createEndpointDetails(e.listDetailsComponent, this.endpointDetails, this.componentFactoryResolver); + this.componentRef = res.componentRef; + this.cell = res.component; + } + + if (this.cell) { + this.cell.row = this.pRow; + this.cell.isTable = true; + } + } + + get row(): EndpointModel { + return this.pRow; + } + + ngOnDestroy(): void { + this.endpointListHelper.destroyEndpointDetails({ + componentRef: this.componentRef, + component: this.cell, + endpointDetails: this.endpointDetails + }); + } +} diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html deleted file mode 100644 index 6de3185e88..0000000000 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html +++ /dev/null @@ -1,3 +0,0 @@ - - -- \ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss deleted file mode 100644 index 8b13789179..0000000000 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts deleted file mode 100644 index d9ba633383..0000000000 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { CoreModule } from '../../../../../../core/core.module'; -import { BooleanIndicatorComponent } from '../../../../boolean-indicator/boolean-indicator.component'; -import { TableCellEndpointIsAdminComponent } from './table-cell-endpoint-is-admin.component'; -import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; - - -describe('TableCellEndpointIsAdminComponent', () => { - let component: TableCellEndpointIsAdminComponent<{}>; - let fixture: ComponentFixture>; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [TableCellEndpointIsAdminComponent, BooleanIndicatorComponent], - imports: [ - CoreModule - ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(TableCellEndpointIsAdminComponent); - component = fixture.componentInstance; - component.row = {} as EndpointModel; - fixture.detectChanges(); - }); - - it('should be created', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts deleted file mode 100644 index 0624a37b3d..0000000000 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; - -import { TableCellCustom } from '../../../list.types'; - -/* tslint:disable:no-access-missing-member https://github.com/mgechev/codelyzer/issues/191*/ -@Component({ - selector: 'app-table-cell-endpoint-is-admin', - templateUrl: './table-cell-endpoint-is-admin.component.html', - styleUrls: ['./table-cell-endpoint-is-admin.component.scss'] -}) -export class TableCellEndpointIsAdminComponent extends TableCellCustom { } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.html index 7bac8d5932..a4f26dd73a 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.html +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.html @@ -1,5 +1,6 @@
- {{ row.name }} - {{ row.name }} - share + {{ row.name }} + {{ row.name }} + share
\ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.spec.ts index 0c79d6d652..0526d50a15 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.spec.ts @@ -1,19 +1,17 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { TableCellEndpointNameComponent } from './table-cell-endpoint-name.component'; -import { CoreModule } from '../../../../../../core/core.module'; import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { CoreModule } from '../../../../../../core/core.module'; +import { TableCellEndpointNameComponent } from './table-cell-endpoint-name.component'; describe('TableCellEndpointNameComponent', () => { - let component: TableCellEndpointNameComponent<{}>; - let fixture: ComponentFixture>; + let component: TableCellEndpointNameComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [TableCellEndpointNameComponent], - imports: [ - CoreModule - ] + imports: [CoreModule] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.ts index f81ab00962..90f64c2ca7 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.ts @@ -1,20 +1,26 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; +import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { EndpointsService } from '../../../../../../core/endpoints.service'; import { TableCellCustom } from '../../../list.types'; -import { getEndpointTypes } from '../../../../../../features/endpoints/endpoint-helpers'; @Component({ selector: 'app-table-cell-endpoint-name', templateUrl: './table-cell-endpoint-name.component.html', styleUrls: ['./table-cell-endpoint-name.component.scss'] }) -export class TableCellEndpointNameComponent extends TableCellCustom { +export class TableCellEndpointNameComponent extends TableCellCustom { - getLinkForEndpoint(row) { - const ext = getEndpointTypes().find(ep => ep.value === row.cnsi_type); - if (ext && ext.homeLink) { - return ext.homeLink(row.guid).join('/'); - } - return ''; + private tableRow: EndpointModel; + @Input('row') + set row(row: EndpointModel) { + this.tableRow = row; + } + get row(): EndpointModel { + return this.tableRow; + } + + getLinkForEndpoint(row = this.tableRow) { + return EndpointsService.getLinkForEndpoint(row); } } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.html index 4229b14f87..c18d5dd67b 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.html +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.html @@ -1,6 +1,6 @@
- cloud_done - cloud_off + cloud_done + cloud_off help_outline -
+
\ No newline at end of file diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.spec.ts index 37b8fe49dc..2bceee6209 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.spec.ts @@ -1,12 +1,12 @@ -import { CoreModule } from '../../../../../../core/core.module'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { TableCellEndpointStatusComponent } from './table-cell-endpoint-status.component'; import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; +import { CoreModule } from '../../../../../../core/core.module'; +import { TableCellEndpointStatusComponent } from './table-cell-endpoint-status.component'; describe('TableCellEndpointStatusComponent', () => { - let component: TableCellEndpointStatusComponent<{}>; - let fixture: ComponentFixture>; + let component: TableCellEndpointStatusComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.ts index 883dcfdfe1..74fe3d4bb3 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.ts @@ -1,5 +1,6 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; +import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types'; import { TableCellCustom } from '../../../list.types'; /* tslint:disable:no-access-missing-member https://github.com/mgechev/codelyzer/issues/191*/ @@ -8,4 +9,6 @@ import { TableCellCustom } from '../../../list.types'; templateUrl: './table-cell-endpoint-status.component.html', styleUrls: ['./table-cell-endpoint-status.component.scss'] }) -export class TableCellEndpointStatusComponent extends TableCellCustom { } +export class TableCellEndpointStatusComponent extends TableCellCustom { + @Input() row: EndpointModel; +} diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/github-commits/github-commits-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/github-commits/github-commits-data-source.ts index ea82a810a3..aa181ba773 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/github-commits/github-commits-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/github-commits/github-commits-data-source.ts @@ -1,14 +1,14 @@ import { Store } from '@ngrx/store'; import { of as observableOf } from 'rxjs'; -import { ListDataSource } from '../../data-sources-controllers/list-data-source'; -import { IListConfig } from '../../list.component.types'; -import { APIResource } from '../../../../../../../store/src/types/api.types'; -import { AppState } from '../../../../../../../store/src/app-state'; import { FetchCommits } from '../../../../../../../store/src/actions/deploy-applications.actions'; +import { AppState } from '../../../../../../../store/src/app-state'; import { EntitySchema, gitCommitSchemaKey } from '../../../../../../../store/src/helpers/entity-factory'; +import { APIResource } from '../../../../../../../store/src/types/api.types'; import { GitCommit } from '../../../../../../../store/src/types/git.types'; import { GitSCM } from '../../../../data-services/scm/scm'; +import { ListDataSource } from '../../data-sources-controllers/list-data-source'; +import { IListConfig } from '../../list.component.types'; export class GithubCommitsDataSource extends ListDataSource> { @@ -16,11 +16,8 @@ export class GithubCommitsDataSource extends ListDataSource} store - * @param {IListConfig>} listConfig - * @param {string} projectName For example `cloudfoundry-incubator/stratos` - * @param {string} sha Branch name, tag, etc - * @memberof GithubCommitsDataSource + * @param projectName For example `cloudfoundry-incubator/stratos` + * @param sha Branch name, tag, etc */ constructor( store: Store, diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts index c56f0b3801..14cbba47ab 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/service-instances/service-instances-list-config.service.ts @@ -2,18 +2,17 @@ import { DatePipe } from '@angular/common'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; +import { AppState } from '../../../../../../../store/src/app-state'; +import { CurrentUserPermissionsService } from '../../../../../core/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'; import { ServiceInstancesDataSource } from './service-instances-data-source'; -import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; -import { AppState } from '../../../../../../../store/src/app-state'; /** * Service instance list shown for `service / service instances` component * * @export - * @class ServiceInstancesListConfigService * @extends {CfServiceInstancesListConfigBase} */ @Injectable() diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/service-plans/service-plans-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/service-plans/service-plans-list-config.service.ts index 0b7d50ab9b..c3a49993b4 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/service-plans/service-plans-list-config.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/service-plans/service-plans-list-config.service.ts @@ -27,7 +27,6 @@ import { * Service instance list shown for `service / service instances` component * * @export - * @class ServicePlansListConfigService */ @Injectable() export class ServicePlansListConfigService implements IListConfig> { diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/service-plans/table-cell-service-plan-price/table-cell-service-plan-price.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/service-plans/table-cell-service-plan-price/table-cell-service-plan-price.component.ts index 763053823b..7798f709d8 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/service-plans/table-cell-service-plan-price/table-cell-service-plan-price.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/service-plans/table-cell-service-plan-price/table-cell-service-plan-price.component.ts @@ -1,9 +1,9 @@ import { Component, Input } from '@angular/core'; +import { APIResource } from '../../../../../../../../store/src/types/api.types'; import { IServicePlan } from '../../../../../../core/cf-api-svc.types'; import { canShowServicePlanCosts } from '../../../../../../features/service-catalog/services-helper'; import { TableCellCustom } from '../../../list.types'; -import { APIResource } from '../../../../../../../../store/src/types/api.types'; @Component({ selector: 'app-table-cell-service-plan-price', @@ -14,10 +14,10 @@ export class TableCellAServicePlanPriceComponent extends TableCellCustom) { - this._servicePlan = servicePlan; + this.pServicePlan = servicePlan; if (!servicePlan) { return; } @@ -25,6 +25,6 @@ export class TableCellAServicePlanPriceComponent extends TableCellCustom { - return this._servicePlan; + return this.pServicePlan; } } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts index b48af5a90b..1e84594fbc 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instance-card/service-instance-card.component.ts @@ -117,6 +117,6 @@ export class ServiceInstanceCardComponent extends CardCell ({ 'breadcrumbs': 'services-wall' }); + getSpaceBreadcrumbs = () => ({ breadcrumbs: 'services-wall' }); } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instances-wall-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instances-wall-data-source.ts index a538b452c3..f19d845f28 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instances-wall-data-source.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instances-wall-data-source.ts @@ -25,7 +25,7 @@ export class ServiceInstancesWallDataSource extends ListDataSource getRowUniqueId: getRowMetadata, paginationKey, isLocal: true, - transformEntities: transformEntities, + transformEntities, listConfig }); } diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts index bb48253464..c72c92127c 100644 --- a/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts +++ b/src/frontend/packages/core/src/shared/components/list/list-types/services-wall/service-instances-wall-list-config.service.ts @@ -2,22 +2,21 @@ import { DatePipe } from '@angular/common'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; +import { ListView } from '../../../../../../../store/src/actions/list.actions'; +import { AppState } from '../../../../../../../store/src/app-state'; import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service'; +import { cfOrgSpaceFilter } from '../../../../../features/cloud-foundry/cf.helpers'; import { CfOrgSpaceDataService, createCfOrgSpaceFilterConfig } from '../../../../data-services/cf-org-space-service.service'; import { ServiceActionHelperService } from '../../../../data-services/service-action-helper.service'; import { defaultPaginationPageSizeOptionsCards, ListViewTypes } from '../../list.component.types'; import { CfServiceInstancesListConfigBase } from '../cf-services/cf-service-instances-list-config.base'; import { ServiceInstanceCardComponent } from './service-instance-card/service-instance-card.component'; import { ServiceInstancesWallDataSource } from './service-instances-wall-data-source'; -import { ListView } from '../../../../../../../store/src/actions/list.actions'; -import { AppState } from '../../../../../../../store/src/app-state'; -import { cfOrgSpaceFilter } from '../../../../../features/cloud-foundry/cf.helpers'; /** * Service instance list shown for `services` nav component * * @export - * @class ServiceInstancesWallListConfigService * @extends {CfServiceInstancesListConfigBase} */ @Injectable() @@ -35,10 +34,10 @@ export class ServiceInstancesWallListConfigService extends CfServiceInstancesLis pageSizeOptions = defaultPaginationPageSizeOptionsCards; constructor(store: Store, - datePipe: DatePipe, - private cfOrgSpaceService: CfOrgSpaceDataService, - currentUserPermissionsService: CurrentUserPermissionsService, - serviceActionHelperService: ServiceActionHelperService + datePipe: DatePipe, + private cfOrgSpaceService: CfOrgSpaceDataService, + currentUserPermissionsService: CurrentUserPermissionsService, + serviceActionHelperService: ServiceActionHelperService ) { super(store, datePipe, currentUserPermissionsService, serviceActionHelperService); const multiFilterConfigs = [ 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 79f5c519b1..939407b770 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 @@ -5,20 +5,21 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, of as observableOf } from 'rxjs'; import { switchMap } from 'rxjs/operators'; -import { CoreModule } from '../../../core/core.module'; +import { ListView } from '../../../../../store/src/actions/list.actions'; +import { AppState } from '../../../../../store/src/app-state'; +import { APIResource } from '../../../../../store/src/types/api.types'; +import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; import { createBasicStoreModule, getInitialTestStoreState } from '../../../../test-framework/store-test-helper'; +import { CoreModule } from '../../../core/core.module'; import { EntityMonitorFactory } from '../../monitors/entity-monitor.factory.service'; import { PaginationMonitorFactory } from '../../monitors/pagination-monitor.factory'; import { SharedModule } from '../../shared.module'; import { ApplicationStateService } from '../application-state/application-state.service'; -import { EndpointCardComponent } from './list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component'; import { EndpointsListConfigService } from './list-types/endpoint/endpoints-list-config.service'; import { ListComponent } from './list.component'; import { ListConfig, ListViewTypes } from './list.component.types'; -import { APIResource } from '../../../../../store/src/types/api.types'; -import { ListView } from '../../../../../store/src/actions/list.actions'; -import { AppState } from '../../../../../store/src/app-state'; -import { EndpointModel } from '../../../../../store/src/types/endpoint.types'; +import { EndpointListHelper } from './list-types/endpoint/endpoint-list.helpers'; +import { EndpointCardComponent } from './list-types/endpoint/endpoint-card/endpoint-card.component'; class MockedNgZone { run = fn => fn(); @@ -57,7 +58,8 @@ describe('ListComponent', () => { providers: [ { provide: ChangeDetectorRef, useValue: { detectChanges: () => { } } }, // Fun fact, NgZone will execute something on import which causes an undefined error - { provide: MockedNgZone, useValue: new MockedNgZone }, + { provide: MockedNgZone, useValue: new MockedNgZone() }, + EndpointListHelper ] }); inject([Store, ChangeDetectorRef, NgZone], (iStore: Store, cd: ChangeDetectorRef, ngZone: MockedNgZone) => { @@ -119,7 +121,8 @@ describe('ListComponent', () => { { provide: ListConfig, useClass: EndpointsListConfigService }, ApplicationStateService, PaginationMonitorFactory, - EntityMonitorFactory + EntityMonitorFactory, + EndpointListHelper ], imports: [ CoreModule, diff --git a/src/frontend/packages/core/src/shared/components/list/list.component.ts b/src/frontend/packages/core/src/shared/components/list/list.component.ts index de30db7019..8a81708f25 100644 --- a/src/frontend/packages/core/src/shared/components/list/list.component.ts +++ b/src/frontend/packages/core/src/shared/components/list/list.component.ts @@ -42,6 +42,18 @@ import { withLatestFrom, } from 'rxjs/operators'; +import { + ListFilter, + ListPagination, + ListSort, + ListView, + SetListViewAction, +} from '../../../../../store/src/actions/list.actions'; +import { AppState } from '../../../../../store/src/app-state'; +import { entityFactory } from '../../../../../store/src/helpers/entity-factory'; +import { ActionState } from '../../../../../store/src/reducers/api-request-reducer/types'; +import { getListStateObservables } from '../../../../../store/src/reducers/list.reducer'; +import { safeUnsubscribe } from '../../../core/utils.service'; import { EntityMonitor } from '../../monitors/entity-monitor'; import { getDefaultRowState, IListDataSource, RowState } from './data-sources-controllers/list-data-source-types'; import { IListPaginationController, ListPaginationController } from './data-sources-controllers/list-pagination-controller'; @@ -57,12 +69,6 @@ import { ListViewTypes, MultiFilterManager, } from './list.component.types'; -import { ListView, ListPagination, ListSort, ListFilter, SetListViewAction } from '../../../../../store/src/actions/list.actions'; -import { AppState } from '../../../../../store/src/app-state'; -import { entityFactory } from '../../../../../store/src/helpers/entity-factory'; -import { getListStateObservables } from '../../../../../store/src/reducers/list.reducer'; -import { ActionState } from '../../../../../store/src/reducers/api-request-reducer/types'; -import { safeUnsubscribe } from '../../../core/utils.service'; @Component({ @@ -139,9 +145,9 @@ export class ListComponent implements OnInit, OnChanges, OnDestroy, AfterView private initialPageEvent: PageEvent; private paginatorSettings: { pageSizeOptions: number[], - pageSize: Number, - pageIndex: Number, - length: Number + pageSize: number, + pageIndex: number, + length: number } = { pageSizeOptions: null, pageSize: null, @@ -348,7 +354,7 @@ export class ListComponent implements OnInit, OnChanges, OnDestroy, AfterView // Ensure we set a pageSize that's relevant to the configured set of page sizes. The default is 9 and in some cases is not a valid // pageSize this.paginationController.pagination$.pipe(first()).subscribe(pagination => { - this.initialPageEvent = new PageEvent; + this.initialPageEvent = new PageEvent(); this.initialPageEvent.pageIndex = pagination.pageIndex - 1; this.initialPageEvent.pageSize = pagination.pageSize; if (this.paginatorSettings.pageSizeOptions.findIndex(pageSize => pageSize === pagination.pageSize) < 0) { diff --git a/src/frontend/packages/core/src/shared/components/list/list.component.types.ts b/src/frontend/packages/core/src/shared/components/list/list.component.types.ts index 48911d2951..374d716ef4 100644 --- a/src/frontend/packages/core/src/shared/components/list/list.component.types.ts +++ b/src/frontend/packages/core/src/shared/components/list/list.component.types.ts @@ -149,8 +149,6 @@ export interface IOptionalAction extends IBaseListAction { export interface IMultiListAction extends IOptionalAction { /** * Return true if the selection should be cleared - * - * @memberof IMultiListAction */ action: (items: T[]) => boolean | Observable; } diff --git a/src/frontend/packages/core/src/shared/components/list/list.types.ts b/src/frontend/packages/core/src/shared/components/list/list.types.ts index 46d07a59d7..84d009cf44 100644 --- a/src/frontend/packages/core/src/shared/components/list/list.types.ts +++ b/src/frontend/packages/core/src/shared/components/list/list.types.ts @@ -1,7 +1,8 @@ import { Component } from '@angular/core'; -import { IListDataSource, RowState } from './data-sources-controllers/list-data-source-types'; import { Observable } from 'rxjs'; +import { IListDataSource, RowState } from './data-sources-controllers/list-data-source-types'; + export abstract class TableCellCustom { dataSource: IListDataSource; row: T; diff --git a/src/frontend/packages/core/src/shared/components/log-viewer/log-viewer.component.spec.ts b/src/frontend/packages/core/src/shared/components/log-viewer/log-viewer.component.spec.ts index 8b86aaa901..50c0dfd715 100644 --- a/src/frontend/packages/core/src/shared/components/log-viewer/log-viewer.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/log-viewer/log-viewer.component.spec.ts @@ -1,13 +1,13 @@ -import { Observable, Subject, from as observableFrom } from 'rxjs'; -import { MDAppModule } from '../../../core/md.module'; -import { RouterTestingModule } from '@angular/router/testing'; import { CommonModule } from '@angular/common'; -import { CoreModule } from '../../../core/core.module'; +import { Component, ViewChild } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { from as observableFrom, Subject } from 'rxjs'; +import { filter, first } from 'rxjs/operators'; +import { CoreModule } from '../../../core/core.module'; +import { MDAppModule } from '../../../core/md.module'; import { LogViewerComponent } from './log-viewer.component'; -import { Component, ViewChild } from '@angular/core'; -import { first, filter } from 'rxjs/operators'; describe('LogViewerComponent', () => { @Component({ @@ -21,7 +21,7 @@ describe('LogViewerComponent', () => { let component: TestHostComponent; let fixture: ComponentFixture; - let stream: Subject; + let stream: Subject; let contentEl: HTMLDivElement; beforeEach(async(() => { diff --git a/src/frontend/packages/core/src/shared/components/log-viewer/log-viewer.component.ts b/src/frontend/packages/core/src/shared/components/log-viewer/log-viewer.component.ts index dc6b44f6e2..caae276988 100644 --- a/src/frontend/packages/core/src/shared/components/log-viewer/log-viewer.component.ts +++ b/src/frontend/packages/core/src/shared/components/log-viewer/log-viewer.component.ts @@ -1,13 +1,12 @@ - import { ChangeDetectionStrategy, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { BehaviorSubject, - Observable, - Subscription, combineLatest as observableCombineLatest, fromEvent as observableFromEvent, interval as observableInterval, - never as observableNever + NEVER, + Observable, + Subscription, } from 'rxjs'; import { buffer, @@ -16,17 +15,17 @@ import { filter, map, sampleTime, - scan, share, startWith, switchMap, tap, throttle, timeInterval, - catchError } from 'rxjs/operators'; + import { AnsiColors } from './ansi-colors'; + interface LogStreamMessage { message: string; isError?: boolean; @@ -40,7 +39,7 @@ interface LogStreamMessage { }) export class LogViewerComponent implements OnInit, OnDestroy { - @Input() filter: Function; + @Input() filter: (a: any) => void; @Input() status: Observable; @@ -76,7 +75,7 @@ export class LogViewerComponent implements OnInit, OnDestroy { const stoppableLogStream$ = this.stopped$.pipe( switchMap( - stopped => (stopped ? observableNever() : this.logStream) + stopped => (stopped ? NEVER : this.logStream) ), share() ); @@ -111,7 +110,7 @@ export class LogViewerComponent implements OnInit, OnDestroy { return high; }), distinctUntilChanged(), - startWith(false), ); + startWith(false)); const buffer$ = observableInterval().pipe( combineLatest(this.isHighThroughput$), @@ -119,7 +118,7 @@ export class LogViewerComponent implements OnInit, OnDestroy { return observableInterval( high ? this.highThroughputBufferIntervalMS : 0 ); - }), ); + })); const addedLogs$ = stoppableLogStream$.pipe( buffer(buffer$)) @@ -156,24 +155,28 @@ export class LogViewerComponent implements OnInit, OnDestroy { containerElement.scrollTop = contentElement.clientHeight; } })) - .subscribe(undefined, e => { - this.statusMessage$.next({ - message: 'An error occurred connecting to the log stream websocket', - isError: true - }); + .subscribe({ + error: e => { + this.statusMessage$.next({ + message: 'An error occurred connecting to the log stream websocket', + isError: true + }); + } }); if (this.status) { - this.statusSub = this.status.subscribe((wsStatus => { - switch (wsStatus) { - case 0: - this.statusMessage$.next({ message: 'Connecting....' }); - break; - default: - this.statusMessage$.next({ message: '' }); - break; + this.statusSub = this.status.subscribe({ + next: wsStatus => { + switch (wsStatus) { + case 0: + this.statusMessage$.next({ message: 'Connecting....' }); + break; + default: + this.statusMessage$.next({ message: '' }); + break; + } } - })); + }); } } diff --git a/src/frontend/packages/core/src/shared/components/metrics-chart/metrics-chart.component.spec.ts b/src/frontend/packages/core/src/shared/components/metrics-chart/metrics-chart.component.spec.ts index 90dac89f88..ad98684c1d 100644 --- a/src/frontend/packages/core/src/shared/components/metrics-chart/metrics-chart.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/metrics-chart/metrics-chart.component.spec.ts @@ -1,13 +1,13 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { MetricsChartComponent } from './metrics-chart.component'; -import { MDAppModule } from '../../../core/md.module'; +import { FetchApplicationMetricsAction, MetricQueryConfig } from '../../../../../store/src/actions/metrics.actions'; +import { createBasicStoreModule } from '../../../../test-framework/store-test-helper'; import { CoreModule } from '../../../core/core.module'; +import { MDAppModule } from '../../../core/md.module'; import { SharedModule } from '../../shared.module'; -import { createBasicStoreModule } from '../../../../test-framework/store-test-helper'; +import { MetricsChartComponent } from './metrics-chart.component'; import { MetricsLineChartConfig } from './metrics-chart.types'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { FetchApplicationMetricsAction, MetricQueryConfig } from '../../../../../store/src/actions/metrics.actions'; describe('MetricsChartComponent', () => { let component: MetricsChartComponent; @@ -31,7 +31,6 @@ describe('MetricsChartComponent', () => { component = fixture.componentInstance; component.chartConfig = new MetricsLineChartConfig(); component.chartConfig.xAxisLabel = 'Time'; - component.chartConfig.yAxisLabel = this.yAxisLabel; component.metricsConfig = { metricsAction: new FetchApplicationMetricsAction( '1', diff --git a/src/frontend/packages/core/src/shared/components/metrics-chart/metrics-chart.types.ts b/src/frontend/packages/core/src/shared/components/metrics-chart/metrics-chart.types.ts index 7b6197ec11..1f25aecc2b 100644 --- a/src/frontend/packages/core/src/shared/components/metrics-chart/metrics-chart.types.ts +++ b/src/frontend/packages/core/src/shared/components/metrics-chart/metrics-chart.types.ts @@ -2,9 +2,9 @@ import { MetricsAction } from '../../../../../store/src/actions/metrics.actions' export interface IMetricsConfig { metricsAction: MetricsAction; - getSeriesName: (T) => string; - mapSeriesItemName?: (any) => any; - mapSeriesItemValue?: (any) => any; + getSeriesName: (obj: T) => string; + mapSeriesItemName?: (anything: any) => any; + mapSeriesItemValue?: (anything: any) => any; } export enum MetricsChartTypes { @@ -12,7 +12,7 @@ export enum MetricsChartTypes { } export type YAxisTickFormattingFunc = (label: string) => string; -interface IMetricsChartConfig { +export interface IMetricsChartConfig { chartType: MetricsChartTypes; xAxisLabel?: string; yAxisLabel?: string; diff --git a/src/frontend/packages/core/src/shared/components/metrics-chart/metrics.component.helpers.ts b/src/frontend/packages/core/src/shared/components/metrics-chart/metrics.component.helpers.ts index da75b325cd..7f90134b87 100644 --- a/src/frontend/packages/core/src/shared/components/metrics-chart/metrics.component.helpers.ts +++ b/src/frontend/packages/core/src/shared/components/metrics-chart/metrics.component.helpers.ts @@ -60,7 +60,7 @@ export function buildMetricsChartConfig( sort: MetricsChartHelpers.sortBySeriesName, mapSeriesItemValue: getServiceItemValueMapper(dataType), metricsAction, - filterSeries: filterSeries, + filterSeries, }, MetricsChartHelpers.buildChartConfig(yAxisLabel, yAxisTickFormatter) ]; 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 c399540a19..bb37b10447 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 @@ -9,14 +9,13 @@
- {{ breadcrumbDef.value }} + {{ breadcrumbDef.value }} {{ breadcrumbDef.value }} chevron_right
- +
@@ -40,7 +39,7 @@

Recent

- 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 3dccce806c..50df215294 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 @@ -24,7 +24,7 @@ export class PageHeaderComponent { public breadcrumbDefinitions: IHeaderBreadcrumbLink[] = null; private breadcrumbKey: string; public eventSeverity = InternalEventSeverity; - public _favorite: UserFavorite; + public pFavorite: UserFavorite; @Input() hideSideNavButton = false; @@ -41,8 +41,8 @@ export class PageHeaderComponent { @Input() showHistory = true; @Input() set favorite(favorite: UserFavorite) { - if (favorite && (!this._favorite || (favorite.guid !== this._favorite.guid))) { - this._favorite = favorite; + if (favorite && (!this.pFavorite || (favorite.guid !== this.pFavorite.guid))) { + this.pFavorite = favorite; const mapperFunction = favoritesConfigMapper.getMapperFunction(favorite); const prettyType = favoritesConfigMapper.getPrettyTypeName(favorite); const prettyEndpointType = favoritesConfigMapper.getPrettyTypeName({ @@ -68,7 +68,7 @@ export class PageHeaderComponent { public userNameFirstLetter$: Observable; public username$: Observable; - public actionsKey: String; + public actionsKey: string; @Input() set breadcrumbs(breadcrumbs: IHeaderBreadcrumb[]) { diff --git a/src/frontend/packages/core/src/shared/components/schema-form/schema-form.component.ts b/src/frontend/packages/core/src/shared/components/schema-form/schema-form.component.ts index 19bb3f0d6f..fabc095c7d 100644 --- a/src/frontend/packages/core/src/shared/components/schema-form/schema-form.component.ts +++ b/src/frontend/packages/core/src/shared/components/schema-form/schema-form.component.ts @@ -23,7 +23,7 @@ export function isValidJsonValidator(): ValidatorFn { } } } catch (e) { - return { 'notValidJson': { value: formField.value } }; + return { notValidJson: { value: formField.value } }; } return null; }; @@ -60,7 +60,7 @@ export class SchemaFormComponent implements OnInit, OnDestroy, AfterContentInit if (this.mode === 'JSON') { this.setJsonFormData(config.initialData); if (!config.initialData) { - this._validChange.next(true); + this.pValidChange.next(true); } } else if (this.mode === 'schema') { this.formInitialData = config.initialData; @@ -69,13 +69,13 @@ export class SchemaFormComponent implements OnInit, OnDestroy, AfterContentInit @Output() dataChange = new EventEmitter(); - _dataChange = new BehaviorSubject(null); + pDataChange = new BehaviorSubject(null); @Input() valid = false; @Output() validChange = new EventEmitter(); - _validChange = new BehaviorSubject(false); + pValidChange = new BehaviorSubject(false); cleanSchema: object; @@ -97,14 +97,14 @@ export class SchemaFormComponent implements OnInit, OnDestroy, AfterContentInit } ngAfterContentInit() { - this.subs.push(this.jsonForm.controls['json'].valueChanges.subscribe(jsonStr => { + this.subs.push(this.jsonForm.controls.json.valueChanges.subscribe(jsonStr => { this.jsonData = safeStringToObj(jsonStr); - this._dataChange.next(this.jsonData); - this._validChange.next(this.isJsonFormValid()); + this.pDataChange.next(this.jsonData); + this.pValidChange.next(this.isJsonFormValid()); })); - this.subs.push(this._dataChange.asObservable().pipe(delay(0)).subscribe(data => this.dataChange.emit(data))); - this.subs.push(this._validChange.asObservable().pipe(delay(0)).subscribe(valid => this.validChange.emit(valid))); + this.subs.push(this.pDataChange.asObservable().pipe(delay(0)).subscribe(data => this.dataChange.emit(data))); + this.subs.push(this.pValidChange.asObservable().pipe(delay(0)).subscribe(valid => this.validChange.emit(valid))); } ngOnDestroy() { @@ -124,12 +124,12 @@ export class SchemaFormComponent implements OnInit, OnDestroy, AfterContentInit setJsonFormData(data: object) { if (this.jsonForm) { const jsonString = data ? JSON.stringify(data) : ''; - this.jsonForm.controls['json'].setValue(jsonString); + this.jsonForm.controls.json.setValue(jsonString); } } private isJsonFormValid(): boolean { - return !this.jsonForm.controls['json'].value || this.jsonForm.controls['json'].valid; + return !this.jsonForm.controls.json.value || this.jsonForm.controls.json.valid; } private filterSchema = (schema?: object): any => { @@ -145,13 +145,13 @@ export class SchemaFormComponent implements OnInit, OnDestroy, AfterContentInit onFormChange(formData) { this.formData = formData; - this._dataChange.next(formData); + this.pDataChange.next(formData); } onFormValidationErrors(data: SchemaFormValidationError[]): void { this.formValidationErrors = data || []; this.formValidationErrorsStr = this.prettyValidationErrorsFn(this.formValidationErrors); - this._validChange.next(!this.formValidationErrors.length); + this.pValidChange.next(!this.formValidationErrors.length); } private prettyValidationErrorsFn = (formValidationErrors: SchemaFormValidationError[]): string => { diff --git a/src/frontend/packages/core/src/shared/components/service-plan-public/service-plan-public.component.ts b/src/frontend/packages/core/src/shared/components/service-plan-public/service-plan-public.component.ts index c6c2fdfdbf..2e0b33cef2 100644 --- a/src/frontend/packages/core/src/shared/components/service-plan-public/service-plan-public.component.ts +++ b/src/frontend/packages/core/src/shared/components/service-plan-public/service-plan-public.component.ts @@ -2,6 +2,7 @@ import { Component, Input } from '@angular/core'; import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; +import { APIResource } from '../../../../../store/src/types/api.types'; import { IServiceBroker, IServicePlan } from '../../../core/cf-api-svc.types'; import { EntityServiceFactory } from '../../../core/entity-service-factory.service'; import { @@ -11,7 +12,6 @@ import { } from '../../../features/service-catalog/services-helper'; import { ServicesService } from '../../../features/service-catalog/services.service'; import { CardStatus } from '../../shared.types'; -import { APIResource } from '../../../../../store/src/types/api.types'; @Component({ selector: 'app-service-plan-public', @@ -22,13 +22,13 @@ export class ServicePlanPublicComponent { planAccessibility$: Observable; planAccessibilityMessage$: Observable; - private _servicePlan: APIResource; + private pServicePlan: APIResource; @Input() get servicePlan(): APIResource { - return this._servicePlan; + return this.pServicePlan; } set servicePlan(servicePlan: APIResource) { - this._servicePlan = servicePlan; + this.pServicePlan = servicePlan; if (!servicePlan) { return; } diff --git a/src/frontend/packages/core/src/shared/components/stateful-icon/stateful-icon.component.ts b/src/frontend/packages/core/src/shared/components/stateful-icon/stateful-icon.component.ts index 3115842bbc..49d2c2e3d8 100644 --- a/src/frontend/packages/core/src/shared/components/stateful-icon/stateful-icon.component.ts +++ b/src/frontend/packages/core/src/shared/components/stateful-icon/stateful-icon.component.ts @@ -32,7 +32,7 @@ export class StatefulIconComponent implements OnInit, OnChanges { selectedState: StatefulIconDefinition; isTemplate(icon: StatefulIconDefinition): icon is IconTemplateDefinition { - return !!(icon).template; + return !!(icon as IconTemplateDefinition).template; } ngOnInit() { diff --git a/src/frontend/packages/core/src/shared/components/stepper/step/step.component.ts b/src/frontend/packages/core/src/shared/components/stepper/step/step.component.ts index baa663fd1a..4cf2a9e742 100644 --- a/src/frontend/packages/core/src/shared/components/stepper/step/step.component.ts +++ b/src/frontend/packages/core/src/shared/components/stepper/step/step.component.ts @@ -27,13 +27,13 @@ export type StepOnNextFunction = () => Observable; }) export class StepComponent { - public _onEnter: (data?: any) => void; + public pOnEnter: (data?: any) => void; active = false; complete = false; error = false; busy = false; - _hidden = false; + pHidden = false; @Input() title: string; @@ -42,12 +42,12 @@ export class StepComponent { @Input() set hidden(hidden: boolean) { - this._hidden = hidden; - this.onHidden.emit(this._hidden); + this.pHidden = hidden; + this.onHidden.emit(this.pHidden); } get hidden() { - return this._hidden; + return this.pHidden; } @Input() @@ -90,7 +90,7 @@ export class StepComponent { onLeave: (isNext?: boolean) => void = () => { } constructor() { - this._onEnter = (data?: any) => { + this.pOnEnter = (data?: any) => { if (this.destructiveStep) { this.busy = true; setTimeout(() => { diff --git a/src/frontend/packages/core/src/shared/components/stepper/steppers/steppers.component.ts b/src/frontend/packages/core/src/shared/components/stepper/steppers/steppers.component.ts index f67aa98b47..946acf66e0 100644 --- a/src/frontend/packages/core/src/shared/components/stepper/steppers/steppers.component.ts +++ b/src/frontend/packages/core/src/shared/components/stepper/steppers/steppers.component.ts @@ -13,12 +13,12 @@ import { Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import { catchError, first, map, switchMap } from 'rxjs/operators'; +import { RouterNav } from '../../../../../../store/src/actions/router.actions'; +import { AppState } from '../../../../../../store/src/app-state'; +import { getPreviousRoutingState } from '../../../../../../store/src/types/routing.type'; import { LoggerService } from '../../../../core/logger.service'; import { SteppersService } from '../steppers.service'; import { StepComponent } from './../step/step.component'; -import { AppState } from '../../../../../../store/src/app-state'; -import { getPreviousRoutingState } from '../../../../../../store/src/types/routing.type'; -import { RouterNav } from '../../../../../../store/src/actions/router.actions'; @@ -34,7 +34,7 @@ export class SteppersComponent implements OnInit, AfterContentInit, OnDestroy { private nextSub: Subscription; cancel$: Observable; - @ContentChildren(StepComponent) _steps: QueryList; + @ContentChildren(StepComponent) stepComponents: QueryList; @Input() cancel = null; @Input() nextButtonProgress = true; @@ -84,7 +84,7 @@ export class SteppersComponent implements OnInit, AfterContentInit, OnDestroy { } ngAfterContentInit() { - this.allSteps = this._steps.toArray(); + this.allSteps = this.stepComponents.toArray(); this.setActive(0); this.allSteps.forEach((step => { @@ -146,7 +146,7 @@ export class SteppersComponent implements OnInit, AfterContentInit, OnDestroy { this.cancelQueryParams$ ).pipe( map(([path, params]) => { - this.store.dispatch(new RouterNav({ path: path, query: params })); + this.store.dispatch(new RouterNav({ path, query: params })); }) ); } @@ -159,7 +159,7 @@ export class SteppersComponent implements OnInit, AfterContentInit, OnDestroy { const timer = setInterval(() => { if (this.allSteps[index].blocked === false) { this.allSteps[index].active = true; - this.allSteps[index]._onEnter(this.enterData); + this.allSteps[index].onEnter(this.enterData); clearInterval(timer); } }, 5); @@ -179,12 +179,12 @@ export class SteppersComponent implements OnInit, AfterContentInit, OnDestroy { } // 3) Set stepper state WRT required step - this.steps.forEach((_step, i) => { - _step.complete = i < index; - _step.active = i === index; + this.steps.forEach((s, i) => { + s.complete = i < index; + s.active = i === index; }); this.currentIndex = index; - this.steps[this.currentIndex]._onEnter(this.enterData); + this.steps[this.currentIndex].onEnter(this.enterData); this.enterData = undefined; } diff --git a/src/frontend/packages/core/src/shared/data-services/cf-org-space-service.service.ts b/src/frontend/packages/core/src/shared/data-services/cf-org-space-service.service.ts index 906c69ec22..689da828ba 100644 --- a/src/frontend/packages/core/src/shared/data-services/cf-org-space-service.service.ts +++ b/src/frontend/packages/core/src/shared/data-services/cf-org-space-service.service.ts @@ -14,31 +14,30 @@ import { withLatestFrom, } from 'rxjs/operators'; -import { IOrganization, ISpace } from '../../core/cf-api.types'; - -import { PaginationMonitorFactory } from '../monitors/pagination-monitor.factory'; -import { AppState } from '../../../../store/src/app-state'; -import { selectPaginationState } from '../../../../store/src/selectors/pagination.selectors'; -import { EndpointModel } from '../../../../store/src/types/endpoint.types'; import { GetAllOrganizations } from '../../../../store/src/actions/organization.actions'; +import { ResetPagination, SetParams } from '../../../../store/src/actions/pagination.actions'; +import { AppState } from '../../../../store/src/app-state'; +import { entityFactory, organizationSchemaKey, spaceSchemaKey } from '../../../../store/src/helpers/entity-factory'; import { createEntityRelationKey } from '../../../../store/src/helpers/entity-relations/entity-relations.types'; -import { organizationSchemaKey, spaceSchemaKey, entityFactory } from '../../../../store/src/helpers/entity-factory'; import { - getPaginationObservables, getCurrentPageRequestInfo, - spreadPaginationParams + getPaginationObservables, + spreadPaginationParams, } from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper'; -import { APIResource } from '../../../../store/src/types/api.types'; import { endpointsRegisteredEntitiesSelector } from '../../../../store/src/selectors/endpoint.selectors'; -import { PaginatedAction, QParam, PaginationParam } from '../../../../store/src/types/pagination.types'; +import { selectPaginationState } from '../../../../store/src/selectors/pagination.selectors'; +import { APIResource } from '../../../../store/src/types/api.types'; +import { EndpointModel } from '../../../../store/src/types/endpoint.types'; +import { PaginatedAction, PaginationParam, QParam } from '../../../../store/src/types/pagination.types'; +import { IOrganization, ISpace } from '../../core/cf-api.types'; import { ListPaginationMultiFilterChange } from '../components/list/data-sources-controllers/list-data-source-types'; import { valueOrCommonFalsy } from '../components/list/data-sources-controllers/list-pagination-controller'; -import { ResetPagination, SetParams } from '../../../../store/src/actions/pagination.actions'; +import { PaginationMonitorFactory } from '../monitors/pagination-monitor.factory'; export function createCfOrgSpaceFilterConfig(key: string, label: string, cfOrgSpaceItem: CfOrgSpaceItem) { return { - key: key, - label: label, + key, + label, ...cfOrgSpaceItem, list$: cfOrgSpaceItem.list$.pipe(map((entities: any[]) => { return entities.map(entity => ({ @@ -69,9 +68,9 @@ export const enum CfOrgSpaceSelectMode { export const initCfOrgSpaceService = (store: Store, - cfOrgSpaceService: CfOrgSpaceDataService, - schemaKey: string, - paginationKey: string): Observable => { + cfOrgSpaceService: CfOrgSpaceDataService, + schemaKey: string, + paginationKey: string): Observable => { return store.select(selectPaginationState(schemaKey, paginationKey)).pipe( filter((pag) => !!pag), first(), @@ -180,8 +179,10 @@ export class CfOrgSpaceDataService implements OnDestroy { // Start watching the cf/org/space plus automatically setting values only when we actually have values to auto select this.org.list$.pipe( first(), - ).subscribe(null, null, () => { - this.setupAutoSelectors(); + ).subscribe({ + complete: () => { + this.setupAutoSelectors(); + } }); this.isLoading$ = combineLatest( @@ -224,8 +225,8 @@ export class CfOrgSpaceDataService implements OnDestroy { map(endpoints => Object.values(endpoints).filter(e => e.cnsi_type === 'cf')), // Ensure we have at least one connected cf filter(cfs => { - for (let i = 0; i < cfs.length; i++) { - if (cfs[i].connectionStatus === 'connected') { + for (const cf of cfs) { + if (cf.connectionStatus === 'connected') { return true; } } diff --git a/src/frontend/packages/core/src/shared/data-services/cf-user.service.ts b/src/frontend/packages/core/src/shared/data-services/cf-user.service.ts index 818f0a011f..90004245ec 100644 --- a/src/frontend/packages/core/src/shared/data-services/cf-user.service.ts +++ b/src/frontend/packages/core/src/shared/data-services/cf-user.service.ts @@ -107,9 +107,9 @@ export class CfUserService { } private parseOrgRole(user: CfUser, - processedOrgs: Set, - orgsToProcess: APIResource[], - result: IUserPermissionInOrg[]) { + processedOrgs: Set, + orgsToProcess: APIResource[], + result: IUserPermissionInOrg[]) { orgsToProcess.forEach(org => { const orgGuid = org.entity.guid; if (processedOrgs.has(orgGuid)) { @@ -146,9 +146,9 @@ export class CfUserService { } private parseSpaceRole(user: CfUser, - processedSpaces: Set, - spacesToProcess: APIResource[], - result: IUserPermissionInSpace[]) { + processedSpaces: Set, + spacesToProcess: APIResource[], + result: IUserPermissionInSpace[]) { spacesToProcess.forEach(space => { const spaceGuid = space.entity.guid; if (processedSpaces.has(spaceGuid)) { @@ -170,7 +170,6 @@ export class CfUserService { /** * Get the space roles for a user - * @param user * @param spaces Only fetch roles for these specific spaces. If missing fetch roles for all spaces */ getSpaceRolesFromUser(user: CfUser, spaces?: APIResource[]): IUserPermissionInSpace[] { @@ -327,8 +326,6 @@ export class CfUserService { /** * Create a paginated action that will fetch a list of users. For admins attempt to fetch all users regardless of cf/org/space level if * there's not too many, otherwise fetch list with respect to cf/org/level - * @param isAdmin - * @param cfGuid * @param orgGuid Populated if user is at org level * @param spaceGuid Populated if user is at space level */ @@ -358,8 +355,6 @@ export class CfUserService { /** * Create a paginated action that will fetch a list of users with respect to the level (cf, org or space) - * @param isAdmin - * @param cfGuid * @param orgGuid Populated if user is at org level * @param spaceGuid Populated if user is at space level */ diff --git a/src/frontend/packages/core/src/shared/data-services/service-action-helper.service.ts b/src/frontend/packages/core/src/shared/data-services/service-action-helper.service.ts index 71ef28bfe9..22d59268a8 100644 --- a/src/frontend/packages/core/src/shared/data-services/service-action-helper.service.ts +++ b/src/frontend/packages/core/src/shared/data-services/service-action-helper.service.ts @@ -69,5 +69,5 @@ export class ServiceActionHelperService { editServiceBinding = (guid: string, endpointGuid: string, query: RouterQueryParams = {}) => - this.store.dispatch(new RouterNav({ path: ['/services', endpointGuid, guid, 'edit'], query: query })) + this.store.dispatch(new RouterNav({ path: ['/services', endpointGuid, guid, 'edit'], query })) } diff --git a/src/frontend/packages/core/src/shared/monitors/entity-monitor.ts b/src/frontend/packages/core/src/shared/monitors/entity-monitor.ts index ecfd64ccea..b903bcc003 100644 --- a/src/frontend/packages/core/src/shared/monitors/entity-monitor.ts +++ b/src/frontend/packages/core/src/shared/monitors/entity-monitor.ts @@ -1,20 +1,31 @@ - import { Store } from '@ngrx/store'; import { denormalize, schema as normalizrSchema } from 'normalizr'; import { combineLatest, interval as observableInterval, Observable } from 'rxjs'; import { tag } from 'rxjs-spy/operators/tag'; -import { distinctUntilChanged, filter, map, publishReplay, refCount, share, startWith, tap, withLatestFrom } from 'rxjs/operators'; +import { + distinctUntilChanged, + filter, + map, + publishReplay, + refCount, + share, + startWith, + tap, + withLatestFrom, +} from 'rxjs/operators'; + import { AppState } from '../../../../store/src/app-state'; import { ActionState, getDefaultActionState, getDefaultRequestState, RequestInfoState, - UpdatingSection + UpdatingSection, } from '../../../../store/src/reducers/api-request-reducer/types'; -import { selectRequestInfo, getAPIRequestDataState, selectEntity } from '../../../../store/src/selectors/api.selectors'; +import { getAPIRequestDataState, selectEntity, selectRequestInfo } from '../../../../store/src/selectors/api.selectors'; import { IRequestDataState } from '../../../../store/src/types/entity.types'; + export class EntityMonitor { constructor( private store: Store, @@ -68,12 +79,12 @@ export class EntityMonitor { */ public entityRequest$: Observable; /** - * An observable that emits a boolean indicating if the entity is being fetched or not. - */ + * An observable that emits a boolean indicating if the entity is being fetched or not. + */ public isFetchingEntity$: Observable; /** - * An observable that emits a boolean indicating if the entity is being deleted or not. - */ + * An observable that emits a boolean indicating if the entity is being deleted or not. + */ public isDeletingEntity$: Observable; /** @@ -122,7 +133,7 @@ export class EntityMonitor { * @param interval - The polling interval in ms. * @param updateKey - The store updating key for the poll */ - poll(interval = 10000, action: Function, getActionState: (request: RequestInfoState) => ActionState) { + poll(interval = 10000, action: () => void, getActionState: (request: RequestInfoState) => ActionState) { return observableInterval(interval) .pipe( tag('poll'), diff --git a/src/frontend/packages/core/src/shared/monitors/pagination-monitor.ts b/src/frontend/packages/core/src/shared/monitors/pagination-monitor.ts index 63c5a827d3..cbacdc7e19 100644 --- a/src/frontend/packages/core/src/shared/monitors/pagination-monitor.ts +++ b/src/frontend/packages/core/src/shared/monitors/pagination-monitor.ts @@ -51,7 +51,6 @@ export class PaginationMonitor { /** * Is the current page ready? - * @param pagination */ private hasPage(pagination: PaginationEntityState) { if (!pagination) { @@ -68,7 +67,6 @@ export class PaginationMonitor { /** * Gets the request info for the current page. - * @param pagination */ private getCurrentPageRequestInfo( pagination: PaginationEntityState, 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 64a49e92c8..f9664e86bc 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 @@ -3,18 +3,18 @@ import * as moment from 'moment'; 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 '../monitors/entity-monitor'; import { MetricsRangeSelectorService } from './metrics-range-selector.service'; import { ITimeRange, MetricQueryType } from './metrics-range-selector.types'; -import { IMetrics } from '../../../../store/src/types/base-metric.types'; -import { MetricsAction } from '../../../../store/src/actions/metrics.actions'; @Injectable() export class MetricsRangeSelectorManagerService { public timeWindow$ = new Subject(); - public commit: Function = null; + public commit: () => void = null; public dateValid = false; diff --git a/src/frontend/packages/core/src/shared/shared.module.ts b/src/frontend/packages/core/src/shared/shared.module.ts index b050afab19..7dedf8ae80 100644 --- a/src/frontend/packages/core/src/shared/shared.module.ts +++ b/src/frontend/packages/core/src/shared/shared.module.ts @@ -1,4 +1,3 @@ -/* tslint:disable:max-line-length */ import { CdkTableModule } from '@angular/cdk/table'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; @@ -94,6 +93,7 @@ import { listTableComponents } from './components/list/list-table/table.types'; import { EventTabActorIconPipe, } from './components/list/list-types/app-event/table-cell-event-action/event-tab-actor-icon.pipe'; +import { EndpointCardComponent } from './components/list/list-types/endpoint/endpoint-card/endpoint-card.component'; import { ListComponent } from './components/list/list.component'; import { ListConfig } from './components/list/list.component.types'; import { LoadingPageComponent } from './components/loading-page/loading-page.component'; @@ -150,6 +150,7 @@ import { ValuesPipe } from './pipes/values.pipe'; import { MetricsRangeSelectorService } from './services/metrics-range-selector.service'; import { UserPermissionDirective } from './user-permission.directive'; +/* tslint:disable:max-line-length */ @NgModule({ imports: [ @@ -264,7 +265,8 @@ import { UserPermissionDirective } from './user-permission.directive'; FavoritesGlobalListComponent, FavoritesMetaCardComponent, FavoritesEntityListComponent, - MultilineTitleComponent + MultilineTitleComponent, + EndpointCardComponent, ], exports: [ FormsModule, diff --git a/src/frontend/packages/core/src/styles.scss b/src/frontend/packages/core/src/styles.scss index 3c984ac5a6..1fe35bd298 100644 --- a/src/frontend/packages/core/src/styles.scss +++ b/src/frontend/packages/core/src/styles.scss @@ -11,8 +11,8 @@ @import '../sass/components/mat-tabs'; @import '../sass/components/mat-table'; body { - margin: 0; font-family: Lato, sans-serif; // font-size: 13px; + margin: 0; } body, @@ -31,10 +31,21 @@ html { } } -.dashboard .mat-drawer-content { - overflow: visible; +.dashboard { + .mat-drawer-content { + overflow: visible; + } + .mat-drawer-side { + border: 0; + } + .mat-card-title { + font-size: inherit; + font-weight: inherit; + } } + + html { box-sizing: border-box; } diff --git a/src/frontend/packages/core/src/test.ts b/src/frontend/packages/core/src/test.ts index f9062ae858..d0b441ad3d 100644 --- a/src/frontend/packages/core/src/test.ts +++ b/src/frontend/packages/core/src/test.ts @@ -1,24 +1,17 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files - import 'zone.js/dist/long-stack-trace-zone'; -import 'zone.js/dist/proxy.js'; +import 'zone.js/dist/proxy'; import 'zone.js/dist/sync-test'; import 'zone.js/dist/jasmine-patch'; import 'zone.js/dist/async-test'; import 'zone.js/dist/fake-async-test'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; + import { APP_BASE_HREF } from '@angular/common'; +import { getTestBed } from '@angular/core/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. -declare const __karma__: any; -declare const require: any; -// Prevent Karma from running prematurely. -__karma__.loaded = function () { }; +declare const require: any; // First, initialize the Angular testing environment. const testBed = getTestBed(); @@ -44,5 +37,3 @@ beforeAll(() => { const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. context.keys().map(context); -// Finally, start Karma to run the tests. -__karma__.start(); diff --git a/src/frontend/packages/core/tslint.json b/src/frontend/packages/core/tslint.json index 9da788b6cb..1f63906f09 100644 --- a/src/frontend/packages/core/tslint.json +++ b/src/frontend/packages/core/tslint.json @@ -1,3 +1,3 @@ { - "extends": "../../../../tslint.json" + "extends": "../../../tslint.json" } diff --git a/src/frontend/packages/store-helpers/src/test.ts b/src/frontend/packages/store-helpers/src/test.ts index e11ff1c97b..d0b441ad3d 100644 --- a/src/frontend/packages/store-helpers/src/test.ts +++ b/src/frontend/packages/store-helpers/src/test.ts @@ -1,21 +1,38 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/proxy'; +import 'zone.js/dist/sync-test'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; -import 'core-js/es7/reflect'; -import 'zone.js/dist/zone'; -import 'zone.js/dist/zone-testing'; +import { APP_BASE_HREF } from '@angular/common'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; + declare const require: any; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( +const testBed = getTestBed(); +testBed.initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting() ); + +beforeEach(() => { + testBed.configureTestingModule({ + providers: [{ provide: APP_BASE_HREF, useValue: '/' }] + }); +}); + +/** + * Bump up the Jasmine timeout from 5 seconds + */ +beforeAll(() => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; +}); + // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/src/frontend/packages/store/src/actions/application.actions.ts b/src/frontend/packages/store/src/actions/application.actions.ts index b5529ab443..a91d1ca040 100644 --- a/src/frontend/packages/store/src/actions/application.actions.ts +++ b/src/frontend/packages/store/src/actions/application.actions.ts @@ -1,4 +1,6 @@ import { Headers, RequestOptions, URLSearchParams } from '@angular/http'; + +import { IApp } from '../../../core/src/core/cf-api.types'; import { applicationSchemaKey, appStatsSchemaKey, entityFactory } from '../helpers/entity-factory'; import { EntityInlineParentAction } from '../helpers/entity-relations/entity-relations.types'; import { pick } from '../helpers/reducer.helper'; @@ -6,7 +8,6 @@ import { ActionMergeFunction } from '../types/api.types'; import { PaginatedAction, PaginationParam } from '../types/pagination.types'; import { CFStartAction, ICFAction } from '../types/request.types'; import { AppMetadataTypes } from './app-metadata.actions'; -import { IApp } from '../../../core/src/core/cf-api.types'; export const GET_ALL = '[Application] Get all'; export const GET_ALL_SUCCESS = '[Application] Get all success'; @@ -113,12 +114,9 @@ export class UpdateExistingApplication extends CFStartAction implements ICFActio /** * Creates an instance of UpdateExistingApplication. - * @param {string} guid - * @param {string} endpointGuid - * @param {UpdateApplication} newApplication Sparsely populated application containing updated settings - * @param {IApp} [existingApplication] Existing application. Used in a few specific cases - * @param {AppMetadataTypes[]} [updateEntities] List of metadata calls to make if we successfully update the application - * @memberof UpdateExistingApplication + * @param newApplication Sparsely populated application containing updated settings + * @param [existingApplication] Existing application. Used in a few specific cases + * @param [updateEntities] List of metadata calls to make if we successfully update the application */ constructor( public guid: string, @@ -141,7 +139,7 @@ export class UpdateExistingApplication extends CFStartAction implements ICFActio entityMerge: ActionMergeFunction = (oldEntities, newEntities) => { const keepFromOld = pick( oldEntities[applicationSchemaKey][this.guid].entity, - Object.keys(applicationEntitySchema['schema']) + Object.keys(applicationEntitySchema.schema) ); newEntities[applicationSchemaKey][this.guid].entity = { ...newEntities[applicationSchemaKey][this.guid].entity, diff --git a/src/frontend/packages/store/src/actions/auth.actions.ts b/src/frontend/packages/store/src/actions/auth.actions.ts index 6fd423defa..a98ca3e741 100644 --- a/src/frontend/packages/store/src/actions/auth.actions.ts +++ b/src/frontend/packages/store/src/actions/auth.actions.ts @@ -45,7 +45,7 @@ export class VerifiedSession implements Action { export class InvalidSession implements Action { constructor(public uaaError: boolean = false, public upgradeInProgress = false, - public domainMismatch = false, public ssoOptions = '') { } + public domainMismatch = false, public ssoOptions = '') { } type = SESSION_INVALID; } diff --git a/src/frontend/packages/store/src/actions/deploy-applications.actions.ts b/src/frontend/packages/store/src/actions/deploy-applications.actions.ts index 5b4dcf4ce8..b71847ffab 100644 --- a/src/frontend/packages/store/src/actions/deploy-applications.actions.ts +++ b/src/frontend/packages/store/src/actions/deploy-applications.actions.ts @@ -1,11 +1,11 @@ import { Action } from '@ngrx/store'; +import { GitSCM } from '../../../core/src/shared/data-services/scm/scm'; import { gitBranchesSchemaKey, gitCommitSchemaKey } from '../helpers/entity-factory'; -import { GitAppDetails, SourceType, OverrideAppDetails } from '../types/deploy-application.types'; +import { GitAppDetails, OverrideAppDetails, SourceType } from '../types/deploy-application.types'; import { GitBranch, GitCommit } from '../types/git.types'; import { PaginatedAction } from '../types/pagination.types'; import { IRequestAction } from '../types/request.types'; -import { GitSCM } from '../../../core/src/shared/data-services/scm/scm'; export const SET_APP_SOURCE_DETAILS = '[Deploy App] Application Source'; export const CHECK_PROJECT_EXISTS = '[Deploy App] Check Projet exists'; @@ -87,9 +87,8 @@ export class FetchCommits implements PaginatedAction { /** * Creates an instance of FetchCommits. - * @param {string} projectName For example `cloudfoundry-incubator/stratos` - * @param {string} sha Branch name, tag, etc - * @memberof FetchCommits + * @param projectName For example `cloudfoundry-incubator/stratos` + * @param sha Branch name, tag, etc */ constructor(public scm: GitSCM, public projectName: string, public sha: string) { this.paginationKey = scm.getType() + projectName + sha; diff --git a/src/frontend/packages/store/src/actions/organization.actions.ts b/src/frontend/packages/store/src/actions/organization.actions.ts index 0dd70109d7..4cf1963abf 100644 --- a/src/frontend/packages/store/src/actions/organization.actions.ts +++ b/src/frontend/packages/store/src/actions/organization.actions.ts @@ -30,9 +30,9 @@ export const GET_ORGANIZATION_USERS_FAILED = '[Organization] Get all org users f export class GetOrganization extends CFStartAction implements ICFAction, EntityInlineParentAction { constructor(public guid: string, - public endpointGuid: string, - public includeRelations: string[] = [], - public populateMissing = true) { + public endpointGuid: string, + public includeRelations: string[] = [], + public populateMissing = true) { super(); this.options = new RequestOptions(); this.options.url = `organizations/${guid}`; @@ -132,7 +132,7 @@ export class CreateOrganization extends CFStartAction implements ICFAction { this.options.method = 'post'; this.guid = name; this.options.body = { - name: name + name }; } actions = getActions('Organizations', 'Create Org'); diff --git a/src/frontend/packages/store/src/actions/pagination.actions.ts b/src/frontend/packages/store/src/actions/pagination.actions.ts index 33e9819e86..0b7a976108 100644 --- a/src/frontend/packages/store/src/actions/pagination.actions.ts +++ b/src/frontend/packages/store/src/actions/pagination.actions.ts @@ -45,8 +45,6 @@ export class ResetPagination implements BasePaginatedAction { export class CreatePagination implements BasePaginatedAction { /** - * @param entityKey - * @param paginationKey * @param seed The pagination key for the section we should use as a seed when creating the new pagination section. */ constructor(public entityKey: string, public paginationKey: string, public seed?: string) { diff --git a/src/frontend/packages/store/src/actions/relation.actions.ts b/src/frontend/packages/store/src/actions/relation.actions.ts index 3fa93c63b7..7cbacbcc1a 100644 --- a/src/frontend/packages/store/src/actions/relation.actions.ts +++ b/src/frontend/packages/store/src/actions/relation.actions.ts @@ -1,7 +1,11 @@ import { RequestOptions, URLSearchParams } from '@angular/http'; import { EntitySchema } from '../helpers/entity-factory'; -import { EntityInlineChildAction, EntityInlineParentAction, EntityTreeRelation } from '../helpers/entity-relations/entity-relations.types'; +import { + EntityInlineChildAction, + EntityInlineParentAction, + EntityTreeRelation, +} from '../helpers/entity-relations/entity-relations.types'; import { PaginatedAction } from '../types/pagination.types'; import { CFStartAction, IRequestActionEntity, RequestEntityLocation } from '../types/request.types'; @@ -35,8 +39,8 @@ export abstract class FetchRelationAction extends CFStartAction implements Entit ]; options: RequestOptions; parentEntitySchema: EntitySchema; - static is(anything): FetchRelationAction { - return (anything['isId'] === relationActionId) ? anything as FetchRelationAction : null; + static is(anything: any): FetchRelationAction { + return (anything.isId === relationActionId) ? anything as FetchRelationAction : null; } } diff --git a/src/frontend/packages/store/src/actions/route.actions.ts b/src/frontend/packages/store/src/actions/route.actions.ts index 54958d1f6a..1a1200a6b7 100644 --- a/src/frontend/packages/store/src/actions/route.actions.ts +++ b/src/frontend/packages/store/src/actions/route.actions.ts @@ -98,7 +98,6 @@ export class DeleteRoute extends BaseRouteAction { export class UnmapRoute extends BaseRouteAction { /** * The key of the pagination section to remove the route from. Note, this should not be called `paginationKey` - * @param clearPaginationKey */ constructor( public routeGuid: string, diff --git a/src/frontend/packages/store/src/actions/router.actions.ts b/src/frontend/packages/store/src/actions/router.actions.ts index 133991c672..ce2745d9d6 100644 --- a/src/frontend/packages/store/src/actions/router.actions.ts +++ b/src/frontend/packages/store/src/actions/router.actions.ts @@ -19,7 +19,7 @@ export class RouterNav implements Action, LoggerAction { path: string[] | string; query?: RouterQueryParams; extras?: NavigationExtras; - }, public redirect?: RouterRedirect) { + }, public redirect?: RouterRedirect) { const path = payload.path as string[]; const pathString = payload.path as string; this.message = path.join ? path.join('/') : pathString; diff --git a/src/frontend/packages/store/src/actions/service-bindings.actions.ts b/src/frontend/packages/store/src/actions/service-bindings.actions.ts index ab95482f65..e2bfd94448 100644 --- a/src/frontend/packages/store/src/actions/service-bindings.actions.ts +++ b/src/frontend/packages/store/src/actions/service-bindings.actions.ts @@ -20,7 +20,7 @@ export class CreateServiceBinding extends CFStartAction implements ICFAction { public guid: string, public appGuid: string, public serviceInstanceGuid: string, - public params: Object, + public params: object, ) { super(); this.options = new RequestOptions(); diff --git a/src/frontend/packages/store/src/actions/service-instances.actions.ts b/src/frontend/packages/store/src/actions/service-instances.actions.ts index 336edd011e..b92845c3f9 100644 --- a/src/frontend/packages/store/src/actions/service-instances.actions.ts +++ b/src/frontend/packages/store/src/actions/service-instances.actions.ts @@ -99,7 +99,7 @@ export class CreateServiceInstance extends CFStartAction implements ICFAction { public name: string, public servicePlanGuid: string, public spaceGuid: string, - public params: Object, + public params: object, public tags: string[], ) { super(); @@ -109,11 +109,11 @@ export class CreateServiceInstance extends CFStartAction implements ICFAction { this.options.params.set('accepts_incomplete', 'true'); this.options.method = 'post'; this.options.body = { - name: name, + name, space_guid: spaceGuid, service_plan_guid: servicePlanGuid, parameters: params, - tags: tags + tags }; } actions = getActions('Service Instances', 'Create Service Instance'); @@ -130,7 +130,7 @@ export class UpdateServiceInstance extends CreateServiceInstance { public name: string, public servicePlanGuid: string, public spaceGuid: string, - public params: Object, + public params: object, public tags: string[], ) { super(endpointGuid, guid, name, servicePlanGuid, spaceGuid, params, tags); diff --git a/src/frontend/packages/store/src/actions/space.actions.ts b/src/frontend/packages/store/src/actions/space.actions.ts index bcdc88c9ea..f8a4f11b9c 100644 --- a/src/frontend/packages/store/src/actions/space.actions.ts +++ b/src/frontend/packages/store/src/actions/space.actions.ts @@ -184,7 +184,7 @@ export class CreateSpace extends BaseSpaceAction { this.options.url = `spaces`; this.options.method = 'post'; this.options.body = { - name: name, + name, organization_guid: orgGuid }; } @@ -269,7 +269,7 @@ export class GetServiceInstancesForSpace this.options.method = 'get'; this.options.params = new URLSearchParams(); if (q) { - this.initialParams['q'] = q; + this.initialParams.q = q; } this.parentGuid = spaceGuid; } @@ -282,6 +282,7 @@ export class GetServiceInstancesForSpace 'results-per-page': 100, 'order-direction': 'desc', 'order-direction-field': 'creation', + q: null }; parentGuid: string; parentEntitySchema = entityFactory(spaceSchemaKey); diff --git a/src/frontend/packages/store/src/actions/users.actions.ts b/src/frontend/packages/store/src/actions/users.actions.ts index b068823549..a428147046 100644 --- a/src/frontend/packages/store/src/actions/users.actions.ts +++ b/src/frontend/packages/store/src/actions/users.actions.ts @@ -74,8 +74,8 @@ export class GetAllUsersAsAdmin extends CFStartAction implements PaginatedAction }; flattenPagination = true; flattenPaginationMax = 600; - static is(action: PaginatedAction): boolean { - return !!action['isGetAllUsersAsAdmin']; + static is(action: any): boolean { + return !!action.isGetAllUsersAsAdmin; } } diff --git a/src/frontend/packages/store/src/effects/action-history.effects.ts b/src/frontend/packages/store/src/effects/action-history.effects.ts index 4cfa88d749..28da9e42f6 100644 --- a/src/frontend/packages/store/src/effects/action-history.effects.ts +++ b/src/frontend/packages/store/src/effects/action-history.effects.ts @@ -1,10 +1,11 @@ - -import { take, map } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; +import { map, take } from 'rxjs/operators'; + +import { ActionHistoryActions, ActionHistoryDump } from '../actions/action-history.actions'; import { AppState } from '../app-state'; -import { Injectable } from '@angular/core'; -import { Effect, Actions } from '@ngrx/effects'; -import { ActionHistoryDump, ActionHistoryActions } from '../actions/action-history.actions'; + @Injectable() @@ -15,7 +16,8 @@ export class ActionHistoryEffect { private store: Store, ) { } - @Effect({ dispatch: false }) dumpActionHistory$ = this.actions$.ofType(ActionHistoryActions.DUMP).pipe( + @Effect({ dispatch: false }) dumpActionHistory$ = this.actions$.pipe( + ofType(ActionHistoryActions.DUMP), map(() => { this.store.select('actionHistory').pipe( take(1)) diff --git a/src/frontend/packages/store/src/effects/api.effects.ts b/src/frontend/packages/store/src/effects/api.effects.ts index 013958a989..62d6a991aa 100644 --- a/src/frontend/packages/store/src/effects/api.effects.ts +++ b/src/frontend/packages/store/src/effects/api.effects.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Headers, Http, Request, RequestOptions, URLSearchParams } from '@angular/http'; import { RequestArgs } from '@angular/http/src/interfaces'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { normalize, Schema } from 'normalizr'; import { Observable } from 'rxjs'; @@ -60,14 +60,13 @@ export class APIEffect { ) { } @Effect() - apiRequest$ = this.actions$ - .ofType(ApiActionTypes.API_REQUEST_START) - .pipe( - withLatestFrom(this.store), - mergeMap(([action, state]) => { - return this.doApiRequest(action, state); - }), - ); + apiRequest$ = this.actions$.pipe( + ofType(ApiActionTypes.API_REQUEST_START), + withLatestFrom(this.store), + mergeMap(([action, state]) => { + return this.doApiRequest(action, state); + }), + ); private doApiRequest(action: ICFAction | PaginatedAction, state: AppState) { const actionClone = { ...action }; @@ -168,7 +167,8 @@ export class APIEffect { this.handleApiEvents(errorsCheck); } - let fakedAction, errorMessage; + let fakedAction; + let errorMessage; errorsCheck.forEach(error => { if (error.error) { // Dispatch a error action for the specific endpoint that's failed @@ -284,7 +284,7 @@ export class APIEffect { } : { entity: { ...resource, cfGuid }, - metadata: { guid: guid }, + metadata: { guid }, }; // Inject `cfGuid` in nested entities @@ -355,7 +355,7 @@ export class APIEffect { errorCode: succeeded ? '200' : errorCode, guid: cfGuid, url: action.options.url, - errorResponse: errorResponse, + errorResponse, }; }); } @@ -425,8 +425,8 @@ export class APIEffect { apiAction.guid, ); } - totalResults += cfData['total_results']; - totalPages += cfData['total_pages']; + totalResults += cfData.total_results; + totalPages += cfData.total_pages; if (!cfData.resources.length) { return null; } @@ -442,6 +442,7 @@ export class APIEffect { const flatEntities = [].concat(...allEntities).filter(e => !!e); let entityArray; + /* tslint:disable-next-line:no-string-literal */ if (apiAction.entity['length'] > 0) { entityArray = apiAction.entity; } else { diff --git a/src/frontend/packages/store/src/effects/app-variables.effects.ts b/src/frontend/packages/store/src/effects/app-variables.effects.ts index 31e8ea1e50..63393d72f1 100644 --- a/src/frontend/packages/store/src/effects/app-variables.effects.ts +++ b/src/frontend/packages/store/src/effects/app-variables.effects.ts @@ -1,12 +1,13 @@ - -import {map} from 'rxjs/operators'; -import { Store } from '@ngrx/store'; -import { AppState } from '../app-state'; import { Injectable } from '@angular/core'; -import { Effect, Actions } from '@ngrx/effects'; -import { AppVariablesUpdate, AppVariables } from '../actions/app-variables.actions'; -import { UpdateExistingApplication } from '../actions/application.actions'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Store } from '@ngrx/store'; +import { map } from 'rxjs/operators'; + import { AppMetadataTypes } from '../actions/app-metadata.actions'; +import { AppVariables, AppVariablesUpdate } from '../actions/app-variables.actions'; +import { UpdateExistingApplication } from '../actions/application.actions'; +import { AppState } from '../app-state'; + @Injectable() @@ -17,7 +18,8 @@ export class AppVariablesEffect { private store: Store, ) { } - @Effect() apiRequestStart$ = this.actions$.ofType(AppVariables.UPDATE).pipe( + @Effect() apiRequestStart$ = this.actions$.pipe( + ofType(AppVariables.UPDATE), map((apiAction: AppVariablesUpdate) => { return new UpdateExistingApplication( apiAction.appGuid, diff --git a/src/frontend/packages/store/src/effects/app.effects.ts b/src/frontend/packages/store/src/effects/app.effects.ts index 050cd9554c..bbe1a612c9 100644 --- a/src/frontend/packages/store/src/effects/app.effects.ts +++ b/src/frontend/packages/store/src/effects/app.effects.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { first, map } from 'rxjs/operators'; @@ -22,13 +22,15 @@ export class AppEffects { private store: Store, ) { } - @Effect({ dispatch: false }) updateSummary$ = this.actions$.ofType(ASSIGN_ROUTE_SUCCESS).pipe( + @Effect({ dispatch: false }) updateSummary$ = this.actions$.pipe( + ofType(ASSIGN_ROUTE_SUCCESS), map(action => { this.store.dispatch(new GetAppSummaryAction(action.apiAction.guid, action.apiAction.endpointGuid)); }), ); - @Effect({ dispatch: false }) clearCellMetrics$ = this.actions$.ofType(UPDATE_SUCCESS).pipe( + @Effect({ dispatch: false }) clearCellMetrics$ = this.actions$.pipe( + ofType(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/store/src/effects/auth.effects.ts b/src/frontend/packages/store/src/effects/auth.effects.ts index 8fc5cd6785..a355c8b80c 100644 --- a/src/frontend/packages/store/src/effects/auth.effects.ts +++ b/src/frontend/packages/store/src/effects/auth.effects.ts @@ -1,8 +1,9 @@ import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { catchError, map, mergeMap, switchMap, tap } from 'rxjs/operators'; +import { BrowserStandardEncoder } from '../../../core/src/helper'; import { GET_ENDPOINTS_SUCCESS, GetAllEndpointsSuccess } from '../actions/endpoint.actions'; import { GetSystemInfo } from '../actions/system.actions'; import { SessionData } from '../types/auth.types'; @@ -25,7 +26,6 @@ import { VERIFY_SESSION, VerifySession, } from './../actions/auth.actions'; -import { BrowserStandardEncoder } from '../../../core/src/helper'; const SETUP_HEADER = 'stratos-setup-required'; const UPGRADE_HEADER = 'retry-after'; @@ -40,33 +40,35 @@ export class AuthEffect { private actions$: Actions ) { } - @Effect() loginRequest$ = this.actions$.ofType(LOGIN).pipe( + @Effect() loginRequest$ = this.actions$.pipe( + ofType(LOGIN), switchMap(({ username, password }) => { const encoder = new BrowserStandardEncoder(); const headers = new HttpHeaders(); const params = new HttpParams({ encoder: new BrowserStandardEncoder(), fromObject: { - username: username, - password: password + username, + password } }); headers.set('Content-Type', 'application/x-www-form-urlencoded'); headers.set('x-cap-request-date', (Math.floor(Date.now() / 1000)).toString()); return this.http.post('/pp/v1/auth/login/uaa', params, { - headers: headers, + headers, }).pipe( map(data => new VerifySession()), catchError((err, caught) => [new LoginFailed(err)])); })); - @Effect() verifyAuth$ = this.actions$.ofType(VERIFY_SESSION).pipe( + @Effect() verifyAuth$ = this.actions$.pipe( + ofType(VERIFY_SESSION), switchMap(action => { const headers = new HttpHeaders(); headers.set('x-cap-request-date', (Math.floor(Date.now() / 1000)).toString()); return this.http.get('/pp/v1/auth/session/verify', { - headers: headers, + headers, observe: 'response', withCredentials: true, }).pipe( @@ -90,7 +92,8 @@ export class AuthEffect { })); })); - @Effect() EndpointsSuccess$ = this.actions$.ofType(GET_ENDPOINTS_SUCCESS).pipe( + @Effect() EndpointsSuccess$ = this.actions$.pipe( + ofType(GET_ENDPOINTS_SUCCESS), mergeMap(action => { if (action.login) { return [new LoginSuccess()]; @@ -98,12 +101,14 @@ export class AuthEffect { return []; })); - @Effect() invalidSessionAuth$ = this.actions$.ofType(SESSION_INVALID).pipe( + @Effect() invalidSessionAuth$ = this.actions$.pipe( + ofType(SESSION_INVALID), map(() => { return new LoginFailed('Invalid session'); })); - @Effect() logoutRequest$ = this.actions$.ofType(LOGOUT).pipe( + @Effect() logoutRequest$ = this.actions$.pipe( + ofType(LOGOUT), switchMap(() => { return this.http.post('/pp/v1/auth/logout', {}).pipe( mergeMap((data: any) => { @@ -116,13 +121,15 @@ export class AuthEffect { catchError((err, caught) => [new LogoutFailed(err)])); })); - @Effect({ dispatch: false }) resetAuth$ = this.actions$.ofType(RESET_AUTH).pipe( + @Effect({ dispatch: false }) resetAuth$ = this.actions$.pipe( + ofType(RESET_AUTH), tap(() => { // Ensure that we clear any path from the location (otherwise would be stored via auth gate as redirectPath for log in) window.location.assign(window.location.origin); })); - @Effect({ dispatch: false }) resetSSOAuth$ = this.actions$.ofType(RESET_SSO_AUTH).pipe( + @Effect({ dispatch: false }) resetSSOAuth$ = this.actions$.pipe( + ofType(RESET_SSO_AUTH), tap(() => { // Ensure that we clear any path from the location (otherwise would be stored via auth gate as redirectPath for log in) const returnUrl = encodeURI(window.location.origin); diff --git a/src/frontend/packages/store/src/effects/cloud-foundry.effects.ts b/src/frontend/packages/store/src/effects/cloud-foundry.effects.ts index 321d444462..13c6c7a660 100644 --- a/src/frontend/packages/store/src/effects/cloud-foundry.effects.ts +++ b/src/frontend/packages/store/src/effects/cloud-foundry.effects.ts @@ -1,15 +1,20 @@ import { Injectable } from '@angular/core'; import { Headers, Http } from '@angular/http'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; -import { flatMap, mergeMap, catchError } from 'rxjs/operators'; +import { catchError, flatMap, mergeMap } from 'rxjs/operators'; +import { environment } from '../../../core/src/environments/environment.prod'; import { GET_INFO, GetCFInfo } from '../actions/cloud-foundry.actions'; +import { cfInfoSchemaKey } from '../helpers/entity-factory'; import { NormalizedResponse } from '../types/api.types'; -import { StartRequestAction, WrapperRequestActionFailed, WrapperRequestActionSuccess, ICFAction } from '../types/request.types'; +import { + ICFAction, + StartRequestAction, + WrapperRequestActionFailed, + WrapperRequestActionSuccess, +} from '../types/request.types'; import { AppState } from './../app-state'; -import { cfInfoSchemaKey } from '../helpers/entity-factory'; -import { environment } from '../../../core/src/environments/environment.prod'; @Injectable() export class CloudFoundryEffects { @@ -21,7 +26,8 @@ export class CloudFoundryEffects { ) { } @Effect() - fetchInfo$ = this.actions$.ofType(GET_INFO).pipe( + fetchInfo$ = this.actions$.pipe( + ofType(GET_INFO), flatMap(action => { const actionType = 'fetch'; const apiAction = { @@ -31,7 +37,7 @@ export class CloudFoundryEffects { this.store.dispatch(new StartRequestAction(apiAction, actionType)); const headers = new Headers({ 'x-cap-cnsi-list': action.cfGuid }); const requestArgs = { - headers: headers + headers }; const url = `/pp/${this.proxyAPIVersion}/proxy/v2/info`; return this.http diff --git a/src/frontend/packages/store/src/effects/create-app-effects.ts b/src/frontend/packages/store/src/effects/create-app-effects.ts index 9f0183f922..921d51f9d9 100644 --- a/src/frontend/packages/store/src/effects/create-app-effects.ts +++ b/src/frontend/packages/store/src/effects/create-app-effects.ts @@ -1,22 +1,16 @@ - -import { of as observableOf, throwError as observableThrowError, Observable } from 'rxjs'; - -import { catchError, map, withLatestFrom, switchMap } from 'rxjs/operators'; -import { selectNewAppCFDetails } from '../selectors/create-application.selectors'; import { Injectable } from '@angular/core'; import { Headers, Http } from '@angular/http'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; +import { of as observableOf, throwError as observableThrowError } from 'rxjs'; +import { catchError, map, switchMap, withLatestFrom } from 'rxjs/operators'; -import { - AppNameFree, - AppNameTaken, - CHECK_NAME, - IsNewAppNameFree -} from '../actions/create-applications-page.actions'; -import { AppState } from './../app-state'; -import { NewAppCFDetails, CreateNewApplicationState } from '../types/create-application.types'; import { environment } from '../../../core/src/environments/environment.prod'; +import { AppNameFree, AppNameTaken, CHECK_NAME, IsNewAppNameFree } from '../actions/create-applications-page.actions'; +import { selectNewAppCFDetails } from '../selectors/create-application.selectors'; +import { CreateNewApplicationState, NewAppCFDetails } from '../types/create-application.types'; +import { AppState } from './../app-state'; + @Injectable() @@ -34,14 +28,15 @@ export class CreateAppPageEffects { proxyAPIVersion: string; cfAPIVersion: string; - @Effect() CheckAppNameIsFree$ = this.actions$.ofType(CHECK_NAME).pipe( + @Effect() CheckAppNameIsFree$ = this.actions$.pipe( + ofType(CHECK_NAME), withLatestFrom(this.store.select(selectNewAppCFDetails)), switchMap(([action, cfDetails]: [any, NewAppCFDetails]) => { const { cloudFoundry, org, space } = cfDetails; const headers = new Headers({ 'x-cap-cnsi-list': cloudFoundry }); return this.http.get(`/pp/${this.proxyAPIVersion}/proxy/${this.cfAPIVersion}/apps`, { params: { - 'q': `name:${action.name};space_guid:${space}` + q: `name:${action.name};space_guid:${space}` }, headers }).pipe( diff --git a/src/frontend/packages/store/src/effects/deploy-app.effects.ts b/src/frontend/packages/store/src/effects/deploy-app.effects.ts index d657feb6a5..1426fa9a4e 100644 --- a/src/frontend/packages/store/src/effects/deploy-app.effects.ts +++ b/src/frontend/packages/store/src/effects/deploy-app.effects.ts @@ -1,23 +1,12 @@ import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { of as observableOf } from 'rxjs'; import { catchError, filter, map, mergeMap, switchMap, withLatestFrom } from 'rxjs/operators'; -import { gitBranchesSchemaKey, gitCommitSchemaKey } from '../helpers/entity-factory'; -import { selectDeployAppState } from '../selectors/deploy-application.selector'; -import { NormalizedResponse } from '../types/api.types'; -import { - ICFAction, - StartRequestAction, - WrapperRequestActionFailed, - WrapperRequestActionSuccess, -} from '../types/request.types'; -import { AppState } from './../app-state'; -import { PaginatedAction } from './../types/pagination.types'; -import { parseHttpPipeError } from '../../../core/src/core/utils.service'; import { LoggerService } from '../../../core/src/core/logger.service'; +import { parseHttpPipeError } from '../../../core/src/core/utils.service'; import { CHECK_PROJECT_EXISTS, CheckProjectExists, @@ -31,11 +20,22 @@ import { ProjectExists, ProjectFetchFail, } from '../actions/deploy-applications.actions'; +import { gitBranchesSchemaKey, gitCommitSchemaKey } from '../helpers/entity-factory'; +import { selectDeployAppState } from '../selectors/deploy-application.selector'; +import { NormalizedResponse } from '../types/api.types'; import { GitCommit } from '../types/git.types'; +import { + ICFAction, + StartRequestAction, + WrapperRequestActionFailed, + WrapperRequestActionSuccess, +} from '../types/request.types'; +import { AppState } from './../app-state'; +import { PaginatedAction } from './../types/pagination.types'; export function createFailedGithubRequestMessage(error) { const response = parseHttpPipeError(error); - const message = response['message'] || ''; + const message = response.message || ''; return error.status === 403 && message.startsWith('API rate limit exceeded for') ? 'Github ' + message.substring(0, message.indexOf('(')) : 'Github request failed'; @@ -51,115 +51,115 @@ export class DeployAppEffects { ) { } @Effect() - checkAppExists$ = this.actions$ - .ofType(CHECK_PROJECT_EXISTS).pipe( - withLatestFrom(this.store.select(selectDeployAppState)), - filter(([action, state]) => { - return state.projectExists && state.projectExists.checking; - }), - switchMap(([action, state]: any) => { - return action.scm.getRepository(action.projectName).pipe( - map(res => new ProjectExists(action.projectName, res)), - catchError(err => observableOf(err.status === 404 ? - new ProjectDoesntExist(action.projectName) : - new ProjectFetchFail(action.projectName, createFailedGithubRequestMessage(err)) - )) - ); - }) - ); + checkAppExists$ = this.actions$.pipe( + ofType(CHECK_PROJECT_EXISTS), + withLatestFrom(this.store.select(selectDeployAppState)), + filter(([action, state]) => { + return state.projectExists && state.projectExists.checking; + }), + switchMap(([action, state]: any) => { + return action.scm.getRepository(action.projectName).pipe( + map(res => new ProjectExists(action.projectName, res)), + catchError(err => observableOf(err.status === 404 ? + new ProjectDoesntExist(action.projectName) : + new ProjectFetchFail(action.projectName, createFailedGithubRequestMessage(err)) + )) + ); + }) + ); @Effect() - fetchBranches$ = this.actions$ - .ofType(FETCH_BRANCHES_FOR_PROJECT).pipe( - mergeMap(action => { - const actionType = 'fetch'; - const apiAction = { - entityKey: gitBranchesSchemaKey, - type: action.type, - paginationKey: 'branches' - } as PaginatedAction; - this.store.dispatch(new StartRequestAction(apiAction, actionType)); - return action.scm.getBranches(action.projectName).pipe( - mergeMap(branches => { - const mappedData = { - entities: { gitBranches: {} }, - result: [] - } as NormalizedResponse; + fetchBranches$ = this.actions$.pipe( + ofType(FETCH_BRANCHES_FOR_PROJECT), + mergeMap(action => { + const actionType = 'fetch'; + const apiAction = { + entityKey: gitBranchesSchemaKey, + type: action.type, + paginationKey: 'branches' + } as PaginatedAction; + this.store.dispatch(new StartRequestAction(apiAction, actionType)); + return action.scm.getBranches(action.projectName).pipe( + mergeMap(branches => { + const mappedData = { + entities: { gitBranches: {} }, + result: [] + } as NormalizedResponse; - const scmType = action.scm.getType(); - branches.forEach(b => { - const id = `${scmType}-${action.projectName}-${b.name}`; - b.projectId = action.projectName; - b.entityId = id; - mappedData.entities[gitBranchesSchemaKey][id] = { - entity: b, - metadata: {} - }; - mappedData.result.push(id); - }); - return [ - new WrapperRequestActionSuccess(mappedData, apiAction, actionType) - ]; - }), - catchError(err => [ - new WrapperRequestActionFailed(createFailedGithubRequestMessage(err), apiAction, actionType) - ])); - })); + const scmType = action.scm.getType(); + branches.forEach(b => { + const id = `${scmType}-${action.projectName}-${b.name}`; + b.projectId = action.projectName; + b.entityId = id; + mappedData.entities[gitBranchesSchemaKey][id] = { + entity: b, + metadata: {} + }; + mappedData.result.push(id); + }); + return [ + new WrapperRequestActionSuccess(mappedData, apiAction, actionType) + ]; + }), + catchError(err => [ + new WrapperRequestActionFailed(createFailedGithubRequestMessage(err), apiAction, actionType) + ])); + })); @Effect() - fetchCommit$ = this.actions$ - .ofType(FETCH_COMMIT).pipe( - mergeMap(action => { - const actionType = 'fetch'; - const apiAction = { - entityKey: gitCommitSchemaKey, - type: action.type - } as ICFAction; - this.store.dispatch(new StartRequestAction(apiAction, actionType)); - return action.scm.getCommit(action.projectName, action.commitSha).pipe( - mergeMap(commit => { - const mappedData = { - entities: { [gitCommitSchemaKey]: {} }, - result: [] - } as NormalizedResponse; - this.addCommit(mappedData, action.scm.getType(), action.projectName, commit); - return [ - new WrapperRequestActionSuccess(mappedData, apiAction, actionType) - ]; - }), - catchError(err => [ - new WrapperRequestActionFailed(createFailedGithubRequestMessage(err), apiAction, actionType) - ])); - })); + fetchCommit$ = this.actions$.pipe( + ofType(FETCH_COMMIT), + mergeMap(action => { + const actionType = 'fetch'; + const apiAction = { + entityKey: gitCommitSchemaKey, + type: action.type + } as ICFAction; + this.store.dispatch(new StartRequestAction(apiAction, actionType)); + return action.scm.getCommit(action.projectName, action.commitSha).pipe( + mergeMap(commit => { + const mappedData = { + entities: { [gitCommitSchemaKey]: {} }, + result: [] + } as NormalizedResponse; + this.addCommit(mappedData, action.scm.getType(), action.projectName, commit); + return [ + new WrapperRequestActionSuccess(mappedData, apiAction, actionType) + ]; + }), + catchError(err => [ + new WrapperRequestActionFailed(createFailedGithubRequestMessage(err), apiAction, actionType) + ])); + })); @Effect() - fetchCommits$ = this.actions$ - .ofType(FETCH_COMMITS).pipe( - mergeMap(action => { - const actionType = 'fetch'; - const apiAction = { - entityKey: gitCommitSchemaKey, - type: action.type, - paginationKey: action.paginationKey - } as PaginatedAction; - this.store.dispatch(new StartRequestAction(apiAction, actionType)); - return action.scm.getCommits(action.projectName, action.sha).pipe( - mergeMap((commits: GitCommit[]) => { - const mappedData = { - entities: { [gitCommitSchemaKey]: {} }, - result: [] - } as NormalizedResponse; - commits.forEach(commit => { - this.addCommit(mappedData, action.scm.getType(), action.projectName, commit); - }); - return [ - new WrapperRequestActionSuccess(mappedData, apiAction, actionType) - ]; - }), - catchError(err => [ - new WrapperRequestActionFailed(createFailedGithubRequestMessage(err), apiAction, actionType) - ])); - })); + fetchCommits$ = this.actions$.pipe( + ofType(FETCH_COMMITS), + mergeMap(action => { + const actionType = 'fetch'; + const apiAction = { + entityKey: gitCommitSchemaKey, + type: action.type, + paginationKey: action.paginationKey + } as PaginatedAction; + this.store.dispatch(new StartRequestAction(apiAction, actionType)); + return action.scm.getCommits(action.projectName, action.sha).pipe( + mergeMap((commits: GitCommit[]) => { + const mappedData = { + entities: { [gitCommitSchemaKey]: {} }, + result: [] + } as NormalizedResponse; + commits.forEach(commit => { + this.addCommit(mappedData, action.scm.getType(), action.projectName, commit); + }); + return [ + new WrapperRequestActionSuccess(mappedData, apiAction, actionType) + ]; + }), + catchError(err => [ + new WrapperRequestActionFailed(createFailedGithubRequestMessage(err), apiAction, actionType) + ])); + })); addCommit(mappedData: NormalizedResponse, scmType: string, projectName: string, commit: GitCommit) { const id = scmType + '-' + projectName + '-' + commit.sha; diff --git a/src/frontend/packages/store/src/effects/endpoint-api-errors.effects.ts b/src/frontend/packages/store/src/effects/endpoint-api-errors.effects.ts index 795c6f49c8..afaa1454a0 100644 --- a/src/frontend/packages/store/src/effects/endpoint-api-errors.effects.ts +++ b/src/frontend/packages/store/src/effects/endpoint-api-errors.effects.ts @@ -1,18 +1,19 @@ - - -// RequestTypes.FAILED - - -import { take, map } from 'rxjs/operators'; -import { Store } from '@ngrx/store'; -import { AppState } from '../app-state'; import { Injectable } from '@angular/core'; -import { Effect, Actions } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Store } from '@ngrx/store'; +import { map } from 'rxjs/operators'; + +import { SendEventAction } from '../actions/internal-events.actions'; import { RequestTypes } from '../actions/request.actions'; -import { WrapperRequestActionFailed } from '../types/request.types'; +import { AppState } from '../app-state'; import { endpointSchemaKey } from '../helpers/entity-factory'; -import { SendEventAction } from '../actions/internal-events.actions'; import { InternalEventSeverity } from '../types/internal-events.types'; +import { WrapperRequestActionFailed } from '../types/request.types'; + + + +// RequestTypes.FAILED + @Injectable() @@ -23,7 +24,8 @@ export class EndpointApiError { private store: Store, ) { } - @Effect({ dispatch: false }) endpointApiError$ = this.actions$.ofType(RequestTypes.FAILED).pipe( + @Effect({ dispatch: false }) endpointApiError$ = this.actions$.pipe( + ofType(RequestTypes.FAILED), map(action => { const internalEndpointError = action.internalEndpointError; if (internalEndpointError) { diff --git a/src/frontend/packages/store/src/effects/endpoint.effects.ts b/src/frontend/packages/store/src/effects/endpoint.effects.ts index 2394b2d5a9..a896715c4b 100644 --- a/src/frontend/packages/store/src/effects/endpoint.effects.ts +++ b/src/frontend/packages/store/src/effects/endpoint.effects.ts @@ -1,6 +1,6 @@ import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, mergeMap } from 'rxjs/operators'; @@ -57,8 +57,9 @@ export class EndpointsEffect { private store: Store ) { } - @Effect() getAllEndpoints$ = this.actions$.ofType(GET_SYSTEM_INFO_SUCCESS) - .pipe(mergeMap(action => { + @Effect() getAllEndpoints$ = this.actions$.pipe( + ofType(GET_SYSTEM_INFO_SUCCESS), + mergeMap(action => { const { associatedAction } = action; const actionType = 'fetch'; const endpoints = action.payload.endpoints; @@ -90,7 +91,8 @@ export class EndpointsEffect { ]; })); - @Effect() connectEndpoint$ = this.actions$.ofType(CONNECT_ENDPOINTS).pipe( + @Effect() connectEndpoint$ = this.actions$.pipe( + ofType(CONNECT_ENDPOINTS), mergeMap(action => { const actionType = 'update'; @@ -106,10 +108,10 @@ export class EndpointsEffect { const apiAction = this.getEndpointUpdateAction(action.guid, action.type, EndpointsEffect.connectingKey); const params: HttpParams = new HttpParams({ fromObject: { - ...action.authValues, - 'cnsi_guid': action.guid, - 'connect_type': action.authType, - 'system_shared': action.systemShared, + ...action.authValues as any, + cnsi_guid: action.guid, + connect_type: action.authType, + system_shared: action.systemShared, }, // Fix for #angular/18261 encoder: new BrowserStandardEncoder() @@ -126,13 +128,14 @@ export class EndpointsEffect { ); })); - @Effect() disconnect$ = this.actions$.ofType(DISCONNECT_ENDPOINTS).pipe( + @Effect() disconnect$ = this.actions$.pipe( + ofType(DISCONNECT_ENDPOINTS), mergeMap(action => { const apiAction = this.getEndpointUpdateAction(action.guid, action.type, EndpointsEffect.disconnectingKey); const params: HttpParams = new HttpParams({ fromObject: { - 'cnsi_guid': action.guid + cnsi_guid: action.guid } }); @@ -146,13 +149,14 @@ export class EndpointsEffect { ); })); - @Effect() unregister$ = this.actions$.ofType(UNREGISTER_ENDPOINTS).pipe( + @Effect() unregister$ = this.actions$.pipe( + ofType(UNREGISTER_ENDPOINTS), mergeMap(action => { const apiAction = this.getEndpointDeleteAction(action.guid, action.type); const params: HttpParams = new HttpParams({ fromObject: { - 'cnsi_guid': action.guid + cnsi_guid: action.guid } }); @@ -166,18 +170,19 @@ export class EndpointsEffect { ); })); - @Effect() register$ = this.actions$.ofType(REGISTER_ENDPOINTS).pipe( + @Effect() register$ = this.actions$.pipe( + ofType(REGISTER_ENDPOINTS), mergeMap(action => { const apiAction = this.getEndpointUpdateAction(action.guid(), action.type, EndpointsEffect.registeringKey); const params: HttpParams = new HttpParams({ fromObject: { - 'cnsi_name': action.name, - 'api_endpoint': action.endpoint, - 'skip_ssl_validation': action.skipSslValidation ? 'true' : 'false', - 'cnsi_client_id': action.clientID, - 'cnsi_client_secret': action.clientSecret, - 'sso_allowed': action.ssoAllowed ? 'true' : 'false', + cnsi_name: action.name, + api_endpoint: action.endpoint, + skip_ssl_validation: action.skipSslValidation ? 'true' : 'false', + cnsi_client_id: action.clientID, + cnsi_client_secret: action.clientSecret, + sso_allowed: action.ssoAllowed ? 'true' : 'false', } }); @@ -226,7 +231,7 @@ export class EndpointsEffect { actionStrings: [string, string] = [null, null], endpointType: EndpointType = 'cf', body?: string, - errorMessageHandler?: Function, + errorMessageHandler?: (e: any) => string, ) { const headers = new HttpHeaders(); headers.set('Content-Type', 'application/x-www-form-urlencoded'); diff --git a/src/frontend/packages/store/src/effects/github.effects.ts b/src/frontend/packages/store/src/effects/github.effects.ts index 2d8847e09b..ed57fbc47e 100644 --- a/src/frontend/packages/store/src/effects/github.effects.ts +++ b/src/frontend/packages/store/src/effects/github.effects.ts @@ -1,16 +1,16 @@ import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, mergeMap } from 'rxjs/operators'; +import { GitSCMService, GitSCMType } from '../../../core/src/shared/data-services/scm/scm.service'; import { FETCH_GITHUB_REPO, FetchGitHubRepoInfo } from '../actions/github.actions'; import { AppState } from '../app-state'; import { gitRepoSchemaKey } from '../helpers/entity-factory'; import { NormalizedResponse } from '../types/api.types'; import { StartRequestAction, WrapperRequestActionFailed, WrapperRequestActionSuccess } from '../types/request.types'; import { createFailedGithubRequestMessage } from './deploy-app.effects'; -import { GitSCMService, GitSCMType } from '../../../core/src/shared/data-services/scm/scm.service'; @Injectable() @@ -22,37 +22,37 @@ export class GithubEffects { private scmService: GitSCMService ) { } @Effect() - fetchCommit$ = this.actions$ - .ofType(FETCH_GITHUB_REPO).pipe( - mergeMap(action => { - const actionType = 'fetch'; - const apiAction = { - entityKey: gitRepoSchemaKey, - type: action.type, - guid: action.stProject.deploySource.project - }; - this.store.dispatch(new StartRequestAction(apiAction, actionType)); - const scmType = action.stProject.deploySource.scm || action.stProject.deploySource.type; - const scm = this.scmService.getSCM(scmType as GitSCMType); - return scm.getRepository(action.stProject.deploySource.project).pipe( - mergeMap(repoDetails => { - const mappedData = { - entities: { gitRepo: {} }, - result: [] - } as NormalizedResponse; - const id = scmType + '-' + repoDetails.full_name; - mappedData.entities.gitRepo[id] = { - entity: repoDetails, - metadata: {} - }; - mappedData.result.push(id); - return [ - new WrapperRequestActionSuccess(mappedData, apiAction, actionType) - ]; - }), - catchError(err => [ - new WrapperRequestActionFailed(createFailedGithubRequestMessage(err), apiAction, actionType) - ] - )); - })); + fetchCommit$ = this.actions$.pipe( + ofType(FETCH_GITHUB_REPO), + mergeMap(action => { + const actionType = 'fetch'; + const apiAction = { + entityKey: gitRepoSchemaKey, + type: action.type, + guid: action.stProject.deploySource.project + }; + this.store.dispatch(new StartRequestAction(apiAction, actionType)); + const scmType = action.stProject.deploySource.scm || action.stProject.deploySource.type; + const scm = this.scmService.getSCM(scmType as GitSCMType); + return scm.getRepository(action.stProject.deploySource.project).pipe( + mergeMap(repoDetails => { + const mappedData = { + entities: { gitRepo: {} }, + result: [] + } as NormalizedResponse; + const id = scmType + '-' + repoDetails.full_name; + mappedData.entities.gitRepo[id] = { + entity: repoDetails, + metadata: {} + }; + mappedData.result.push(id); + return [ + new WrapperRequestActionSuccess(mappedData, apiAction, actionType) + ]; + }), + catchError(err => [ + new WrapperRequestActionFailed(createFailedGithubRequestMessage(err), apiAction, actionType) + ] + )); + })); } diff --git a/src/frontend/packages/store/src/effects/metrics.effects.ts b/src/frontend/packages/store/src/effects/metrics.effects.ts index 347e2d4ce7..e2d9beca53 100644 --- a/src/frontend/packages/store/src/effects/metrics.effects.ts +++ b/src/frontend/packages/store/src/effects/metrics.effects.ts @@ -1,6 +1,6 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, map, mergeMap } from 'rxjs/operators'; @@ -14,12 +14,7 @@ import { getFullMetricQueryQuery, METRICS_START, MetricsAction } from '../action import { metricSchemaKey } from '../helpers/entity-factory'; import { IMetricsResponse } from '../types/base-metric.types'; import { AppState } from './../app-state'; -import { - IRequestAction, - StartRequestAction, - WrapperRequestActionFailed, - WrapperRequestActionSuccess, -} from './../types/request.types'; +import { StartRequestAction, WrapperRequestActionFailed, WrapperRequestActionSuccess } from './../types/request.types'; @Injectable() export class MetricsEffect { @@ -30,7 +25,8 @@ export class MetricsEffect { private store: Store ) { } - @Effect() metrics$ = this.actions$.ofType(METRICS_START).pipe( + @Effect() metrics$ = this.actions$.pipe( + ofType(METRICS_START), mergeMap(action => { const fullUrl = action.directApi ? action.url : this.buildFullUrl(action); const { guid } = action; @@ -73,7 +69,8 @@ export class MetricsEffect { })); })); - @Effect() metricsAPI$ = this.actions$.ofType(METRIC_API_START).pipe( + @Effect() metricsAPI$ = this.actions$.pipe( + ofType(METRIC_API_START), mergeMap(action => { return this.httpClient.get<{ [cfguid: string]: IMetricsResponse }>(action.url, { headers: { 'x-cap-cnsi-list': action.endpointGuid } diff --git a/src/frontend/packages/store/src/effects/pagination.effects.ts b/src/frontend/packages/store/src/effects/pagination.effects.ts index b8c2a4a071..5116582256 100644 --- a/src/frontend/packages/store/src/effects/pagination.effects.ts +++ b/src/frontend/packages/store/src/effects/pagination.effects.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { map } from 'rxjs/operators'; @@ -22,12 +22,12 @@ export class PaginationEffects { private store: Store ) { } - @Effect({ dispatch: false }) clearPaginationOnParamChange$ = - this.actions$.ofType(SET_PARAMS, ADD_PARAMS, REMOVE_PARAMS).pipe( - map(action => { - const addAction = action as AddParams; - if (!addAction.keepPages) { - this.store.dispatch(new ResetPagination(action.entityKey, action.paginationKey)); - } - })); + @Effect({ dispatch: false }) clearPaginationOnParamChange$ = this.actions$.pipe( + ofType(SET_PARAMS, ADD_PARAMS, REMOVE_PARAMS), + map(action => { + const addAction = action as AddParams; + if (!addAction.keepPages) { + this.store.dispatch(new ResetPagination(action.entityKey, action.paginationKey)); + } + })); } diff --git a/src/frontend/packages/store/src/effects/permissions.effect.ts b/src/frontend/packages/store/src/effects/permissions.effect.ts index fca7d35d80..b66821f272 100644 --- a/src/frontend/packages/store/src/effects/permissions.effect.ts +++ b/src/frontend/packages/store/src/effects/permissions.effect.ts @@ -1,10 +1,14 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Action, Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { catchError, first, map, mergeMap, share, switchMap, tap, withLatestFrom } from 'rxjs/operators'; +import { LoggerService } from '../../../core/src/core/logger.service'; +import { + createCfFeatureFlagFetchAction, +} from '../../../core/src/shared/components/list/list-types/cf-feature-flags/cf-feature-flags-data-source.helpers'; import { CONNECT_ENDPOINTS_SUCCESS, EndpointActionComplete } from '../actions/endpoint.actions'; import { GET_CURRENT_USER_CF_RELATIONS, @@ -26,10 +30,6 @@ import { createPaginationCompleteWatcher } from '../helpers/store-helpers'; import { endpointsRegisteredCFEntitiesSelector } from '../selectors/endpoint.selectors'; import { CFResponse } from '../types/api.types'; import { EndpointModel, INewlyConnectedEndpointInfo } from '../types/endpoint.types'; -import { LoggerService } from '../../../core/src/core/logger.service'; -import { - createCfFeatureFlagFetchAction, -} from '../../../core/src/shared/components/list/list-types/cf-feature-flags/cf-feature-flags-data-source.helpers'; class PermissionFlattener extends BaseHttpClientFetcher implements IPaginationFlattener { @@ -100,10 +100,9 @@ export class PermissionsEffects { private logService: LoggerService ) { } - @Effect() getCurrentUsersPermissions$ = this.actions$.ofType(GET_CURRENT_USER_RELATIONS).pipe( - withLatestFrom( - this.store.select(endpointsRegisteredCFEntitiesSelector) - ), + @Effect() getCurrentUsersPermissions$ = this.actions$.pipe( + ofType(GET_CURRENT_USER_RELATIONS), + withLatestFrom(this.store.select(endpointsRegisteredCFEntitiesSelector)), switchMap(([action, endpoints]) => { const endpointsArray = Object.values(endpoints); const isAllAdmins = endpointsArray.every(endpoint => !!endpoint.user.admin); @@ -130,7 +129,8 @@ export class PermissionsEffects { ); - @Effect() getPermissionForNewlyConnectedEndpoint$ = this.actions$.ofType(CONNECT_ENDPOINTS_SUCCESS).pipe( + @Effect() getPermissionForNewlyConnectedEndpoint$ = this.actions$.pipe( + ofType(CONNECT_ENDPOINTS_SUCCESS), switchMap(action => { const endpoint = action.endpoint as INewlyConnectedEndpointInfo; if (endpoint.user.admin || action.endpointType !== 'cf') { @@ -220,7 +220,8 @@ export class PermissionEffects { private store: Store ) { } - @Effect() getCurrentUsersPermissions$ = this.actions$.ofType(GET_CURRENT_USER_RELATION).pipe( + @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/store/src/effects/recursive-entity-delete.effect.ts b/src/frontend/packages/store/src/effects/recursive-entity-delete.effect.ts index b431dcea5c..a9f26c76d0 100644 --- a/src/frontend/packages/store/src/effects/recursive-entity-delete.effect.ts +++ b/src/frontend/packages/store/src/effects/recursive-entity-delete.effect.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Action, Store } from '@ngrx/store'; import { map, mergeMap, withLatestFrom } from 'rxjs/operators'; @@ -71,7 +71,8 @@ export class RecursiveDeleteEffect { }; @Effect() - delete$ = this.actions$.ofType(RECURSIVE_ENTITY_DELETE).pipe( + delete$ = this.actions$.pipe( + ofType(RECURSIVE_ENTITY_DELETE), withLatestFrom(this.store.select(getAPIRequestDataState)), map(([action, state]) => { const tree = this.getTree(action, state); @@ -80,7 +81,8 @@ export class RecursiveDeleteEffect { ); @Effect() - deleteComplete$ = this.actions$.ofType(RECURSIVE_ENTITY_DELETE_COMPLETE).pipe( + deleteComplete$ = this.actions$.pipe( + ofType(RECURSIVE_ENTITY_DELETE_COMPLETE), withLatestFrom(this.store.select(getAPIRequestDataState)), mergeMap(([action, state]) => { const tree = this.getTree(action, state); @@ -98,7 +100,8 @@ export class RecursiveDeleteEffect { ); @Effect() - deleteFailed$ = this.actions$.ofType(RECURSIVE_ENTITY_DELETE_FAILED).pipe( + deleteFailed$ = this.actions$.pipe( + ofType(RECURSIVE_ENTITY_DELETE_FAILED), withLatestFrom(this.store.select(getAPIRequestDataState)), map(([action, state]) => { const tree = this.getTree(action, state); diff --git a/src/frontend/packages/store/src/effects/request.effects.ts b/src/frontend/packages/store/src/effects/request.effects.ts index 72b5cfbee0..4b6f7cbaf9 100644 --- a/src/frontend/packages/store/src/effects/request.effects.ts +++ b/src/frontend/packages/store/src/effects/request.effects.ts @@ -1,9 +1,11 @@ import { Injectable } from '@angular/core'; import { RequestMethod } from '@angular/http'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, first, map, mergeMap, withLatestFrom } from 'rxjs/operators'; +import { LoggerService } from '../../../core/src/core/logger.service'; +import { UtilsService } from '../../../core/src/core/utils.service'; import { ClearPaginationOfEntity, ClearPaginationOfType, SET_PAGE_BUSY } from '../actions/pagination.actions'; import { APIResponse, @@ -22,8 +24,6 @@ import { rootUpdatingKey } from '../reducers/api-request-reducer/types'; import { getAPIRequestDataState } from '../selectors/api.selectors'; import { getPaginationState } from '../selectors/pagination.selectors'; import { UpdateCfAction } from '../types/request.types'; -import { UtilsService } from '../../../core/src/core/utils.service'; -import { LoggerService } from '../../../core/src/core/logger.service'; @Injectable() @@ -66,9 +66,9 @@ export class RequestEffect { * 5) alternatively... if we've reached here for the same space but from an api request for that space.. ensure that the routes have not * been dropped because their count is over 50 * - * @memberof RequestEffect */ - @Effect() validateEntities$ = this.actions$.ofType(EntitiesPipelineActionTypes.VALIDATE).pipe( + @Effect() validateEntities$ = this.actions$.pipe( + ofType(EntitiesPipelineActionTypes.VALIDATE), mergeMap(action => { const validateAction: ValidateEntitiesStart = action; const apiAction = validateAction.action; @@ -128,7 +128,8 @@ export class RequestEffect { }) ); - @Effect() completeEntities$ = this.actions$.ofType(EntitiesPipelineActionTypes.COMPLETE).pipe( + @Effect() completeEntities$ = this.actions$.pipe( + ofType(EntitiesPipelineActionTypes.COMPLETE), mergeMap(action => { const completeAction: EntitiesPipelineCompleted = action; const actions = []; @@ -165,11 +166,11 @@ export class RequestEffect { update(apiAction, busy: boolean, error: string) { - if (apiAction['paginationKey']) { + if (apiAction.paginationKey) { this.store.dispatch({ type: SET_PAGE_BUSY, - busy: busy, - error: error, + busy, + error, apiAction }); } else { diff --git a/src/frontend/packages/store/src/effects/route.effects.ts b/src/frontend/packages/store/src/effects/route.effects.ts index cd8dda4198..072e0ef331 100644 --- a/src/frontend/packages/store/src/effects/route.effects.ts +++ b/src/frontend/packages/store/src/effects/route.effects.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { map } from 'rxjs/operators'; @@ -18,7 +18,8 @@ export class RouteEffect { ) { } @Effect({ dispatch: false }) - unmapEffect$ = this.actions$.ofType(RouteEvents.UNMAP_ROUTE_SUCCESS).pipe( + unmapEffect$ = this.actions$.pipe( + ofType(RouteEvents.UNMAP_ROUTE_SUCCESS), map((action: APISuccessOrFailedAction) => { const unmapAction: UnmapRoute = action.apiAction as UnmapRoute; if (unmapAction.clearPaginationKey) { diff --git a/src/frontend/packages/store/src/effects/router.effects.ts b/src/frontend/packages/store/src/effects/router.effects.ts index e38202a4b8..7bd80c2006 100644 --- a/src/frontend/packages/store/src/effects/router.effects.ts +++ b/src/frontend/packages/store/src/effects/router.effects.ts @@ -1,12 +1,12 @@ - -import {tap, map} from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { map, tap } from 'rxjs/operators'; import { RouterActions, RouterNav } from '../actions/router.actions'; + @Injectable() export class RouterEffect { @@ -16,7 +16,8 @@ export class RouterEffect { ) { } @Effect({ dispatch: false }) - routerGoUrl$ = this.actions$.ofType(RouterActions.GO).pipe( + routerGoUrl$ = this.actions$.pipe( + ofType(RouterActions.GO), map((action: RouterNav) => action.payload), tap(({ path, query: queryParams, extras = {} }) => { const extraParams = { ...extras, queryParams }; @@ -24,5 +25,5 @@ export class RouterEffect { path = path.split('/'); } this.router.navigate(path, extraParams); - }), ); + })); } diff --git a/src/frontend/packages/store/src/effects/set-client-filter.effect.ts b/src/frontend/packages/store/src/effects/set-client-filter.effect.ts index 331bfd3194..85d93ef816 100644 --- a/src/frontend/packages/store/src/effects/set-client-filter.effect.ts +++ b/src/frontend/packages/store/src/effects/set-client-filter.effect.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { map } from 'rxjs/operators'; @@ -16,7 +16,8 @@ export class SetClientFilterEffect { private store: Store, ) { } - @Effect({ dispatch: false }) clearPageNumber$ = this.actions$.ofType(SET_CLIENT_FILTER).pipe( + @Effect({ dispatch: false }) clearPageNumber$ = this.actions$.pipe( + ofType(SET_CLIENT_FILTER), map(action => { // We reset the page when a param is changed. this.store.dispatch(new SetClientPage(action.entityKey, action.paginationKey, 1)); diff --git a/src/frontend/packages/store/src/effects/snackBar.effects.ts b/src/frontend/packages/store/src/effects/snackBar.effects.ts index 194a667168..a624e29bc5 100644 --- a/src/frontend/packages/store/src/effects/snackBar.effects.ts +++ b/src/frontend/packages/store/src/effects/snackBar.effects.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { MatSnackBar } from '@angular/material'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { map } from 'rxjs/operators'; import { SHOW_SNACK_BAR, ShowSnackBar } from '../actions/snackBar.actions'; @@ -12,7 +12,8 @@ export class SnackBarEffects { private actions$: Actions, public snackBar: MatSnackBar ) { } - @Effect({ dispatch: false }) getInfo$ = this.actions$.ofType(SHOW_SNACK_BAR).pipe( + @Effect({ dispatch: false }) getInfo$ = this.actions$.pipe( + ofType(SHOW_SNACK_BAR), map(action => { const snackBarRef = this.snackBar.open(action.message, null, { duration: 5000 diff --git a/src/frontend/packages/store/src/effects/system.effects.ts b/src/frontend/packages/store/src/effects/system.effects.ts index 442d2a2e38..b39a35262c 100644 --- a/src/frontend/packages/store/src/effects/system.effects.ts +++ b/src/frontend/packages/store/src/effects/system.effects.ts @@ -1,6 +1,6 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, mergeMap } from 'rxjs/operators'; @@ -20,7 +20,8 @@ export class SystemEffects { static guid = 'info'; - @Effect() getInfo$ = this.actions$.ofType(GET_SYSTEM_INFO).pipe( + @Effect() getInfo$ = this.actions$.pipe( + ofType(GET_SYSTEM_INFO), mergeMap(action => { const apiAction = { entityKey: systemStoreNames.type, 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 4ba9528644..bff86f821e 100644 --- a/src/frontend/packages/store/src/effects/uaa-setup.effects.ts +++ b/src/frontend/packages/store/src/effects/uaa-setup.effects.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { Headers, Http, URLSearchParams } from '@angular/http'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, map, switchMap } from 'rxjs/operators'; @@ -26,7 +26,8 @@ export class UAASetupEffect { baseUrl = '/pp/v1/setup'; - @Effect() uaaSetupRequest$ = this.actions$.ofType(SETUP_UAA).pipe( + @Effect() uaaSetupRequest$ = this.actions$.pipe( + ofType(SETUP_UAA), switchMap(({ setupData }) => { const headers = new Headers(); @@ -53,7 +54,8 @@ export class UAASetupEffect { })); - @Effect() uassSetScope = this.actions$.ofType(SETUP_UAA_SCOPE).pipe( + @Effect() uassSetScope = this.actions$.pipe( + ofType(SETUP_UAA_SCOPE), switchMap(({ scope }) => { const headers = new Headers(); const params = new URLSearchParams(); diff --git a/src/frontend/packages/store/src/effects/update-app-effects.ts b/src/frontend/packages/store/src/effects/update-app-effects.ts index 0ce66ab289..d3a29bf311 100644 --- a/src/frontend/packages/store/src/effects/update-app-effects.ts +++ b/src/frontend/packages/store/src/effects/update-app-effects.ts @@ -1,9 +1,8 @@ - -import {mergeMap} from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; +import { mergeMap } from 'rxjs/operators'; import { UPDATE_SUCCESS, UpdateExistingApplication } from '../actions/application.actions'; import { WrapperRequestActionSuccess } from '../types/request.types'; @@ -16,6 +15,7 @@ import { import { AppState } from './../app-state'; + @Injectable() export class UpdateAppEffects { @@ -26,7 +26,8 @@ export class UpdateAppEffects { ) { } - @Effect() UpdateAppInStore$ = this.actions$.ofType(UPDATE_SUCCESS).pipe( + @Effect() UpdateAppInStore$ = this.actions$.pipe( + ofType(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/store/src/effects/user-favorites-effect.ts b/src/frontend/packages/store/src/effects/user-favorites-effect.ts index 6b3435820f..6c49299ada 100644 --- a/src/frontend/packages/store/src/effects/user-favorites-effect.ts +++ b/src/frontend/packages/store/src/effects/user-favorites-effect.ts @@ -1,6 +1,6 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { catchError, first, map, mergeMap, switchMap } from 'rxjs/operators'; @@ -31,6 +31,7 @@ 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 { LoggerService } from '../../../core/src/core/logger.service'; const { proxyAPIVersion } = environment; const favoriteUrlPath = `/pp/${proxyAPIVersion}/favorites`; @@ -39,15 +40,19 @@ const favoriteUrlPath = `/pp/${proxyAPIVersion}/favorites`; @Injectable() export class UserFavoritesEffect { + private userFavoriteManager: UserFavoriteManager; + constructor( private http: HttpClient, private actions$: Actions, private store: Store, - ) { } - - private userFavoriteManager = new UserFavoriteManager(this.store); + private logger: LoggerService + ) { + this.userFavoriteManager = new UserFavoriteManager(this.store, this.logger); + } - @Effect() saveFavorite = this.actions$.ofType(SaveUserFavoriteAction.ACTION_TYPE).pipe( + @Effect() saveFavorite = this.actions$.pipe( + ofType(SaveUserFavoriteAction.ACTION_TYPE), mergeMap(action => { return this.http.post>(favoriteUrlPath, action.favorite).pipe( mergeMap(newFavorite => { @@ -59,7 +64,8 @@ export class UserFavoritesEffect { }) ); - @Effect({ dispatch: false }) getFavorite$ = this.actions$.ofType(GetUserFavoritesAction.ACTION_TYPE).pipe( + @Effect({ dispatch: false }) getFavorite$ = this.actions$.pipe( + ofType(GetUserFavoritesAction.ACTION_TYPE), switchMap((action: GetUserFavoritesAction) => { const apiAction = { entityKey: userFavoritesSchemaKey, @@ -86,7 +92,8 @@ export class UserFavoritesEffect { }) ); - @Effect() toggleFavorite = this.actions$.ofType(ToggleUserFavoriteAction.ACTION_TYPE).pipe( + @Effect() toggleFavorite = this.actions$.pipe( + ofType(ToggleUserFavoriteAction.ACTION_TYPE), mergeMap(action => this.userFavoriteManager.getIsFavoriteObservable(action.favorite).pipe( first(), @@ -101,7 +108,8 @@ export class UserFavoritesEffect { ) ); - @Effect({ dispatch: false }) removeFavorite$ = this.actions$.ofType(RemoveUserFavoriteAction.ACTION_TYPE).pipe( + @Effect({ dispatch: false }) removeFavorite$ = this.actions$.pipe( + ofType(RemoveUserFavoriteAction.ACTION_TYPE), switchMap((action: RemoveUserFavoriteAction) => { const { guid } = action.favorite; this.store.dispatch(new RemoveUserFavoriteSuccessAction(action.favorite)); @@ -110,7 +118,8 @@ export class UserFavoritesEffect { }) ); - @Effect() updateMetadata$ = this.actions$.ofType(UpdateUserFavoriteMetadataAction.ACTION_TYPE).pipe( + @Effect() updateMetadata$ = this.actions$.pipe( + ofType(UpdateUserFavoriteMetadataAction.ACTION_TYPE), mergeMap((action: UpdateUserFavoriteMetadataAction) => { return this.http.post>( `${favoriteUrlPath}/${action.favorite.guid}/metadata`, 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 21a95dfe41..ce6ce61662 100644 --- a/src/frontend/packages/store/src/effects/user-profile.effects.ts +++ b/src/frontend/packages/store/src/effects/user-profile.effects.ts @@ -1,10 +1,10 @@ - -import { switchMap, mergeMap, catchError } from 'rxjs/operators'; import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; +import { catchError, mergeMap, switchMap } from 'rxjs/operators'; +import { environment } from '../../../core/src/environments/environment'; import { FetchUserProfileAction, GET_USERPROFILE, @@ -22,7 +22,7 @@ import { WrapperRequestActionFailed, WrapperRequestActionSuccess, } from './../types/request.types'; -import { environment } from '../../../core/src/environments/environment'; + const { proxyAPIVersion } = environment; @@ -40,7 +40,8 @@ export class UserProfileEffect { private httpClient: HttpClient, ) { } - @Effect() getUserProfileInfo$ = this.actions$.ofType(GET_USERPROFILE).pipe( + @Effect() getUserProfileInfo$ = this.actions$.pipe( + ofType(GET_USERPROFILE), mergeMap(action => { const apiAction = { entityKey: userProfileStoreNames.type, @@ -63,7 +64,8 @@ export class UserProfileEffect { })); })); - @Effect() updateUserProfileInfo$ = this.actions$.ofType(UPDATE_USERPROFILE).pipe( + @Effect() updateUserProfileInfo$ = this.actions$.pipe( + ofType(UPDATE_USERPROFILE), mergeMap(action => { const apiAction = { entityKey: userProfileStoreNames.type, @@ -95,7 +97,8 @@ export class UserProfileEffect { })); })); - @Effect() updateUserPrassword$ = this.actions$.ofType(UPDATE_USERPASSWORD).pipe( + @Effect() updateUserPrassword$ = this.actions$.pipe( + ofType(UPDATE_USERPASSWORD), mergeMap(action => { const apiAction = { entityKey: userProfileStoreNames.type, diff --git a/src/frontend/packages/store/src/effects/users-roles.effects.ts b/src/frontend/packages/store/src/effects/users-roles.effects.ts index 6566e80ec4..ab7a47673c 100644 --- a/src/frontend/packages/store/src/effects/users-roles.effects.ts +++ b/src/frontend/packages/store/src/effects/users-roles.effects.ts @@ -1,9 +1,10 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { filter, first, map, mergeMap, pairwise, withLatestFrom } from 'rxjs/operators'; +import { EntityMonitor } from '../../../core/src/shared/monitors/entity-monitor'; import { UsersRolesActions, UsersRolesClearUpdateState, UsersRolesExecuteChanges } from '../actions/users-roles.actions'; import { AddUserRole, ChangeUserRole, RemoveUserRole } from '../actions/users.actions'; import { AppState } from '../app-state'; @@ -14,7 +15,6 @@ import { SessionDataEndpoint } from '../types/auth.types'; import { ICFAction, UpdateCfAction } from '../types/request.types'; import { OrgUserRoleNames } from '../types/user.types'; import { CfRoleChange } from '../types/users-roles.types'; -import { EntityMonitor } from '../../../core/src/shared/monitors/entity-monitor'; @Injectable() @@ -25,7 +25,8 @@ export class UsersRolesEffects { private store: Store, ) { } - @Effect() clearEntityUpdates$ = this.actions$.ofType(UsersRolesActions.ClearUpdateState).pipe( + @Effect() clearEntityUpdates$ = this.actions$.pipe( + ofType(UsersRolesActions.ClearUpdateState), mergeMap(action => { const actions = []; action.changedRoles.forEach(change => { @@ -43,7 +44,8 @@ export class UsersRolesEffects { }) ); - @Effect() executeUsersRolesChange$ = this.actions$.ofType(UsersRolesActions.ExecuteChanges).pipe( + @Effect() executeUsersRolesChange$ = this.actions$.pipe( + ofType(UsersRolesActions.ExecuteChanges), withLatestFrom( this.store.select(selectUsersRoles), this.store.select(selectSessionData()) @@ -61,8 +63,7 @@ export class UsersRolesEffects { // Split changes into `org user` and `other` const orgUserChanges: CfRoleChange[] = []; const nonOrgUserChanges: CfRoleChange[] = []; - for (let i = 0; i < changes.length; i++) { - const change = changes[i]; + for (const change of changes) { if (!change.spaceGuid && change.role === OrgUserRoleNames.USER) { orgUserChanges.push(change); } else { diff --git a/src/frontend/packages/store/src/effects/users.effects.ts b/src/frontend/packages/store/src/effects/users.effects.ts index 215f383ea5..fb263361ba 100644 --- a/src/frontend/packages/store/src/effects/users.effects.ts +++ b/src/frontend/packages/store/src/effects/users.effects.ts @@ -1,9 +1,12 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { catchError, filter, first, map, switchMap } from 'rxjs/operators'; +import { IOrganization } from '../../../core/src/core/cf-api.types'; +import { EntityServiceFactory } from '../../../core/src/core/entity-service-factory.service'; +import { PaginationMonitorFactory } from '../../../core/src/shared/monitors/pagination-monitor.factory'; import { GetAllOrganizations, GetAllOrgUsers } from '../actions/organization.actions'; import { GET_CF_USERS_AS_NON_ADMIN, GetAllUsersAsNonAdmin } from '../actions/users.actions'; import { AppState } from '../app-state'; @@ -16,9 +19,6 @@ import { endpointsEntityRequestDataSelector } from '../selectors/endpoint.select import { APIResource, NormalizedResponse } from '../types/api.types'; import { PaginatedAction, PaginationEntityState } from '../types/pagination.types'; import { StartRequestAction, WrapperRequestActionFailed, WrapperRequestActionSuccess } from '../types/request.types'; -import { PaginationMonitorFactory } from '../../../core/src/shared/monitors/pagination-monitor.factory'; -import { EntityServiceFactory } from '../../../core/src/core/entity-service-factory.service'; -import { IOrganization } from '../../../core/src/core/cf-api.types'; @Injectable() @@ -34,7 +34,8 @@ export class UsersEffects { /** * Fetch users from each organisation. This is used when the user connected to cf is non-admin and cannot access the global users/ list */ - @Effect() fetchUsersByOrg$ = this.actions$.ofType(GET_CF_USERS_AS_NON_ADMIN).pipe( + @Effect() fetchUsersByOrg$ = this.actions$.pipe( + ofType(GET_CF_USERS_AS_NON_ADMIN), switchMap(action => { const mockRequestType: ApiRequestTypes = 'fetch'; const mockPaginationAction: PaginatedAction = { diff --git a/src/frontend/packages/store/src/helpers/entity-factory.ts b/src/frontend/packages/store/src/helpers/entity-factory.ts index a774c13f2d..265b5d5c24 100644 --- a/src/frontend/packages/store/src/helpers/entity-factory.ts +++ b/src/frontend/packages/store/src/helpers/entity-factory.ts @@ -48,19 +48,17 @@ export const entityCache: { * Mostly a wrapper around schema.Entity. Allows a lot of uniformity of types through console. Includes some minor per entity type config * * @export - * @class EntitySchema * @extends {schema.Entity} */ export class EntitySchema extends schema.Entity { schema: Schema; public getId: (input, parent?, key?) => string; /** - * @param {string} entityKey As per schema.Entity ctor - * @param {Schema} [definition] As per schema.Entity ctor - * @param {schema.EntityOptions} [options] As per schema.Entity ctor - * @param {string} [relationKey] Allows multiple children of the same type within a single parent entity. For instance user with developer + * @param entityKey As per schema.Entity ctor + * @param [definition] As per schema.Entity ctor + * @param [options] As per schema.Entity ctor + * @param [relationKey] Allows multiple children of the same type within a single parent entity. For instance user with developer * spaces, manager spaces, auditor space, etc - * @memberof EntitySchema */ constructor( private entityKey: string, diff --git a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations-from-parent.spec.ts b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations-from-parent.spec.ts index b8eafc82f0..6e2e397cd6 100644 --- a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations-from-parent.spec.ts +++ b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations-from-parent.spec.ts @@ -2,6 +2,8 @@ import { async, inject, TestBed } from '@angular/core/testing'; import { Store } from '@ngrx/store'; import { first } from 'rxjs/operators'; +import { ISpace } from '../../../../core/src/core/cf-api.types'; +import { createBasicStoreModule, getInitialTestStoreState } from '../../../../core/test-framework/store-test-helper'; import { GetAllOrganizationSpaces } from '../../actions/organization.actions'; import { RequestTypes } from '../../actions/request.actions'; import { AppState } from '../../app-state'; @@ -11,8 +13,6 @@ import { WrapperRequestActionSuccess } from '../../types/request.types'; import { organizationSchemaKey } from '../entity-factory'; import { populatePaginationFromParent } from './entity-relations'; import { EntityRelationSpecHelper } from './entity-relations.spec'; -import { getInitialTestStoreState, createBasicStoreModule } from '../../../../core/test-framework/store-test-helper'; -import { ISpace } from '../../../../core/src/core/cf-api.types'; describe('Entity Relations - populate from parent', () => { @@ -69,7 +69,7 @@ describe('Entity Relations - populate from parent', () => { expect(action.totalResults).toBe(spaces.length); expect(action.totalPages).toBe(1); expect(action.response.result).toEqual(spaceGuids); - expect(action.response.entities.space).toEqual(spaces.reduce(function (map, space) { + expect(action.response.entities.space).toEqual(spaces.reduce((map, space) => { map[space.metadata.guid] = space; return map; }, {})); diff --git a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations-post-processor.ts b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations-post-processor.ts index 7120e0c17c..b94f76fbd6 100644 --- a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations-post-processor.ts +++ b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations-post-processor.ts @@ -5,7 +5,7 @@ import { ApiActionTypes, APIResponse } from '../../actions/request.actions'; import { GET_SPACE, GetSpace } from '../../actions/space.actions'; import { AppState } from '../../app-state'; import { IRequestDataState } from '../../types/entity.types'; -import { CFStartAction, IRequestAction } from '../../types/request.types'; +import { ICFAction, IRequestAction } from '../../types/request.types'; import { ValidateEntityResult } from './entity-relations.types'; import { orgSpacePostProcess } from './processors/org-space-post-processor'; @@ -15,16 +15,17 @@ export function validationPostProcessor( apiResponse: APIResponse, allEntities: IRequestDataState): ValidateEntityResult { if (action.type === ApiActionTypes.API_REQUEST_START) { - return apiAction(store, action as CFStartAction, apiResponse, allEntities); + return apiAction(store, action, apiResponse, allEntities); } } function apiAction( store: Store, - action: CFStartAction, + action: IRequestAction, apiResponse: APIResponse, allEntities: IRequestDataState): ValidateEntityResult { - const actions = action['actions'] || []; + const cfAction = action as ICFAction; + const actions = cfAction.actions || []; switch (actions[0]) { case GET_ORGANIZATION: return orgSpacePostProcess(store, action as GetOrganization, apiResponse, allEntities); diff --git a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.tree.ts b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.tree.ts index 2d82c566fc..20e9ae2097 100644 --- a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.tree.ts +++ b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.tree.ts @@ -16,10 +16,11 @@ function generateCacheKey(entityKey: string, action: EntityInlineParentAction): } export function fetchEntityTree(action: EntityInlineParentAction, fromCache = true): EntityTree { - let entity = action.entity; - const isArray = entity['length'] > 0; - entity = isArray ? entity[0] : entity; - const entityKey = entity['key']; + const actionEntity = action.entity; + /* tslint:disable-next-line:no-string-literal */ + const isArray = actionEntity['length'] > 0; + const entity: EntitySchema = isArray ? actionEntity[0] : actionEntity; + const entityKey = entity.key; const cacheKey = generateCacheKey(entityKey, action); const cachedTree = entityTreeCache[cacheKey]; const entityTree = fromCache && cachedTree ? cachedTree : createEntityTree(entity as EntitySchema, isArray); @@ -47,10 +48,10 @@ function createEntityTree(entity: EntitySchema, isArray: boolean) { } function buildEntityTree(tree: EntityTree, entityRelation: EntityTreeRelation, schemaObj?, path: string = '') { - const rootEntitySchema = schemaObj || entityRelation.entity['schema']; + const rootEntitySchema = schemaObj || entityRelation.entity.schema; Object.keys(rootEntitySchema).forEach(key => { let value = rootEntitySchema[key]; - const isArray = value['length'] > 0; + const isArray = value.length > 0; value = isArray ? value[0] : value; const newPath = path ? path + '.' + key : key; diff --git a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.ts b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.ts index fbca4da34f..450d40644a 100644 --- a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.ts +++ b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.ts @@ -3,6 +3,9 @@ import { denormalize } from 'normalizr'; import { Observable, of as observableOf } from 'rxjs'; import { filter, first, map, mergeMap, pairwise, skipWhile, switchMap, withLatestFrom } from 'rxjs/operators'; +import { isEntityBlocked } from '../../../../core/src/core/entity-service'; +import { pathGet } from '../../../../core/src/core/utils.service'; +import { environment } from '../../../../core/src/environments/environment'; import { SetInitialParams } from '../../actions/pagination.actions'; import { FetchRelationAction, @@ -33,8 +36,7 @@ import { ValidateEntityRelationsConfig, ValidationResult, } from './entity-relations.types'; -import { pathGet } from '../../../../core/src/core/utils.service'; -import { isEntityBlocked } from '../../../../core/src/core/entity-service'; + interface ValidateResultFetchingState { fetching: boolean; @@ -43,7 +45,6 @@ interface ValidateResultFetchingState { /** * An object to represent the action and status of a missing inline depth/entity relation. * @export - * @interface ValidateEntityResult */ interface ValidateEntityResult { action: FetchRelationAction; @@ -54,23 +55,14 @@ interface ValidateEntityResult { class ValidateLoopConfig extends ValidateEntityRelationsConfig { /** * List of `{parent entity key} - {child entity key}` strings which should exist in entities structure - * - * @type {string[]} - * @memberof ValidateLoopConfig */ includeRelations: string[]; /** * List of entities to validate - * - * @type {any[]} - * @memberof ValidateLoopConfig */ entities: APIResource[]; /** * Parent entity relation of children in the entities param - * - * @type {EntityTreeRelation} - * @memberof ValidateLoopConfig */ parentRelation: EntityTreeRelation; } @@ -125,9 +117,6 @@ function createEntityWatcher(store, paramAction, guid: string): Observable} store - * @param {PaginatedAction} action - * @returns {Observable} */ export function populatePaginationFromParent(store: Store, action: PaginatedAction): Observable { - if (!isEntityInlineChildAction(action) || !action.flattenPagination) { + const eicAction = isEntityInlineChildAction(action); + if (!eicAction || !action.flattenPagination) { return observableOf(null); } - const parentEntitySchema = action['parentEntitySchema'] as EntitySchema; - const parentGuid = action['parentGuid']; + const parentEntitySchema = eicAction.parentEntitySchema as EntitySchema; + const parentGuid = eicAction.parentGuid; // What the hell is going on here hey? Well I'll tell you... // Ensure that the parent is not blocked (fetching, updating, etc) before we check if it has the child param that we need @@ -497,11 +476,12 @@ export function populatePaginationFromParent(store: Store, action: Pag return; } // Find the property name (for instance a list of routes in a parent space would have param name `routes`) + /* tslint:disable-next-line:no-string-literal */ const entities = parentEntitySchema.schema['entity'] || {}; const params = Object.keys(entities); - for (let i = 0; i < params.length; i++) { - const paramName = params[i]; + for (const paramName of params) { const entitySchema: EntitySchema | [EntitySchema] = entities[paramName]; + /* tslint:disable-next-line:no-string-literal */ const arraySafeEntitySchema: EntitySchema = entitySchema['length'] >= 0 ? entitySchema[0] : entitySchema; if (arraySafeEntitySchema.key === action.entityKey) { // Found it! Does the entity contain a value for the property name? diff --git a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.types.ts b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.types.ts index aefdefd3a8..3f4e653f6b 100644 --- a/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.types.ts +++ b/src/frontend/packages/store/src/helpers/entity-relations/entity-relations.types.ts @@ -15,59 +15,39 @@ import { EntitySchema } from '../entity-factory'; export class ValidateEntityRelationsConfig { /** * The guid of the cf. If this is null or not known we'll try to extract it from the list of parentEntities - * - * @type {string} - * @memberof ValidateEntityRelationsConfig */ cfGuid: string; store: Store; /** * Entities store. Used to determine if we already have the entity/entities and to watch when fetching entities - * - * @type {IRequestDataState} - * @memberof ValidateEntityRelationsConfig */ allEntities: IRequestDataState; /** * Pagination store. Used to determine if we already have the entity/entites. This and allEntities make the inner loop code much easier * and quicker - * - * @type {IRequestTypeState} - * @memberof ValidateEntityRelationsConfig */ allPagination: IRequestTypeState; /** * New entities that have not yet made it into the store (as a result of being called mid-api handling). Used to determine if we already * have an entity/entities - * - * @type {IRequestTypeState} - * @memberof ValidateEntityRelationsConfig */ newEntities?: IRequestTypeState; /** * The action that has fetched the entity/entities - * - * @type {IRequestAction} - * @memberof ValidateEntityRelationsConfig */ action: IRequestAction; /** * Collection of entity (guids) whose children may be missing. For example a list of organizations that have missing spaces - * - * @type {string[]} - * @memberof ValidateEntityRelationsConfig */ parentEntities: string[]; /** * If a child is missing, should we raise an action to fetch it? * - * @memberof ValidateEntityRelationsConfig */ populateMissing = true; /** * If we're validating an api request we'll have the apiResponse, otherwise it's null and we're ad hoc validating an entity/list * - * @memberof ValidateEntityRelationsConfig */ apiResponse: APIResponse; } @@ -82,20 +62,16 @@ export class EntityTree { * A structure which represents the tree like layout of entity dependencies. For example organization --> space --> routes * * @export - * @class EntityTreeRelation */ export class EntityTreeRelation { entityKey: string; /** - * Creates an instance of EntityTreeRelation. - * @param {EntitySchema} entity - * @param {boolean} [isArray=false] is this a collection of entities (should be paginationed) or not - * @param {string} paramName parameter name of the entity within the schema. For example `space` may be `spaces` (entity.spaces) - * @param {string} [path=''] location of the entity within the parent. For example `space` entity maybe be `entity.spaces` - * @param {EntityTreeRelation[]} childRelations - * @memberof EntityTreeRelation - */ + * Creates an instance of EntityTreeRelation. + * @param [isArray=false] is this a collection of entities (should be paginationed) or not + * @param paramName parameter name of the entity within the schema. For example `space` may be `spaces` (entity.spaces) + * @param [path=''] location of the entity within the parent. For example `space` entity maybe be `entity.spaces` + */ constructor( public entity: EntitySchema, public isArray = false, @@ -111,7 +87,6 @@ export class EntityTreeRelation { * Helper interface. Actions with entities that are children of a parent entity should specify the parent guid. * * @export - * @interface EntityInlineChildAction */ export interface EntityInlineChildAction { entityKey: string; @@ -123,8 +98,8 @@ export interface EntityInlineChildAction { export function isEntityInlineChildAction(anything): EntityInlineChildAction { return anything && - !!anything['parentGuid'] && - !!anything['parentEntitySchema'] + !!anything.parentGuid && + !!anything.parentEntitySchema ? anything as EntityInlineChildAction : null; } @@ -132,7 +107,6 @@ export function isEntityInlineChildAction(anything): EntityInlineChildAction { * Helper interface. Actions that are a parent of children entities should have these included parent-child relations * * @export - * @interface EntityInlineParentAction * @extends {PaginatedAction} */ export interface EntityInlineParentAction extends IRequestAction { @@ -140,8 +114,8 @@ export interface EntityInlineParentAction extends IRequestAction { populateMissing: boolean; } -export function isEntityInlineParentAction(action: Action) { - return action && !!action['includeRelations'] && action['populateMissing'] !== undefined; +export function isEntityInlineParentAction(anything: any): boolean { + return anything && !!anything.includeRelations && anything.populateMissing !== undefined; } export function createEntityRelationKey(parentKey: string, childKey) { return `${parentKey}-${childKey}`; } @@ -163,22 +137,15 @@ export function createEntityRelationPaginationKey(parentSchemaKey: string, paren * The result of a validation run. Indicates if any separate api requests have been started and a promise firing when they have completed * * @export - * @class ValidationResult */ export class ValidationResult { /** * True if data was missing an api requests have been kicked off to fetch - * - * @type {boolean} - * @memberof ValidationResult */ started: boolean; /** * Promise that fires when the api requests kicked off to fetch missing data have all completed. Contains the new apiResponse (for the * case of validating api calls this might be updated to ensure parent entities are associated with missing children). - * - * @type {Promise} - * @memberof ValidationResult */ completed: Promise; } @@ -190,7 +157,6 @@ export interface ValidateResultFetchingState { /** * An object to represent the action and status of a missing inline depth/entity relation. * @export - * @interface ValidateEntityResult */ export interface ValidateEntityResult { action: Action; diff --git a/src/frontend/packages/store/src/helpers/store-helpers.ts b/src/frontend/packages/store/src/helpers/store-helpers.ts index 82347c11ef..509d051537 100644 --- a/src/frontend/packages/store/src/helpers/store-helpers.ts +++ b/src/frontend/packages/store/src/helpers/store-helpers.ts @@ -31,6 +31,6 @@ export const createPaginationCompleteWatcher = (store: Store, action: first(), ); - export function initStore() { +export function initStore() { setDefaultPaginationState({ ...defaultCfEntitiesState }); } diff --git a/src/frontend/packages/store/src/reducers.module.ts b/src/frontend/packages/store/src/reducers.module.ts index 89a30d4de0..8c804cc1cb 100644 --- a/src/frontend/packages/store/src/reducers.module.ts +++ b/src/frontend/packages/store/src/reducers.module.ts @@ -2,7 +2,6 @@ import { NgModule } from '@angular/core'; import { ActionReducerMap, StoreModule } from '@ngrx/store'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { storeFreeze } from 'ngrx-store-freeze'; -import { storeLogger } from 'ngrx-store-logger'; import { environment } from '../../core/src/environments/environment'; import { actionHistoryReducer } from './reducers/action-history-reducer'; @@ -23,10 +22,15 @@ import { routingReducer } from './reducers/routing.reducer'; import { uaaSetupReducer } from './reducers/uaa-setup.reducers'; import { UsersRolesReducer } from './reducers/users-roles.reducer'; -export function logger(reducer) { - // default, no options - return storeLogger()(reducer); -} +// NOTE: Revisit when ngrx-store-logger supports Angular 7 (https://github.com/btroncone/ngrx-store-logger) + +// import { storeLogger } from 'ngrx-store-logger'; + +// https://github.com/btroncone/ngrx-store-logger/issues/34 +// export function logger(reducer) { +// // default, no options +// return storeLogger()(reducer); +// } export const appReducers = { auth: authReducer, @@ -52,9 +56,9 @@ export const appReducers = { const metaReducers = []; if (!environment.production) { metaReducers.push(storeFreeze); - if (environment.logEnableConsoleActions) { - metaReducers.push(logger); - } + // if (environment.logEnableConsoleActions) { + // metaReducers.push(logger); + // } } const store = StoreModule.forRoot( diff --git a/src/frontend/packages/store/src/reducers/api-request-reducers.generator.ts b/src/frontend/packages/store/src/reducers/api-request-reducers.generator.ts index a38a0f475e..59cad718d5 100644 --- a/src/frontend/packages/store/src/reducers/api-request-reducers.generator.ts +++ b/src/frontend/packages/store/src/reducers/api-request-reducers.generator.ts @@ -1,3 +1,5 @@ +import { Action } from '@ngrx/store'; + import { appEnvVarsSchemaKey, applicationSchemaKey, @@ -24,26 +26,25 @@ import { serviceSchemaKey, spaceQuotaSchemaKey, spaceSchemaKey, - userProfileSchemaKey, userFavoritesSchemaKey, + userProfileSchemaKey, } from '../helpers/entity-factory'; import { endpointStoreNames } from '../types/endpoint.types'; +import { IRequestDataState, IRequestState } from '../types/entity.types'; import { RequestTypes } from './../actions/request.actions'; import { requestDataReducerFactory } from './api-request-data-reducer/request-data-reducer.factory'; import { requestReducerFactory } from './api-request-reducer/request-reducer.factory'; import { IRequestArray } from './api-request-reducer/types'; import { appStatsReducer } from './app-stats-request.reducer'; +import { applicationAddRemoveReducer } from './application-add-remove-reducer'; import { updateApplicationRoutesReducer } from './application-route.reducer'; import { endpointDisconnectApplicationReducer } from './endpoint-disconnect-application.reducer'; +import { addOrUpdateUserFavoriteMetadataReducer, deleteUserFavoriteMetadataReducer } from './favorite.reducer'; import { updateOrganizationSpaceReducer } from './organization-space.reducer'; import { routeReducer, updateAppSummaryRoutesReducer } from './routes.reducer'; import { serviceInstanceReducer } from './service-instance.reducer'; import { systemEndpointsReducer } from './system-endpoints.reducer'; -import { userReducer, userSpaceOrgReducer, endpointDisconnectUserReducer } from './users.reducer'; -import { applicationAddRemoveReducer } from './application-add-remove-reducer'; -import { addOrUpdateUserFavoriteMetadataReducer, deleteUserFavoriteMetadataReducer } from './favorite.reducer'; -import { IRequestDataState, IRequestState } from '../types/entity.types'; -import { Action } from '@ngrx/store'; +import { endpointDisconnectUserReducer, userReducer, userSpaceOrgReducer } from './users.reducer'; /** * This module uses the request data reducer and request reducer factories to create @@ -58,12 +59,12 @@ const requestActions = [ ] as IRequestArray; function chainReducers(baseReducer, extraReducers) { - return function (state, action) { + return (state, action) => { let newState = baseReducer(state, action); let nextState; Object.keys(extraReducers).forEach(key => { - nextState = extraReducers[key].reduce((_state, reducer) => { - return reducer(_state, action); + nextState = extraReducers[key].reduce((s, reducer) => { + return reducer(s, action); }, newState[key]); if (nextState !== newState[key]) { newState = { diff --git a/src/frontend/packages/store/src/reducers/application-add-remove-reducer.ts b/src/frontend/packages/store/src/reducers/application-add-remove-reducer.ts index c59355b310..cf618def09 100644 --- a/src/frontend/packages/store/src/reducers/application-add-remove-reducer.ts +++ b/src/frontend/packages/store/src/reducers/application-add-remove-reducer.ts @@ -1,12 +1,12 @@ -import { APIResource } from '../types/api.types'; -import { APISuccessOrFailedAction } from '../types/request.types'; +import { IApp, ISpace } from '../../../core/src/core/cf-api.types'; import { CREATE_SUCCESS, DELETE_SUCCESS } from '../actions/application.actions'; import { deepMergeState } from '../helpers/reducer.helper'; -import { IApp, ISpace } from '../../../core/src/core/cf-api.types'; +import { APIResource } from '../types/api.types'; +import { APISuccessOrFailedAction } from '../types/request.types'; export function applicationAddRemoveReducer() { - return function (state: APIResource, action: APISuccessOrFailedAction) { + return (state: APIResource, action: APISuccessOrFailedAction) => { switch (action.type) { case CREATE_SUCCESS: return addApplicationToSpace(state, action); @@ -53,7 +53,7 @@ function deleteApplicationFromSpace(state: APIResource, action: APISuccessOrFail const updatedSpaces = {}; Object.keys(state).forEach(spaceGuid => { const space = state[spaceGuid] as APIResource; - const apps = space.entity.apps; + const apps = space.entity.apps as string[]; if (apps && apps.findIndex((value) => value === appGuid) >= 0) { const newSpaceEntity = { entity: { diff --git a/src/frontend/packages/store/src/reducers/application-route.reducer.ts b/src/frontend/packages/store/src/reducers/application-route.reducer.ts index 95160bdf16..a073d3bf5d 100644 --- a/src/frontend/packages/store/src/reducers/application-route.reducer.ts +++ b/src/frontend/packages/store/src/reducers/application-route.reducer.ts @@ -4,7 +4,7 @@ import { APIResource } from '../types/api.types'; import { APISuccessOrFailedAction } from '../types/request.types'; export function updateApplicationRoutesReducer() { - return function (state: APIResource, action: APISuccessOrFailedAction) { + return (state: APIResource, action: APISuccessOrFailedAction) => { switch (action.type) { case ASSIGN_ROUTE_SUCCESS: const assignAction: AssociateRouteWithAppApplication = action.apiAction as AssociateRouteWithAppApplication; 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 021d8e6c31..342c061f47 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 @@ -122,20 +122,20 @@ function addEntityFavorite(favoriteGroups: IUserFavoritesGroups, action: SaveUse }; } -function addFavoriteToGroup(_favoriteGroup: IUserFavoriteGroup = getDefaultFavoriteGroup(), favorite: UserFavorite) { - const favoriteGroup = { - ..._favoriteGroup, +function addFavoriteToGroup(favoriteGroup: IUserFavoriteGroup = getDefaultFavoriteGroup(), favorite: UserFavorite) { + const fg = { + ...favoriteGroup, entitiesIds: [ - ..._favoriteGroup.entitiesIds + ...favoriteGroup.entitiesIds ] }; const { guid } = favorite; const isEndpoint = isEndpointTypeFavorite(favorite); - if (!isEndpoint && guid && !favoriteGroup.entitiesIds.includes(guid)) { - favoriteGroup.entitiesIds.push(guid); + if (!isEndpoint && guid && !fg.entitiesIds.includes(guid)) { + fg.entitiesIds.push(guid); } if (isEndpoint) { - favoriteGroup.ethereal = false; + fg.ethereal = false; } - return favoriteGroup; + return fg; } diff --git a/src/frontend/packages/store/src/reducers/endpoint-disconnect-application.reducer.ts b/src/frontend/packages/store/src/reducers/endpoint-disconnect-application.reducer.ts index 39c266b288..839a31f18b 100644 --- a/src/frontend/packages/store/src/reducers/endpoint-disconnect-application.reducer.ts +++ b/src/frontend/packages/store/src/reducers/endpoint-disconnect-application.reducer.ts @@ -2,7 +2,7 @@ import { DISCONNECT_ENDPOINTS_SUCCESS, DisconnectEndpoint, UNREGISTER_ENDPOINTS_ import { APIResource } from '../types/api.types'; export function endpointDisconnectApplicationReducer() { - return function (state: { [appGuid: string]: APIResource<{ cfGuid: string }> }, action: DisconnectEndpoint) { + return (state: { [appGuid: string]: APIResource<{ cfGuid: string }> }, action: DisconnectEndpoint) => { switch (action.type) { case DISCONNECT_ENDPOINTS_SUCCESS: case UNREGISTER_ENDPOINTS_SUCCESS: diff --git a/src/frontend/packages/store/src/reducers/endpoints.reducer.ts b/src/frontend/packages/store/src/reducers/endpoints.reducer.ts index 5f7cca5991..1a5796c694 100644 --- a/src/frontend/packages/store/src/reducers/endpoints.reducer.ts +++ b/src/frontend/packages/store/src/reducers/endpoints.reducer.ts @@ -5,7 +5,7 @@ export function endpointsReducer(state: EndpointState = { loading: false, error: false, message: '' -}, action): EndpointState { +}, action): EndpointState { switch (action.type) { case GET_ENDPOINTS: return { ...state, loading: true, message: '', error: false }; diff --git a/src/frontend/packages/store/src/reducers/list.reducer.ts b/src/frontend/packages/store/src/reducers/list.reducer.ts index 50f2f4a210..c3dd2a140f 100644 --- a/src/frontend/packages/store/src/reducers/list.reducer.ts +++ b/src/frontend/packages/store/src/reducers/list.reducer.ts @@ -64,11 +64,11 @@ export const getListStateObservables = ( }; function selectListState(key: string) { - return state => state['lists'][key]; + return state => state.lists[key]; } function selectListStateProperty(key: string, property: string) { return state => { - return (state['lists'][key] || {})[property]; + return (state.lists[key] || {})[property]; }; } diff --git a/src/frontend/packages/store/src/reducers/organization-space.reducer.ts b/src/frontend/packages/store/src/reducers/organization-space.reducer.ts index 5fdba52e89..05794d9505 100644 --- a/src/frontend/packages/store/src/reducers/organization-space.reducer.ts +++ b/src/frontend/packages/store/src/reducers/organization-space.reducer.ts @@ -1,19 +1,14 @@ -import { - CREATE_SPACE_SUCCESS, - CreateSpace, - DELETE_SPACE_SUCCESS, - DeleteSpace, -} from '../actions/space.actions'; +import { IOrganization, ISpace } from '../../../core/src/core/cf-api.types'; +import { CREATE_SPACE_SUCCESS, CreateSpace, DELETE_SPACE_SUCCESS, DeleteSpace } from '../actions/space.actions'; +import { IRequestEntityTypeState } from '../app-state'; import { spaceSchemaKey } from '../helpers/entity-factory'; import { APIResource, NormalizedResponse } from '../types/api.types'; import { APISuccessOrFailedAction } from '../types/request.types'; -import { IRequestEntityTypeState } from '../app-state'; -import { IOrganization, ISpace } from '../../../core/src/core/cf-api.types'; type entityOrgType = APIResource>; // Note - This reducer will be updated when we address general deletion of entities within inline lists (not paginated lists) export function updateOrganizationSpaceReducer() { - return function (state: IRequestEntityTypeState, action: APISuccessOrFailedAction) { + return (state: IRequestEntityTypeState, action: APISuccessOrFailedAction) => { switch (action.type) { case DELETE_SPACE_SUCCESS: const deleteSpaceAction: DeleteSpace = action.apiAction as DeleteSpace; diff --git a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-create-pagination.spec.ts b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-create-pagination.spec.ts index b7ad0c66d0..eb50776114 100644 --- a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-create-pagination.spec.ts +++ b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-create-pagination.spec.ts @@ -1,6 +1,6 @@ import { CreatePagination } from '../../actions/pagination.actions'; -import { createNewPaginationSection } from './pagination-reducer-create-pagination'; import { PaginationState } from '../../types/pagination.types'; +import { createNewPaginationSection } from './pagination-reducer-create-pagination'; import { getDefaultPaginationEntityState } from './pagination-reducer.helper'; describe('CreatePaginationActionReducer', () => { @@ -66,8 +66,8 @@ describe('CreatePaginationActionReducer', () => { 'paginationKey' ); const state = createNewPaginationSection(paginationState, action, getDefaultPaginationEntityState()); - expect(paginationState[entityKey]['paginationKey'].ids).toEqual(state[entityKey][paginationKey].ids); - expect(paginationState[entityKey]['paginationKey'].pageRequests).toEqual(state[entityKey][paginationKey].pageRequests); + expect(paginationState[entityKey].paginationKey.ids).toEqual(state[entityKey][paginationKey].ids); + expect(paginationState[entityKey].paginationKey.pageRequests).toEqual(state[entityKey][paginationKey].pageRequests); }); }); diff --git a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-create-pagination.ts b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-create-pagination.ts index b74da1c2a1..5573a39e67 100644 --- a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-create-pagination.ts +++ b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-create-pagination.ts @@ -6,8 +6,6 @@ import { spreadClientPagination } from './pagination-reducer.helper'; * Creates new pagination from default values or a seed pagination section. * If the pagination exists and a seed pagination key is provided, sync the current pagination section and the seed. * If the pagination exists and no seed is given then do nothing. - * @param state - * @param action * @param defaultState The default state to create the pagination section with. */ export function createNewPaginationSection(state: PaginationState, action: CreatePagination, defaultState: PaginationEntityState) diff --git a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-update.ts b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-update.ts index 518315bc16..27620f7644 100644 --- a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-update.ts +++ b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination-reducer-update.ts @@ -9,7 +9,7 @@ export function paginationPageBusy(state: PaginationEntityState, action): Pagina pageRequests: { ...state.pageRequests, [page]: { - busy: busy, + busy, error: !!error, message: error } 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 cfbbe1d4e1..b28c03eeec 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 @@ -207,7 +207,7 @@ describe('PaginationReducer', () => { currentPage: 1, totalResults: 0, ids: {}, - pageRequests: { 1: { busy: false, error: true, message: message } }, + pageRequests: { 1: { busy: false, error: true, message } }, clientPagination: { ...defaultClientPagination } diff --git a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination.reducer.ts b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination.reducer.ts index 54f6a550d0..ca7c29c8d6 100644 --- a/src/frontend/packages/store/src/reducers/pagination-reducer/pagination.reducer.ts +++ b/src/frontend/packages/store/src/reducers/pagination-reducer/pagination.reducer.ts @@ -1,9 +1,10 @@ -import { CreatePagination, ResetPagination, ClearPaginationOfType, ClearPaginationOfEntity } from './../../actions/pagination.actions'; +import { Action } from '@ngrx/store'; + import { CONNECT_ENDPOINTS_SUCCESS, DISCONNECT_ENDPOINTS_SUCCESS, - UNREGISTER_ENDPOINTS, EndpointAction, + UNREGISTER_ENDPOINTS, } from '../../actions/endpoint.actions'; import { ADD_PARAMS, @@ -26,6 +27,12 @@ import { import { ApiActionTypes } from '../../actions/request.actions'; import { mergeState } from '../../helpers/reducer.helper'; import { PaginationEntityState, PaginationState } from '../../types/pagination.types'; +import { + ClearPaginationOfEntity, + ClearPaginationOfType, + CreatePagination, + ResetPagination, +} from './../../actions/pagination.actions'; import { paginationAddParams } from './pagination-reducer-add-params'; import { paginationClearPages } from './pagination-reducer-clear-pages'; import { paginationClearOfEntity } from './pagination-reducer-clear-pagination-of-entity'; @@ -44,8 +51,12 @@ import { paginationStart } from './pagination-reducer-start'; import { paginationSuccess } from './pagination-reducer-success'; import { paginationPageBusy } from './pagination-reducer-update'; import { paginationFailure } from './pagination-reducer.failure'; -import { getActionKey, getActionType, getPaginationKeyFromAction, getDefaultPaginationEntityState } from './pagination-reducer.helper'; -import { Action } from '@ngrx/store'; +import { + getActionKey, + getActionType, + getDefaultPaginationEntityState, + getPaginationKeyFromAction, +} from './pagination-reducer.helper'; @@ -58,9 +69,9 @@ export function setDefaultPaginationState(state: any) { defaultPaginationState = state; } -const getPaginationUpdater = function (types: [string, string, string]) { +const getPaginationUpdater = (types: [string, string, string]) => { const [requestType, successType, failureType] = types; - return function (state: PaginationEntityState = getDefaultPaginationEntityState(), action, actionType): PaginationEntityState { + return (state: PaginationEntityState = getDefaultPaginationEntityState(), action, actionType): PaginationEntityState => { switch (action.type) { case requestType: return paginationStart(state, action); @@ -98,7 +109,7 @@ export function createPaginationReducer(types: [string, string, string]) { } function paginationReducer(updatePagination, types) { - return function (state, action) { + return (state, action) => { state = state || defaultPaginationState; return paginate(action, state, updatePagination); }; diff --git a/src/frontend/packages/store/src/reducers/routes.reducer.ts b/src/frontend/packages/store/src/reducers/routes.reducer.ts index f1d324ac5c..66ed22bbbb 100644 --- a/src/frontend/packages/store/src/reducers/routes.reducer.ts +++ b/src/frontend/packages/store/src/reducers/routes.reducer.ts @@ -1,9 +1,9 @@ +import { IAppSummary, IRoute } from '../../../core/src/core/cf-api.types'; +import { ASSIGN_ROUTE_SUCCESS, AssociateRouteWithAppApplication } from '../actions/application-service-routes.actions'; +import { DeleteRoute, RouteEvents, UnmapRoute } from '../actions/route.actions'; import { IRequestEntityTypeState } from '../app-state'; import { APIResource } from '../types/api.types'; import { APISuccessOrFailedAction } from '../types/request.types'; -import { ASSIGN_ROUTE_SUCCESS, AssociateRouteWithAppApplication } from '../actions/application-service-routes.actions'; -import { IRoute, IAppSummary } from '../../../core/src/core/cf-api.types'; -import { RouteEvents, UnmapRoute, DeleteRoute } from '../actions/route.actions'; export function routeReducer(state: IRequestEntityTypeState>, action: APISuccessOrFailedAction) { switch (action.type) { @@ -32,7 +32,8 @@ export function routeReducer(state: IRequestEntityTypeState> } } export function updateAppSummaryRoutesReducer(state: IRequestEntityTypeState>, action: APISuccessOrFailedAction) { - let currentState, routeGuid; + let currentState; + let routeGuid; switch (action.type) { case RouteEvents.UNMAP_ROUTE_SUCCESS: const unmapRouteAction = action.apiAction as UnmapRoute; diff --git a/src/frontend/packages/store/src/reducers/service-instance.reducer.ts b/src/frontend/packages/store/src/reducers/service-instance.reducer.ts index 13357914fa..070eeea7d4 100644 --- a/src/frontend/packages/store/src/reducers/service-instance.reducer.ts +++ b/src/frontend/packages/store/src/reducers/service-instance.reducer.ts @@ -1,17 +1,19 @@ +import { IServiceBinding, IServiceInstance } from '../../../core/src/core/cf-api-svc.types'; import { - DELETE_SERVICE_BINDING_ACTION_SUCCESS, CREATE_SERVICE_BINDING_ACTION_SUCCESS, + CreateServiceBinding, + DELETE_SERVICE_BINDING_ACTION_SUCCESS, DeleteServiceBinding, - CreateServiceBinding } from '../actions/service-bindings.actions'; +import { UPDATE_SERVICE_INSTANCE_SUCCESS, UpdateServiceInstance } from '../actions/service-instances.actions'; import { IRequestEntityTypeState } from '../app-state'; import { APIResource } from '../types/api.types'; import { APISuccessOrFailedAction } from '../types/request.types'; -import { UpdateServiceInstance, UPDATE_SERVICE_INSTANCE_SUCCESS } from '../actions/service-instances.actions'; -import { IServiceInstance, IServiceBinding } from '../../../core/src/core/cf-api-svc.types'; export function serviceInstanceReducer(state: IRequestEntityTypeState>, action: APISuccessOrFailedAction) { - let serviceInstanceGuid, serviceInstanceEntity, serviceBindingGuid; + let serviceInstanceGuid; + let serviceInstanceEntity; + let serviceBindingGuid; switch (action.type) { case DELETE_SERVICE_BINDING_ACTION_SUCCESS: const deleteServiceBindingAction = (action.apiAction as DeleteServiceBinding); @@ -41,9 +43,9 @@ export function serviceInstanceReducer(state: IRequestEntityTypeState, action: { guid: string -}, connectionStatus: endpointConnectionStatus) { +}, connectionStatus: endpointConnectionStatus) { if (!action.guid) { return state; } diff --git a/src/frontend/packages/store/src/reducers/users-roles.reducer.ts b/src/frontend/packages/store/src/reducers/users-roles.reducer.ts index d3f4a1fc1c..70bc92e492 100644 --- a/src/frontend/packages/store/src/reducers/users-roles.reducer.ts +++ b/src/frontend/packages/store/src/reducers/users-roles.reducer.ts @@ -20,7 +20,7 @@ import { UsersRolesState } from '../types/users-roles.types'; export function createDefaultOrgRoles(orgGuid: string): IUserPermissionInOrg { return { name: '', - orgGuid: orgGuid, + orgGuid, permissions: createUserRoleInOrg( undefined, undefined, diff --git a/src/frontend/packages/store/src/reducers/users.reducer.ts b/src/frontend/packages/store/src/reducers/users.reducer.ts index 134be5c1e5..32c1482587 100644 --- a/src/frontend/packages/store/src/reducers/users.reducer.ts +++ b/src/frontend/packages/store/src/reducers/users.reducer.ts @@ -89,7 +89,7 @@ type StateEntity = ISpace | IOrganization; interface StateEntities { [guid: string]: APIResource; } export function userSpaceOrgReducer(isSpace: boolean) { - return function (state: StateEntities, action: APISuccessOrFailedAction) { + return (state: StateEntities, action: APISuccessOrFailedAction) => { switch (action.type) { case ADD_ROLE_SUCCESS: case REMOVE_ROLE_SUCCESS: diff --git a/src/frontend/packages/store/src/test.ts b/src/frontend/packages/store/src/test.ts index d1e154d3ac..18653a67a2 100644 --- a/src/frontend/packages/store/src/test.ts +++ b/src/frontend/packages/store/src/test.ts @@ -1,14 +1,12 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files - import 'core-js/es7/reflect'; import 'zone.js/dist/zone'; import 'zone.js/dist/zone-testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; + import { APP_BASE_HREF } from '@angular/common'; +import { getTestBed } from '@angular/core/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; + declare const require: any; @@ -32,7 +30,6 @@ beforeAll(() => { jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; }); - // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/src/frontend/packages/store/src/types/domain.types.ts b/src/frontend/packages/store/src/types/domain.types.ts index f02b543425..5df1aaecdf 100644 --- a/src/frontend/packages/store/src/types/domain.types.ts +++ b/src/frontend/packages/store/src/types/domain.types.ts @@ -3,7 +3,9 @@ export class Domain { constructor( public guid: string, public name: string, + /* tslint:disable-next-line:variable-name */ public router_group_guid?: string, + /* tslint:disable-next-line:variable-name */ public router_group_type?: string, - ) {} + ) { } } diff --git a/src/frontend/packages/store/src/types/request.types.ts b/src/frontend/packages/store/src/types/request.types.ts index 2277871652..68ba4ef03e 100644 --- a/src/frontend/packages/store/src/types/request.types.ts +++ b/src/frontend/packages/store/src/types/request.types.ts @@ -21,7 +21,6 @@ export interface RequestAction extends Action, SingleEntityAction { /** * The entities in the response can live in a few different places. This will tell us where to look in the response to gather the entities * @export - * @enum {number} */ export enum RequestEntityLocation { RESOURCE, // The response is an object and the entities list is within a 'resource' param. Falls back to 'OBJECT' if missing. diff --git a/src/frontend/packages/store/src/types/route.types.ts b/src/frontend/packages/store/src/types/route.types.ts index 5749f40697..08df24062b 100644 --- a/src/frontend/packages/store/src/types/route.types.ts +++ b/src/frontend/packages/store/src/types/route.types.ts @@ -1,9 +1,12 @@ -import { APIResource } from './api.types'; import { IApp } from '../../../core/src/core/cf-api.types'; +import { APIResource } from './api.types'; + export class Route { constructor( + /* tslint:disable-next-line:variable-name */ public domain_guid: string, + /* tslint:disable-next-line:variable-name */ public space_guid: string, public host?: string, public path?: string, @@ -19,7 +22,9 @@ export interface RouteMode { export class CfRoute { + /* tslint:disable-next-line:variable-name */ domain_guid: string; + /* tslint:disable-next-line:variable-name */ space_guid: string; path?: string; host?: string; 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 8124017cd2..8b405a582b 100644 --- a/src/frontend/packages/store/src/types/user-favorites.types.ts +++ b/src/frontend/packages/store/src/types/user-favorites.types.ts @@ -1,6 +1,7 @@ import { favoritesConfigMapper } from '../../../core/src/shared/components/favorites-meta-card/favorite-config-mapper'; import { endpointSchemaKey } from '../helpers/entity-factory'; import { EndpointModel } from './endpoint.types'; +import { LoggerService } from '../../../core/src/core/logger.service'; export const userFavoritesPaginationKey = 'userFavorites'; @@ -78,8 +79,19 @@ export class UserFavorite implements IFavo .join(favoriteGuidSeparator); } - static getEntityGuidFromFavoriteGuid(favoriteGuid: string) { - return favoriteGuid.split(favoriteGuidSeparator)[0]; + static getEntityGuidFromFavoriteGuid(favoriteGuid: string, logger: LoggerService): string { + const parts = favoriteGuid.split(favoriteGuidSeparator); + if (parts.length < 3) { + logger.error('Failed to determine entity guid from favorite guid: ', parts); + return null; + } else if (parts.length === 3) { + return favoriteGuid.split(favoriteGuidSeparator)[0]; + } else { + // cf guid may contain a hypen meaning there are more than 3 parts, so use everything prior to the 2nd to last part + return favoriteGuid.replace( + `${favoriteGuidSeparator}${parts[parts.length - 2]}${favoriteGuidSeparator}${parts[parts.length - 1]}`, + ''); + } } } diff --git a/src/frontend/packages/store/src/types/user.types.ts b/src/frontend/packages/store/src/types/user.types.ts index b57e9635d8..dd5025e10b 100644 --- a/src/frontend/packages/store/src/types/user.types.ts +++ b/src/frontend/packages/store/src/types/user.types.ts @@ -1,5 +1,5 @@ -import { APIResource } from './api.types'; import { IOrganization, ISpace } from '../../../core/src/core/cf-api.types'; +import { APIResource } from './api.types'; export function getDefaultCfUserMissingRoles(): CfUserMissingRoles { return { @@ -72,39 +72,28 @@ export enum SpaceUserRoleNames { export class UserRoleInOrg { /** * See {OrgUserRoleNames.MANAGER} for name - * - * @type {Boolean} - * @memberof UserRoleInOrg */ - managers: Boolean; + managers: boolean; /** * See {OrgUserRoleNames.BILLING_MANAGERS} for name - * - * @type {Boolean} - * @memberof UserRoleInOrg */ - billing_managers: Boolean; + /* tslint:disable-next-line:variable-name */ + billing_managers: boolean; /** * See {OrgUserRoleNames.AUDITOR} for name - * - * @type {Boolean} - * @memberof UserRoleInOrg */ - auditors: Boolean; + auditors: boolean; /** * See {OrgUserRoleNames.USER} for name - * - * @type {Boolean} - * @memberof UserRoleInOrg */ - users: Boolean; + users: boolean; } /** * Temporary function. Once we move to typescript 2.7 (blocked on angular/compiler cli) we can use constant named properties in * UserRoleInOrg, thus can create roles without this workaround function. See * https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#constant-named-properties for details */ -export function createUserRoleInOrg(manager: Boolean, billingManager: Boolean, auditor: Boolean, user: Boolean): UserRoleInOrg { +export function createUserRoleInOrg(manager: boolean, billingManager: boolean, auditor: boolean, user: boolean): UserRoleInOrg { const res = {}; res[OrgUserRoleNames.MANAGER] = manager; res[OrgUserRoleNames.BILLING_MANAGERS] = billingManager; @@ -129,25 +118,16 @@ export interface IUserPermissionInSpace { export interface UserRoleInSpace { /** * See {SpaceUserRoleNames.MANAGER} for name - * - * @type {Boolean} - * @memberof UserRoleInSpace */ - managers: Boolean; + managers: boolean; /** * See {SpaceUserRoleNames.DEVELOPER} for name - * - * @type {Boolean} - * @memberof UserRoleInSpace */ - developers: Boolean; + developers: boolean; /** * See {SpaceUserRoleNames.AUDITOR} for name - * - * @type {Boolean} - * @memberof UserRoleInSpace */ - auditors: Boolean; + auditors: boolean; } /** @@ -156,7 +136,7 @@ export interface UserRoleInSpace { * https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#constant-named-properties for details * */ -export function createUserRoleInSpace(manager: Boolean, auditor: Boolean, developer: Boolean): UserRoleInSpace { +export function createUserRoleInSpace(manager: boolean, auditor: boolean, developer: boolean): UserRoleInSpace { const res = {}; res[SpaceUserRoleNames.MANAGER] = manager; res[SpaceUserRoleNames.DEVELOPER] = developer; diff --git a/src/jetstream/auth_test.go b/src/jetstream/auth_test.go index b3b4c9ec29..3e83c47b29 100644 --- a/src/jetstream/auth_test.go +++ b/src/jetstream/auth_test.go @@ -183,8 +183,8 @@ func TestLoginToCNSI(t *testing.T) { DopplerLoggingEndpoint: mockDopplerEndpoint, } - expectedCNSIRow := sqlmock.NewRows([]string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso"}). - AddRow(mockCNSIGUID, mockCNSI.Name, stringCFType, mockUAA.URL, mockCNSI.AuthorizationEndpoint, mockCNSI.TokenEndpoint, mockCNSI.DopplerLoggingEndpoint, true, mockCNSI.ClientId, cipherClientSecret, true) + expectedCNSIRow := sqlmock.NewRows([]string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso", "sub_type", "meta_data"}). + AddRow(mockCNSIGUID, mockCNSI.Name, stringCFType, mockUAA.URL, mockCNSI.AuthorizationEndpoint, mockCNSI.TokenEndpoint, mockCNSI.DopplerLoggingEndpoint, true, mockCNSI.ClientId, cipherClientSecret, true, "", "") mock.ExpectQuery(selectAnyFromCNSIs). WithArgs(mockCNSIGUID). diff --git a/src/jetstream/cnsi.go b/src/jetstream/cnsi.go index 6698503fc7..3660326fc7 100644 --- a/src/jetstream/cnsi.go +++ b/src/jetstream/cnsi.go @@ -57,13 +57,14 @@ func (p *portalProxy) RegisterEndpoint(c echo.Context, fetchInfo interfaces.Info cnsiClientId := c.FormValue("cnsi_client_id") cnsiClientSecret := c.FormValue("cnsi_client_secret") + subType := c.FormValue("sub_type") if cnsiClientId == "" { cnsiClientId = p.GetConfig().CFClient cnsiClientSecret = p.GetConfig().CFClientSecret } - newCNSI, err := p.DoRegisterEndpoint(cnsiName, apiEndpoint, skipSSLValidation, cnsiClientId, cnsiClientSecret, ssoAllowed, fetchInfo) + newCNSI, err := p.DoRegisterEndpoint(cnsiName, apiEndpoint, skipSSLValidation, cnsiClientId, cnsiClientSecret, ssoAllowed, subType, fetchInfo) if err != nil { return err } @@ -72,7 +73,7 @@ func (p *portalProxy) RegisterEndpoint(c echo.Context, fetchInfo interfaces.Info return nil } -func (p *portalProxy) DoRegisterEndpoint(cnsiName string, apiEndpoint string, skipSSLValidation bool, clientId string, clientSecret string, ssoAllowed bool, fetchInfo interfaces.InfoFunc) (interfaces.CNSIRecord, error) { +func (p *portalProxy) DoRegisterEndpoint(cnsiName string, apiEndpoint string, skipSSLValidation bool, clientId string, clientSecret string, ssoAllowed bool, subType string, fetchInfo interfaces.InfoFunc) (interfaces.CNSIRecord, error) { if len(cnsiName) == 0 || len(apiEndpoint) == 0 { return interfaces.CNSIRecord{}, interfaces.NewHTTPShadowError( @@ -129,6 +130,7 @@ func (p *portalProxy) DoRegisterEndpoint(cnsiName string, apiEndpoint string, sk newCNSI.ClientId = clientId newCNSI.ClientSecret = clientSecret newCNSI.SSOAllowed = ssoAllowed + newCNSI.SubType = subType err = p.setCNSIRecord(guid, newCNSI) @@ -264,6 +266,24 @@ func marshalClusterList(clusterList []*interfaces.ConnectedEndpoint) ([]byte, er return jsonString, nil } +func (p *portalProxy) UpdateEndointMetadata(guid string, metadata string) error { + log.Debug("UpdateEndointMetadata") + cnsiRepo, err := cnsis.NewPostgresCNSIRepository(p.DatabaseConnectionPool) + if err != nil { + log.Errorf(dbReferenceError, err) + return fmt.Errorf(dbReferenceError, err) + } + + err = cnsiRepo.UpdateMetadata(guid, metadata) + if err != nil { + msg := "Unable to update endpoint metadata: %v" + log.Errorf(msg, err) + return fmt.Errorf(msg, err) + } + + return nil +} + func (p *portalProxy) GetCNSIRecord(guid string) (interfaces.CNSIRecord, error) { log.Debug("GetCNSIRecord") cnsiRepo, err := cnsis.NewPostgresCNSIRepository(p.DatabaseConnectionPool) diff --git a/src/jetstream/cnsi_test.go b/src/jetstream/cnsi_test.go index a085f4aa1e..75d06549d2 100644 --- a/src/jetstream/cnsi_test.go +++ b/src/jetstream/cnsi_test.go @@ -33,7 +33,7 @@ func TestRegisterCFCluster(t *testing.T) { defer db.Close() mock.ExpectExec(insertIntoCNSIs). - WithArgs(sqlmock.AnyArg(), "Some fancy CF Cluster", "cf", mockV2Info.URL, mockAuthEndpoint, mockTokenEndpoint, mockDopplerEndpoint, true, mockClientId, sqlmock.AnyArg(), false). + WithArgs(sqlmock.AnyArg(), "Some fancy CF Cluster", "cf", mockV2Info.URL, mockAuthEndpoint, mockTokenEndpoint, mockDopplerEndpoint, true, mockClientId, sqlmock.AnyArg(), false, "", ""). WillReturnResult(sqlmock.NewResult(1, 1)) if err := pp.RegisterEndpoint(ctx, getCFPlugin(pp, "cf").Info); err != nil { diff --git a/src/jetstream/datastore/20190305144600_EndpointSubtype.go b/src/jetstream/datastore/20190305144600_EndpointSubtype.go new file mode 100644 index 0000000000..ba9a4fbc3a --- /dev/null +++ b/src/jetstream/datastore/20190305144600_EndpointSubtype.go @@ -0,0 +1,26 @@ +package datastore + +import ( + "database/sql" + + "bitbucket.org/liamstask/goose/lib/goose" +) + +func init() { + RegisterMigration(20190305144600, "EndpointSubtype", func(txn *sql.Tx, conf *goose.DBConf) error { + + addColumn := "ALTER TABLE cnsis ADD sub_type VARCHAR(64) DEFAULT NULL" + _, err := txn.Exec(addColumn) + if err != nil { + return err + } + + addColumn = "ALTER TABLE cnsis ADD meta_data TEXT DEFAULT NULL" + _, err = txn.Exec(addColumn) + if err != nil { + return err + } + + return nil + }) +} diff --git a/src/jetstream/mock_server_test.go b/src/jetstream/mock_server_test.go index 08e719a80d..cdedcce327 100644 --- a/src/jetstream/mock_server_test.go +++ b/src/jetstream/mock_server_test.go @@ -156,18 +156,18 @@ func expectOneRow() sqlmock.Rows { func expectCFRow() sqlmock.Rows { return sqlmock.NewRows(rowFieldsForCNSI). - AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, true) + AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, true, "", "") } func expectCERow() sqlmock.Rows { return sqlmock.NewRows(rowFieldsForCNSI). - AddRow(mockCEGUID, "Some fancy HCE Cluster", "hce", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, "", true, mockClientId, cipherClientSecret, true) + AddRow(mockCEGUID, "Some fancy HCE Cluster", "hce", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, "", true, mockClientId, cipherClientSecret, true, "", "") } func expectCFAndCERows() sqlmock.Rows { return sqlmock.NewRows(rowFieldsForCNSI). - AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret). - AddRow(mockCEGUID, "Some fancy HCE Cluster", "hce", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, "", true, mockClientId, cipherClientSecret) + AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, false, "", ""). + AddRow(mockCEGUID, "Some fancy HCE Cluster", "hce", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, "", true, mockClientId, cipherClientSecret, false, "", "") } func expectTokenRow() sqlmock.Rows { @@ -276,7 +276,7 @@ const ( getDbVersion = `SELECT version_id FROM goose_db_version WHERE is_applied = '1' ORDER BY id DESC LIMIT 1` ) -var rowFieldsForCNSI = []string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso"} +var rowFieldsForCNSI = []string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso", "sub_type", "meta_data"} var mockEncryptionKey = make([]byte, 32) diff --git a/src/jetstream/oauth_requests_test.go b/src/jetstream/oauth_requests_test.go index fba2d8ac49..926cf00c9b 100644 --- a/src/jetstream/oauth_requests_test.go +++ b/src/jetstream/oauth_requests_test.go @@ -107,8 +107,8 @@ func TestDoOauthFlowRequestWithValidToken(t *testing.T) { // p.GetCNSIRecord(r.GUID) -> cnsiRepo.Find(guid) - expectedCNSIRecordRow := sqlmock.NewRows([]string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso"}). - AddRow(mockCNSI.GUID, mockCNSI.Name, mockCNSI.CNSIType, mockURLasString, mockCNSI.AuthorizationEndpoint, mockCNSI.TokenEndpoint, mockCNSI.DopplerLoggingEndpoint, true, mockCNSI.ClientId, cipherClientSecret, true) + expectedCNSIRecordRow := sqlmock.NewRows([]string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso", "sub_type", "meta_data"}). + AddRow(mockCNSI.GUID, mockCNSI.Name, mockCNSI.CNSIType, mockURLasString, mockCNSI.AuthorizationEndpoint, mockCNSI.TokenEndpoint, mockCNSI.DopplerLoggingEndpoint, true, mockCNSI.ClientId, cipherClientSecret, true, "", "") mock.ExpectQuery(selectAnyFromCNSIs). WithArgs(mockCNSIGUID). WillReturnRows(expectedCNSIRecordRow) @@ -238,8 +238,8 @@ func TestDoOauthFlowRequestWithExpiredToken(t *testing.T) { WillReturnRows(expectedCNSITokenRow) // p.GetCNSIRecord(r.GUID) -> cnsiRepo.Find(guid) - expectedCNSIRecordRow := sqlmock.NewRows([]string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso"}). - AddRow(mockCNSI.GUID, mockCNSI.Name, mockCNSI.CNSIType, mockURLasString, mockCNSI.AuthorizationEndpoint, mockCNSI.TokenEndpoint, mockCNSI.DopplerLoggingEndpoint, true, mockCNSI.ClientId, cipherClientSecret, true) + expectedCNSIRecordRow := sqlmock.NewRows([]string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso", "sub_type", "meta_data"}). + AddRow(mockCNSI.GUID, mockCNSI.Name, mockCNSI.CNSIType, mockURLasString, mockCNSI.AuthorizationEndpoint, mockCNSI.TokenEndpoint, mockCNSI.DopplerLoggingEndpoint, true, mockCNSI.ClientId, cipherClientSecret, true, "", "") mock.ExpectQuery(selectAnyFromCNSIs). WithArgs(mockCNSIGUID). WillReturnRows(expectedCNSIRecordRow) diff --git a/src/jetstream/passthrough_test.go b/src/jetstream/passthrough_test.go index 6fd31cd846..5aa2f2e756 100644 --- a/src/jetstream/passthrough_test.go +++ b/src/jetstream/passthrough_test.go @@ -272,8 +272,8 @@ func TestValidateCNSIListWithValidGUID(t *testing.T) { _, _, _, pp, db, mock := setupHTTPTest(req) defer db.Close() - expectedCNSIRecordRow := sqlmock.NewRows([]string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso"}). - AddRow("valid-guid-abc123", "mock-name", "cf", "http://localhost", "http://localhost", "http://localhost", mockDopplerEndpoint, true, mockClientId, cipherClientSecret, true) + expectedCNSIRecordRow := sqlmock.NewRows([]string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "allow_sso", "sub_type", "meta_data"}). + AddRow("valid-guid-abc123", "mock-name", "cf", "http://localhost", "http://localhost", "http://localhost", mockDopplerEndpoint, true, mockClientId, cipherClientSecret, true, "", "") mock.ExpectQuery(selectAnyFromCNSIs). WithArgs("valid-guid-abc123"). WillReturnRows(expectedCNSIRecordRow) diff --git a/src/jetstream/plugins/cloudfoundry/main.go b/src/jetstream/plugins/cloudfoundry/main.go index 115dca1d99..ccc1850065 100644 --- a/src/jetstream/plugins/cloudfoundry/main.go +++ b/src/jetstream/plugins/cloudfoundry/main.go @@ -111,7 +111,7 @@ func (c *CloudFoundrySpecification) cfLoginHook(context echo.Context) error { log.Infof("Auto-registering cloud foundry endpoint %s as \"%s\"", cfAPI, autoRegName) // Auto-register the Cloud Foundry - cfCnsi, err = c.portalProxy.DoRegisterEndpoint(autoRegName, cfAPI, true, c.portalProxy.GetConfig().CFClient, c.portalProxy.GetConfig().CFClientSecret, false, cfEndpointSpec.Info) + cfCnsi, err = c.portalProxy.DoRegisterEndpoint(autoRegName, cfAPI, true, c.portalProxy.GetConfig().CFClient, c.portalProxy.GetConfig().CFClientSecret, false, "", cfEndpointSpec.Info) if err != nil { log.Fatal("Could not auto-register Cloud Foundry endpoint", err) return nil diff --git a/src/jetstream/repository/cnsis/cnsis.go b/src/jetstream/repository/cnsis/cnsis.go index a90e3e1580..1aad608178 100644 --- a/src/jetstream/repository/cnsis/cnsis.go +++ b/src/jetstream/repository/cnsis/cnsis.go @@ -13,6 +13,7 @@ type Repository interface { Delete(guid string) error Save(guid string, cnsiRecord interfaces.CNSIRecord, encryptionKey []byte) error Update(guid string, ssoAllowed bool) error + UpdateMetadata(guid string, metadata string) error } type Endpoint interface { diff --git a/src/jetstream/repository/cnsis/pgsql_cnsis.go b/src/jetstream/repository/cnsis/pgsql_cnsis.go index e885f462f9..81201f6e3d 100644 --- a/src/jetstream/repository/cnsis/pgsql_cnsis.go +++ b/src/jetstream/repository/cnsis/pgsql_cnsis.go @@ -12,29 +12,32 @@ import ( log "github.com/sirupsen/logrus" ) -var listCNSIs = `SELECT guid, name, cnsi_type, api_endpoint, auth_endpoint, token_endpoint, doppler_logging_endpoint, skip_ssl_validation, client_id, client_secret, sso_allowed +var listCNSIs = `SELECT guid, name, cnsi_type, api_endpoint, auth_endpoint, token_endpoint, doppler_logging_endpoint, skip_ssl_validation, client_id, client_secret, sso_allowed, sub_type, meta_data FROM cnsis` -var listCNSIsByUser = `SELECT c.guid, c.name, c.cnsi_type, c.api_endpoint, c.doppler_logging_endpoint, t.user_guid, t.token_expiry, c.skip_ssl_validation, t.disconnected, t.meta_data +var listCNSIsByUser = `SELECT c.guid, c.name, c.cnsi_type, c.api_endpoint, c.doppler_logging_endpoint, t.user_guid, t.token_expiry, c.skip_ssl_validation, t.disconnected, t.meta_data, c.sub_type, c.meta_data as endpoint_metadata FROM cnsis c, tokens t WHERE c.guid = t.cnsi_guid AND t.token_type=$1 AND t.user_guid=$2 AND t.disconnected = '0'` -var findCNSI = `SELECT guid, name, cnsi_type, api_endpoint, auth_endpoint, token_endpoint, doppler_logging_endpoint, skip_ssl_validation, client_id, client_secret, sso_allowed +var findCNSI = `SELECT guid, name, cnsi_type, api_endpoint, auth_endpoint, token_endpoint, doppler_logging_endpoint, skip_ssl_validation, client_id, client_secret, sso_allowed, sub_type, meta_data FROM cnsis WHERE guid=$1` -var findCNSIByAPIEndpoint = `SELECT guid, name, cnsi_type, api_endpoint, auth_endpoint, token_endpoint, doppler_logging_endpoint, skip_ssl_validation, client_id, client_secret, sso_allowed +var findCNSIByAPIEndpoint = `SELECT guid, name, cnsi_type, api_endpoint, auth_endpoint, token_endpoint, doppler_logging_endpoint, skip_ssl_validation, client_id, client_secret, sso_allowed, sub_type, meta_data FROM cnsis WHERE api_endpoint=$1` -var saveCNSI = `INSERT INTO cnsis (guid, name, cnsi_type, api_endpoint, auth_endpoint, token_endpoint, doppler_logging_endpoint, skip_ssl_validation, client_id, client_secret, sso_allowed) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)` +var saveCNSI = `INSERT INTO cnsis (guid, name, cnsi_type, api_endpoint, auth_endpoint, token_endpoint, doppler_logging_endpoint, skip_ssl_validation, client_id, client_secret, sso_allowed, sub_type, meta_data) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)` var deleteCNSI = `DELETE FROM cnsis WHERE guid = $1` // Just update the SSO Allowed state for now var updateCNSI = `UPDATE cnsis SET sso_allowed = $1 WHERE guid = $2` +// Update the metadata +var updateCNSIMetadata = `UPDATE cnsis SET metadata = $1 WHERE guid = $2` + // PostgresCNSIRepository is a PostgreSQL-backed CNSI repository type PostgresCNSIRepository struct { db *sql.DB @@ -55,6 +58,7 @@ func InitRepositoryProvider(databaseProvider string) { saveCNSI = datastore.ModifySQLStatement(saveCNSI, databaseProvider) deleteCNSI = datastore.ModifySQLStatement(deleteCNSI, databaseProvider) updateCNSI = datastore.ModifySQLStatement(updateCNSI, databaseProvider) + updateCNSIMetadata = datastore.ModifySQLStatement(updateCNSIMetadata, databaseProvider) } // List - Returns a list of CNSI Records @@ -74,11 +78,13 @@ func (p *PostgresCNSIRepository) List(encryptionKey []byte) ([]*interfaces.CNSIR pCNSIType string pURL string cipherTextClientSecret []byte + subType sql.NullString + metadata sql.NullString ) cnsi := new(interfaces.CNSIRecord) - err := rows.Scan(&cnsi.GUID, &cnsi.Name, &pCNSIType, &pURL, &cnsi.AuthorizationEndpoint, &cnsi.TokenEndpoint, &cnsi.DopplerLoggingEndpoint, &cnsi.SkipSSLValidation, &cnsi.ClientId, &cipherTextClientSecret, &cnsi.SSOAllowed) + err := rows.Scan(&cnsi.GUID, &cnsi.Name, &pCNSIType, &pURL, &cnsi.AuthorizationEndpoint, &cnsi.TokenEndpoint, &cnsi.DopplerLoggingEndpoint, &cnsi.SkipSSLValidation, &cnsi.ClientId, &cipherTextClientSecret, &cnsi.SSOAllowed, &subType, &metadata) if err != nil { return nil, fmt.Errorf("Unable to scan CNSI records: %v", err) } @@ -89,6 +95,14 @@ func (p *PostgresCNSIRepository) List(encryptionKey []byte) ([]*interfaces.CNSIR return nil, fmt.Errorf("Unable to parse API Endpoint: %v", err) } + if subType.Valid { + cnsi.SubType = subType.String + } + + if metadata.Valid { + cnsi.Metadata = metadata.String + } + if len(cipherTextClientSecret) > 0 { plaintextClientSecret, err := crypto.DecryptToken(encryptionKey, cipherTextClientSecret) if err != nil { @@ -129,14 +143,25 @@ func (p *PostgresCNSIRepository) ListByUser(userGUID string) ([]*interfaces.Conn pCNSIType string pURL string disconnected bool + subType sql.NullString + metadata sql.NullString ) cluster := new(interfaces.ConnectedEndpoint) - err := rows.Scan(&cluster.GUID, &cluster.Name, &pCNSIType, &pURL, &cluster.DopplerLoggingEndpoint, &cluster.Account, &cluster.TokenExpiry, &cluster.SkipSSLValidation, &disconnected, &cluster.TokenMetadata) + err := rows.Scan(&cluster.GUID, &cluster.Name, &pCNSIType, &pURL, &cluster.DopplerLoggingEndpoint, &cluster.Account, &cluster.TokenExpiry, &cluster.SkipSSLValidation, + &disconnected, &cluster.TokenMetadata, &subType, &metadata) if err != nil { return nil, fmt.Errorf("Unable to scan cluster records: %v", err) } + if subType.Valid { + cluster.SubType = subType.String + } + + if metadata.Valid { + cluster.EndpointMetadata = metadata.String + } + cluster.CNSIType = pCNSIType if cluster.APIEndpoint, err = url.Parse(pURL); err != nil { @@ -173,12 +198,14 @@ func (p *PostgresCNSIRepository) findBy(query, match string, encryptionKey []byt pCNSIType string pURL string cipherTextClientSecret []byte + subType sql.NullString + metadata sql.NullString ) cnsi := new(interfaces.CNSIRecord) err := p.db.QueryRow(query, match).Scan(&cnsi.GUID, &cnsi.Name, &pCNSIType, &pURL, - &cnsi.AuthorizationEndpoint, &cnsi.TokenEndpoint, &cnsi.DopplerLoggingEndpoint, &cnsi.SkipSSLValidation, &cnsi.ClientId, &cipherTextClientSecret, &cnsi.SSOAllowed) + &cnsi.AuthorizationEndpoint, &cnsi.TokenEndpoint, &cnsi.DopplerLoggingEndpoint, &cnsi.SkipSSLValidation, &cnsi.ClientId, &cipherTextClientSecret, &cnsi.SSOAllowed, &subType, &metadata) switch { case err == sql.ErrNoRows: @@ -189,6 +216,14 @@ func (p *PostgresCNSIRepository) findBy(query, match string, encryptionKey []byt // do nothing } + if subType.Valid { + cnsi.SubType = subType.String + } + + if metadata.Valid { + cnsi.Metadata = metadata.String + } + cnsi.CNSIType = pCNSIType if cnsi.APIEndpoint, err = url.Parse(pURL); err != nil { @@ -218,7 +253,7 @@ func (p *PostgresCNSIRepository) Save(guid string, cnsi interfaces.CNSIRecord, e } if _, err := p.db.Exec(saveCNSI, guid, cnsi.Name, fmt.Sprintf("%s", cnsi.CNSIType), fmt.Sprintf("%s", cnsi.APIEndpoint), cnsi.AuthorizationEndpoint, cnsi.TokenEndpoint, cnsi.DopplerLoggingEndpoint, cnsi.SkipSSLValidation, - cnsi.ClientId, cipherTextClientSecret, cnsi.SSOAllowed); err != nil { + cnsi.ClientId, cipherTextClientSecret, cnsi.SSOAllowed, cnsi.SubType, cnsi.Metadata); err != nil { return fmt.Errorf("Unable to Save CNSI record: %v", err) } @@ -271,3 +306,40 @@ func (p *PostgresCNSIRepository) Update(guid string, ssoAllowed bool) error { return nil } + +// UpdateMetadata - Update an endpoint's metadata +func (p *PostgresCNSIRepository) UpdateMetadata(guid string, metadata string) error { + log.Debug("UpdateMetadata") + + if guid == "" { + msg := "Unable to update Endpoint without a valid guid." + log.Debug(msg) + return errors.New(msg) + } + + var err error + + result, err := p.db.Exec(updateCNSIMetadata, metadata, guid) + if err != nil { + msg := "Unable to UPDATE endpoint: %v" + log.Debugf(msg, err) + return fmt.Errorf(msg, err) + } + + rowsUpdates, err := result.RowsAffected() + if err != nil { + return errors.New("Unable to UPDATE endpoint: could not determine number of rows that were updated") + } + + if rowsUpdates < 1 { + return errors.New("Unable to UPDATE endpoint: no rows were updated") + } + + if rowsUpdates > 1 { + log.Warn("UPDATE endpoint: More than 1 row was updated (expected only 1)") + } + + log.Debug("Endpoint UPDATE complete") + + return nil +} diff --git a/src/jetstream/repository/cnsis/pgsql_cnsis_test.go b/src/jetstream/repository/cnsis/pgsql_cnsis_test.go index 7c82be5dae..b097cd7bea 100644 --- a/src/jetstream/repository/cnsis/pgsql_cnsis_test.go +++ b/src/jetstream/repository/cnsis/pgsql_cnsis_test.go @@ -32,7 +32,7 @@ func TestPgSQLCNSIs(t *testing.T) { insertIntoCNSIs = `INSERT INTO cnsis` deleteFromCNSIs = `DELETE FROM cnsis WHERE (.+)` rowFieldsForCNSI = []string{"guid", "name", "cnsi_type", "api_endpoint", "auth_endpoint", - "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "sso_allowed"} + "token_endpoint", "doppler_logging_endpoint", "skip_ssl_validation", "client_id", "client_secret", "sso_allowed", "sub_type", "meta_data"} mockEncryptionKey = make([]byte, 32) ) cipherClientSecret, _ := crypto.EncryptToken(mockEncryptionKey, mockClientSecret) @@ -116,8 +116,8 @@ func TestPgSQLCNSIs(t *testing.T) { expectedList = append(expectedList, r1, r2) mockCFAndCERows = sqlmock.NewRows(rowFieldsForCNSI). - AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, false). - AddRow(mockCEGUID, "Some fancy HCE Cluster", "hce", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, "", true, mockClientId, cipherClientSecret, false) + AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, false, "", ""). + AddRow(mockCEGUID, "Some fancy HCE Cluster", "hce", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, "", true, mockClientId, cipherClientSecret, false, "", "") mock.ExpectQuery(selectAnyFromCNSIs). WillReturnRows(mockCFAndCERows) @@ -182,7 +182,7 @@ func TestPgSQLCNSIs(t *testing.T) { var ( //SELECT c.guid, c.name, c.cnsi_type, c.api_endpoint, c.doppler_logging_endpoint, t.user_guid, t.token_expiry, c.skip_ssl_validation, t.disconnected, t.meta_data //rowFieldsForCluster = []string{"guid", "name", "cnsi_type", "api_endpoint", "account", "token_expiry", "skip_ssl_validation"} - rowFieldsForCluster = []string{"guid", "name", "cnsi_type", "api_endpoint", "doppler_logging_endpoint", "account", "token_expiry", "skip_ssl_validation", "disconnected", "meta_data"} + rowFieldsForCluster = []string{"guid", "name", "cnsi_type", "api_endpoint", "doppler_logging_endpoint", "account", "token_expiry", "skip_ssl_validation", "disconnected", "meta_data", "sub_type", "endpoint_metadata"} expectedList []*interfaces.ConnectedEndpoint mockAccount = "asd-gjfg-bob" ) @@ -244,8 +244,8 @@ func TestPgSQLCNSIs(t *testing.T) { expectedList = append(expectedList, r1, r2) mockClusterList = sqlmock.NewRows(rowFieldsForCluster). - AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockDopplerEndpoint, mockAccount, mockTokenExpiry, true, false, ""). - AddRow(mockCEGUID, "Some fancy HCE Cluster", "hce", mockAPIEndpoint, mockDopplerEndpoint, mockAccount, mockTokenExpiry, true, false, "") + AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockDopplerEndpoint, mockAccount, mockTokenExpiry, true, false, "", "", ""). + AddRow(mockCEGUID, "Some fancy HCE Cluster", "hce", mockAPIEndpoint, mockDopplerEndpoint, mockAccount, mockTokenExpiry, true, false, "", "", "") mock.ExpectQuery(selectFromCNSIandTokensWhere). WillReturnRows(mockClusterList) @@ -320,7 +320,7 @@ func TestPgSQLCNSIs(t *testing.T) { expectedCNSIRecord := interfaces.CNSIRecord{GUID: mockCFGUID, Name: "Some fancy CF Cluster", CNSIType: "cf", APIEndpoint: u, AuthorizationEndpoint: mockAuthEndpoint, TokenEndpoint: mockAuthEndpoint, DopplerLoggingEndpoint: mockDopplerEndpoint, SkipSSLValidation: true, ClientId: mockClientId, ClientSecret: mockClientSecret, SSOAllowed: false} rs := sqlmock.NewRows(rowFieldsForCNSI). - AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, false) + AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, false, "", "") mock.ExpectQuery(selectFromCNSIsWhere). WillReturnRows(rs) @@ -417,7 +417,7 @@ func TestPgSQLCNSIs(t *testing.T) { expectedCNSIRecord := interfaces.CNSIRecord{GUID: mockCFGUID, Name: "Some fancy CF Cluster", CNSIType: "cf", APIEndpoint: u, AuthorizationEndpoint: mockAuthEndpoint, TokenEndpoint: mockAuthEndpoint, DopplerLoggingEndpoint: mockDopplerEndpoint, SkipSSLValidation: true, ClientId: mockClientId, ClientSecret: mockClientSecret, SSOAllowed: true} rs := sqlmock.NewRows(rowFieldsForCNSI). - AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, true) + AddRow(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, cipherClientSecret, true, "", "") mock.ExpectQuery(selectFromCNSIsWhere). WillReturnRows(rs) @@ -515,7 +515,7 @@ func TestPgSQLCNSIs(t *testing.T) { cnsi := interfaces.CNSIRecord{GUID: mockCFGUID, Name: "Some fancy CF Cluster", CNSIType: "cf", APIEndpoint: u, AuthorizationEndpoint: mockAuthEndpoint, TokenEndpoint: mockAuthEndpoint, DopplerLoggingEndpoint: mockDopplerEndpoint, SkipSSLValidation: true, ClientId: mockClientId, ClientSecret: mockClientSecret, SSOAllowed: true} mock.ExpectExec(insertIntoCNSIs). - WithArgs(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, sqlmock.AnyArg(), true). + WithArgs(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, sqlmock.AnyArg(), true, sqlmock.AnyArg(), sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) Convey("there should be no error returned", func() { @@ -536,7 +536,7 @@ func TestPgSQLCNSIs(t *testing.T) { expectedErrorMessage := fmt.Sprintf("Unable to Save CNSI record: %s", unknownDBError) mock.ExpectExec(insertIntoCNSIs). - WithArgs(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, sqlmock.AnyArg(), true). + WithArgs(mockCFGUID, "Some fancy CF Cluster", "cf", mockAPIEndpoint, mockAuthEndpoint, mockAuthEndpoint, mockDopplerEndpoint, true, mockClientId, sqlmock.AnyArg(), true, sqlmock.AnyArg(), sqlmock.AnyArg()). WillReturnError(errors.New(unknownDBError)) Convey("there should be an error returned", func() { diff --git a/src/jetstream/repository/interfaces/portal_proxy.go b/src/jetstream/repository/interfaces/portal_proxy.go index 8a81113513..29e7919081 100644 --- a/src/jetstream/repository/interfaces/portal_proxy.go +++ b/src/jetstream/repository/interfaces/portal_proxy.go @@ -15,7 +15,7 @@ type PortalProxy interface { GetHttpClientForRequest(req *http.Request, skipSSLValidation bool) http.Client RegisterEndpoint(c echo.Context, fetchInfo InfoFunc) error - DoRegisterEndpoint(cnsiName string, apiEndpoint string, skipSSLValidation bool, clientId string, clientSecret string, ssoAllowed bool, fetchInfo InfoFunc) (CNSIRecord, error) + DoRegisterEndpoint(cnsiName string, apiEndpoint string, skipSSLValidation bool, clientId string, clientSecret string, ssoAllowed bool, subType string, fetchInfo InfoFunc) (CNSIRecord, error) GetEndpointTypeSpec(typeName string) (EndpointPlugin, error) @@ -45,6 +45,7 @@ type PortalProxy interface { GetConfig() *PortalConfig Env() *env.VarSet ListEndpointsByUser(userGUID string) ([]*ConnectedEndpoint, error) + UpdateEndointMetadata(guid string, metadata string) error // UAA Token GetUAATokenRecord(userGUID string) (TokenRecord, error) diff --git a/src/jetstream/repository/interfaces/structs.go b/src/jetstream/repository/interfaces/structs.go index ceab8b18e7..666a6aedfb 100644 --- a/src/jetstream/repository/interfaces/structs.go +++ b/src/jetstream/repository/interfaces/structs.go @@ -44,6 +44,8 @@ type CNSIRecord struct { ClientId string `json:"client_id"` ClientSecret string `json:"-"` SSOAllowed bool `json:"sso_allowed"` + SubType string `json:"sub_type"` + Metadata string `json:"metadata"` } // ConnectedEndpoint @@ -58,6 +60,8 @@ type ConnectedEndpoint struct { AuthorizationEndpoint string `json:"-"` SkipSSLValidation bool `json:"skip_ssl_validation"` TokenMetadata string `json:"-"` + SubType string `json:"sub_type"` + EndpointMetadata string `json:"metadata"` } const ( diff --git a/src/test-e2e/application/application-e2e-helpers.ts b/src/test-e2e/application/application-e2e-helpers.ts index 296d7cafa0..6927fff558 100644 --- a/src/test-e2e/application/application-e2e-helpers.ts +++ b/src/test-e2e/application/application-e2e-helpers.ts @@ -27,8 +27,8 @@ export class ApplicationE2eHelper { /** * Get default sanitized URL name for App - * @param {string} appName Name of the app - * @returns {string} URL friendly name + * @param appName Name of the app + * @returns URL friendly name */ static getHostName = (appName) => appName.replace(/[\.:-]/g, '_'); diff --git a/src/test-e2e/endpoints/endpoints-connect-e2e.spec.ts b/src/test-e2e/endpoints/endpoints-connect-e2e.spec.ts index 58cf8d0843..cd6f325bdc 100644 --- a/src/test-e2e/endpoints/endpoints-connect-e2e.spec.ts +++ b/src/test-e2e/endpoints/endpoints-connect-e2e.spec.ts @@ -32,30 +32,28 @@ describe('Endpoints', () => { connectDialog.snackBar.waitForMessage('There are no connected endpoints, connect with your personal credentials to get started.'); connectDialog.snackBar.safeClose(); - // Get the row in the table for this endpoint - endpointsPage.table.getRowForEndpoint(toConnect.name).then(row => { - endpointsPage.table.openRowActionMenuByRow(row); - const menu = new MenuComponent(); - menu.waitUntilShown(); - return menu.getItemMap().then(items => { - expect(items['connect']).toBeDefined(); - items['connect'].click(); + + endpointsPage.cards.findCardByTitle(toConnect.name) + .then(card => card.openActionMenu()) + .then(actionMenu => actionMenu.getItem('Connect')) + .then(connect => { + expect(connect).toBeDefined(); + connect.click(); connectDialog.waitUntilShown(); // Connect dialog should be shown expect(connectDialog.isPresent()).toBeTruthy(); expect(connectDialog.isDisplayed()).toBeTruthy(); }); - }); }); it('should have empty username and password fields in the form', () => { connectDialog.form.getControlsMap().then((ctrls: FormItemMap) => { - expect(ctrls['authtype']).toBeDefined(); - expect(ctrls['username']).toBeDefined(); - expect(ctrls['password']).toBeDefined(); - expect(ctrls['authtype'].value).toEqual('creds'); - expect(ctrls['username'].text).toEqual(''); - expect(ctrls['password'].text).toEqual(''); + expect(ctrls.authtype).toBeDefined(); + expect(ctrls.username).toBeDefined(); + expect(ctrls.password).toBeDefined(); + expect(ctrls.authtype.value).toEqual('creds'); + expect(ctrls.username.text).toEqual(''); + expect(ctrls.password.text).toEqual(''); }); }); @@ -71,28 +69,27 @@ describe('Endpoints', () => { expect(connectDialog.canConnect()).toBeTruthy(); }); - it('should update service instance data on register', () => { + it('should update endpoints data on register', () => { connectDialog.connect(); // Wait for snackbar connectDialog.snackBar.waitForMessage(`Connected endpoint '${toConnect.name}'`); - endpointsPage.table.getEndpointDataForEndpoint(toConnect.name).then((ep: EndpointMetadata) => { + endpointsPage.cards.getEndpointDataForEndpoint(toConnect.name).then((ep: EndpointMetadata) => { expect(ep).toBeDefined(); expect(ep.connected).toBeTruthy(); }); connectDialog.waitUntilNotShown(); - endpointsPage.table.getRowForEndpoint(toConnect.name).then(row => { - endpointsPage.table.openRowActionMenuByRow(row); - const menu = new MenuComponent(); - menu.waitUntilShown('Endpoint Action Menu'); - return menu.getItemMap().then(items => { - expect(items['connect']).not.toBeDefined(); - expect(items['disconnect']).toBeDefined(); - // Only admins can unregister - expect(items['unregister']).not.toBeDefined(); - return menu.close(); + endpointsPage.cards.findCardByTitle(toConnect.name) + .then(card => card.openActionMenu()) + .then(menu => { + menu.waitUntilShown('Endpoint Action Menu'); + return menu.getItemMap().then(items => { + expect(items.connect).not.toBeDefined(); + expect(items.disconnect).toBeDefined(); + // Only admins can unregister + expect(items.unregister).not.toBeDefined(); + return menu.close(); + }); }); - - }); }); // NOTE: We connected as the User not the Admin, so logging in as admin will NOT have the endpoint connected @@ -126,21 +123,21 @@ describe('Endpoints', () => { it('should update row in table when disconnected', () => { endpointsPage.navigateTo(); - endpointsPage.table.getRowForEndpoint(toDisconnect.name).then(row => { - endpointsPage.table.openRowActionMenuByRow(row); + endpointsPage.cards.findCardByTitle(toDisconnect.name).then(card => { + card.openActionMenu(); const menu = new MenuComponent(); menu.waitUntilShown(); return menu.getItemMap().then(items => { - expect(items['connect']).not.toBeDefined(); - expect(items['disconnect']).toBeDefined(); - items['disconnect'].click(); + expect(items.connect).not.toBeDefined(); + expect(items.disconnect).toBeDefined(); + items.disconnect.click(); ConfirmDialogComponent.expectDialogAndConfirm('Disconnect', 'Disconnect Endpoint'); // Wait for snackbar const snackBar = new SnackBarComponent(); snackBar.waitUntilShown(); expect(endpointsPage.isNoneConnectedSnackBar(snackBar)).toBeTruthy(); - endpointsPage.table.getEndpointDataForEndpoint(toDisconnect.name).then((data: EndpointMetadata) => { + endpointsPage.cards.getEndpointDataForEndpoint(toDisconnect.name).then((data: EndpointMetadata) => { expect(data.connected).toBeFalsy(); }); }); diff --git a/src/test-e2e/endpoints/endpoints-e2e.spec.ts b/src/test-e2e/endpoints/endpoints-e2e.spec.ts index 5dd9a01cd3..4211654685 100644 --- a/src/test-e2e/endpoints/endpoints-e2e.spec.ts +++ b/src/test-e2e/endpoints/endpoints-e2e.spec.ts @@ -2,19 +2,17 @@ import { ApplicationsPage } from '../applications/applications.po'; import { CfTopLevelPage } from '../cloud-foundry/cf-level/cf-top-level-page.po'; import { e2e } from '../e2e'; import { ConsoleUserType } from '../helpers/e2e-helpers'; -import { LoginPage } from '../login/login.po'; import { MenuComponent } from '../po/menu.po'; import { SideNavMenuItem } from '../po/side-nav.po'; import { SnackBarComponent } from '../po/snackbar.po'; import { ServicesPage } from '../services/services.po'; -import { EndpointMetadata, EndpointsPage } from './endpoints.po'; +import { EndpointsPage } from './endpoints.po'; describe('Endpoints', () => { const endpointsPage = new EndpointsPage(); const applications = new ApplicationsPage(); const services = new ServicesPage(); const cloudFoundry = new CfTopLevelPage(); - const login = new LoginPage(); describe('Workflow on log in (admin/non-admin + no endpoints/some endpoints) -', () => { describe('As Admin -', () => { @@ -90,63 +88,53 @@ describe('Endpoints', () => { describe('Some registered endpoints -', () => { beforeAll(() => { - beforeAll(() => { - e2e.setup(ConsoleUserType.user) - .clearAllEndpoints() - .registerDefaultCloudFoundry(); - }); + e2e.setup(ConsoleUserType.user) + .clearAllEndpoints() + .registerDefaultCloudFoundry(); + }); - describe('endpoints table -', () => { - it('should be displayed', () => { - expect(endpointsPage.isActivePage()).toBeTruthy(); - }); + describe('endpoints table -', () => { + it('should be displayed', () => { + expect(endpointsPage.isActivePage()).toBeTruthy(); + }); - it('should not show register button', () => { - expect(endpointsPage.header.hasIconButton('add')).toBeFalsy(); - }); + it('should not show register button', () => { + expect(endpointsPage.header.hasIconButton('add')).toBeFalsy(); + }); - it('should show at least one endpoint', () => { - expect(endpointsPage.list.isDisplayed).toBeTruthy(); - expect(endpointsPage.list.isTableView()).toBeTruthy(); - expect(endpointsPage.list.table.getRows().count()).toBeGreaterThan(0); - }); + it('should show at least one endpoint', () => { + expect(endpointsPage.list.isDisplayed).toBeTruthy(); + expect(endpointsPage.list.isCardsView()).toBeTruthy(); + expect(endpointsPage.list.cards.getCardCount()).toBe(1); + }); - it('should show correct table content', () => { - // For each endpoint - // 1) we show the correct type - // 2) the icon is the correct 'disconnected' one - // 3) the address is correct - // 4) the 'connect' button is available in the action menu - - const endpointsTable = endpointsPage.table; - endpointsTable.getRows().map(row => endpointsTable.getEndpointData(row)).then(data => { - data.forEach((ep: EndpointMetadata) => { - const endpointConfig = e2e.secrets.getEndpointByName(ep.name); - expect(endpointConfig).not.toBeNull(); - expect(endpointConfig.url).toEqual(ep.url); - expect(endpointConfig.typeLabel).toEqual(ep.type); - - endpointsPage.table.getRowForEndpoint(ep.name).then(row => { - endpointsPage.table.openRowActionMenuByRow(row); - const menu = new MenuComponent(); - menu.waitUntilShown(); - menu.getItemMap().then(items => { - expect(items['connect']).toBeDefined(); - expect(items['disconnect']).not.toBeDefined(); - }); - menu.close(); - }); + it('should show correct cards content', () => { + const cf = e2e.secrets.getDefaultCFEndpoint().name; + return endpointsPage.cards.getEndpointDataForEndpoint(cf).then(ep => { + const endpointConfig = e2e.secrets.getEndpointByName(ep.name); + expect(endpointConfig).not.toBeNull(); + expect(endpointConfig.url).toEqual(ep.url); + expect(endpointConfig.typeLabel).toEqual(ep.type); + + return endpointsPage.cards.findCardByTitle(ep.name).then(card => { + card.openActionMenu(); + const menu = new MenuComponent(); + menu.waitUntilShown(); + menu.getItemMap().then(items => { + expect(items['connect']).toBeDefined(); + expect(items['disconnect']).not.toBeDefined(); }); + return menu.close(); }); }); + }); - it('Welcome snackbar message should be displayed', () => { - endpointsPage.sideNav.goto(SideNavMenuItem.Endpoints); - const snackBar = new SnackBarComponent(); - expect(snackBar.isDisplayed()).toBeTruthy(); - expect(endpointsPage.isNoneConnectedSnackBar(snackBar)).toBeTruthy(); - snackBar.close(); - }); + it('Welcome snackbar message should be displayed', () => { + endpointsPage.sideNav.goto(SideNavMenuItem.Endpoints); + const snackBar = new SnackBarComponent(); + expect(snackBar.isDisplayed()).toBeTruthy(); + expect(endpointsPage.isNoneConnectedSnackBar(snackBar)).toBeTruthy(); + snackBar.close(); }); }); }); diff --git a/src/test-e2e/endpoints/endpoints-register-e2e.spec.ts b/src/test-e2e/endpoints/endpoints-register-e2e.spec.ts index 7dfbb283b6..ae7f2130b8 100644 --- a/src/test-e2e/endpoints/endpoints-register-e2e.spec.ts +++ b/src/test-e2e/endpoints/endpoints-register-e2e.spec.ts @@ -155,7 +155,7 @@ describe('Endpoints', () => { expect(snackBar.hasMessage('SSL error - x509: certificate')).toBeTruthy(); /* tslint:disable-line:max-line-length*/ expect(snackBar.messageContains('Please check "Skip SSL validation for the endpoint" if the certificate issuer is trusted"')) - .toBeTruthy(); + .toBeTruthy(); }); it('Successful register', () => { @@ -169,9 +169,9 @@ describe('Endpoints', () => { register.stepper.next(); expect(endpointsPage.isActivePage()).toBeTruthy(); - expect(endpointsPage.table.isPresent()).toBeTruthy(); + expect(endpointsPage.cards.isPresent()).toBeTruthy(); - endpointsPage.table.getEndpointDataForEndpoint(validEndpoint.name).then((data: EndpointMetadata) => { + endpointsPage.cards.getEndpointDataForEndpoint(validEndpoint.name).then((data: EndpointMetadata) => { expect(data.name).toEqual(validEndpoint.name); expect(data.url).toEqual(validEndpoint.url); expect(data.connected).toBeFalsy(); diff --git a/src/test-e2e/endpoints/endpoints-unregister-e2e.spec.ts b/src/test-e2e/endpoints/endpoints-unregister-e2e.spec.ts index 683f4df46c..2362f6773f 100644 --- a/src/test-e2e/endpoints/endpoints-unregister-e2e.spec.ts +++ b/src/test-e2e/endpoints/endpoints-unregister-e2e.spec.ts @@ -26,16 +26,16 @@ describe('Endpoints', () => { expect(endpointsPage.isActivePage()).toBeTruthy(); // Should have a single row initially - endpointsPage.table.getRows().then(rows => { expect(rows.length).toBe(1); }); + expect(endpointsPage.cards.getCardCount()).toBe(1); // Get the row in the table for this endpoint - endpointsPage.table.getRowForEndpoint(toUnregister.name).then(row => { - endpointsPage.table.openRowActionMenuByRow(row); + endpointsPage.cards.findCardByTitle(toUnregister.name).then(card => { + card.openActionMenu(); const menu = new MenuComponent(); menu.waitUntilShown(); menu.clickItem('Unregister'); ConfirmDialogComponent.expectDialogAndConfirm('Unregister', 'Unregister Endpoint'); - endpointsPage.table.waitUntilNotBusy(); + endpointsPage.list.waitForNoLoadingIndicator(); // Should have removed the only row, so we should see welcome message again expect(endpointsPage.isWelcomeMessageAdmin()).toBeTruthy(); }); @@ -56,19 +56,17 @@ describe('Endpoints', () => { // Current number of rows let endpointCount = 0; - endpointsPage.table.getRows().then(rows => endpointCount = rows.length); + endpointsPage.cards.getCardCount().then(count => endpointCount = count); // Get the row in the table for this endpoint - endpointsPage.table.getRowForEndpoint(toUnregister.name).then(row => { - endpointsPage.table.openRowActionMenuByRow(row); + endpointsPage.cards.findCardByTitle(toUnregister.name).then(card => { + card.openActionMenu(); const menu = new MenuComponent(); menu.waitUntilShown(); menu.clickItem('Unregister'); ConfirmDialogComponent.expectDialogAndConfirm('Unregister', 'Unregister Endpoint'); - endpointsPage.table.waitUntilNotBusy(); - endpointsPage.table.getRows().then(rows => { - expect(rows.length).toBe(endpointCount - 1); - }); + endpointsPage.list.waitForNoLoadingIndicator(); + expect(endpointsPage.cards.getCardCount()).toBe(endpointCount - 1); }); }); }); @@ -86,11 +84,11 @@ describe('Endpoints', () => { expect(endpointsPage.isActivePage()).toBeTruthy(); // Should have a single row initially - endpointsPage.table.getRows().then(rows => { expect(rows.length).toBe(1); }); + expect(endpointsPage.cards.getCardCount()).toBe(1); // Get the row in the table for this endpoint - endpointsPage.table.getRowForEndpoint(toUnregister.name).then(row => { - endpointsPage.table.openRowActionMenuByRow(row); + endpointsPage.cards.findCardByTitle(toUnregister.name).then(card => { + card.openActionMenu(); const menu = new MenuComponent(); menu.waitUntilShown(); menu.getItemMap().then(items => { diff --git a/src/test-e2e/endpoints/endpoints.po.ts b/src/test-e2e/endpoints/endpoints.po.ts index a39d2cbda7..e53a61b6d3 100644 --- a/src/test-e2e/endpoints/endpoints.po.ts +++ b/src/test-e2e/endpoints/endpoints.po.ts @@ -1,19 +1,60 @@ -import { browser, by, element } from 'protractor'; +import { browser, by, element, promise } from 'protractor'; import { ElementFinder } from 'protractor/built'; import { E2EEndpointConfig } from '../e2e.types'; import { ConsoleUserType, E2EHelpers } from '../helpers/e2e-helpers'; -import { ListComponent, ListTableComponent } from '../po/list.po'; +import { ListCardComponent, ListComponent, ListHeaderComponent, ListTableComponent } from '../po/list.po'; +import { MetaCard, MetaCardItem } from '../po/meta-card.po'; import { Page } from '../po/page.po'; import { SnackBarComponent } from '../po/snackbar.po'; +export class EndpointCards extends ListCardComponent { + constructor(locator: ElementFinder, header: ListHeaderComponent) { + super(locator, header); + } + + findCardByTitle(title: string, subtitle = 'Cloud Foundry'): promise.Promise { + return super.findCardByTitle(`${title}\n${subtitle}`); + } + + getEndpointDataForEndpoint(title: string, subtitle = 'Cloud Foundry'): promise.Promise { + return this.findCardByTitle(title, subtitle).then(card => this.getEndpointData(card)); + } + + getEndpointData(card: MetaCard): promise.Promise { + const title = card.getTitle(); + const metaCardItems = card.getMetaCardItemsAsText(); + return promise.all[]>([ + title, + metaCardItems + ]).then(([t, m]: [string, MetaCardItem[]]) => { + const details = m.find(item => item.key === 'Details'); + // Protect against zero details + const safeDetails = details ? details.value : ''; + // If we have details, assume they're cf details + const cleanDetails = safeDetails.split('\n'); + const user = cleanDetails[1] ? cleanDetails[1].replace(' (Administrator)', '') : ''; + const isAdmin = safeDetails.endsWith(' (Administrator)'); + return { + name: t.substring(0, t.indexOf('\n')), + connected: m.find(item => item.key === 'Status').value === 'cloud_done', + type: t.substring(t.indexOf('\n') + 1, t.length), + user, + isAdmin, + url: m.find(item => item.key === 'Address').value, + // favorite: data[6] + } as EndpointMetadata; + }); + } +} + export class EndpointsTable extends ListTableComponent { constructor(locator: ElementFinder) { super(locator); } - getEndpointData(row: ElementFinder) { + getEndpointData(row: ElementFinder): promise.Promise { // Get all of the columns return row.all(by.tagName('app-table-cell')).map(col => col.getText()).then((data: string[]) => { return { @@ -65,6 +106,7 @@ export class EndpointsPage extends Page { // Endpoints table (as opposed to generic list.table) public table = new EndpointsTable(this.list.getComponent()); + public cards = new EndpointCards(this.list.locator, this.list.header); constructor() { super('/endpoints'); diff --git a/src/test-e2e/metrics/metrics-registration-e2e.spec.ts b/src/test-e2e/metrics/metrics-registration-e2e.spec.ts index 3bead4f90a..0536aa7ded 100644 --- a/src/test-e2e/metrics/metrics-registration-e2e.spec.ts +++ b/src/test-e2e/metrics/metrics-registration-e2e.spec.ts @@ -45,10 +45,10 @@ describe('Metrics', () => { // Check that we have one row expect(endpointsPage.isActivePage()).toBeTruthy(); - expect(endpointsPage.table.isPresent()).toBeTruthy(); + expect(endpointsPage.cards.isPresent()).toBeTruthy(); - expect(endpointsPage.table.getRows().count()).toBe(1); - endpointsPage.table.getEndpointDataForEndpoint('MetricsTest').then((data: EndpointMetadata) => { + expect(endpointsPage.cards.getCardCount()).toBe(1); + endpointsPage.cards.getEndpointDataForEndpoint('MetricsTest', 'Metrics').then((data: EndpointMetadata) => { expect(data.name).toEqual('MetricsTest'); expect(data.url).toEqual('https://www.google.com'); expect(data.connected).toBeFalsy(); diff --git a/src/test-e2e/po/list.po.ts b/src/test-e2e/po/list.po.ts index 002b4dcb30..b8963e0a99 100644 --- a/src/test-e2e/po/list.po.ts +++ b/src/test-e2e/po/list.po.ts @@ -142,7 +142,7 @@ export class ListCardComponent extends Component { } private findCardElementByTitle(title: string, metaType = MetaCardTitleType.CUSTOM): ElementFinder { - const card = this.locator.all(by.cssContainingText(`${ListCardComponent.cardsCss} ${metaType}`, title)).filter(elem => + const card = this.locator.all(by.css(`${ListCardComponent.cardsCss} ${metaType}`)).filter(elem => elem.getText().then(text => text === title) ).first(); browser.wait(until.presenceOf(card)); @@ -426,7 +426,7 @@ export class ListComponent extends Component { public empty: ListEmptyComponent; - constructor(locator: ElementFinder = element(by.tagName('app-list'))) { + constructor(public locator: ElementFinder = element(by.tagName('app-list'))) { super(locator); this.table = new ListTableComponent(locator); this.header = new ListHeaderComponent(locator); diff --git a/src/test-e2e/po/meta-card.po.ts b/src/test-e2e/po/meta-card.po.ts index 5f4bcaaf03..59e6b80a3e 100644 --- a/src/test-e2e/po/meta-card.po.ts +++ b/src/test-e2e/po/meta-card.po.ts @@ -17,9 +17,9 @@ export enum MetaCardTitleType { CUSTOM = '.meta-card__title' } -export interface MetaCardItem { - key: promise.Promise; - value: promise.Promise; +export interface MetaCardItem> { + key: T; + value: T; } export class MetaCard extends Component { @@ -64,6 +64,16 @@ export class MetaCard extends Component { }))); } + getMetaCardItemsAsText(): promise.Promise[]> { + return this.getMetaCardItems() + .then((rows: MetaCardItem[]) => rows.map(row => promise.all([row.key, row.value]))) + .then(promises => promise.all(promises)) + .then(res => res.map(a => ({ + key: a[0].replace(':', ''), + value: a[1] + }))); + } + click() { return this.elementFinder.click(); } diff --git a/src/test-e2e/po/page-header.po.ts b/src/test-e2e/po/page-header.po.ts index dbebc4420f..6ba30f26ad 100644 --- a/src/test-e2e/po/page-header.po.ts +++ b/src/test-e2e/po/page-header.po.ts @@ -19,13 +19,13 @@ export class PageHeader extends Component { return this.locator.all(by.css('.page-header button.mat-icon-button')); } - getIconButton(iconName: string) { - return this.getIconButtons().map(button => { - return button.getText(); - }).then(icons => { - const index = icons.findIndex(name => name === iconName); - return this.getIconButtons().get(index); - }); + getIconButton(iconName: string): promise.Promise { + return this.getIconButtons() + .map(button => button.getText()) + .then(icons => { + const index = icons.findIndex(name => name === iconName); + return index >= 0 ? this.getIconButtons().get(index) : null; + }); } clickIconButton(iconName: string): promise.Promise { @@ -51,14 +51,16 @@ export class PageHeader extends Component { } logout(): promise.Promise { - return this.clickIconButton('more_vert').then(() => { - browser.driver.sleep(2000); - const menu = new MenuComponent(); - menu.waitUntilShown(); - menu.clickItem('Logout'); - browser.driver.sleep(2000); - return browser.waitForAngular(); - }); + return this.locator.element(by.id('userMenu')) + .click() + .then(() => { + // browser.driver.sleep(2000); + const menu = new MenuComponent(); + menu.waitUntilShown(); + menu.clickItem('Logout'); + // browser.driver.sleep(2000); + return browser.waitForAngular(); + }); } } diff --git a/src/test-e2e/po/snackbar.po.ts b/src/test-e2e/po/snackbar.po.ts index dd80cd0525..5b78aa5471 100644 --- a/src/test-e2e/po/snackbar.po.ts +++ b/src/test-e2e/po/snackbar.po.ts @@ -1,10 +1,8 @@ -import { by, element, ElementFinder } from 'protractor'; -import { browser, promise } from 'protractor'; +import { browser, by, element, ElementFinder, promise } from 'protractor'; import { protractor } from 'protractor/built'; import { Component } from './component.po'; - const until = protractor.ExpectedConditions; /** @@ -53,11 +51,12 @@ export class SnackBarComponent extends Component { } // Wait for snackbar with given message - waitForMessage(message): promise.Promise { + waitForMessage(message: string): promise.Promise { const mesgElm = element(by.cssContainingText('.mat-simple-snackbar', message)); - return browser.wait(until.presenceOf(mesgElm), 5000, - 'Snackbar: ' + message + ' taking too long to appear in the DOM').then(() => { - return browser.driver.sleep(100); - }); + return browser.wait( + until.presenceOf(mesgElm), + 10000, + 'Snackbar: "' + message + '" taking too long to appear in the DOM' + ).then(() => browser.driver.sleep(100)); } } diff --git a/src/tsconfig.json b/src/tsconfig.json index eb7fa187ed..ef785a5cbb 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -9,6 +9,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es5", + "module": "es2015", "types": [ "hammerjs", "jasmine", diff --git a/tslint.json b/tslint.json index 8c4e3ed9a2..9353da4a5e 100644 --- a/tslint.json +++ b/tslint.json @@ -1,29 +1,26 @@ { + "extends": "tslint:recommended", "rulesDirectory": [ - "node_modules/codelyzer", - "node_modules/rxjs-tslint" + "codelyzer", + "rxjs-tslint" ], "rules": { - "arrow-return-shorthand": true, - "callable-types": true, - "class-name": true, - "comment-format": [ + "align": [ true, - "check-space" + "parameters", + "statements" ], - "curly": true, - "eofline": true, - "forin": true, + "array-type": false, + "arrow-parens": false, + "deprecation": { + "severity": "warn" + }, "import-blacklist": [ - true - ], - "import-spacing": true, - "indent": [ true, - "spaces" + "rxjs/Rx" ], - "interface-over-type-literal": true, - "label-position": true, + "interface-name": false, + "max-classes-per-file": false, "max-line-length": [ true, 140 @@ -40,90 +37,37 @@ ] } ], - "no-arg": true, - "no-bitwise": true, + "no-consecutive-blank-lines": false, "no-console": [ - true + true, + "debug", + "info", + "time", + "timeEnd", + "trace" ], - "no-construct": true, - "no-debugger": true, - "no-duplicate-super": true, "no-empty": false, - "no-empty-interface": true, - "no-eval": true, "no-inferrable-types": [ true, "ignore-params" ], - "no-misused-new": true, "no-non-null-assertion": true, - "no-shadowed-variable": true, - "no-string-literal": false, - "no-string-throw": true, + "no-redundant-jsdoc": true, "no-switch-case-fall-through": true, - "no-trailing-whitespace": true, - "no-unnecessary-initializer": true, - "no-unused-expression": true, "no-use-before-declare": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, - "one-line": [ + "no-var-requires": false, + "object-literal-key-quotes": [ true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" + "as-needed" ], - "prefer-const": true, + "object-literal-sort-keys": false, + "ordered-imports": false, "quotemark": [ true, "single" ], - "radix": true, - "rxjs-collapse-imports": true, - "rxjs-pipeable-operators-only": true, - "rxjs-no-static-observable-methods": true, - "rxjs-proper-imports": true, - "semicolon": [ - true, - "always" - ], - "triple-equals": [ - true, - "allow-null-check" - ], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - } - ], - "unified-signatures": true, - "variable-name": false, - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ], - "directive-selector": [ - true, - "attribute", - "app", - "camelCase" - ], - "component-selector": [ - true, - "element", - "app", - "kebab-case" - ], + "trailing-comma": false, + "no-output-on-prefix": false, "use-input-property-decorator": true, "use-output-property-decorator": true, "use-host-property-decorator": true, @@ -132,6 +76,10 @@ "use-life-cycle-interface": true, "use-pipe-transform-interface": true, "component-class-suffix": true, - "directive-class-suffix": true + "directive-class-suffix": true, + "rxjs-collapse-imports": true, + "rxjs-pipeable-operators-only": true, + "rxjs-no-static-observable-methods": true, + "rxjs-proper-imports": true } }