@gitpod/gitpod-protocol 0.1.5-sje-installation-admin-dashboard.22 → 0.1.5-sje-installer-fun.1

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