UNPKG

@theia/core

Version:

Theia is a cloud & desktop IDE framework implemented in TypeScript.

137 lines (121 loc) 4.34 kB
// ***************************************************************************** // Copyright (C) 2017 TypeFox and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** import URI from '../common/uri'; /** * An endpoint provides URLs for http and ws, based on configuration and defaults. */ export class Endpoint { static readonly PROTO_HTTPS: string = 'https:'; static readonly PROTO_HTTP: string = 'http:'; static readonly PROTO_WS: string = 'ws:'; static readonly PROTO_WSS: string = 'wss:'; static readonly PROTO_FILE: string = 'file:'; constructor( protected readonly options: Endpoint.Options = {}, protected readonly location: Endpoint.Location = self.location ) { } getWebSocketUrl(): URI { return new URI(`${this.wsScheme}//${this.host}${this.pathname}${this.path}`); } getRestUrl(): URI { return new URI(`${this.httpScheme}//${this.host}${this.pathname}${this.path}`); } protected get pathname(): string { if (this.location.protocol === Endpoint.PROTO_FILE) { return ''; } if (this.location.pathname === '/') { return ''; } if (this.location.pathname.endsWith('/')) { return this.location.pathname.substring(0, this.location.pathname.length - 1); } return this.location.pathname; } get host(): string { if (this.options.host) { return this.options.host; } if (this.location.host) { return this.location.host; } return 'localhost:' + this.port; } get origin(): string { return `${this.httpScheme}//${this.host}`; } protected get port(): string { return this.getSearchParam('port', '3000'); } protected getSearchParam(name: string, defaultValue: string): string { const search = this.location.search; if (!search) { return defaultValue; } return search.substring(1).split('&') .filter(value => value.startsWith(name + '=')) .map(value => { const encoded = value.substring(name.length + 1); return decodeURIComponent(encoded); })[0] || defaultValue; } protected get wsScheme(): string { if (this.options.wsScheme) { return this.options.wsScheme; } return this.httpScheme === Endpoint.PROTO_HTTPS ? Endpoint.PROTO_WSS : Endpoint.PROTO_WS; } /** * The HTTP/HTTPS scheme of the endpoint, or the user defined one. * See: `Endpoint.Options.httpScheme`. */ get httpScheme(): string { if (this.options.httpScheme) { return this.options.httpScheme; } if (this.location.protocol === Endpoint.PROTO_HTTP || this.location.protocol === Endpoint.PROTO_HTTPS) { return this.location.protocol; } return Endpoint.PROTO_HTTP; } protected get path(): string { if (this.options.path) { if (this.options.path.startsWith('/')) { return this.options.path; } else { return '/' + this.options.path; } } return ''; } } export namespace Endpoint { export class Options { host?: string; wsScheme?: string; httpScheme?: string; path?: string; } // Necessary for running tests with dependency on TS lib on node // FIXME figure out how to mock with ts-node export class Location { host: string; pathname: string; search: string; protocol: string; } }