@gitpod/gitpod-protocol 0.1.5-prs-dazzlev2-test.3 → 0.1.5-prs-prebuilds.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/data/gitpod-schema.json +163 -2
  2. package/lib/accounting-protocol.d.ts +10 -10
  3. package/lib/accounting-protocol.d.ts.map +1 -1
  4. package/lib/accounting-protocol.js +22 -31
  5. package/lib/accounting-protocol.js.map +1 -1
  6. package/lib/admin-protocol.d.ts +9 -0
  7. package/lib/admin-protocol.d.ts.map +1 -1
  8. package/lib/admin-protocol.js.map +1 -1
  9. package/lib/analytics.d.ts +4 -5
  10. package/lib/analytics.d.ts.map +1 -1
  11. package/lib/analytics.js.map +1 -1
  12. package/lib/auth.d.ts.map +1 -1
  13. package/lib/context-url.d.ts +17 -5
  14. package/lib/context-url.d.ts.map +1 -1
  15. package/lib/context-url.js +57 -6
  16. package/lib/context-url.js.map +1 -1
  17. package/lib/context-url.spec.d.ts +2 -0
  18. package/lib/context-url.spec.d.ts.map +1 -1
  19. package/lib/context-url.spec.js +40 -4
  20. package/lib/context-url.spec.js.map +1 -1
  21. package/lib/email-protocol.d.ts +1 -1
  22. package/lib/email-protocol.d.ts.map +1 -1
  23. package/lib/email-protocol.js.map +1 -1
  24. package/lib/encryption/container-module.d.ts.map +1 -1
  25. package/lib/encryption/container-module.js +1 -1
  26. package/lib/encryption/container-module.js.map +1 -1
  27. package/lib/encryption/encryption-engine.d.ts.map +1 -1
  28. package/lib/encryption/encryption-engine.js +7 -7
  29. package/lib/encryption/encryption-engine.js.map +1 -1
  30. package/lib/encryption/encryption-engine.spec.d.ts.map +1 -1
  31. package/lib/encryption/encryption-engine.spec.js +2 -3
  32. package/lib/encryption/encryption-engine.spec.js.map +1 -1
  33. package/lib/encryption/encryption-service.d.ts.map +1 -1
  34. package/lib/encryption/encryption-service.js +1 -1
  35. package/lib/encryption/encryption-service.js.map +1 -1
  36. package/lib/encryption/key-provider.d.ts.map +1 -1
  37. package/lib/encryption/key-provider.js +7 -9
  38. package/lib/encryption/key-provider.js.map +1 -1
  39. package/lib/env.d.ts +0 -5
  40. package/lib/env.d.ts.map +1 -1
  41. package/lib/env.js +1 -20
  42. package/lib/env.js.map +1 -1
  43. package/lib/gitpod-file-parser.d.ts.map +1 -1
  44. package/lib/gitpod-file-parser.js +6 -6
  45. package/lib/gitpod-file-parser.js.map +1 -1
  46. package/lib/gitpod-file-parser.spec.js +42 -39
  47. package/lib/gitpod-file-parser.spec.js.map +1 -1
  48. package/lib/gitpod-service.d.ts +33 -26
  49. package/lib/gitpod-service.d.ts.map +1 -1
  50. package/lib/gitpod-service.js +39 -32
  51. package/lib/gitpod-service.js.map +1 -1
  52. package/lib/headless-workspace-log.d.ts +1 -0
  53. package/lib/headless-workspace-log.d.ts.map +1 -1
  54. package/lib/headless-workspace-log.js +2 -1
  55. package/lib/headless-workspace-log.js.map +1 -1
  56. package/lib/ide-frontend-service.d.ts +1 -1
  57. package/lib/ide-protocol.d.ts +10 -6
  58. package/lib/ide-protocol.d.ts.map +1 -1
  59. package/lib/index.d.ts +16 -16
  60. package/lib/installation-admin-protocol.d.ts +6 -0
  61. package/lib/installation-admin-protocol.d.ts.map +1 -1
  62. package/lib/installation-admin-protocol.js +2 -2
  63. package/lib/installation-admin-protocol.js.map +1 -1
  64. package/lib/license-protocol.d.ts.map +1 -1
  65. package/lib/license-protocol.js.map +1 -1
  66. package/lib/messaging/browser/connection.d.ts +1 -1
  67. package/lib/messaging/browser/connection.d.ts.map +1 -1
  68. package/lib/messaging/browser/connection.js +19 -19
  69. package/lib/messaging/browser/connection.js.map +1 -1
  70. package/lib/messaging/browser/window-connection.d.ts +4 -4
  71. package/lib/messaging/browser/window-connection.d.ts.map +1 -1
  72. package/lib/messaging/browser/window-connection.js +9 -6
  73. package/lib/messaging/browser/window-connection.js.map +1 -1
  74. package/lib/messaging/client-call-metrics.d.ts +2 -2
  75. package/lib/messaging/client-call-metrics.d.ts.map +1 -1
  76. package/lib/messaging/client-call-metrics.js +20 -20
  77. package/lib/messaging/client-call-metrics.js.map +1 -1
  78. package/lib/messaging/error.d.ts +2 -0
  79. package/lib/messaging/error.d.ts.map +1 -1
  80. package/lib/messaging/error.js +4 -0
  81. package/lib/messaging/error.js.map +1 -1
  82. package/lib/messaging/handler.d.ts.map +1 -1
  83. package/lib/messaging/handler.js +1 -1
  84. package/lib/messaging/node/connection.js +8 -8
  85. package/lib/messaging/node/connection.js.map +1 -1
  86. package/lib/messaging/proxy-factory.d.ts +1 -1
  87. package/lib/messaging/proxy-factory.d.ts.map +1 -1
  88. package/lib/messaging/proxy-factory.js +7 -9
  89. package/lib/messaging/proxy-factory.js.map +1 -1
  90. package/lib/payment-protocol.d.ts.map +1 -1
  91. package/lib/payment-protocol.js +1 -1
  92. package/lib/payment-protocol.js.map +1 -1
  93. package/lib/permission.d.ts +9 -3
  94. package/lib/permission.d.ts.map +1 -1
  95. package/lib/permission.js +34 -25
  96. package/lib/permission.js.map +1 -1
  97. package/lib/plans.d.ts +3 -3
  98. package/lib/plans.d.ts.map +1 -1
  99. package/lib/plans.js +206 -171
  100. package/lib/plans.js.map +1 -1
  101. package/lib/protocol.d.ts +79 -38
  102. package/lib/protocol.d.ts.map +1 -1
  103. package/lib/protocol.js +160 -88
  104. package/lib/protocol.js.map +1 -1
  105. package/lib/snapshot-url.spec.js.map +1 -1
  106. package/lib/team-subscription-protocol.d.ts +5 -3
  107. package/lib/team-subscription-protocol.d.ts.map +1 -1
  108. package/lib/team-subscription-protocol.js +4 -4
  109. package/lib/team-subscription-protocol.js.map +1 -1
  110. package/lib/teams-projects-protocol.d.ts +10 -3
  111. package/lib/teams-projects-protocol.d.ts.map +1 -1
  112. package/lib/teams-projects-protocol.js +8 -1
  113. package/lib/teams-projects-protocol.js.map +1 -1
  114. package/lib/typings/globals.d.ts +2 -2
  115. package/lib/typings/globals.d.ts.map +1 -1
  116. package/lib/util/analytics.d.ts.map +1 -1
  117. package/lib/util/analytics.js +12 -3
  118. package/lib/util/analytics.js.map +1 -1
  119. package/lib/util/async-iterator.d.ts.map +1 -1
  120. package/lib/util/async-iterator.js +3 -3
  121. package/lib/util/async-iterator.js.map +1 -1
  122. package/lib/util/cancelable.js.map +1 -1
  123. package/lib/util/date-time.js +6 -6
  124. package/lib/util/date-time.js.map +1 -1
  125. package/lib/util/deferred.js.map +1 -1
  126. package/lib/util/disposable.d.ts.map +1 -1
  127. package/lib/util/disposable.js +2 -2
  128. package/lib/util/disposable.js.map +1 -1
  129. package/lib/util/event.d.ts.map +1 -1
  130. package/lib/util/event.js +5 -3
  131. package/lib/util/event.js.map +1 -1
  132. package/lib/util/garbage-collected-cache.d.ts.map +1 -1
  133. package/lib/util/garbage-collected-cache.js +1 -1
  134. package/lib/util/garbage-collected-cache.js.map +1 -1
  135. package/lib/util/generate-workspace-id.d.ts +5 -0
  136. package/lib/util/generate-workspace-id.d.ts.map +1 -1
  137. package/lib/util/generate-workspace-id.js +446 -442
  138. package/lib/util/generate-workspace-id.js.map +1 -1
  139. package/lib/util/generate-workspace-id.spec.js +18 -7
  140. package/lib/util/generate-workspace-id.spec.js.map +1 -1
  141. package/lib/util/gitpod-cookie.d.ts +1 -1
  142. package/lib/util/gitpod-cookie.d.ts.map +1 -1
  143. package/lib/util/gitpod-cookie.js +0 -3
  144. package/lib/util/gitpod-cookie.js.map +1 -1
  145. package/lib/util/gitpod-host-url.d.ts.map +1 -1
  146. package/lib/util/gitpod-host-url.js +31 -29
  147. package/lib/util/gitpod-host-url.js.map +1 -1
  148. package/lib/util/gitpod-host-url.spec.d.ts.map +1 -1
  149. package/lib/util/gitpod-host-url.spec.js +15 -5
  150. package/lib/util/gitpod-host-url.spec.js.map +1 -1
  151. package/lib/util/grpc.d.ts.map +1 -1
  152. package/lib/util/grpc.js.map +1 -1
  153. package/lib/util/jaeger-client-types.d.ts.map +1 -1
  154. package/lib/util/logging.d.ts +1 -1
  155. package/lib/util/logging.d.ts.map +1 -1
  156. package/lib/util/logging.js +23 -24
  157. package/lib/util/logging.js.map +1 -1
  158. package/lib/util/make-link.js +5 -5
  159. package/lib/util/make-link.js.map +1 -1
  160. package/lib/util/parse-workspace-id.d.ts.map +1 -1
  161. package/lib/util/parse-workspace-id.js +1 -2
  162. package/lib/util/parse-workspace-id.js.map +1 -1
  163. package/lib/util/parse-workspace-id.spec.d.ts.map +1 -1
  164. package/lib/util/parse-workspace-id.spec.js.map +1 -1
  165. package/lib/util/queue.spec.js +9 -6
  166. package/lib/util/queue.spec.js.map +1 -1
  167. package/lib/util/semaphore.d.ts.map +1 -1
  168. package/lib/util/semaphore.js.map +1 -1
  169. package/lib/util/skip-if.d.ts.map +1 -1
  170. package/lib/util/skip-if.js.map +1 -1
  171. package/lib/util/timeutil.d.ts.map +1 -1
  172. package/lib/util/timeutil.js +2 -2
  173. package/lib/util/timeutil.js.map +1 -1
  174. package/lib/util/timeutil.spec.d.ts.map +1 -1
  175. package/lib/util/timeutil.spec.js.map +1 -1
  176. package/lib/util/tracing.d.ts +8 -8
  177. package/lib/util/tracing.d.ts.map +1 -1
  178. package/lib/util/tracing.js +19 -20
  179. package/lib/util/tracing.js.map +1 -1
  180. package/lib/util/tracing.spec.js +3 -3
  181. package/lib/util/tracing.spec.js.map +1 -1
  182. package/lib/util/workspace-port-authentication.d.ts +7 -7
  183. package/lib/util/workspace-port-authentication.d.ts.map +1 -1
  184. package/lib/util/workspace-port-authentication.js +8 -11
  185. package/lib/util/workspace-port-authentication.js.map +1 -1
  186. package/lib/workspace-cluster.d.ts +10 -8
  187. package/lib/workspace-cluster.d.ts.map +1 -1
  188. package/lib/workspace-cluster.js +16 -1
  189. package/lib/workspace-cluster.js.map +1 -1
  190. package/lib/workspace-instance.d.ts +27 -3
  191. package/lib/workspace-instance.d.ts.map +1 -1
  192. package/lib/wsready.d.ts +1 -1
  193. package/lib/wsready.d.ts.map +1 -1
  194. package/lib/wsready.js +2 -2
  195. package/package.json +2 -2
  196. package/pkg-yarn.lock +2 -2
  197. package/provenance-bundle.jsonl +1 -1
  198. package/src/accounting-protocol.ts +53 -51
  199. package/src/admin-protocol.ts +33 -20
  200. package/src/analytics.ts +26 -28
  201. package/src/auth.ts +2 -2
  202. package/src/context-url.spec.ts +37 -9
  203. package/src/context-url.ts +96 -40
  204. package/src/email-protocol.ts +5 -6
  205. package/src/encryption/container-module.ts +2 -3
  206. package/src/encryption/encryption-engine.spec.ts +9 -8
  207. package/src/encryption/encryption-engine.ts +14 -14
  208. package/src/encryption/encryption-service.ts +4 -5
  209. package/src/encryption/key-provider.ts +16 -19
  210. package/src/env.ts +0 -22
  211. package/src/gitpod-file-parser.spec.ts +55 -61
  212. package/src/gitpod-file-parser.ts +16 -17
  213. package/src/gitpod-service.ts +147 -108
  214. package/src/headless-workspace-log.ts +6 -4
  215. package/src/ide-frontend-service.ts +2 -2
  216. package/src/ide-protocol.ts +13 -8
  217. package/src/index.ts +16 -16
  218. package/src/installation-admin-protocol.ts +11 -4
  219. package/src/license-protocol.ts +5 -6
  220. package/src/messaging/browser/connection.ts +45 -47
  221. package/src/messaging/browser/window-connection.ts +39 -29
  222. package/src/messaging/client-call-metrics.ts +70 -71
  223. package/src/messaging/error.ts +7 -3
  224. package/src/messaging/handler.ts +6 -6
  225. package/src/messaging/node/connection.ts +8 -8
  226. package/src/messaging/proxy-factory.ts +23 -30
  227. package/src/oss-allowlist.ts +3 -3
  228. package/src/payment-protocol.ts +2 -2
  229. package/src/permission.ts +40 -32
  230. package/src/plans.ts +236 -189
  231. package/src/protocol.ts +333 -241
  232. package/src/snapshot-url.spec.ts +9 -7
  233. package/src/team-subscription-protocol.ts +33 -23
  234. package/src/teams-projects-protocol.ts +20 -9
  235. package/src/typings/globals.ts +4 -4
  236. package/src/util/analytics.ts +46 -24
  237. package/src/util/async-iterator.ts +4 -5
  238. package/src/util/cancelable.ts +3 -3
  239. package/src/util/date-time.ts +8 -8
  240. package/src/util/deferred.ts +6 -6
  241. package/src/util/disposable.ts +3 -6
  242. package/src/util/event.ts +9 -11
  243. package/src/util/garbage-collected-cache.ts +3 -6
  244. package/src/util/generate-workspace-id.spec.ts +26 -16
  245. package/src/util/generate-workspace-id.ts +460 -454
  246. package/src/util/gitpod-cookie.ts +8 -9
  247. package/src/util/gitpod-host-url.spec.ts +40 -13
  248. package/src/util/gitpod-host-url.ts +37 -34
  249. package/src/util/grpc.ts +1 -1
  250. package/src/util/jaeger-client-types.ts +2 -2
  251. package/src/util/logging.ts +49 -40
  252. package/src/util/make-link.ts +6 -7
  253. package/src/util/parse-workspace-id.spec.ts +17 -8
  254. package/src/util/parse-workspace-id.ts +5 -6
  255. package/src/util/queue.spec.ts +27 -25
  256. package/src/util/repeat.ts +1 -1
  257. package/src/util/semaphore.ts +4 -6
  258. package/src/util/skip-if.ts +9 -6
  259. package/src/util/timeutil.spec.ts +14 -15
  260. package/src/util/timeutil.ts +15 -11
  261. package/src/util/tracing.spec.ts +28 -23
  262. package/src/util/tracing.ts +58 -54
  263. package/src/util/workspace-port-authentication.ts +10 -13
  264. package/src/workspace-cluster.ts +26 -15
  265. package/src/workspace-instance.ts +56 -20
  266. package/src/wsready.ts +3 -3
  267. package/data/builtin-theia-plugins.json +0 -372
  268. package/lib/messaging/connection-error-handler.d.ts +0 -27
  269. package/lib/messaging/connection-error-handler.d.ts.map +0 -1
  270. package/lib/messaging/connection-error-handler.js +0 -34
  271. package/lib/messaging/connection-error-handler.js.map +0 -1
  272. package/lib/theia-plugins.d.ts +0 -11
  273. package/lib/theia-plugins.d.ts.map +0 -1
  274. package/lib/theia-plugins.js +0 -8
  275. package/lib/theia-plugins.js.map +0 -1
  276. package/lib/util/safe-promise.d.ts +0 -11
  277. package/lib/util/safe-promise.d.ts.map +0 -1
  278. package/lib/util/safe-promise.js +0 -31
  279. package/lib/util/safe-promise.js.map +0 -1
  280. package/src/messaging/connection-error-handler.ts +0 -62
  281. package/src/theia-plugins.ts +0 -11
  282. package/src/util/safe-promise.ts +0 -26
