@gitpod/gitpod-protocol 0.1.5-wth-test.41 → 0.1.5-yh-vmoptions-fork.3

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