Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/gitpod-protocol/src/context-url.ts
2498 views
1
/**
2
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import { Workspace } from ".";
8
9
/**
10
* The whole point of these methods is to overcome inconsistencies in our data model.
11
* Ideally we remove it at some point once we fixed our model, as it:
12
* - duplicates logic
13
* - but additional burden on clients (using this, copying this to other languages!)
14
*
15
* TODO(gpl) See if we can get this into `server` code to remove the burden from clients
16
*/
17
export namespace ContextURL {
18
export const IMAGEBUILD_PREFIX = "imagebuild";
19
export const SNAPSHOT_PREFIX = "snapshot";
20
export const REFERRER_PREFIX = "referrer:";
21
22
/**
23
* This function will (try to) return the HTTP(S) URL of the context the user originally created this workspace on.
24
* Especially it will not contain any modifiers or be of different scheme than HTTP(S).
25
*
26
* Use this function if you need to provided a _working_ URL to the original context.
27
* @param ws
28
* @returns
29
*/
30
export function getNormalizedURL(ws: Pick<Workspace, "context" | "contextURL"> | undefined): URL | undefined {
31
const normalized = normalize(ws);
32
if (!normalized) {
33
return undefined;
34
}
35
36
try {
37
return new URL(normalized);
38
} catch (err) {
39
console.debug(`unable to parse URL from normalized contextURL: '${normalized}'`);
40
}
41
return undefined;
42
}
43
44
export function normalize(ws: Pick<Workspace, "context" | "contextURL"> | undefined): string | undefined {
45
if (!ws) {
46
return undefined;
47
}
48
if (ws.context.normalizedContextURL) {
49
return ws.context.normalizedContextURL;
50
}
51
52
// fallback: we do not yet set normalizedContextURL on all workspaces, yet, let alone older existing workspaces
53
let fallback: string | undefined = undefined;
54
try {
55
fallback = removePrefixes(ws.contextURL);
56
} catch (err) {
57
console.error(`unable to remove prefixes from contextURL: '${ws.contextURL}'`, err);
58
}
59
return fallback;
60
}
61
62
/**
63
* The field "contextUrl" might contain prefixes like:
64
* - envvar1=value1/...
65
* - prebuild/...
66
* This is the analogon to the (Prefix)ContextParser structure in "server".
67
*/
68
function removePrefixes(contextUrl: string | undefined): string | undefined {
69
if (contextUrl === undefined) {
70
return undefined;
71
}
72
73
const segments = contextUrl.split("/");
74
if (segments.length === 1) {
75
return segments[0]; // this might be something, we just try
76
}
77
78
const segmentsToURL = (offset: number): string => {
79
let rest = segments.slice(offset).join("/");
80
if (/^git@[^:\/]+:/.test(rest)) {
81
rest = rest.replace(/^git@([^:\/]+):/, "https://$1/");
82
}
83
if (!rest.startsWith("http")) {
84
rest = "https://" + rest;
85
}
86
return rest;
87
};
88
89
const firstSegment = segments[0];
90
if (
91
firstSegment === IMAGEBUILD_PREFIX ||
92
firstSegment === SNAPSHOT_PREFIX ||
93
firstSegment.startsWith(REFERRER_PREFIX)
94
) {
95
return segmentsToURL(1);
96
}
97
98
// check for env vars
99
if (firstSegment.indexOf("=") !== -1) {
100
return segmentsToURL(1);
101
}
102
103
return segmentsToURL(0);
104
}
105
}
106
107