package/src/protocol.ts CHANGED
@@ -7,26 +7,27 @@
7
7
  import { WorkspaceInstance, PortVisibility } from "./workspace-instance";
8
8
  import { RoleOrPermission } from "./permission";
9
9
  import { Project } from "./teams-projects-protocol";
10
+ import { createHash } from "crypto";
10
11
 
11
12
  export interface UserInfo {
12
- name?: string
13
+ name?: string;
13
14
  }
14
15
 
15
16
  export interface User {
16
17
  /** The user id */
17
- id: string
18
+ id: string;
18
19
 
19
20
  /** The timestamp when the user entry was created */
20
- creationDate: string
21
+ creationDate: string;
21
22
 
22
- avatarUrl?: string
23
+ avatarUrl?: string;
23
24
 
24
- name?: string
25
+ name?: string;
25
26
 
26
27
  /** Optional for backwards compatibility */
27
- fullName?: string
28
+ fullName?: string;
28
29
 
29
- identities: Identity[]
30
+ identities: Identity[];
30
31
 
31
32
  /**
32
33
  * Whether the user has been blocked to use our service, because of TOS violation for example.
@@ -48,34 +49,38 @@ export interface User {
48
49
 
49
50
  export namespace User {
50
51
  export function is(data: any): data is User {
51
- return data
52
- && data.hasOwnProperty('id')
53
- && data.hasOwnProperty('identities')
52
+ return data && data.hasOwnProperty("id") && data.hasOwnProperty("identities");
54
53
  }
55
54
  export function getIdentity(user: User, authProviderId: string): Identity | undefined {
56
- return user.identities.find(id => id.authProviderId === authProviderId);
55
+ return user.identities.find((id) => id.authProviderId === authProviderId);
57
56
  }
58
57
  export function censor(user: User): User {
59
58
  const res = { ...user };
60
- delete (res.additionalData);
61
- res.identities = res.identities.map(i => {
62
- delete (i.tokens);
59
+ delete res.additionalData;
60
+ res.identities = res.identities.map((i) => {
61
+ delete i.tokens;
63
62
 
64
63
  // The user field is not in the Identity shape, but actually exists on DBIdentity.
65
64
  // Trying to push this object out via JSON RPC will fail because of the cyclic nature
66
65
  // of this field.
67
- delete ((i as any).user);
66
+ delete (i as any).user;
68
67
  return i;
69
68
  });
70
69
  return res;
71
70
  }
72
- export function getPrimaryEmail(user: User): string {
73
- const identities = user.identities.filter(i => !!i.primaryEmail);
71
+
72
+ /**
73
+ * Tries to return the primaryEmail of the first identity this user signed up with.
74
+ * @param user
75
+ * @returns A primaryEmail, or undefined if there is none.
76
+ */
77
+ export function getPrimaryEmail(user: User): string | undefined {
78
+ const identities = user.identities.filter((i) => !!i.primaryEmail);
74
79
  if (identities.length <= 0) {
75
- throw new Error(`No identity with primary email for user: ${user.id}!`);
80
+ return undefined;
76
81
  }
77
82
 
78
- return identities[0].primaryEmail!;
83
+ return identities[0].primaryEmail || undefined;
79
84
  }
80
85
  export function getName(user: User): string | undefined {
81
86
  const name = user.fullName || user.name;
@@ -90,6 +95,47 @@ export namespace User {
90
95
  }
91
96
  return undefined;
92
97
  }
98
+
99
+ export function hasPreferredIde(user: User) {
100
+ return (
101
+ typeof user?.additionalData?.ideSettings?.defaultIde !== "undefined" ||
102
+ typeof user?.additionalData?.ideSettings?.useLatestVersion !== "undefined"
103
+ );
104
+ }
105
+
106
+ export function isOnboardingUser(user: User) {
107
+ return !hasPreferredIde(user);
108
+ }
109
+
110
+ export function migrationIDESettings(user: User) {
111
+ if (
112
+ !user?.additionalData?.ideSettings ||
113
+ Object.keys(user.additionalData.ideSettings).length === 0 ||
114
+ user.additionalData.ideSettings.settingVersion === "2.0"
115
+ ) {
116
+ return;
117
+ }
118
+ const newIDESettings: IDESettings = {
119
+ settingVersion: "2.0",
120
+ };
121
+ const ideSettings = user.additionalData.ideSettings;
122
+ if (ideSettings.useDesktopIde) {
123
+ if (ideSettings.defaultDesktopIde === "code-desktop") {
124
+ newIDESettings.defaultIde = "code-desktop";
125
+ } else if (ideSettings.defaultDesktopIde === "code-desktop-insiders") {
126
+ newIDESettings.defaultIde = "code-desktop";
127
+ newIDESettings.useLatestVersion = true;
128
+ } else {
129
+ newIDESettings.defaultIde = ideSettings.defaultDesktopIde;
130
+ newIDESettings.useLatestVersion = ideSettings.useLatestVersion;
131
+ }
132
+ } else {
133
+ const useLatest = ideSettings.defaultIde === "code-latest";
134
+ newIDESettings.defaultIde = "code";
135
+ newIDESettings.useLatestVersion = useLatest;
136
+ }
137
+ user.additionalData.ideSettings = newIDESettings;
138
+ }
93
139
  }
