From 462b06b25dd284318dad58296bee4b39ae9891b5 Mon Sep 17 00:00:00 2001 From: Oleksii Kurinnyi Date: Fri, 21 Jun 2019 10:14:10 +0300 Subject: [PATCH] Apply TS formatter and linter to workspace-loader (#13532) * Added linter and formatter for Typescript. Signed-off-by: Oleksii Kurinnyi * Fixed linting warnings. Signed-off-by: Oleksii Kurinnyi * Fixed formatting. Signed-off-by: Oleksii Kurinnyi --- workspace-loader/package.json | 11 +- workspace-loader/src/custom.d.ts | 2 +- workspace-loader/src/index.ts | 4 +- .../src/json-rpc/che-json-rpc-api-service.ts | 123 +++--- .../src/json-rpc/che-json-rpc-master-api.ts | 409 +++++++++--------- .../src/json-rpc/json-rpc-client.ts | 341 ++++++++------- workspace-loader/src/json-rpc/util.ts | 7 +- .../src/json-rpc/websocket-client.ts | 22 +- workspace-loader/src/keycloak-loader.ts | 84 ++-- workspace-loader/src/loader/loader.ts | 26 +- workspace-loader/src/workspace-loader.ts | 84 ++-- workspace-loader/test/test.spec.ts | 293 ++++++------- workspace-loader/tsconfig.json | 3 +- workspace-loader/tsfmt.json | 18 + workspace-loader/tslint.json | 49 ++- workspace-loader/webpack.common.js | 13 +- workspace-loader/yarn.lock | 104 ++++- 17 files changed, 879 insertions(+), 714 deletions(-) create mode 100644 workspace-loader/tsfmt.json diff --git a/workspace-loader/package.json b/workspace-loader/package.json index 0d3cafcfeaa..5c3c0cd8cee 100644 --- a/workspace-loader/package.json +++ b/workspace-loader/package.json @@ -6,8 +6,11 @@ "scripts": { "test": "jest", "test:watch": "jest --watch", - "build": "webpack --config webpack.prod.js", - "start": "webpack-dev-server --open --config webpack.dev.js" + "compile": "webpack --config webpack.prod.js", + "start": "webpack-dev-server --open --config webpack.dev.js", + "format": "tsfmt -r --useTsfmt tsfmt.json", + "lint:fix": "tslint -c tslint.json --fix --project .", + "build": "yarn run format && yarn run compile" }, "author": "", "license": "EPL-1.0", @@ -20,7 +23,10 @@ "mini-css-extract-plugin": "^0.5.0", "style-loader": "^0.20.1", "ts-loader": "^5.3.3", + "tslint": "5.9.1", + "tslint-loader": "^3.5.4", "typescript": "^2.7.1", + "typescript-formatter": "7.2.2", "uglifyjs-webpack-plugin": "^1.1.8", "webpack": "^4.0.0", "webpack-cli": "^3.2.1", @@ -28,6 +34,7 @@ "webpack-merge": "^4.1.1" }, "dependencies": { + "@eclipse-che/api": "^7.0.0-beta-4.0-80162ea6d2", "lodash": "4.17.11", "reconnecting-websocket": "3.2.2" }, diff --git a/workspace-loader/src/custom.d.ts b/workspace-loader/src/custom.d.ts index 02aa338a9ce..1ca492e66be 100644 --- a/workspace-loader/src/custom.d.ts +++ b/workspace-loader/src/custom.d.ts @@ -80,7 +80,7 @@ declare namespace che { properties?: any; attributes?: { [attrName: string]: string | number; - }; + }; } export interface IEnvironmentMachineVolume { diff --git a/workspace-loader/src/index.ts b/workspace-loader/src/index.ts index 29e6e340457..acbd5b45253 100644 --- a/workspace-loader/src/index.ts +++ b/workspace-loader/src/index.ts @@ -19,11 +19,11 @@ import { WorkspaceLoader } from './workspace-loader'; /** Initialize */ if (document.getElementById('workspace-console')) { - new KeycloakLoader().loadKeycloakSettings().catch((error: any) => { + new KeycloakLoader().loadKeycloakSettings().catch(error => { if (error) { console.log(error); } - }).then((keycloak: any) => { + }).then(keycloak => { new WorkspaceLoader(new Loader(), keycloak).load(); }); } diff --git a/workspace-loader/src/json-rpc/che-json-rpc-api-service.ts b/workspace-loader/src/json-rpc/che-json-rpc-api-service.ts index 479d43f574a..9e0e684915f 100644 --- a/workspace-loader/src/json-rpc/che-json-rpc-api-service.ts +++ b/workspace-loader/src/json-rpc/che-json-rpc-api-service.ts @@ -10,12 +10,15 @@ * Red Hat, Inc. - initial API and implementation */ 'use strict'; -import {ICommunicationClient, JsonRpcClient} from './json-rpc-client'; + +import { ICommunicationClient, JsonRpcClient } from './json-rpc-client'; + +// tslint:disable:no-any export class IChannel { - subscription: string; - unsubscription: string; - notification: string; + subscription: string; + unsubscription: string; + notification: string; } /** @@ -24,64 +27,66 @@ export class IChannel { * @author Ann Shumilova */ export class CheJsonRpcApiClient { - /** - * Client that implements JSON RPC protocol. - */ - private jsonRpcClient: JsonRpcClient; - /** - * Communication client (can be http, websocket). - */ - private client: ICommunicationClient; + /** + * Client that implements JSON RPC protocol. + */ + private jsonRpcClient: JsonRpcClient; + /** + * Communication client (can be http, websocket). + */ + private client: ICommunicationClient; - constructor (client: ICommunicationClient) { - this.client = client; - this.jsonRpcClient = new JsonRpcClient(client); - } + constructor(client: ICommunicationClient) { + this.client = client; + this.jsonRpcClient = new JsonRpcClient(client); + } - /** - * Subscribe on the events from service. - * - * @param event event's name to subscribe - * @param notification notification name to handle - * @param handler event's handler - * @param params params (optional) - */ - subscribe(event: string, notification: string, handler: Function, params?: any): void { - this.jsonRpcClient.addNotificationHandler(notification, handler); - this.jsonRpcClient.notify(event, params); - } + /** + * Subscribe on the events from service. + * + * @param event event's name to subscribe + * @param notification notification name to handle + * @param handler event's handler + * @param params params (optional) + */ + /* tslint:disable-next-line:no-any */ + subscribe(event: string, notification: string, handler: Function, params?: any): void { + this.jsonRpcClient.addNotificationHandler(notification, handler); + this.jsonRpcClient.notify(event, params); + } - /** - * Unsubscribe concrete handler from events from service. - * - * @param event event's name to unsubscribe - * @param notification notification name binded to the event - * @param handler handler to be removed - * @param params params (optional) - */ - unsubscribe(event: string, notification: string, handler: Function, params?: any): void { - this.jsonRpcClient.removeNotificationHandler(notification, handler); - this.jsonRpcClient.notify(event, params); - } + /** + * Unsubscribe concrete handler from events from service. + * + * @param event event's name to unsubscribe + * @param notification notification name binded to the event + * @param handler handler to be removed + * @param params params (optional) + */ + /* tslint:disable-next-line:no-any */ + unsubscribe(event: string, notification: string, handler: Function, params?: any): void { + this.jsonRpcClient.removeNotificationHandler(notification, handler); + this.jsonRpcClient.notify(event, params); + } - /** - * Connects to the pointed entrypoint - * - * @param entrypoint entrypoint to connect to - * @returns {Promise} promise - */ - connect(entrypoint: () => string): Promise { - return this.client.connect(entrypoint); - } + /** + * Connects to the pointed entrypoint + * + * @param entrypoint entrypoint to connect to + * @returns {Promise} promise + */ + connect(entrypoint: () => string): Promise { + return this.client.connect(entrypoint); + } - /** - * Makes request. - * - * @param method - * @param params - * @returns {ng.IPromise} - */ - request(method: string, params?: any): Promise { - return this.jsonRpcClient.request(method, params); - } + /** + * Makes request. + * + * @param method + * @param params + * @returns {Promise} + */ + request(method: string, params?: any): Promise { + return this.jsonRpcClient.request(method, params); + } } diff --git a/workspace-loader/src/json-rpc/che-json-rpc-master-api.ts b/workspace-loader/src/json-rpc/che-json-rpc-master-api.ts index c33da9af25c..77cc8af1dc3 100644 --- a/workspace-loader/src/json-rpc/che-json-rpc-master-api.ts +++ b/workspace-loader/src/json-rpc/che-json-rpc-master-api.ts @@ -10,24 +10,26 @@ * Red Hat, Inc. - initial API and implementation */ 'use strict'; -import {CheJsonRpcApiClient} from './che-json-rpc-api-service'; + +import { che } from '@eclipse-che/api'; +import { CheJsonRpcApiClient } from './che-json-rpc-api-service'; import { ICommunicationClient, CODE_REQUEST_TIMEOUT, CommunicationClientEvent } from './json-rpc-client'; import { WorkspaceLoader } from '../workspace-loader'; enum MasterChannels { - ENVIRONMENT_OUTPUT = 'runtime/log', - ENVIRONMENT_STATUS = 'machine/statusChanged', - INSTALLER_OUTPUT = 'installer/log', - WORKSPACE_STATUS = 'workspace/statusChanged' + ENVIRONMENT_OUTPUT = 'runtime/log', + ENVIRONMENT_STATUS = 'machine/statusChanged', + INSTALLER_OUTPUT = 'installer/log', + WORKSPACE_STATUS = 'workspace/statusChanged' } const SUBSCRIBE: string = 'subscribe'; const UNSUBSCRIBE: string = 'unsubscribe'; export interface WorkspaceStatusChangedEvent { - status: string; - prevStatus: string; - workspaceId: string; - error: string; + status: string; + prevStatus: string; + workspaceId: string; + error: string; } /** @@ -36,225 +38,226 @@ export interface WorkspaceStatusChangedEvent { * @author Ann Shumilova */ export class CheJsonRpcMasterApi { - private cheJsonRpcApi: CheJsonRpcApiClient; - private clientId: string; - - private checkingInterval: number; - private checkingDelay = 10000; - private fetchingClientIdTimeout = 5000; + private cheJsonRpcApi: CheJsonRpcApiClient; + private clientId: string; - constructor(private readonly client: ICommunicationClient, - private readonly entryPoint: string, - private readonly loader: WorkspaceLoader) { - this.cheJsonRpcApi = new CheJsonRpcApiClient(client); + private checkingInterval: number; + private checkingDelay = 10000; + private fetchingClientIdTimeout = 5000; - client.addListener('open', () => this.onConnectionOpen()); - } + constructor(private readonly client: ICommunicationClient, + private readonly entryPoint: string, + private readonly loader: WorkspaceLoader) { + this.cheJsonRpcApi = new CheJsonRpcApiClient(client); - addListener(eventType: CommunicationClientEvent, handler: Function): void { - this.client.addListener(eventType, handler); - } + client.addListener('open', () => this.onConnectionOpen()); + } - removeListener(eventType: CommunicationClientEvent, handler: Function): void { - this.client.removeListener(eventType, handler); - } + addListener(eventType: CommunicationClientEvent, handler: Function): void { + this.client.addListener(eventType, handler); + } - onConnectionOpen(): void { - if (this.checkingInterval) { - clearInterval(this.checkingInterval); - this.checkingInterval = undefined; + removeListener(eventType: CommunicationClientEvent, handler: Function): void { + this.client.removeListener(eventType, handler); } - this.checkingInterval = setInterval(() => { - let isAlive = false; - const fetchClientPromise = new Promise((resolve) => { - this.fetchClientId().then(() => { - isAlive = true; - resolve(isAlive); - }, () => { - isAlive = false; - resolve(isAlive); - }); - }); + onConnectionOpen(): void { + if (this.checkingInterval) { + clearInterval(this.checkingInterval); + this.checkingInterval = undefined; + } - // this is timeout of fetchClientId request - const fetchClientTimeoutPromise = new Promise((resolve) => { - setTimeout(() => { - resolve(isAlive); - }, this.fetchingClientIdTimeout); - }); + this.checkingInterval = setInterval(() => { + let isAlive = false; + const fetchClientPromise = new Promise(resolve => { + this.fetchClientId().then(() => { + isAlive = true; + resolve(isAlive); + }, () => { + isAlive = false; + resolve(isAlive); + }); + }); - Promise.race([fetchClientPromise, fetchClientTimeoutPromise]).then((isAlive: boolean) => { - if (isAlive) { - return; - } + // this is timeout of fetchClientId request + const fetchClientTimeoutPromise = new Promise(resolve => { + setTimeout(() => { + resolve(isAlive); + }, this.fetchingClientIdTimeout); + }); - clearInterval(this.checkingInterval); - this.checkingInterval = undefined; + Promise.race([fetchClientPromise, fetchClientTimeoutPromise]).then((_isAlive: boolean) => { + if (_isAlive) { + return; + } - this.client.disconnect(CODE_REQUEST_TIMEOUT); - }); + clearInterval(this.checkingInterval); + this.checkingInterval = undefined; - }, this.checkingDelay); - } + this.client.disconnect(CODE_REQUEST_TIMEOUT); + }); - /** - * Opens connection to pointed entryPoint. - * - * @returns {IPromise>} - */ - connect(): Promise { - const entryPointFunction = () => { - const entryPoint = this.entryPoint + this.loader.getAuthenticationToken(); - if (this.clientId) { - let clientId = `clientId=${this.clientId}`; - // in case of reconnection - // we need to test entrypoint on existing query parameters - // to add already gotten clientId - if (/\?/.test(entryPoint) === false) { - clientId = '?' + clientId; - } else { - clientId = '&' + clientId; - } - return entryPoint + clientId; - } - return entryPoint; + }, this.checkingDelay); } - return this.cheJsonRpcApi.connect(entryPointFunction).then(() => - this.fetchClientId()); - } + /** + * Opens connection to pointed entryPoint. + * + * @returns {Promise} + */ + connect(): Promise { + const entryPointFunction = () => { + const entryPoint = this.entryPoint + this.loader.getAuthenticationToken(); + if (this.clientId) { + let clientId = `clientId=${this.clientId}`; + // in case of reconnection + // we need to test entrypoint on existing query parameters + // to add already gotten clientId + if (/\?/.test(entryPoint) === false) { + clientId = '?' + clientId; + } else { + clientId = '&' + clientId; + } + return entryPoint + clientId; + } + return entryPoint; + }; - /** - * Subscribes the environment output. - * - * @param workspaceId workspace's id - * @param machineName machine's name - * @param callback callback to process event - */ - subscribeEnvironmentOutput(workspaceId: string, callback: Function): void { - this.subscribe(MasterChannels.ENVIRONMENT_OUTPUT, workspaceId, callback); - } + return this.cheJsonRpcApi.connect(entryPointFunction).then(() => + this.fetchClientId() + ); + } - /** - * Un-subscribes the pointed callback from the environment output. - * - * @param workspaceId workspace's id - * @param machineName machine's name - * @param callback callback to process event - */ - unSubscribeEnvironmentOutput(workspaceId: string, callback: Function): void { - this.unsubscribe(MasterChannels.ENVIRONMENT_OUTPUT, workspaceId, callback); - } + /** + * Subscribes the environment output. + * + * @param workspaceId workspace's id + * @param machineName machine's name + * @param callback callback to process event + */ + subscribeEnvironmentOutput(workspaceId: string, callback: Function): void { + this.subscribe(MasterChannels.ENVIRONMENT_OUTPUT, workspaceId, callback); + } - /** - * Subscribes the environment status changed. - * - * @param workspaceId workspace's id - * @param callback callback to process event - */ - subscribeEnvironmentStatus(workspaceId: string, callback: Function): void { - this.subscribe(MasterChannels.ENVIRONMENT_STATUS, workspaceId, callback); - } + /** + * Un-subscribes the pointed callback from the environment output. + * + * @param workspaceId workspace's id + * @param machineName machine's name + * @param callback callback to process event + */ + unSubscribeEnvironmentOutput(workspaceId: string, callback: Function): void { + this.unsubscribe(MasterChannels.ENVIRONMENT_OUTPUT, workspaceId, callback); + } - /** - * Un-subscribes the pointed callback from environment status changed. - * - * @param workspaceId workspace's id - * @param callback callback to process event - */ - unSubscribeEnvironmentStatus(workspaceId: string, callback: Function): void { - this.unsubscribe(MasterChannels.ENVIRONMENT_STATUS, workspaceId, callback); - } + /** + * Subscribes the environment status changed. + * + * @param workspaceId workspace's id + * @param callback callback to process event + */ + subscribeEnvironmentStatus(workspaceId: string, callback: Function): void { + this.subscribe(MasterChannels.ENVIRONMENT_STATUS, workspaceId, callback); + } - /** - * Subscribes on workspace agent output. - * - * @param workspaceId workspace's id - * @param callback callback to process event - */ - subscribeInstallerOutput(workspaceId: string, callback: Function): void { - this.subscribe(MasterChannels.INSTALLER_OUTPUT, workspaceId, callback); - } + /** + * Un-subscribes the pointed callback from environment status changed. + * + * @param workspaceId workspace's id + * @param callback callback to process event + */ + unSubscribeEnvironmentStatus(workspaceId: string, callback: Function): void { + this.unsubscribe(MasterChannels.ENVIRONMENT_STATUS, workspaceId, callback); + } - /** - * Un-subscribes from workspace agent output. - * - * @param workspaceId workspace's id - * @param callback callback to process event - */ - unSubscribeInstallerOutput(workspaceId: string, callback: Function): void { - this.unsubscribe(MasterChannels.INSTALLER_OUTPUT, workspaceId, callback); - } + /** + * Subscribes on workspace agent output. + * + * @param workspaceId workspace's id + * @param callback callback to process event + */ + subscribeInstallerOutput(workspaceId: string, callback: Function): void { + this.subscribe(MasterChannels.INSTALLER_OUTPUT, workspaceId, callback); + } - /** - * Subscribes to workspace's status. - * - * @param workspaceId workspace's id - * @param callback callback to process event - */ - subscribeWorkspaceStatus(workspaceId: string, callback: Function): void { - const statusHandler = (message: any) => { - if (workspaceId === message.workspaceId) { - callback(message); - } - }; - this.subscribe(MasterChannels.WORKSPACE_STATUS, workspaceId, statusHandler); - } + /** + * Un-subscribes from workspace agent output. + * + * @param workspaceId workspace's id + * @param callback callback to process event + */ + unSubscribeInstallerOutput(workspaceId: string, callback: Function): void { + this.unsubscribe(MasterChannels.INSTALLER_OUTPUT, workspaceId, callback); + } - /** - * Un-subscribes pointed callback from workspace's status. - * - * @param workspaceId - * @param callback - */ - unSubscribeWorkspaceStatus(workspaceId: string, callback: Function): void { - this.unsubscribe(MasterChannels.WORKSPACE_STATUS, workspaceId, callback); - } + /** + * Subscribes to workspace's status. + * + * @param workspaceId workspace's id + * @param callback callback to process event + */ + subscribeWorkspaceStatus(workspaceId: string, callback: Function): void { + const statusHandler = (message: che.workspace.event.WorkspaceStatusEvent) => { + if (workspaceId === message.workspaceId) { + callback(message); + } + }; + this.subscribe(MasterChannels.WORKSPACE_STATUS, workspaceId, statusHandler); + } - /** - * Fetch client's id and stores it. - * - * @returns {IPromise} - */ - fetchClientId(): Promise { - return this.cheJsonRpcApi.request('websocketIdService/getId').then((data: any) => { - this.clientId = data[0]; - }); - } + /** + * Un-subscribes pointed callback from workspace's status. + * + * @param workspaceId + * @param callback + */ + unSubscribeWorkspaceStatus(workspaceId: string, callback: Function): void { + this.unsubscribe(MasterChannels.WORKSPACE_STATUS, workspaceId, callback); + } - /** - * Returns client's id. - * - * @returns {string} clinet connection identifier - */ - getClientId(): string { - return this.clientId; - } + /** + * Fetch client's id and stores it. + * + * @returns {Promise} + */ + fetchClientId(): Promise { + return this.cheJsonRpcApi.request('websocketIdService/getId').then((data: string[]) => { + this.clientId = data[0]; + }); + } - /** - * Performs subscribe to the pointed channel for pointed workspace's ID and callback. - * - * @param channel channel to un-subscribe - * @param workspaceId workspace's id - * @param callback callback - */ - private subscribe(channel: MasterChannels, workspaceId: string, callback: Function): void { - const method: string = channel.toString(); - const params = {method: method, scope: {workspaceId: workspaceId}}; - this.cheJsonRpcApi.subscribe(SUBSCRIBE, method, callback, params); - } + /** + * Returns client's id. + * + * @returns {string} client connection identifier + */ + getClientId(): string { + return this.clientId; + } - /** - * Performs un-subscribe of the pointed channel by pointed workspace's ID and callback. - * - * @param channel channel to un-subscribe - * @param workspaceId workspace's id - * @param callback callback - */ - private unsubscribe(channel: MasterChannels, workspaceId: string, callback: Function): void { - const method: string = channel.toString(); - const params = {method: method, scope: {workspaceId: workspaceId}}; - this.cheJsonRpcApi.unsubscribe(UNSUBSCRIBE, method, callback, params); - } + /** + * Performs subscribe to the pointed channel for pointed workspace's ID and callback. + * + * @param channel channel to un-subscribe + * @param workspaceId workspace's id + * @param callback callback + */ + private subscribe(channel: MasterChannels, workspaceId: string, callback: Function): void { + const method: string = channel.toString(); + const params = { method: method, scope: { workspaceId: workspaceId } }; + this.cheJsonRpcApi.subscribe(SUBSCRIBE, method, callback, params); + } + + /** + * Performs un-subscribe of the pointed channel by pointed workspace's ID and callback. + * + * @param channel channel to un-subscribe + * @param workspaceId workspace's id + * @param callback callback + */ + private unsubscribe(channel: MasterChannels, workspaceId: string, callback: Function): void { + const method: string = channel.toString(); + const params = { method: method, scope: { workspaceId: workspaceId } }; + this.cheJsonRpcApi.unsubscribe(UNSUBSCRIBE, method, callback, params); + } } diff --git a/workspace-loader/src/json-rpc/json-rpc-client.ts b/workspace-loader/src/json-rpc/json-rpc-client.ts index 0e48cc42dd0..9f0e0b0dec2 100644 --- a/workspace-loader/src/json-rpc/json-rpc-client.ts +++ b/workspace-loader/src/json-rpc/json-rpc-client.ts @@ -10,7 +10,11 @@ * Red Hat, Inc. - initial API and implementation */ 'use strict'; -import { IDeffered, Deffered } from './util'; + +import { IDeferred, Deferred } from './util'; + +// tslint:disable:no-any + const JSON_RPC_VERSION: string = '2.0'; export type CommunicationClientEvent = 'close' | 'error' | 'open' | 'message'; @@ -21,48 +25,49 @@ export const CODE_REQUEST_TIMEOUT = 4000; * The implementation can be through websocket or http protocol. */ export interface ICommunicationClient { - /** - * Adds listener callbacks for specified client event. - * @param {CommunicationClientEvent} eventType an event type - * @param {Function} handler a callback function - */ - addListener(eventType: CommunicationClientEvent, handler: Function): void; - /** - * Removes listener. - * @param {CommunicationClientEvent} eventType an event type - * @param {Function} handler a callback function - */ - removeListener(eventType: CommunicationClientEvent, handler: Function): void; - /** - * Performs connections. - * - * @param entrypoint - */ - connect(entrypoint: () => string): Promise; - /** - * Close the connection. - * @param {number} code close code - */ - disconnect(code?: number): void; - /** - * Send pointed data. - * - * @param data data to be sent - */ - send(data: any): void; + /** + * Adds listener callbacks for specified client event. + * @param {CommunicationClientEvent} eventType an event type + * @param {Function} handler a callback function + */ + addListener(eventType: CommunicationClientEvent, handler: Function): void; + /** + * Removes listener. + * @param {CommunicationClientEvent} eventType an event type + * @param {Function} handler a callback function + */ + removeListener(eventType: CommunicationClientEvent, handler: Function): void; + /** + * Performs connections. + * + * @param entrypoint + */ + connect(entrypoint: () => string): Promise; + /** + * Close the connection. + * @param {number} code close code + */ + disconnect(code?: number): void; + /** + * Send pointed data. + * + * @param data data to be sent + */ + /* tslint:disable-next-line:no-any */ + send(data: any): void; } interface IRequest { - jsonrpc: string; - id: string; - method: string; - params: any; + jsonrpc: string; + id: string; + method: string; + params: any; } interface INotification { - jsonrpc: string; - method: string; - params: any; + jsonrpc: string; + method: string; + params: any; } /** @@ -71,141 +76,141 @@ interface INotification { * @author Ann Shumilova */ export class JsonRpcClient { - /** - * Client for performing communications. - */ - private client: ICommunicationClient; - /** - * The list of the pending requests by request id. - */ - private pendingRequests: Map>; - /** - * The list of notification handlers by method name. - */ - private notificationHandlers: Map>; - private counter: number = 100; - - constructor(client: ICommunicationClient) { - this.client = client; - this.pendingRequests = new Map>(); - this.notificationHandlers = new Map>(); - - this.client.addListener("message", (message: any) => { - this.processResponse(message); - }); - } - - /** - * Performs JSON RPC request. - * - * @param method method's name - * @param params params - * @returns {IPromise} - */ - request(method: string, params?: any): Promise { - const deferred = new Deffered(); - const id: string = (this.counter++).toString(); - this.pendingRequests.set(id, deferred); - - const request: IRequest = { - jsonrpc: JSON_RPC_VERSION, - id: id, - method: method, - params: params - }; - - this.client.send(request); - return deferred.promise; - } - - /** - * Sends JSON RPC notification. - * - * @param method method's name - * @param params params (optional) - */ - notify(method: string, params?: any): void { - const request: INotification = { - jsonrpc: JSON_RPC_VERSION, - method: method, - params: params - }; - - this.client.send(request); - } - - /** - * Adds notification handler. - * - * @param method method's name - * @param handler handler to process notification - */ - public addNotificationHandler(method: string, handler: Function): void { - let handlers = this.notificationHandlers.get(method); - - if (handlers) { - handlers.push(handler); - } else { - handlers = [handler]; - this.notificationHandlers.set(method, handlers); + /** + * Client for performing communications. + */ + private client: ICommunicationClient; + /** + * The list of the pending requests by request id. + */ + private pendingRequests: Map>; + /** + * The list of notification handlers by method name. + */ + private notificationHandlers: Map>; + private counter: number = 100; + + constructor(client: ICommunicationClient) { + this.client = client; + this.pendingRequests = new Map>(); + this.notificationHandlers = new Map>(); + + this.client.addListener('message', (message: any) => { + this.processResponse(message); + }); + } + + /** + * Performs JSON RPC request. + * + * @param method method's name + * @param params params + * @returns {IPromise} + */ + request(method: string, params?: any): Promise { + const deferred = new Deferred(); + const id: string = (this.counter++).toString(); + this.pendingRequests.set(id, deferred); + + const request: IRequest = { + jsonrpc: JSON_RPC_VERSION, + id: id, + method: method, + params: params + }; + + this.client.send(request); + return deferred.promise; + } + + /** + * Sends JSON RPC notification. + * + * @param method method's name + * @param params params (optional) + */ + notify(method: string, params?: any): void { + const request: INotification = { + jsonrpc: JSON_RPC_VERSION, + method: method, + params: params + }; + + this.client.send(request); } - } - - /** - * Removes notification handler. - * - * @param method method's name - * @param handler handler - */ - public removeNotificationHandler(method: string, handler: Function): void { - const handlers = this.notificationHandlers.get(method); - - if (handlers) { - handlers.splice(handlers.indexOf(handler), 1); + + /** + * Adds notification handler. + * + * @param method method's name + * @param handler handler to process notification + */ + public addNotificationHandler(method: string, handler: Function): void { + let handlers = this.notificationHandlers.get(method); + + if (handlers) { + handlers.push(handler); + } else { + handlers = [handler]; + this.notificationHandlers.set(method, handlers); + } } - } - - /** - * Processes response - detects whether it is JSON RPC response or notification. - * - * @param message - */ - private processResponse(message: any): void { - if (message.id && this.pendingRequests.has(message.id)) { - this.processResponseMessage(message); - } else { - this.processNotification(message); + + /** + * Removes notification handler. + * + * @param method method's name + * @param handler handler + */ + public removeNotificationHandler(method: string, handler: Function): void { + const handlers = this.notificationHandlers.get(method); + + if (handlers) { + handlers.splice(handlers.indexOf(handler), 1); + } } - } - - /** - * Processes JSON RPC notification. - * - * @param message message - */ - private processNotification(message: any): void { - const method = message.method; - const handlers = this.notificationHandlers.get(method); - if (handlers && handlers.length > 0) { - handlers.forEach((handler: Function) => { - handler(message.params); - }); + + /** + * Processes response - detects whether it is JSON RPC response or notification. + * + * @param message + */ + private processResponse(message: any): void { + if (message.id && this.pendingRequests.has(message.id)) { + this.processResponseMessage(message); + } else { + this.processNotification(message); + } } - } - - /** - * Process JSON RPC response. - * - * @param message - */ - private processResponseMessage(message: any): void { - const promise = this.pendingRequests.get(message.id); - if (message.result) { - promise.resolve(message.result); - return; + + /** + * Processes JSON RPC notification. + * + * @param message message + */ + private processNotification(message: any): void { + const method = message.method; + const handlers = this.notificationHandlers.get(method); + if (handlers && handlers.length > 0) { + handlers.forEach((handler: Function) => { + handler(message.params); + }); + } } - if (message.error) { - promise.reject(message.error); + + /** + * Process JSON RPC response. + * + * @param message + */ + private processResponseMessage(message: any): void { + const promise = this.pendingRequests.get(message.id); + if (message.result) { + promise.resolve(message.result); + return; + } + if (message.error) { + promise.reject(message.error); + } } - } } diff --git a/workspace-loader/src/json-rpc/util.ts b/workspace-loader/src/json-rpc/util.ts index 5577b7a3eab..cf1842980db 100644 --- a/workspace-loader/src/json-rpc/util.ts +++ b/workspace-loader/src/json-rpc/util.ts @@ -9,13 +9,16 @@ * Contributors: * Red Hat, Inc. - initial API and implementation */ -export interface IDeffered { + +// tslint:disable:no-any */ + +export interface IDeferred { resolve(value?: T): void; reject(reason?: any): void; promise: Promise; } -export class Deffered implements IDeffered { +export class Deferred implements IDeferred { promise: Promise; private resolveF; diff --git a/workspace-loader/src/json-rpc/websocket-client.ts b/workspace-loader/src/json-rpc/websocket-client.ts index 066e2624574..3325063ffc7 100644 --- a/workspace-loader/src/json-rpc/websocket-client.ts +++ b/workspace-loader/src/json-rpc/websocket-client.ts @@ -10,8 +10,12 @@ * Red Hat, Inc. - initial API and implementation */ 'use strict'; + import { ICommunicationClient, CommunicationClientEvent } from './json-rpc-client'; import * as ReconnectingWebsocket from 'reconnecting-websocket'; + +// tslint:disable:no-any + const RWS = require('reconnecting-websocket'); /** @@ -21,7 +25,7 @@ const RWS = require('reconnecting-websocket'); */ export class WebsocketClient implements ICommunicationClient { private websocketStream: ReconnectingWebsocket; - private handlers: {[event: string]: Function[]} = {}; + private handlers: { [event: string]: Function[] } = {}; /** * Performs connection to the pointed entrypoint. @@ -33,23 +37,23 @@ export class WebsocketClient implements ICommunicationClient { this.websocketStream = new RWS(entrypoint, [], { connectionTimeout: 10000 }); - this.websocketStream.addEventListener("open", (event: Event) => { - const eventType: CommunicationClientEvent = "open"; + this.websocketStream.addEventListener('open', (event: Event) => { + const eventType: CommunicationClientEvent = 'open'; this.callHandlers(eventType, event); resolve(); }); - this.websocketStream.addEventListener("error", (event: Event) => { - const eventType: CommunicationClientEvent = "error"; + this.websocketStream.addEventListener('error', (event: Event) => { + const eventType: CommunicationClientEvent = 'error'; this.callHandlers(eventType, event); reject(); }); - this.websocketStream.addEventListener("message", (message: any) => { + this.websocketStream.addEventListener('message', (message: any) => { const data = JSON.parse(message.data); - const eventType: CommunicationClientEvent = "message"; + const eventType: CommunicationClientEvent = 'message'; this.callHandlers(eventType, data); }); - this.websocketStream.addEventListener("close", (event: Event) => { - const eventType: CommunicationClientEvent = "close"; + this.websocketStream.addEventListener('close', (event: Event) => { + const eventType: CommunicationClientEvent = 'close'; this.callHandlers(eventType, event); }); }); diff --git a/workspace-loader/src/keycloak-loader.ts b/workspace-loader/src/keycloak-loader.ts index e718c885d55..62ffc57b3b6 100644 --- a/workspace-loader/src/keycloak-loader.ts +++ b/workspace-loader/src/keycloak-loader.ts @@ -11,13 +11,16 @@ */ 'use strict'; +// tslint:disable:no-any + declare const Keycloak: Function; + export class KeycloakLoader { /** * Load keycloak settings */ public loadKeycloakSettings(): Promise { - const msg = "Cannot load keycloak settings. This is normal for single-user mode."; + const msg = 'Cannot load keycloak settings. This is normal for single-user mode.'; return new Promise((resolve, reject) => { if (window.parent && window.parent['_keycloak']) { @@ -25,27 +28,24 @@ export class KeycloakLoader { resolve(window['_keycloak']); return; } - try { - const request = new XMLHttpRequest(); - request.onerror = request.onabort = function () { - reject(msg); - }; + const request = new XMLHttpRequest(); - request.onload = () => { - if (request.status == 200) { - resolve(this.injectKeycloakScript(JSON.parse(request.responseText))); - } else { - reject(new Error('Cannot load keycloak script')); - } - }; + request.onerror = request.onabort = function () { + reject(new Error(msg)); + }; - const url = "/api/keycloak/settings"; - request.open("GET", url, true); - request.send(); - } catch (e) { - reject(msg + e.message); - } + request.onload = () => { + if (request.status === 200) { + resolve(this.injectKeycloakScript(JSON.parse(request.responseText))); + } else { + reject(new Error(msg + ' Cannot load keycloak script')); + } + }; + + const url = '/api/keycloak/settings'; + request.open('GET', url, true); + request.send(); }); } @@ -56,7 +56,6 @@ export class KeycloakLoader { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.type = 'text/javascript'; - (script as any).language = 'javascript'; script.async = true; script.src = keycloakSettings['che.keycloak.js_adapter_url']; @@ -76,31 +75,32 @@ export class KeycloakLoader { * Initialize keycloak and load the IDE */ private initKeycloak(keycloakSettings: any): Promise { - return new Promise((resolve, reject) => { - function keycloakConfig() { - const theOidcProvider = keycloakSettings['che.keycloak.oidc_provider']; - if (!theOidcProvider) { - return { - url: keycloakSettings['che.keycloak.auth_server_url'], - realm: keycloakSettings['che.keycloak.realm'], - clientId: keycloakSettings['che.keycloak.client_id'] - }; - } else { - return { - oidcProvider: theOidcProvider, - clientId: keycloakSettings['che.keycloak.client_id'] - }; - } + function keycloakConfig() { + const theOidcProvider = keycloakSettings['che.keycloak.oidc_provider']; + if (!theOidcProvider) { + return { + url: keycloakSettings['che.keycloak.auth_server_url'], + realm: keycloakSettings['che.keycloak.realm'], + clientId: keycloakSettings['che.keycloak.client_id'] + }; + } else { + return { + oidcProvider: theOidcProvider, + clientId: keycloakSettings['che.keycloak.client_id'] + }; } - const keycloak = Keycloak(keycloakConfig()); + } + const keycloak = Keycloak(keycloakConfig()); - window['_keycloak'] = keycloak; + window['_keycloak'] = keycloak; - var useNonce; - if (typeof keycloakSettings['che.keycloak.use_nonce'] === 'string') { - useNonce = keycloakSettings['che.keycloak.use_nonce'].toLowerCase() === 'true'; - } - window.sessionStorage.setItem('oidcIdeRedirectUrl', location.href); + let useNonce: boolean; + if (typeof keycloakSettings['che.keycloak.use_nonce'] === 'string') { + useNonce = keycloakSettings['che.keycloak.use_nonce'].toLowerCase() === 'true'; + } + window.sessionStorage.setItem('oidcIdeRedirectUrl', location.href); + + return new Promise((resolve, reject) => { keycloak .init({ onLoad: 'login-required', diff --git a/workspace-loader/src/loader/loader.ts b/workspace-loader/src/loader/loader.ts index df9890d8d44..4274204534d 100644 --- a/workspace-loader/src/loader/loader.ts +++ b/workspace-loader/src/loader/loader.ts @@ -19,9 +19,9 @@ export class Loader { constructor() { /** Show the loader */ setTimeout(() => { - document.getElementById('workspace-loader').style.display = "block"; + document.getElementById('workspace-loader').style.display = 'block'; setTimeout(() => { - document.getElementById('workspace-loader').style.opacity = "1"; + document.getElementById('workspace-loader').style.opacity = '1'; }, 1); }, 1); @@ -42,16 +42,16 @@ export class Loader { /** * Adds a message to output console. - * + * * @param message message to log */ log(message: string): HTMLElement { - let container = document.getElementById("workspace-console-container"); + const container = document.getElementById('workspace-console-container'); if (container.childElementCount > 500) { - container.removeChild(container.firstChild) + container.removeChild(container.firstChild); } - let element = document.createElement("pre"); + const element = document.createElement('pre'); element.innerHTML = message; container.appendChild(element); if (element.scrollIntoView) { @@ -66,17 +66,17 @@ export class Loader { * @param message error message */ error(message: string): void { - let element = this.log(message); - element.className = "error"; + const element = this.log(message); + element.className = 'error'; } onclickConsole(): void { - if (document.getElementById('workspace-loader').hasAttribute("max")) { - document.getElementById('workspace-loader').removeAttribute("max"); - document.getElementById('workspace-console').removeAttribute("max"); + if (document.getElementById('workspace-loader').hasAttribute('max')) { + document.getElementById('workspace-loader').removeAttribute('max'); + document.getElementById('workspace-console').removeAttribute('max'); } else { - document.getElementById('workspace-loader').setAttribute("max", ""); - document.getElementById('workspace-console').setAttribute("max", ""); + document.getElementById('workspace-loader').setAttribute('max', ''); + document.getElementById('workspace-console').setAttribute('max', ''); } } diff --git a/workspace-loader/src/workspace-loader.ts b/workspace-loader/src/workspace-loader.ts index 65f820cd232..06d4c151fb8 100644 --- a/workspace-loader/src/workspace-loader.ts +++ b/workspace-loader/src/workspace-loader.ts @@ -14,25 +14,28 @@ import { WebsocketClient } from './json-rpc/websocket-client'; import { CheJsonRpcMasterApi, WorkspaceStatusChangedEvent } from './json-rpc/che-json-rpc-master-api'; import { Loader } from './loader/loader'; +import { che } from '@eclipse-che/api'; + +// tslint:disable:no-any const WEBSOCKET_CONTEXT = '/api/websocket'; export class WorkspaceLoader { - workspace: che.IWorkspace; + workspace: che.workspace.Workspace; startAfterStopping = false; constructor(private readonly loader: Loader, - private readonly keycloak?: any) { + private readonly keycloak?: any) { /** Ask dashboard to show the IDE. */ - window.parent.postMessage("show-ide", "*"); + window.parent.postMessage('show-ide', '*'); } async load(): Promise { const workspaceKey = this.getWorkspaceKey(); - if (!workspaceKey || workspaceKey === "") { - console.error("Workspace is not defined"); + if (!workspaceKey || workspaceKey === '') { + console.error('Workspace is not defined'); return; } @@ -40,9 +43,8 @@ export class WorkspaceLoader { this.workspace = await this.getWorkspace(workspaceKey); await this.handleWorkspace(); await this.openIDE(); - } - catch(err) { - if(err) { + } catch (err) { + if (err) { console.error(err); this.loader.error(err); } else { @@ -81,11 +83,11 @@ export class WorkspaceLoader { * * @param workspaceId workspace id */ - getWorkspace(workspaceId: string): Promise { + getWorkspace(workspaceId: string): Promise { const request = new XMLHttpRequest(); - request.open("GET", '/api/workspace/' + workspaceId); - return this.setAuthorizationHeader(request).then((xhr: XMLHttpRequest) => { - return new Promise((resolve, reject) => { + request.open('GET', '/api/workspace/' + workspaceId); + return this.setAuthorizationHeader(request).then((xhr: XMLHttpRequest) => + new Promise((resolve, reject) => { xhr.send(); xhr.onreadystatechange = () => { if (xhr.readyState !== 4) { return; } @@ -96,30 +98,28 @@ export class WorkspaceLoader { } resolve(JSON.parse(xhr.responseText)); }; - }); - }); + })); } /** * Start current workspace. */ - startWorkspace(): Promise { + startWorkspace(): Promise { const request = new XMLHttpRequest(); - request.open("POST", `/api/workspace/${this.workspace.id}/runtime`); - return this.setAuthorizationHeader(request).then((xhr: XMLHttpRequest) => { - return new Promise((resolve, reject) => { + request.open('POST', `/api/workspace/${this.workspace.id}/runtime`); + return this.setAuthorizationHeader(request).then((xhr: XMLHttpRequest) => + new Promise((resolve, reject) => { xhr.send(); xhr.onreadystatechange = () => { if (xhr.readyState !== 4) { return; } if (xhr.status !== 200) { - const errorMessage = 'Failed to start the workspace: "' + this.getRequestErrorMessage(xhr) + '"'; + const errorMessage = 'Failed to start the workspace: "' + this.getRequestErrorMessage(xhr) + '"'; reject(new Error(errorMessage)); return; } resolve(JSON.parse(xhr.responseText)); }; - }); - }); + })); } getRequestErrorMessage(xhr: XMLHttpRequest): string { @@ -137,7 +137,7 @@ export class WorkspaceLoader { return xhr.statusText; } - return "Unknown error"; + return 'Unknown error'; } /** @@ -158,23 +158,19 @@ export class WorkspaceLoader { } else { resolve(); } - }).then(() => { - return this.connectMasterApi(); - }); + }).then(() => this.connectMasterApi()); const runningOnConnectionPromise = masterApiConnectionPromise - .then((masterApi: CheJsonRpcMasterApi) => { - return new Promise((resolve, reject) => { + .then((masterApi: CheJsonRpcMasterApi) => + new Promise((resolve, reject) => { masterApi.addListener('open', () => { this.checkWorkspaceRuntime().then(resolve, reject); }); - }); - }); + })); const runningOnStatusChangePromise = masterApiConnectionPromise - .then((masterApi: CheJsonRpcMasterApi) => { - return this.subscribeWorkspaceEvents(masterApi); - }); + .then((masterApi: CheJsonRpcMasterApi) => + this.subscribeWorkspaceEvents(masterApi)); return Promise.race([runningOnConnectionPromise, runningOnStatusChangePromise]); } @@ -184,7 +180,7 @@ export class WorkspaceLoader { * * @param message output message */ - onEnvironmentOutput(message) : void { + onEnvironmentOutput(message): void { this.loader.log(message); } @@ -201,12 +197,12 @@ export class WorkspaceLoader { /** * Subscribes to the workspace events. */ - subscribeWorkspaceEvents(masterApi: CheJsonRpcMasterApi) : Promise { + subscribeWorkspaceEvents(masterApi: CheJsonRpcMasterApi): Promise { return new Promise((resolve, reject) => { masterApi.subscribeEnvironmentOutput(this.workspace.id, (message: any) => this.onEnvironmentOutput(message.text)); masterApi.subscribeInstallerOutput(this.workspace.id, - (message: any) => this.onEnvironmentOutput(message.text)); + (message: any) => this.onEnvironmentOutput(message.text)); masterApi.subscribeWorkspaceStatus(this.workspace.id, (message: WorkspaceStatusChangedEvent) => { if (message.error) { @@ -214,7 +210,7 @@ export class WorkspaceLoader { } else if (message.status === 'RUNNING') { this.checkWorkspaceRuntime().then(resolve, reject); } else if (message.status === 'STOPPED') { - if (message.prevStatus == 'STARTING') { + if (message.prevStatus === 'STARTING') { this.loader.error('Workspace stopped.'); this.loader.hideLoader(); this.loader.showReload(); @@ -229,7 +225,7 @@ export class WorkspaceLoader { checkWorkspaceRuntime(): Promise { return new Promise((resolve, reject) => { - this.getWorkspace(this.workspace.id).then((workspace) => { + this.getWorkspace(this.workspace.id).then(workspace => { if (workspace.status === 'RUNNING') { if (workspace.runtime) { resolve(); @@ -244,12 +240,12 @@ export class WorkspaceLoader { /** * Opens IDE for the workspace. */ - openIDE() : void { - this.getWorkspace(this.workspace.id).then((workspace) => { - const machines = workspace.runtime.machines; - for (const machineName in machines) { - const servers = machines[machineName].servers; - for (const serverId in servers) { + openIDE(): void { + this.getWorkspace(this.workspace.id).then(workspace => { + const machines = workspace.runtime.machines || []; + for (const machineName of Object.keys(machines)) { + const servers = machines[machineName].servers || []; + for (const serverId of Object.keys(servers)) { const attributes = servers[serverId].attributes; if (attributes['type'] === 'ide') { this.openURL(servers[serverId].url + this.getQueryString()); @@ -267,7 +263,7 @@ export class WorkspaceLoader { * * @param url url to be opened */ - openURL(url) : void { + openURL(url: string): void { // Preconfigured IDE may use dedicated port. In this case Chrome browser fails // with error net::ERR_CONNECTION_REFUSED. Timer helps to open the URL without errors. setTimeout(() => { diff --git a/workspace-loader/test/test.spec.ts b/workspace-loader/test/test.spec.ts index d09b8a7c40c..1fa07a39e53 100644 --- a/workspace-loader/test/test.spec.ts +++ b/workspace-loader/test/test.spec.ts @@ -16,12 +16,15 @@ import { WorkspaceLoader } from '../src/workspace-loader'; import { Loader } from '../src/loader/loader'; +import { che } from '@eclipse-che/api'; + +// tslint:disable:no-any describe('Workspace Loader', () => { - let fakeWorkspaceConfig: che.IWorkspace; + let fakeWorkspaceConfig: che.workspace.Workspace; - beforeEach(function() { + beforeEach(function () { document.body.innerHTML = `
Loading...
@@ -38,32 +41,32 @@ describe('Workspace Loader', () => { fakeWorkspaceConfig = { status: 'STOPPED', links: { - ide: "test url" + ide: 'test url' }, config: { - defaultEnv: "default", - "environments": { - "default": { + defaultEnv: 'default', + 'environments': { + 'default': { machines: { machine: { servers: { server1: { attributes: { - type: "ide" + type: 'ide' }, - port: 0, - protocol: "" + port: '0', + protocol: '' } } }, }, recipe: { - type: "" + type: '' } } } } - } as che.IWorkspace; + } as che.workspace.Workspace; }); it('should have "workspace-loader" in DOM', () => { @@ -88,70 +91,67 @@ describe('Workspace Loader', () => { const loader = new Loader(); const workspaceLoader = new WorkspaceLoader(loader); - spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue("foo/bar"); + spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue('foo/bar'); - spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => { - return new Promise((resolve) => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { resolve(fakeWorkspaceConfig); - }); - }); + })); workspaceLoader.load(); expect(workspaceLoader.getWorkspaceKey).toHaveBeenCalled(); - expect(workspaceLoader.getWorkspace).toHaveBeenCalledWith("foo/bar"); + expect(workspaceLoader.getWorkspace).toHaveBeenCalledWith('foo/bar'); }); describe('if workspace has a preconfigured IDE with query parameters', () => { - let ideURL = "ide URL" - let workspaceLoader; + const ideURL = 'ide URL'; + let workspaceLoader: WorkspaceLoader; - beforeEach((done) => { + beforeEach(done => { const loader = new Loader(); workspaceLoader = new WorkspaceLoader(loader); - spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue("foo/bar"); - spyOn(workspaceLoader, 'getQueryString').and.returnValue("?param=value"); + spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue('foo/bar'); + spyOn(workspaceLoader, 'getQueryString').and.returnValue('?param=value'); - spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => { - return new Promise((resolve) => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'RUNNING'; - fakeWorkspaceConfig.runtime = { machines: { ide: { servers: { server1: { attributes: { type: "ide" }, url: ideURL } } } } } as any; + fakeWorkspaceConfig.runtime = { machines: { ide: { servers: { server1: { attributes: { type: 'ide' }, url: ideURL } } } } } as any; resolve(fakeWorkspaceConfig); - }); - }); + })); - spyOn(workspaceLoader, "openIDE").and.callThrough(); - spyOn(workspaceLoader, "openURL"); + spyOn(workspaceLoader, 'openIDE').and.callThrough(); + spyOn(workspaceLoader, 'openURL'); workspaceLoader.load().then(done); }); it('should call openURL method with correct parameter', () => { - expect(workspaceLoader.openURL).toHaveBeenCalledWith(ideURL + "?param=value"); + expect(workspaceLoader.openURL).toHaveBeenCalledWith(ideURL + '?param=value'); }); }); describe('if workspace does not have an IDE server', () => { - let workspaceLoader; + let workspaceLoader: WorkspaceLoader; - beforeEach((done) => { + beforeEach(done => { const loader = new Loader(); workspaceLoader = new WorkspaceLoader(loader); - spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue("foo/bar"); - spyOn(workspaceLoader, 'getQueryString').and.returnValue(""); + spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue('foo/bar'); + spyOn(workspaceLoader, 'getQueryString').and.returnValue(''); - spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => { - return new Promise((resolve) => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'RUNNING'; - fakeWorkspaceConfig.config.environments["default"].machines = {}; - fakeWorkspaceConfig.runtime = {} as che.IWorkspaceRuntime; + fakeWorkspaceConfig.config.environments['default'].machines = {}; + fakeWorkspaceConfig.runtime = {} as che.workspace.Runtime; resolve(fakeWorkspaceConfig); - }); - }); + })); - spyOn(workspaceLoader, "openIDE").and.callThrough(); - spyOn(workspaceLoader, "openURL"); + spyOn(workspaceLoader, 'openIDE').and.callThrough(); + spyOn(workspaceLoader, 'openURL'); workspaceLoader.load().then(done); }); @@ -167,25 +167,24 @@ describe('Workspace Loader', () => { const loader = new Loader(); workspaceLoader = new WorkspaceLoader(loader); - spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue("foo/bar"); + spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue('foo/bar'); - spyOn(workspaceLoader, "connectMasterApi"); + spyOn(workspaceLoader, 'connectMasterApi'); - spyOn(workspaceLoader, "subscribeWorkspaceEvents"); + spyOn(workspaceLoader, 'subscribeWorkspaceEvents'); - spyOn(workspaceLoader, "openIDE"); + spyOn(workspaceLoader, 'openIDE'); }); describe('and user owns the workspace or has been granted permissions for shared workspace', () => { - beforeEach((done) => { - spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => { - return new Promise((resolve) => { + beforeEach(done => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'RUNNING'; - fakeWorkspaceConfig.runtime = {} as che.IWorkspaceRuntime; + fakeWorkspaceConfig.runtime = {} as che.workspace.Runtime; resolve(fakeWorkspaceConfig); - }); - }); + })); workspaceLoader.load().then(done); }); @@ -204,15 +203,14 @@ describe('Workspace Loader', () => { }); - describe(`and user hasn't been granted permissions for shared workspace`, () => { + describe('and user hasn\'t been granted permissions for shared workspace', () => { - beforeEach((done) => { - spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => { - return new Promise((resolve) => { + beforeEach(done => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'RUNNING'; resolve(fakeWorkspaceConfig); - }); - }); + })); workspaceLoader.load().then(done); }); @@ -237,40 +235,35 @@ describe('Workspace Loader', () => { let statusChangeCallback: Function; let workspaceLoadPromise: Promise; - beforeEach((done) => { + beforeEach(done => { const loader = new Loader(); workspaceLoader = new WorkspaceLoader(loader); - spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue("foo/bar"); + spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue('foo/bar'); - spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => { - return new Promise((resolve) => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'STOPPED'; resolve(fakeWorkspaceConfig); - }); - }); + })); - spyOn(workspaceLoader, "subscribeWorkspaceEvents").and.callThrough(); + spyOn(workspaceLoader, 'subscribeWorkspaceEvents').and.callThrough(); - spyOn(workspaceLoader, "startWorkspace").and.callFake(() => { - return Promise.resolve(); - }); + spyOn(workspaceLoader, 'startWorkspace').and.callFake(() => Promise.resolve()); - spyOn(workspaceLoader, "connectMasterApi").and.callFake(() => { + spyOn(workspaceLoader, 'connectMasterApi').and.callFake(() => { done(); return Promise.resolve({ addListener: () => { }, subscribeEnvironmentOutput: () => { }, subscribeInstallerOutput: () => { }, - subscribeWorkspaceStatus: (workspaceId, callback) => { + subscribeWorkspaceStatus: (_workspaceId, callback) => { statusChangeCallback = callback; } }); }); - spyOn(workspaceLoader, "openIDE").and.callFake(() => { - return Promise.resolve(); - }); + spyOn(workspaceLoader, 'openIDE').and.callFake(() => Promise.resolve()); workspaceLoadPromise = workspaceLoader.load(); }); @@ -291,7 +284,7 @@ describe('Workspace Loader', () => { beforeEach(() => { statusChangeCallback({ status: 'STARTING' }); - }) + }); it('should not open an IDE', () => { expect(workspaceLoader.openIDE).not.toHaveBeenCalled(); @@ -301,14 +294,13 @@ describe('Workspace Loader', () => { describe('and user owns workspace or has been granted permissions for shared workspace', () => { - beforeEach((done) => { - workspaceLoader.getWorkspace.and.callFake(() => { - return new Promise((resolve) => { + beforeEach(done => { + (workspaceLoader.getWorkspace as any).and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'RUNNING'; - fakeWorkspaceConfig.runtime = {} as che.IWorkspaceRuntime; + fakeWorkspaceConfig.runtime = {} as che.workspace.Runtime; resolve(fakeWorkspaceConfig); - }); - }); + })); statusChangeCallback({ status: 'RUNNING' }); @@ -321,15 +313,14 @@ describe('Workspace Loader', () => { }); - describe(`and user hasn't been granted permissions for shared workspace`, () => { + describe('and user hasn\'t been granted permissions for shared workspace', () => { - beforeEach((done) => { - workspaceLoader.getWorkspace.and.callFake(() => { - return new Promise((resolve) => { + beforeEach(done => { + (workspaceLoader.getWorkspace as any).and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'RUNNING'; resolve(fakeWorkspaceConfig); - }); - }); + })); statusChangeCallback({ status: 'RUNNING' }); @@ -349,7 +340,7 @@ describe('Workspace Loader', () => { describe('then receives an error on websocket', () => { - beforeEach((done) => { + beforeEach(done => { statusChangeCallback({ error: 'Something bad happened.' }); workspaceLoadPromise.then(done); @@ -373,38 +364,34 @@ describe('Workspace Loader', () => { let workspaceLoader: WorkspaceLoader; let workspaceLoadPromise: Promise; - beforeEach((done) => { + beforeEach(done => { const loader = new Loader(); workspaceLoader = new WorkspaceLoader(loader); - spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue("foo/bar"); + spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue('foo/bar'); - spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => { - return new Promise((resolve) => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'STOPPED'; resolve(fakeWorkspaceConfig); - }); - }); + })); - spyOn(workspaceLoader, "connectMasterApi").and.callFake(() => { - return Promise.resolve({ - addListener: () => {}, - subscribeEnvironmentOutput: () => {}, - subscribeInstallerOutput: () => {}, - subscribeWorkspaceStatus: () => {} - }); - }); + spyOn(workspaceLoader, 'connectMasterApi').and.callFake(() => + Promise.resolve({ + addListener: () => { }, + subscribeEnvironmentOutput: () => { }, + subscribeInstallerOutput: () => { }, + subscribeWorkspaceStatus: () => { } + })); - spyOn(workspaceLoader, "subscribeWorkspaceEvents").and.callThrough(); + spyOn(workspaceLoader, 'subscribeWorkspaceEvents').and.callThrough(); - spyOn(workspaceLoader, "startWorkspace").and.callFake(() => { + spyOn(workspaceLoader, 'startWorkspace').and.callFake(() => { done(); return Promise.reject(); }); - spyOn(workspaceLoader, "openIDE").and.callFake(() => { - return Promise.resolve(); - }); + spyOn(workspaceLoader, 'openIDE').and.callFake(() => Promise.resolve()); workspaceLoadPromise = workspaceLoader.load(); }); @@ -427,7 +414,7 @@ describe('Workspace Loader', () => { describe('then the request for starting the workspace fails', () => { - beforeEach((done) => { + beforeEach(done => { workspaceLoadPromise.then(done); }); @@ -441,53 +428,48 @@ describe('Workspace Loader', () => { describe('show error if workspace became stopped on starting', () => { let workspaceLoader: WorkspaceLoader; const loader = { - log: () => { return undefined; }, - hideLoader: () => {}, - showReload: () => {}, - error: () => {}, - onclickConsole: () => {}, - onclickReload: () => { return true } + log: () => undefined, + hideLoader: () => { }, + showReload: () => { }, + error: () => { }, + onclickConsole: () => { }, + onclickReload: () => true }; let statusChangeCallback: Function; - beforeEach((done) => { - spyOn(loader, "error").and.callThrough(); - spyOn(loader, "log").and.callThrough(); - spyOn(loader, "hideLoader").and.callThrough(); - spyOn(loader, "showReload").and.callThrough(); + beforeEach(done => { + spyOn(loader, 'error').and.callThrough(); + spyOn(loader, 'log').and.callThrough(); + spyOn(loader, 'hideLoader').and.callThrough(); + spyOn(loader, 'showReload').and.callThrough(); workspaceLoader = new WorkspaceLoader(loader); - spyOn(workspaceLoader, "getWorkspaceKey").and.returnValue("foo/bar"); + spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue('foo/bar'); - spyOn(workspaceLoader, "getWorkspace").and.callFake(() => { - return new Promise((resolve) => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'STARTING'; resolve(fakeWorkspaceConfig); - }); - }); + })); - spyOn(workspaceLoader, "subscribeWorkspaceEvents").and.callThrough(); + spyOn(workspaceLoader, 'subscribeWorkspaceEvents').and.callThrough(); - spyOn(workspaceLoader, "startWorkspace").and.callFake(() => { - return Promise.resolve(); - }); + spyOn(workspaceLoader, 'startWorkspace').and.callFake(() => Promise.resolve()); - spyOn(workspaceLoader, "connectMasterApi").and.callFake(() => { + spyOn(workspaceLoader, 'connectMasterApi').and.callFake(() => { done(); return Promise.resolve({ - addListener: () => {}, - subscribeEnvironmentOutput: () => {}, - subscribeInstallerOutput: () => {}, - subscribeWorkspaceStatus: (workspaceId, callback) => { + addListener: () => { }, + subscribeEnvironmentOutput: () => { }, + subscribeInstallerOutput: () => { }, + subscribeWorkspaceStatus: (_workspaceId, callback) => { statusChangeCallback = callback; } }); }); - spyOn(workspaceLoader, "openIDE").and.callFake(() => { - return Promise.resolve(); - }); + spyOn(workspaceLoader, 'openIDE').and.callFake(() => Promise.resolve()); workspaceLoader.load(); }); @@ -510,7 +492,7 @@ describe('Workspace Loader', () => { describe('then receives workspace stopped event on websocket, when workspace starting', () => { beforeEach(() => { - statusChangeCallback({ status: 'STOPPED', prevStatus: "STARTING", workspaceId: "someID-bla-bla" }); + statusChangeCallback({ status: 'STOPPED', prevStatus: 'STARTING', workspaceId: 'someID-bla-bla' }); }); it('should not open an IDE', () => { @@ -518,7 +500,7 @@ describe('Workspace Loader', () => { }); it('should log error', () => { - expect(loader.error).toBeCalledWith("Workspace stopped."); + expect(loader.error).toBeCalledWith('Workspace stopped.'); }); it('should hide loader', () => { @@ -536,40 +518,36 @@ describe('Workspace Loader', () => { let statusChangeCallback: Function; let workspaceLoadPromise: Promise; - beforeEach((done) => { + beforeEach(done => { const loader = new Loader(); workspaceLoader = new WorkspaceLoader(loader); - spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue("foo/bar"); + spyOn(workspaceLoader, 'getWorkspaceKey').and.returnValue('foo/bar'); - spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => { - return new Promise((resolve) => { + spyOn(workspaceLoader, 'getWorkspace').and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'STOPPING'; resolve(fakeWorkspaceConfig); - }); - }); + })); - spyOn(workspaceLoader, "subscribeWorkspaceEvents").and.callThrough() + spyOn(workspaceLoader, 'subscribeWorkspaceEvents').and.callThrough(); - spyOn(workspaceLoader, "startWorkspace").and.callFake(() => { - return Promise.resolve(); - }); + spyOn(workspaceLoader, 'startWorkspace').and.callFake(() => + Promise.resolve()); - spyOn(workspaceLoader, "connectMasterApi").and.callFake(() => { + spyOn(workspaceLoader, 'connectMasterApi').and.callFake(() => { done(); return Promise.resolve({ addListener: () => { }, subscribeEnvironmentOutput: () => { }, subscribeInstallerOutput: () => { }, - subscribeWorkspaceStatus: (workspaceId, callback) => { + subscribeWorkspaceStatus: (_workspaceId, callback) => { statusChangeCallback = callback; } }); }); - spyOn(workspaceLoader, "openIDE").and.callFake(() => { - return Promise.resolve(); - }); + spyOn(workspaceLoader, 'openIDE').and.callFake(() => Promise.resolve()); workspaceLoadPromise = workspaceLoader.load(); }); @@ -602,14 +580,13 @@ describe('Workspace Loader', () => { describe('then becomes RUNNING', () => { - beforeEach((done) => { - workspaceLoader.getWorkspace.and.callFake(() => { - return new Promise((resolve) => { + beforeEach(done => { + (workspaceLoader.getWorkspace as any).and.callFake(() => + new Promise(resolve => { fakeWorkspaceConfig.status = 'RUNNING'; - fakeWorkspaceConfig.runtime = {} as che.IWorkspaceRuntime; + fakeWorkspaceConfig.runtime = {} as che.workspace.Runtime; resolve(fakeWorkspaceConfig); - }); - }); + })); statusChangeCallback({ status: 'RUNNING' }); diff --git a/workspace-loader/tsconfig.json b/workspace-loader/tsconfig.json index 01d3a5928dc..9a714292285 100644 --- a/workspace-loader/tsconfig.json +++ b/workspace-loader/tsconfig.json @@ -1,6 +1,7 @@ { "include": [ - "src" + "src", + "test" ], "compilerOptions": { "target": "es5", diff --git a/workspace-loader/tsfmt.json b/workspace-loader/tsfmt.json new file mode 100644 index 00000000000..3d7212562c4 --- /dev/null +++ b/workspace-loader/tsfmt.json @@ -0,0 +1,18 @@ +{ + "baseIndentSize": 0, + "newLineCharacter": "\n", + "indentSize": 4, + "tabSize": 4, + "indentStyle": 4, + "convertTabsToSpaces": true, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": true, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false +} diff --git a/workspace-loader/tslint.json b/workspace-loader/tslint.json index 2b8cd8612cb..42b15d48e6c 100644 --- a/workspace-loader/tslint.json +++ b/workspace-loader/tslint.json @@ -1,9 +1,13 @@ { "defaultSeverity": "error", "rules": { - "file-header": [ + "arrow-parens": [ + true, + "ban-single-arg-parens" + ], + "arrow-return-shorthand": [ true, - "[\n\r]+ \\* Copyright \\(c\\) \\d{4}(-\\d{4})? .*[\n\r]+" + "multiline" ], "class-name": true, "comment-format": [ @@ -12,17 +16,34 @@ ], "curly": true, "eofline": true, + "file-header": [ + true, + "SPDX-License-Identifier: EPL-2\\.0" + ], "forin": true, "indent": [ true, - "spaces" + "spaces", + 4 + ], + "interface-over-type-literal": true, + "jsdoc-format": [ + true, + "check-multiline-start" ], "max-line-length": [ true, 180 ], + "no-any": true, "no-consecutive-blank-lines": true, + "no-construct": true, + "no-magic-numbers": false, + "no-null-keyword": true, + "no-shadowed-variable": true, + "no-string-throw": true, "no-trailing-whitespace": true, + "no-unused-expression": true, "no-var-keyword": true, "one-line": [ true, @@ -31,15 +52,33 @@ "check-else", "check-whitespace" ], + "one-variable-per-declaration": true, + "prefer-const": [ + true, + { + "destructuring": "all" + } + ], + "quotemark": [ + true, + "single", + "jsx-single", + "avoid-escape", + "avoid-template" + ], "radix": true, "semicolon": [ true, "always", "ignore-interfaces" ], - "trailing-comma": [ - false + "space-before-function-paren": [ + true, + { + "anonymous": "always" + } ], + "trailing-comma": false, "triple-equals": [ true, "allow-null-check" diff --git a/workspace-loader/webpack.common.js b/workspace-loader/webpack.common.js index 0dbc2486869..a4140849b1c 100644 --- a/workspace-loader/webpack.common.js +++ b/workspace-loader/webpack.common.js @@ -19,7 +19,18 @@ module.exports = { rules: [ { test: /\.ts$/, - use: 'ts-loader', + use: [ + { + loader: 'ts-loader' + }, + { + loader: 'tslint-loader', + options: { + configFile: './tslint.json', + tsConfigFile: './tsconfig.json' + } + } + ], exclude: /node_modules/ }, ] diff --git a/workspace-loader/yarn.lock b/workspace-loader/yarn.lock index 5b0da587b81..d5054e8daa4 100644 --- a/workspace-loader/yarn.lock +++ b/workspace-loader/yarn.lock @@ -18,6 +18,11 @@ esutils "^2.0.2" js-tokens "^3.0.0" +"@eclipse-che/api@^7.0.0-beta-4.0-80162ea6d2": + version "7.0.0-beta-4.0-80162ea6d2" + resolved "https://registry.yarnpkg.com/@eclipse-che/api/-/api-7.0.0-beta-4.0-80162ea6d2.tgz#f7bb5c7e996332b151e6fb34dae64fc0c4d92619" + integrity sha512-CDIfdDV1D5LafVpWcEm2uvWgyAMqpxWTco9BHIXmci4l4ILxEmwdYnVRAye6SU+KqDGi2ZlglhC85ujX5Lb2Hw== + "@types/jest@^22.1.3": version "22.2.3" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-22.2.3.tgz#0157c0316dc3722c43a7b71de3fdf3acbccef10d" @@ -498,7 +503,7 @@ aws4@^1.6.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" integrity sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w== -babel-code-frame@^6.26.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= @@ -905,7 +910,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= @@ -1245,6 +1250,11 @@ commander@2.16.x, commander@~2.16.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50" integrity sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew== +commander@^2.12.1, commander@^2.19.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" @@ -1255,6 +1265,11 @@ commander@~2.17.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== +commandpost@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/commandpost/-/commandpost-1.4.0.tgz#89218012089dfc9b67a337ba162f15c88e0f1048" + integrity sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1878,6 +1893,16 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +editorconfig@^0.15.0: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4052,6 +4077,14 @@ lru-cache@^4.0.1, lru-cache@^4.1.1: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -4904,7 +4937,7 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5: +path-parse@^1.0.5, path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== @@ -5743,6 +5776,13 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= +resolve@^1.3.2: + version "1.11.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232" + integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw== + dependencies: + path-parse "^1.0.6" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -5762,6 +5802,13 @@ rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: dependencies: glob "^7.0.5" +rimraf@^2.4.4: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -5989,6 +6036,11 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -6565,11 +6617,47 @@ ts-loader@^5.3.3: micromatch "^3.1.4" semver "^5.0.1" -tslib@^1.9.0: +tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tslint-loader@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/tslint-loader/-/tslint-loader-3.5.4.tgz#052af7f0772434451ea1b247bb55407f878a4c40" + integrity sha512-jBHNNppXut6SgZ7CsTBh+6oMwVum9n8azbmcYSeMlsABhWWoHwjq631vIFXef3VSd75cCdX3rc6kstsB7rSVVw== + dependencies: + loader-utils "^1.0.2" + mkdirp "^0.5.1" + object-assign "^4.1.1" + rimraf "^2.4.4" + semver "^5.3.0" + +tslint@5.9.1: + version "5.9.1" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae" + integrity sha1-ElX4ej/1frCw4fDmEKi0dIBGya4= + dependencies: + babel-code-frame "^6.22.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.7.0" + minimatch "^3.0.4" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.12.1" + +tsutils@^2.12.1: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -6607,6 +6695,14 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript-formatter@7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/typescript-formatter/-/typescript-formatter-7.2.2.tgz#a147181839b7bb09c2377b072f20f6336547c00a" + integrity sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ== + dependencies: + commandpost "^1.0.0" + editorconfig "^0.15.0" + typescript@^2.7.1: version "2.9.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"