@gitpod/gitpod-protocol 0.1.5-pd-add-latest-jb.7 → 0.1.5-pd-metrics.33

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