94
140
 
95
141
  export interface AdditionalUserData {
@@ -98,10 +144,10 @@ export interface AdditionalUserData {
98
144
  featurePreview?: boolean;
99
145
  ideSettings?: IDESettings;
100
146
  // key is the name of the news, string the iso date when it was seen
101
- whatsNewSeen?: { [key: string]: string }
147
+ whatsNewSeen?: { [key: string]: string };
102
148
  // key is the name of the OAuth client i.e. local app, string the iso date when it was approved
103
149
  // TODO(rl): provide a management UX to allow rescinding of approval
104
- oauthClientsApproved?: { [key: string]: string }
150
+ oauthClientsApproved?: { [key: string]: string };
105
151
  // to remember GH Orgs the user installed/updated the GH App for
106
152
  knownGitHubOrgs?: string[];
107
153
 
@@ -116,10 +162,14 @@ export interface EmailNotificationSettings {
116
162
  }
117
163
 
118
164
  export type IDESettings = {
119
- defaultIde?: string
120
- useDesktopIde?: boolean
121
- defaultDesktopIde?: string
122
- }
165
+ settingVersion?: string;
166
+ defaultIde?: string;
167
+ // DEPRECATED: Use defaultIde after `settingVersion: 2.0`, no more specialify desktop or browser.
168
+ useDesktopIde?: boolean;
169
+ // DEPRECATED: Same with useDesktopIde.
170
+ defaultDesktopIde?: string;
171
+ useLatestVersion?: boolean;
172
+ };
123
173
 
124
174
  export interface UserPlatform {
125
175
  uid: string;
@@ -151,8 +201,12 @@ export interface UserFeatureSettings {
151
201
  * The values of this type MUST MATCH enum values in WorkspaceFeatureFlag from ws-manager/client/core_pb.d.ts
152
202
  * If they don't we'll break things during workspace startup.
153
203
  */
154
- export const WorkspaceFeatureFlags = { "full_workspace_backup": undefined, "fixed_resources": undefined };
155
- export type NamedWorkspaceFeatureFlag = keyof (typeof WorkspaceFeatureFlags);
204
+ export const WorkspaceFeatureFlags = {
205
+ full_workspace_backup: undefined,
206
+ fixed_resources: undefined,
207
+ persistent_volume_claim: undefined,
208
+ };
209
+ export type NamedWorkspaceFeatureFlag = keyof typeof WorkspaceFeatureFlags;
156
210
 
157
211
  export interface EnvVarWithValue {
158
212
  name: string;
@@ -165,7 +219,7 @@ export interface ProjectEnvVarWithValue extends EnvVarWithValue {
165
219
  censored: boolean;
166
220
  }
167
221
 
168
- export type ProjectEnvVar = Omit<ProjectEnvVarWithValue, 'value'>;
222
+ export type ProjectEnvVar = Omit<ProjectEnvVarWithValue, "value">;
169
223
 
170
224
  export interface UserEnvVarValue extends EnvVarWithValue {
171
225
  id?: string;
@@ -178,6 +232,38 @@ export interface UserEnvVar extends UserEnvVarValue {
178
232
  }
179
233
 
180
234
  export namespace UserEnvVar {
235
+ /**
236
+ * @param variable
237
+ * @returns Either a string containing an error message or undefined.
238
+ */
239
+ export function validate(variable: UserEnvVarValue): string | undefined {
240
+ const name = variable.name;
241
+ const pattern = variable.repositoryPattern;
242
+ if (name.trim() === "") {
243
+ return "Name must not be empty.";
244
+ }
245
+ if (!/^[a-zA-Z_]+[a-zA-Z0-9_]*$/.test(name)) {
246
+ return "Name must match /^[a-zA-Z_]+[a-zA-Z0-9_]*$/.";
247
+ }
248
+ if (variable.value.trim() === "") {
249
+ return "Value must not be empty.";
250
+ }
251
+ if (pattern.trim() === "") {
252
+ return "Scope must not be empty.";
253
+ }
254
+ const split = pattern.split("/");
255
+ if (split.length < 2) {
256
+ return "A scope must use the form 'organization/repo'.";
257
+ }
258
+ for (const name of split) {
259
+ if (name !== "*") {
260
+ if (!/^[a-zA-Z0-9_\-.\*]+$/.test(name)) {
261
+ return "Invalid scope segment. Only ASCII characters, numbers, -, _, . or * are allowed.";
262
+ }
263
+ }
264
+ }
265
+ return undefined;
266
+ }
181
267
 
182
268
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
183
269
  export function normalizeRepoPattern(pattern: string) {
@@ -198,7 +284,7 @@ export namespace UserEnvVar {
198
284
  if (repoPattern == "*") {
199
285
  score += 1;
200
286
  }
201
- if (ownerPattern == '*') {
287
+ if (ownerPattern == "*") {
202
288
  score += 2;
203
289
  }
204
290
  if (ownerPattern == "#" || repoPattern == "#") {
@@ -209,20 +295,20 @@ export namespace UserEnvVar {
209
295
 
210
296
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
211
297
  export function filter<T extends UserEnvVarValue>(vars: T[], owner: string, repo: string): T[] {
212
- let result = vars.filter(e => {
298
+ let result = vars.filter((e) => {
213
299
  const [ownerPattern, repoPattern] = splitRepositoryPattern(e.repositoryPattern);
214
- if (ownerPattern !== '*' && ownerPattern !== '#' && (!!owner && ownerPattern !== owner.toLocaleLowerCase())) {
300
+ if (ownerPattern !== "*" && ownerPattern !== "#" && !!owner && ownerPattern !== owner.toLocaleLowerCase()) {
215
301
  return false;
216
302
  }
217
- if (repoPattern !== '*' && repoPattern !== '#' && (!!repo && repoPattern !== repo.toLocaleLowerCase())) {
303
+ if (repoPattern !== "*" && repoPattern !== "#" && !!repo && repoPattern !== repo.toLocaleLowerCase()) {
218
304
  return false;
219
305
  }
220
306
  return true;
221
307
  });
222
308
 
223
309
  const resmap = new Map<string, T[]>();
224
- result.forEach(e => {
225
- const l = (resmap.get(e.name) || []);
310
+ result.forEach((e) => {
311
+ const l = resmap.get(e.name) || [];
226
312
  l.push(e);
227
313
  resmap.set(e.name, l);
228
314
  });
@@ -257,46 +343,45 @@ export namespace UserEnvVar {
257
343
 
258
344
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
259
345
  export function splitRepositoryPattern(repositoryPattern: string): string[] {
260
- const patterns = repositoryPattern.split('/');
261
- const repoPattern = patterns.pop() || "";
262
- const ownerPattern = patterns.join('/');
346
+ const patterns = repositoryPattern.split("/");
347
+ const repoPattern = patterns.slice(1).join("/");
348
+ const ownerPattern = patterns[0];
263
349
  return [ownerPattern, repoPattern];
264
350
  }
265
351
  }
266
352
 
267
353
  export interface GitpodToken {
268
-
269
354
  /** Hash value (SHA256) of the token (primary key). */
270
- tokenHash: string
355
+ tokenHash: string;
271
356
 
272
357
  /** Human readable name of the token */
273
- name?: string
358
+ name?: string;
274
359
 
275
360
  /** Token kind */
276
- type: GitpodTokenType
361
+ type: GitpodTokenType;
277
362
 
278
363
  /** The user the token belongs to. */
279
- user: User
364
+ user: User;
280
365
 
281
366
  /** Scopes (e.g. limition to read-only) */
282
- scopes: string[]
367
+ scopes: string[];
283
368
 
284
369
  /** Created timestamp */
285
- created: string
370
+ created: string;
286
371
 
287
372
  // token is deleted on the database and about to be collected by db-sync
288
- deleted?: boolean
373
+ deleted?: boolean;
289
374
  }
290
375
 
291
376
  export enum GitpodTokenType {
292
377
  API_AUTH_TOKEN = 0,
293
- MACHINE_AUTH_TOKEN = 1
378
+ MACHINE_AUTH_TOKEN = 1,
294
379
  }
295
380
 
296
381
  export interface OneTimeSecret {
297
- id: string
382
+ id: string;
298
383
 
299
- value: string
384
+ value: string;
300
385
 
301
386
  expirationTime: string;
302
387
 
@@ -328,13 +413,12 @@ export type IdentityLookup = Pick<Identity, "authProviderId" | "authId">;
328
413
 
329
414
  export namespace Identity {
330
415
  export function is(data: any): data is Identity {
331
- return data.hasOwnProperty('authProviderId')
332
- && data.hasOwnProperty('authId')
333
- && data.hasOwnProperty('authName')
416
+ return (
417
+ data.hasOwnProperty("authProviderId") && data.hasOwnProperty("authId") && data.hasOwnProperty("authName")
418
+ );
334
419
  }
335
420
  export function equals(id1: IdentityLookup, id2: IdentityLookup) {
336
- return id1.authProviderId === id2.authProviderId
337
- && id1.authId === id2.authId
421
+ return id1.authProviderId === id2.authProviderId && id1.authId === id2.authId;
338
422
  }
339
423
  }
340
424
 
@@ -398,7 +482,7 @@ export interface Snapshot {
398
482
  message?: string;
399
483
  }
400
484
 
401
- export type SnapshotState = 'pending' | 'available' | 'error';
485
+ export type SnapshotState = "pending" | "available" | "error";
402
486
 
403
487
  export interface LayoutData {
404
488
  workspaceId: string;
@@ -427,13 +511,13 @@ export interface Workspace {
427
511
  * The resolved, fix name of the workspace image. We only use this
428
512
  * to access the logs during an image build.
429
513
  */
430
- imageNameResolved?: string
514
+ imageNameResolved?: string;
431
515
 
432
516
  /**
433
517
  * The resolved/built fixed named of the base image. This field is only set if the workspace
434
518
  * already has its base image built.
435
519
  */
436
- baseImageNameResolved?: string
520
+ baseImageNameResolved?: string;
437
521
 
438
522
  shareable?: boolean;
439
523
  pinned?: boolean;
@@ -470,17 +554,16 @@ export type WorkspaceSoftDeletion = "user" | "gc";
470
554
  export type WorkspaceType = "regular" | "prebuild" | "probe";
471
555
 
472
556
  export namespace Workspace {
473
-
474
557
  export function getFullRepositoryName(ws: Workspace): string | undefined {
475
558
  if (CommitContext.is(ws.context)) {
476
- return ws.context.repository.owner + '/' + ws.context.repository.name
559
+ return ws.context.repository.owner + "/" + ws.context.repository.name;
477
560
  }
478
561
  return undefined;
479
562
  }
480
563
 
481
564
  export function getFullRepositoryUrl(ws: Workspace): string | undefined {
482
565
  if (CommitContext.is(ws.context)) {
483
- return `https://${ws.context.repository.host}/${getFullRepositoryName(ws)}`
566
+ return `https://${ws.context.repository.host}/${getFullRepositoryName(ws)}`;
484
567
  }
485
568
  return undefined;
486
569
  }
@@ -514,59 +597,49 @@ export namespace Workspace {
514
597
  }
515
598
  }
516
599
 
517
- export interface PreparePluginUploadParams {
518
- fullPluginName: string;
519
- }
520
-
521
- export interface ResolvePluginsParams {
522
- config?: WorkspaceConfig
523
- builtins?: ResolvedPlugins
524
- vsxRegistryUrl?: string
525
- }
526
-
527
- export interface InstallPluginsParams {
528
- pluginIds: string[]
529
- }
530
-
531
- export interface UninstallPluginParams {
532
- pluginId: string;
533
- }
534
-
535
600
  export interface GuessGitTokenScopesParams {
536
- host: string
537
- repoUrl: string
538
- gitCommand: string
539
- currentToken: GitToken
601
+ host: string;
602
+ repoUrl: string;
603
+ gitCommand: string;
604
+ currentToken: GitToken;
540
605
  }
541
606
 
542
607
  export interface GitToken {
543
- token: string
544
- user: string
545
- scopes: string[]
608
+ token: string;
609
+ user: string;
610
+ scopes: string[];
546
611
  }
547
612
 
548
613
  export interface GuessedGitTokenScopes {
549
- message?: string
550
- scopes?: string[]
614
+ message?: string;
615
+ scopes?: string[];
551
616
  }
552
617
 
553
- export type ResolvedPluginKind = 'user' | 'workspace' | 'builtin';
554
-
555
- export interface ResolvedPlugins {
556
- [pluginId: string]: ResolvedPlugin | undefined
618
+ export interface VSCodeConfig {
619
+ extensions?: string[];
557
620
  }
558
621
 
559
- export interface ResolvedPlugin {
560
- fullPluginName: string;
561
- url: string;
562
- kind: ResolvedPluginKind;
622
+ export interface JetBrainsConfig {
623
+ intellij?: JetBrainsProductConfig;
624
+ goland?: JetBrainsProductConfig;
625
+ pycharm?: JetBrainsProductConfig;
626
+ phpstorm?: JetBrainsProductConfig;
627
+ }
628
+ export interface JetBrainsProductConfig {
629
+ prebuilds?: JetBrainsPrebuilds;
630
+ }
631
+ export interface JetBrainsPrebuilds {
632
+ version?: "stable" | "latest" | "both";
563
633
  }
564
634
 
565
- export interface VSCodeConfig {
566
- extensions?: string[];
635
+ export interface RepositoryCloneInformation {
636
+ url: string;
637
+ checkoutLocation?: string;
567
638
  }
568
639
 
569
640
  export interface WorkspaceConfig {
641
+ mainConfiguration?: string;
642
+ additionalRepositories?: RepositoryCloneInformation[];
570
643
  image?: ImageConfig;
571
644
  ports?: PortConfig[];
572
645
  tasks?: TaskConfig[];
@@ -575,6 +648,7 @@ export interface WorkspaceConfig {
575
648
  gitConfig?: { [config: string]: string };
576
649
  github?: GithubAppConfig;
577
650
  vscode?: VSCodeConfig;
651
+ jetbrains?: JetBrainsConfig;
578
652
 
579
653
  /** deprecated. Enabled by default **/
580
654
  experimentalNetwork?: boolean;
@@ -589,7 +663,7 @@ export interface WorkspaceConfig {
589
663
  * additional-content - config comes from additional content, usually provided through the project's configuration
590
664
  * default - our static catch-all default config
591
665
  */
592
- _origin?: 'repo' | 'project-db' | 'definitely-gp' | 'derived' | 'additional-content' | 'default';
666
+ _origin?: "repo" | "project-db" | "definitely-gp" | "derived" | "additional-content" | "default";
593
667
 
594
668
  /**
595
669
  * Set of automatically infered feature flags. That's not something the user can set, but
@@ -599,34 +673,33 @@ export interface WorkspaceConfig {
599
673
  }
600
674
 
601
675
  export interface GithubAppConfig {
602
- prebuilds?: GithubAppPrebuildConfig
676
+ prebuilds?: GithubAppPrebuildConfig;
603
677
  }
604
678
  export interface GithubAppPrebuildConfig {
605
- master?: boolean
606
- branches?: boolean
607
- pullRequests?: boolean
608
- pullRequestsFromForks?: boolean
609
- addCheck?: boolean | 'prevent-merge-on-error'
610
- addBadge?: boolean
611
- addLabel?: boolean | string
612
- addComment?: boolean
679
+ master?: boolean;
680
+ branches?: boolean;
681
+ pullRequests?: boolean;
682
+ pullRequestsFromForks?: boolean;
683
+ addCheck?: boolean | "prevent-merge-on-error";
684
+ addBadge?: boolean;
685
+ addLabel?: boolean | string;
686
+ addComment?: boolean;
613
687
  }
614
688
  export namespace GithubAppPrebuildConfig {
615
689
  export function is(obj: boolean | GithubAppPrebuildConfig): obj is GithubAppPrebuildConfig {
616
- return !(typeof obj === 'boolean');
690
+ return !(typeof obj === "boolean");
617
691
  }
618
692
  }
619
693
 
620
694
  export type WorkspaceImageSource = WorkspaceImageSourceDocker | WorkspaceImageSourceReference;
621
695
  export interface WorkspaceImageSourceDocker {
622
- dockerFilePath: string
623
- dockerFileHash: string
624
- dockerFileSource?: Commit
696
+ dockerFilePath: string;
697
+ dockerFileHash: string;
698
+ dockerFileSource?: Commit;
625
699
  }
626
700
  export namespace WorkspaceImageSourceDocker {
627
701
  export function is(obj: object): obj is WorkspaceImageSourceDocker {
628
- return 'dockerFileHash' in obj
629
- && 'dockerFilePath' in obj;
702
+ return "dockerFileHash" in obj && "dockerFilePath" in obj;
630
703
  }
631
704
  }
632
705
  export interface WorkspaceImageSourceReference {
@@ -635,21 +708,23 @@ export interface WorkspaceImageSourceReference {
635
708
  }
636
709
  export namespace WorkspaceImageSourceReference {
637
710
  export function is(obj: object): obj is WorkspaceImageSourceReference {
638
- return 'baseImageResolved' in obj;
711
+ return "baseImageResolved" in obj;
639
712
  }
640
713
  }
641
714
 
642
- export type PrebuiltWorkspaceState
715
+ export type PrebuiltWorkspaceState =
643
716
  // the prebuild is queued and may start at anytime
644
- = "queued"
717
+ | "queued"
645
718
  // the workspace prebuild is currently running (i.e. there's a workspace pod deployed)
646
719
  | "building"
647
- // the prebuild failed due to some issue with the system (e.g. missed a message, could not start workspace)
720
+ // the prebuild was aborted
648
721
  | "aborted"
649
722
  // the prebuild timed out
650
723
  | "timeout"
651
- // the prebuild has finished and a snapshot is available
652
- | "available";
724
+ // the prebuild has finished (even if a headless task failed) and a snapshot is available
725
+ | "available"
726
+ // the prebuild (headless workspace) failed due to some system error
727
+ | "failed";
653
728
 
654
729
  export interface PrebuiltWorkspace {
655
730
  id: string;
@@ -660,13 +735,14 @@ export interface PrebuiltWorkspace {
660
735
  buildWorkspaceId: string;
661
736
  creationTime: string;
662
737
  state: PrebuiltWorkspaceState;
738
+ statusVersion: number;
663
739
  error?: string;
664
740
  snapshot?: string;
665
741
  }
666
742
 
667
743
  export namespace PrebuiltWorkspace {
668
744
  export function isDone(pws: PrebuiltWorkspace) {
669
- return pws.state === "available" || pws.state === "timeout" || pws.state === 'aborted';
745
+ return pws.state === "available" || pws.state === "timeout" || pws.state === "aborted";
670
746
  }
671
747
 
672
748
  export function isAvailable(pws: PrebuiltWorkspace) {
@@ -685,18 +761,22 @@ export interface PrebuiltWorkspaceUpdatable {
685
761
  repo: string;
686
762
  isResolved: boolean;
687
763
  installationId: string;
764
+ /**
765
+ * the commitSHA of the commit that triggered the prebuild
766
+ */
767
+ commitSHA?: string;
688
768
  issue?: string;
689
769
  contextUrl?: string;
690
770
  }
691
771
 
692
772
  export interface WhitelistedRepository {
693
- url: string
694
- name: string
695
- description?: string
696
- avatar?: string
773
+ url: string;
774
+ name: string;
775
+ description?: string;
776
+ avatar?: string;
697
777
  }
698
778
 
699
- export type PortOnOpen = 'open-browser' | 'open-preview' | 'notify' | 'ignore';
779
+ export type PortOnOpen = "open-browser" | "open-preview" | "notify" | "ignore";
700
780
 
701
781
  export interface PortConfig {
702
782
  port: number;
@@ -707,7 +787,7 @@ export interface PortConfig {
707
787
  }
708
788
  export namespace PortConfig {
709
789
  export function is(config: any): config is PortConfig {
710
- return config && ('port' in config) && (typeof config.port === 'number');
790
+ return config && "port" in config && typeof config.port === "number";
711
791
  }
712
792
  }
713
793
 
@@ -717,7 +797,7 @@ export interface PortRangeConfig {
717
797
  }
718
798
  export namespace PortRangeConfig {
719
799
  export function is(config: any): config is PortRangeConfig {
720
- return config && ('port' in config) && (typeof config.port === 'string' || config.port instanceof String);
800
+ return config && "port" in config && (typeof config.port === "string" || config.port instanceof String);
721
801
  }
722
802
  }
723
803
 
@@ -728,32 +808,31 @@ export interface TaskConfig {
728
808
  prebuild?: string;
729
809
  command?: string;
730
810
  env?: { [env: string]: any };
731
- openIn?: 'bottom' | 'main' | 'left' | 'right';
732
- openMode?: 'split-top' | 'split-left' | 'split-right' | 'split-bottom' | 'tab-before' | 'tab-after';
811
+ openIn?: "bottom" | "main" | "left" | "right";
812
+ openMode?: "split-top" | "split-left" | "split-right" | "split-bottom" | "tab-before" | "tab-after";
733
813
  }
734
814
 
735
815
  export namespace TaskConfig {
736
816
  export function is(config: any): config is TaskConfig {
737
- return config
738
- && ('command' in config || 'init' in config || 'before' in config);
817
+ return config && ("command" in config || "init" in config || "before" in config);
739
818
  }
740
819
  }
741
820
 
742
821
  export namespace WorkspaceImageBuild {
743
- export type Phase = 'BaseImage' | 'GitpodLayer' | 'Error' | 'Done';
822
+ export type Phase = "BaseImage" | "GitpodLayer" | "Error" | "Done";
744
823
  export interface StateInfo {
745
- phase: Phase
746
- currentStep?: number
747
- maxSteps?: number
824
+ phase: Phase;
825
+ currentStep?: number;
826
+ maxSteps?: number;
748
827
  }
749
828
  export interface LogContent {
750
- text: string
751
- upToLine?: number
752
- isDiff?: boolean
829
+ text: string;
830
+ upToLine?: number;
831
+ isDiff?: boolean;
753
832
  }
754
833
  export type LogCallback = (info: StateInfo, content: LogContent | undefined) => void;
755
834
  export namespace LogLine {
756
- export const DELIMITER = '\r\n';
835
+ export const DELIMITER = "\r\n";
757
836
  export const DELIMITER_REGEX = /\r?\n/;
758
837
  }
759
838
  }
@@ -762,20 +841,18 @@ export type ImageConfig = ImageConfigString | ImageConfigFile;
762
841
  export type ImageConfigString = string;
763
842
  export namespace ImageConfigString {
764
843
  export function is(config: ImageConfig | undefined): config is ImageConfigString {
765
- return typeof config === 'string';
844
+ return typeof config === "string";
766
845
  }
767
-
768
846
  }
769
847
  export interface ImageConfigFile {
770
848
  // Path to the Dockerfile relative to repository root
771
- file: string,
849
+ file: string;
772
850
  // Path to the docker build context relative to repository root
773
- context?: string
851
+ context?: string;
774
852
  }
775
853
  export namespace ImageConfigFile {
776
854
  export function is(config: ImageConfig | undefined): config is ImageConfigFile {
777
- return typeof config === 'object'
778
- && 'file' in config;
855
+ return typeof config === "object" && "file" in config;
779
856
  }
780
857
  }
781
858
  export interface ExternalImageConfigFile extends ImageConfigFile {
@@ -783,9 +860,7 @@ export interface ExternalImageConfigFile extends ImageConfigFile {
783
860
  }
784
861
  export namespace ExternalImageConfigFile {
785
862
  export function is(config: any | undefined): config is ExternalImageConfigFile {
786
- return typeof config === 'object'
787
- && 'file' in config
788
- && 'externalSource' in config;
863
+ return typeof config === "object" && "file" in config && "externalSource" in config;
789
864
  }
790
865
  }
791
866
 
@@ -799,8 +874,7 @@ export interface WorkspaceContext {
799
874
 
800
875
  export namespace WorkspaceContext {
801
876
  export function is(context: any): context is WorkspaceContext {
802
- return context
803
- && 'title' in context;
877
+ return context && "title" in context;
804
878
  }
805
879
  }
806
880
 
@@ -809,22 +883,17 @@ export interface WithSnapshot {
809
883
  }
810
884
  export namespace WithSnapshot {
811
885
  export function is(context: any): context is WithSnapshot {
812
- return context
813
- && 'snapshotBucketId' in context;
886
+ return context && "snapshotBucketId" in context;
814
887
  }
815
888
  }
816
889
 
817
- export interface WithPrebuild {
818
- snapshotBucketId: string;
890
+ export interface WithPrebuild extends WithSnapshot {
819
891
  prebuildWorkspaceId: string;
820
892
  wasPrebuilt: true;
821
893
  }
822
894
  export namespace WithPrebuild {
823
895
  export function is(context: any): context is WithPrebuild {
824
- return context
825
- && 'snapshotBucketId' in context
826
- && 'prebuildWorkspaceId' in context
827
- && 'wasPrebuilt' in context;
896
+ return context && WithSnapshot.is(context) && "prebuildWorkspaceId" in context && "wasPrebuilt" in context;
828
897
  }
829
898
  }
830
899
 
@@ -838,16 +907,14 @@ export interface WithDefaultConfig {
838
907
 
839
908
  export namespace WithDefaultConfig {
840
909
  export function is(context: any): context is WithDefaultConfig {
841
- return context
842
- && 'withDefaultConfig' in context
843
- && context.withDefaultConfig;
910
+ return context && "withDefaultConfig" in context && context.withDefaultConfig;
844
911
  }
845
912
 
846
913
  export function mark(ctx: WorkspaceContext): WorkspaceContext & WithDefaultConfig {
847
914
  return {
848
915
  ...ctx,
849
- withDefaultConfig: true
850
- }
916
+ withDefaultConfig: true,
917
+ };
851
918
  }
852
919
  }
853
920
 
@@ -857,23 +924,24 @@ export interface SnapshotContext extends WorkspaceContext, WithSnapshot {
857
924
 
858
925
  export namespace SnapshotContext {
859
926
  export function is(context: any): context is SnapshotContext {
860
- return context
861
- && WithSnapshot.is(context)
862
- && 'snapshotId' in context;
927
+ return context && WithSnapshot.is(context) && "snapshotId" in context;
863
928
  }
864
929
  }
865
930
 
866
931
  export interface StartPrebuildContext extends WorkspaceContext {
867
932
  actual: WorkspaceContext;
868
933
  commitHistory?: string[];
934
+ additionalRepositoryCommitHistories?: {
935
+ cloneUrl: string;
936
+ commitHistory: string[];
937
+ }[];
869
938
  project?: Project;
870
939
  branch?: string;
871
940
  }
872
941
 
873
942
  export namespace StartPrebuildContext {
874
943
  export function is(context: any): context is StartPrebuildContext {
875
- return context
876
- && 'actual' in context;
944
+ return context && "actual" in context;
877
945
  }
878
946
  }
879
947
 
@@ -885,21 +953,18 @@ export interface PrebuiltWorkspaceContext extends WorkspaceContext {
885
953
 
886
954
  export namespace PrebuiltWorkspaceContext {
887
955
  export function is(context: any): context is PrebuiltWorkspaceContext {
888
- return context
889
- && 'originalContext' in context
890
- && 'prebuiltWorkspace' in context;
956
+ return context && "originalContext" in context && "prebuiltWorkspace" in context;
891
957
  }
892
958
  }
893
959
 
894
960
  export interface WithReferrerContext extends WorkspaceContext {
895
- referrer: string
896
- referrerIde?: string
961
+ referrer: string;
962
+ referrerIde?: string;
897
963
  }
898
964
 
899
965
  export namespace WithReferrerContext {
900
966
  export function is(context: any): context is WithReferrerContext {
901
- return context
902
- && 'referrer' in context;
967
+ return context && "referrer" in context;
903
968
  }
904
969
  }
905
970
 
@@ -909,21 +974,18 @@ export interface WithEnvvarsContext extends WorkspaceContext {
909
974
 
910
975
  export namespace WithEnvvarsContext {
911
976
  export function is(context: any): context is WithEnvvarsContext {
912
- return context
913
- && 'envvars' in context
977
+ return context && "envvars" in context;
914
978
  }
915
979
  }
916
980
 
917
981
  export interface WorkspaceProbeContext extends WorkspaceContext {
918
- responseURL: string
919
- responseToken: string
982
+ responseURL: string;
983
+ responseToken: string;
920
984
  }
921
985
 
922
986
  export namespace WorkspaceProbeContext {
923
987
  export function is(context: any): context is WorkspaceProbeContext {
924
- return context
925
- && 'responseURL' in context
926
- && 'responseToken' in context;
988
+ return context && "responseURL" in context && "responseToken" in context;
927
989
  }
928
990
  }
929
991
 
@@ -935,32 +997,30 @@ export namespace RefType {
935
997
  }
936
998
  // This fallback is meant to handle the cases where (for historic reasons) ref is present but refType is missing
937
999
  return commit.refType || "branch";
938
- }
1000
+ };
939
1001
  }
940
1002
 
941
1003
  export interface Commit {
942
- repository: Repository
943
- revision: string
1004
+ repository: Repository;
1005
+ revision: string;
944
1006
 
945
1007
  // Might contain either a branch or a tag (determined by refType)
946
- ref?: string
1008
+ ref?: string;
947
1009
 
948
1010
  // refType is only set if ref is present (and not for old workspaces, before this feature was added)
949
- refType?: RefType
1011
+ refType?: RefType;
950
1012
  }
951
1013
 
952
1014
  export interface AdditionalContentContext extends WorkspaceContext {
953
-
954
1015
  /**
955
1016
  * utf-8 encoded contents that will be copied on top of the workspace's filesystem
956
1017
  */
957
- additionalFiles: {[filePath: string]: string};
958
-
1018
+ additionalFiles: { [filePath: string]: string };
959
1019
  }
960
1020
 
961
1021
  export namespace AdditionalContentContext {
962
1022
  export function is(ctx: any): ctx is AdditionalContentContext {
963
- return 'additionalFiles' in ctx;
1023
+ return "additionalFiles" in ctx;
964
1024
  }
965
1025
 
966
1026
  export function hasDockerConfig(ctx: any, config: WorkspaceConfig): boolean {
@@ -968,16 +1028,49 @@ export namespace AdditionalContentContext {
968
1028
  }
969
1029
  }
970
1030
 
971
- export interface CommitContext extends WorkspaceContext, Commit {
1031
+ export interface CommitContext extends WorkspaceContext, GitCheckoutInfo {
972
1032
  /** @deprecated Moved to .repository.cloneUrl, left here for backwards-compatibility for old workspace contextes in the DB */
973
- cloneUrl?: string
1033
+ cloneUrl?: string;
1034
+
1035
+ /**
1036
+ * The clone and checkout information for additional repositories in case of multi-repo projects.
1037
+ */
1038
+ additionalRepositoryCheckoutInfo?: GitCheckoutInfo[];
1039
+ }
1040
+
1041
+ export namespace CommitContext {
1042
+ /**
1043
+ * Creates a hash for all the commits of the CommitContext and all sub-repo commit infos.
1044
+ * The hash is max 255 chars long.
1045
+ * @param commitContext
1046
+ * @returns hash for commitcontext
1047
+ */
1048
+ export function computeHash(commitContext: CommitContext): string {
1049
+ // for single commits we use the revision to be backward compatible.
1050
+ if (
1051
+ !commitContext.additionalRepositoryCheckoutInfo ||
1052
+ commitContext.additionalRepositoryCheckoutInfo.length === 0
1053
+ ) {
1054
+ return commitContext.revision;
1055
+ }
1056
+ const hasher = createHash("sha256");
1057
+ hasher.update(commitContext.revision);
1058
+ for (const info of commitContext.additionalRepositoryCheckoutInfo) {
1059
+ hasher.update(info.revision);
1060
+ }
1061
+ return hasher.digest("hex");
1062
+ }
1063
+ }
1064
+
1065
+ export interface GitCheckoutInfo extends Commit {
1066
+ checkoutLocation?: string;
1067
+ upstreamRemoteURI?: string;
1068
+ localBranch?: string;
974
1069
  }
975
1070
 
976
1071
  export namespace CommitContext {
977
1072
  export function is(commit: any): commit is CommitContext {
978
- return WorkspaceContext.is(commit)
979
- && 'repository' in commit
980
- && 'revision' in commit
1073
+ return WorkspaceContext.is(commit) && "repository" in commit && "revision" in commit;
981
1074
  }
982
1075
  }
983
1076
 
@@ -985,17 +1078,14 @@ export interface PullRequestContext extends CommitContext {
985
1078
  nr: number;
986
1079
  ref: string;
987
1080
  base: {
988
- repository: Repository
989
- ref: string
990
- }
1081
+ repository: Repository;
1082
+ ref: string;
1083
+ };
991
1084
  }
992
1085
 
993
1086
  export namespace PullRequestContext {
994
1087
  export function is(ctx: any): ctx is PullRequestContext {
995
- return CommitContext.is(ctx)
996
- && 'nr' in ctx
997
- && 'ref' in ctx
998
- && 'base' in ctx
1088
+ return CommitContext.is(ctx) && "nr" in ctx && "ref" in ctx && "base" in ctx;
999
1089
  }
1000
1090
  }
1001
1091
 
@@ -1007,10 +1097,7 @@ export interface IssueContext extends CommitContext {
1007
1097
 
1008
1098
  export namespace IssueContext {
1009
1099
  export function is(ctx: any): ctx is IssueContext {
1010
- return CommitContext.is(ctx)
1011
- && 'nr' in ctx
1012
- && 'ref' in ctx
1013
- && 'localBranch' in ctx
1100
+ return CommitContext.is(ctx) && "nr" in ctx && "ref" in ctx && "localBranch" in ctx;
1014
1101
  }
1015
1102
  }
1016
1103
 
@@ -1021,9 +1108,7 @@ export interface NavigatorContext extends CommitContext {
1021
1108
 
1022
1109
  export namespace NavigatorContext {
1023
1110
  export function is(ctx: any): ctx is NavigatorContext {
1024
- return CommitContext.is(ctx)
1025
- && 'path' in ctx
1026
- && 'isFile' in ctx
1111
+ return CommitContext.is(ctx) && "path" in ctx && "isFile" in ctx;
1027
1112
  }
1028
1113
  }
1029
1114
 
@@ -1032,6 +1117,8 @@ export interface Repository {
1032
1117
  owner: string;
1033
1118
  name: string;
1034
1119
  cloneUrl: string;
1120
+ /* Optional kind to differentiate between repositories of orgs/groups/projects and personal repos. */
1121
+ repoKind?: string;
1035
1122
  description?: string;
1036
1123
  avatarUrl?: string;
1037
1124
  webUrl?: string;
@@ -1040,8 +1127,8 @@ export interface Repository {
1040
1127
  private?: boolean;
1041
1128
  fork?: {
1042
1129
  // The direct parent of this fork
1043
- parent: Repository
1044
- }
1130
+ parent: Repository;
1131
+ };
1045
1132
  }
1046
1133
  export interface Branch {
1047
1134
  name: string;
@@ -1066,21 +1153,19 @@ export namespace Repository {
1066
1153
  export interface WorkspaceInstancePortsChangedEvent {
1067
1154
  type: "PortsChanged";
1068
1155
  instanceID: string;
1069
- portsOpened: number[]
1070
- portsClosed: number[]
1156
+ portsOpened: number[];
1157
+ portsClosed: number[];
1071
1158
  }
1072
1159
 
1073
1160
  export namespace WorkspaceInstancePortsChangedEvent {
1074
-
1075
1161
  export function is(data: any): data is WorkspaceInstancePortsChangedEvent {
1076
1162
  return data && data.type == "PortsChanged";
1077
1163
  }
1078
-
1079
1164
  }
1080
1165
 
1081
1166
  export interface WorkspaceInfo {
1082
- workspace: Workspace
1083
- latestInstance?: WorkspaceInstance
1167
+ workspace: Workspace;
1168
+ latestInstance?: WorkspaceInstance;
1084
1169
  }
1085
1170
 
1086
1171
  export namespace WorkspaceInfo {
@@ -1096,35 +1181,36 @@ export interface WorkspaceCreationResult {
1096
1181
  workspaceURL?: string;
1097
1182
  existingWorkspaces?: WorkspaceInfo[];
1098
1183
  runningWorkspacePrebuild?: {
1099
- prebuildID: string
1100
- workspaceID: string
1101
- instanceID: string
1102
- starting: RunningWorkspacePrebuildStarting
1103
- sameCluster: boolean
1104
- }
1184
+ prebuildID: string;
1185
+ workspaceID: string;
1186
+ instanceID: string;
1187
+ starting: RunningWorkspacePrebuildStarting;
1188
+ sameCluster: boolean;
1189
+ };
1105
1190
  runningPrebuildWorkspaceID?: string;
1106
1191
  }
1107
- export type RunningWorkspacePrebuildStarting = 'queued' | 'starting' | 'running';
1192
+ export type RunningWorkspacePrebuildStarting = "queued" | "starting" | "running";
1108
1193
 
1109
1194
  export enum CreateWorkspaceMode {
1110
1195
  // Default returns a running prebuild if there is any, otherwise creates a new workspace (using a prebuild if one is available)
1111
- Default = 'default',
1196
+ Default = "default",
1112
1197
  // ForceNew creates a new workspace irrespective of any running prebuilds. This mode is guaranteed to actually create a workspace - but may degrade user experience as currently runnig prebuilds are ignored.
1113
- ForceNew = 'force-new',
1198
+ ForceNew = "force-new",
1114
1199
  // UsePrebuild polls the database waiting for a currently running prebuild to become available. This mode exists to handle the db-sync delay.
1115
- UsePrebuild = 'use-prebuild',
1200
+ UsePrebuild = "use-prebuild",
1116
1201
  // SelectIfRunning returns a list of currently running workspaces for the context URL if there are any, otherwise falls back to Default mode
1117
- SelectIfRunning = 'select-if-running',
1202
+ SelectIfRunning = "select-if-running",
1118
1203
  }
1119
1204
 
1120
1205
  export namespace WorkspaceCreationResult {
1121
1206
  export function is(data: any): data is WorkspaceCreationResult {
1122
- return data && (
1123
- 'createdWorkspaceId' in data
1124
- || 'existingWorkspaces' in data
1125
- || 'runningWorkspacePrebuild' in data
1126
- || 'runningPrebuildWorkspaceID' in data
1127
- )
1207
+ return (
1208
+ data &&
1209
+ ("createdWorkspaceId" in data ||
1210
+ "existingWorkspaces" in data ||
1211
+ "runningWorkspacePrebuild" in data ||
1212
+ "runningPrebuildWorkspaceID" in data)
1213
+ );
1128
1214
  }
1129
1215
  }
1130
1216
 
@@ -1158,7 +1244,7 @@ export interface AuthProviderInfo {
1158
1244
  readonly default: string[];
1159
1245
  readonly publicRepo: string[];
1160
1246
  readonly privateRepo: string[];
1161
- }
1247
+ };
1162
1248
  }
1163
1249
 
1164
1250
  export interface AuthProviderEntry {
@@ -1170,6 +1256,8 @@ export interface AuthProviderEntry {
1170
1256
  readonly status: AuthProviderEntry.Status;
1171
1257
 
1172
1258
  readonly oauth: OAuth2Config;
1259
+ /** A random string that is to change whenever oauth changes (enforced on DB level) */
1260
+ readonly oauthRevision?: string;
1173
1261
  }
1174
1262
 
1175
1263
  export interface OAuth2Config {
@@ -1182,23 +1270,27 @@ export interface OAuth2Config {
1182
1270
  readonly scopeSeparator?: string;
1183
1271
 
1184
1272
  readonly settingsUrl?: string;
1185
- readonly authorizationParams?: { [key: string]: string }
1273
+ readonly authorizationParams?: { [key: string]: string };
1186
1274
  readonly configURL?: string;
1187
1275
  }
1188
1276
 
1189
1277
  export namespace AuthProviderEntry {
1190
1278
  export type Type = "GitHub" | "GitLab" | string;
1191
1279
  export type Status = "pending" | "verified";
1192
- export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type"> & { clientId?: string, clientSecret?: string };
1193
- export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> & Pick<OAuth2Config, "clientId" | "clientSecret">;
1280
+ export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type"> & {
1281
+ clientId?: string;
1282
+ clientSecret?: string;
1283
+ };
1284
+ export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> &
1285
+ Pick<OAuth2Config, "clientId" | "clientSecret">;
1194
1286
  export function redact(entry: AuthProviderEntry): AuthProviderEntry {
1195
1287
  return {
1196
1288
  ...entry,
1197
1289
  oauth: {
1198
1290
  ...entry.oauth,
1199
- clientSecret: "redacted"
1200
- }
1201
- }
1291
+ clientSecret: "redacted",
1292
+ },
1293
+ };
1202
1294
  }
1203
1295
  }
1204
1296