@gitpod/gitpod-protocol 0.1.5-to-new-image.2 → 0.1.5-to-monitor-delete.18

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 (348) hide show
  1. package/data/gitpod-schema.json +124 -5
  2. package/lib/accounting-protocol.d.ts +18 -10
  3. package/lib/accounting-protocol.d.ts.map +1 -1
  4. package/lib/accounting-protocol.js +34 -32
  5. package/lib/accounting-protocol.js.map +1 -1
  6. package/lib/admin-protocol.d.ts +7 -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.map +1 -1
  10. package/lib/analytics.js.map +1 -1
  11. package/lib/attribution.d.ts +24 -0
  12. package/lib/attribution.d.ts.map +1 -0
  13. package/lib/attribution.js +54 -0
  14. package/lib/attribution.js.map +1 -0
  15. package/lib/auth.d.ts.map +1 -1
  16. package/lib/billing-mode.d.ts +45 -0
  17. package/lib/billing-mode.d.ts.map +1 -0
  18. package/lib/billing-mode.js +44 -0
  19. package/lib/billing-mode.js.map +1 -0
  20. package/lib/blocked-repositories-protocol.d.ts +13 -0
  21. package/lib/blocked-repositories-protocol.d.ts.map +1 -0
  22. package/lib/blocked-repositories-protocol.js +8 -0
  23. package/lib/blocked-repositories-protocol.js.map +1 -0
  24. package/lib/context-url.d.ts.map +1 -1
  25. package/lib/context-url.js +4 -4
  26. package/lib/context-url.js.map +1 -1
  27. package/lib/context-url.spec.d.ts.map +1 -1
  28. package/lib/context-url.spec.js +20 -5
  29. package/lib/context-url.spec.js.map +1 -1
  30. package/lib/encryption/container-module.d.ts.map +1 -1
  31. package/lib/encryption/container-module.js +1 -1
  32. package/lib/encryption/container-module.js.map +1 -1
  33. package/lib/encryption/encryption-engine.d.ts.map +1 -1
  34. package/lib/encryption/encryption-engine.js +9 -9
  35. package/lib/encryption/encryption-engine.js.map +1 -1
  36. package/lib/encryption/encryption-engine.spec.d.ts.map +1 -1
  37. package/lib/encryption/encryption-engine.spec.js +2 -3
  38. package/lib/encryption/encryption-engine.spec.js.map +1 -1
  39. package/lib/encryption/encryption-service.d.ts.map +1 -1
  40. package/lib/encryption/encryption-service.js +1 -1
  41. package/lib/encryption/encryption-service.js.map +1 -1
  42. package/lib/encryption/key-provider.d.ts.map +1 -1
  43. package/lib/encryption/key-provider.js +7 -9
  44. package/lib/encryption/key-provider.js.map +1 -1
  45. package/lib/env.d.ts +0 -5
  46. package/lib/env.d.ts.map +1 -1
  47. package/lib/env.js +1 -20
  48. package/lib/env.js.map +1 -1
  49. package/lib/experiments/always-default.d.ts +8 -0
  50. package/lib/experiments/always-default.d.ts.map +1 -0
  51. package/lib/experiments/always-default.js +20 -0
  52. package/lib/experiments/always-default.js.map +1 -0
  53. package/lib/experiments/configcat-server.d.ts +10 -0
  54. package/lib/experiments/configcat-server.d.ts.map +1 -0
  55. package/lib/experiments/configcat-server.js +36 -0
  56. package/lib/experiments/configcat-server.js.map +1 -0
  57. package/lib/experiments/configcat.d.ts +21 -0
  58. package/lib/experiments/configcat.d.ts.map +1 -0
  59. package/lib/experiments/configcat.js +51 -0
  60. package/lib/experiments/configcat.js.map +1 -0
  61. package/lib/experiments/types.d.ts +22 -0
  62. package/lib/experiments/types.d.ts.map +1 -0
  63. package/lib/experiments/types.js +10 -0
  64. package/lib/experiments/types.js.map +1 -0
  65. package/lib/gitpod-file-parser.d.ts.map +1 -1
  66. package/lib/gitpod-file-parser.js +6 -6
  67. package/lib/gitpod-file-parser.js.map +1 -1
  68. package/lib/gitpod-file-parser.spec.js +42 -39
  69. package/lib/gitpod-file-parser.spec.js.map +1 -1
  70. package/lib/gitpod-service.d.ts +65 -46
  71. package/lib/gitpod-service.d.ts.map +1 -1
  72. package/lib/gitpod-service.js +52 -33
  73. package/lib/gitpod-service.js.map +1 -1
  74. package/lib/headless-workspace-log.d.ts +1 -0
  75. package/lib/headless-workspace-log.d.ts.map +1 -1
  76. package/lib/headless-workspace-log.js +2 -1
  77. package/lib/headless-workspace-log.js.map +1 -1
  78. package/lib/ide-frontend-service.d.ts +1 -1
  79. package/lib/ide-protocol.d.ts +14 -6
  80. package/lib/ide-protocol.d.ts.map +1 -1
  81. package/lib/index.d.ts +16 -16
  82. package/lib/index.d.ts.map +1 -1
  83. package/lib/index.js +1 -1
  84. package/lib/index.js.map +1 -1
  85. package/lib/installation-admin-protocol.d.ts +3 -0
  86. package/lib/installation-admin-protocol.d.ts.map +1 -1
  87. package/lib/installation-admin-protocol.js +3 -2
  88. package/lib/installation-admin-protocol.js.map +1 -1
  89. package/lib/license-protocol.d.ts +7 -0
  90. package/lib/license-protocol.d.ts.map +1 -1
  91. package/lib/license-protocol.js.map +1 -1
  92. package/lib/messaging/browser/connection.d.ts +1 -1
  93. package/lib/messaging/browser/connection.d.ts.map +1 -1
  94. package/lib/messaging/browser/connection.js +19 -19
  95. package/lib/messaging/browser/connection.js.map +1 -1
  96. package/lib/messaging/browser/window-connection.d.ts +4 -4
  97. package/lib/messaging/browser/window-connection.d.ts.map +1 -1
  98. package/lib/messaging/browser/window-connection.js +9 -6
  99. package/lib/messaging/browser/window-connection.js.map +1 -1
  100. package/lib/messaging/client-call-metrics.d.ts +2 -18
  101. package/lib/messaging/client-call-metrics.d.ts.map +1 -1
  102. package/lib/messaging/client-call-metrics.js +21 -22
  103. package/lib/messaging/client-call-metrics.js.map +1 -1
  104. package/lib/messaging/error.d.ts +7 -1
  105. package/lib/messaging/error.d.ts.map +1 -1
  106. package/lib/messaging/error.js +15 -3
  107. package/lib/messaging/error.js.map +1 -1
  108. package/lib/messaging/handler.d.ts.map +1 -1
  109. package/lib/messaging/handler.js +1 -1
  110. package/lib/messaging/node/connection.js +8 -8
  111. package/lib/messaging/node/connection.js.map +1 -1
  112. package/lib/messaging/proxy-factory.d.ts +1 -1
  113. package/lib/messaging/proxy-factory.d.ts.map +1 -1
  114. package/lib/messaging/proxy-factory.js +7 -9
  115. package/lib/messaging/proxy-factory.js.map +1 -1
  116. package/lib/payment-protocol.d.ts.map +1 -1
  117. package/lib/payment-protocol.js +1 -1
  118. package/lib/payment-protocol.js.map +1 -1
  119. package/lib/permission.d.ts +2 -2
  120. package/lib/permission.d.ts.map +1 -1
  121. package/lib/permission.js +12 -23
  122. package/lib/permission.js.map +1 -1
  123. package/lib/plans.d.ts +4 -3
  124. package/lib/plans.d.ts.map +1 -1
  125. package/lib/plans.js +210 -171
  126. package/lib/plans.js.map +1 -1
  127. package/lib/protocol.d.ts +181 -57
  128. package/lib/protocol.d.ts.map +1 -1
  129. package/lib/protocol.js +285 -105
  130. package/lib/protocol.js.map +1 -1
  131. package/{src/theia-plugins.ts → lib/protocol.spec.d.ts} +2 -6
  132. package/lib/protocol.spec.d.ts.map +1 -0
  133. package/lib/protocol.spec.js +127 -0
  134. package/lib/protocol.spec.js.map +1 -0
  135. package/lib/snapshot-url.spec.js.map +1 -1
  136. package/lib/team-subscription-protocol.d.ts +22 -3
  137. package/lib/team-subscription-protocol.d.ts.map +1 -1
  138. package/lib/team-subscription-protocol.js +20 -5
  139. package/lib/team-subscription-protocol.js.map +1 -1
  140. package/lib/teams-projects-protocol.d.ts +26 -5
  141. package/lib/teams-projects-protocol.d.ts.map +1 -1
  142. package/lib/teams-projects-protocol.js +1 -1
  143. package/lib/teams-projects-protocol.js.map +1 -1
  144. package/lib/typings/globals.d.ts +2 -2
  145. package/lib/typings/globals.d.ts.map +1 -1
  146. package/lib/usage.d.ts +61 -0
  147. package/lib/usage.d.ts.map +1 -0
  148. package/lib/usage.js +14 -0
  149. package/lib/usage.js.map +1 -0
  150. package/lib/util/analytics.d.ts.map +1 -1
  151. package/lib/util/analytics.js +12 -3
  152. package/lib/util/analytics.js.map +1 -1
  153. package/lib/util/async-iterator.d.ts.map +1 -1
  154. package/lib/util/async-iterator.js +3 -3
  155. package/lib/util/async-iterator.js.map +1 -1
  156. package/lib/util/cancelable.js.map +1 -1
  157. package/lib/util/date-time.js +6 -6
  158. package/lib/util/date-time.js.map +1 -1
  159. package/lib/util/debug-app.d.ts +25 -0
  160. package/lib/util/debug-app.d.ts.map +1 -0
  161. package/lib/util/debug-app.js +100 -0
  162. package/lib/util/debug-app.js.map +1 -0
  163. package/lib/util/deferred.js.map +1 -1
  164. package/lib/util/disposable.d.ts.map +1 -1
  165. package/lib/util/disposable.js +2 -2
  166. package/lib/util/disposable.js.map +1 -1
  167. package/lib/util/event.d.ts.map +1 -1
  168. package/lib/util/event.js +5 -3
  169. package/lib/util/event.js.map +1 -1
  170. package/lib/util/garbage-collected-cache.d.ts.map +1 -1
  171. package/lib/util/garbage-collected-cache.js +6 -1
  172. package/lib/util/garbage-collected-cache.js.map +1 -1
  173. package/lib/util/generate-workspace-id.d.ts +5 -0
  174. package/lib/util/generate-workspace-id.d.ts.map +1 -1
  175. package/lib/util/generate-workspace-id.js +446 -442
  176. package/lib/util/generate-workspace-id.js.map +1 -1
  177. package/lib/util/generate-workspace-id.spec.js +18 -7
  178. package/lib/util/generate-workspace-id.spec.js.map +1 -1
  179. package/lib/util/gitpod-cookie.d.ts +1 -1
  180. package/lib/util/gitpod-cookie.d.ts.map +1 -1
  181. package/lib/util/gitpod-cookie.js +0 -3
  182. package/lib/util/gitpod-cookie.js.map +1 -1
  183. package/lib/util/gitpod-host-url.d.ts +3 -0
  184. package/lib/util/gitpod-host-url.d.ts.map +1 -1
  185. package/lib/util/gitpod-host-url.js +49 -29
  186. package/lib/util/gitpod-host-url.js.map +1 -1
  187. package/lib/util/gitpod-host-url.spec.d.ts.map +1 -1
  188. package/lib/util/gitpod-host-url.spec.js +15 -5
  189. package/lib/util/gitpod-host-url.spec.js.map +1 -1
  190. package/lib/util/grpc.d.ts +19 -0
  191. package/lib/util/grpc.d.ts.map +1 -1
  192. package/lib/util/grpc.js +73 -1
  193. package/lib/util/grpc.js.map +1 -1
  194. package/lib/util/jaeger-client-types.d.ts.map +1 -1
  195. package/lib/util/logging.d.ts +1 -1
  196. package/lib/util/logging.d.ts.map +1 -1
  197. package/lib/util/logging.js +31 -25
  198. package/lib/util/logging.js.map +1 -1
  199. package/lib/util/logging.spec.d.ts +7 -0
  200. package/lib/util/logging.spec.d.ts.map +1 -0
  201. package/lib/util/logging.spec.js +52 -0
  202. package/lib/util/logging.spec.js.map +1 -0
  203. package/lib/util/make-link.js +5 -5
  204. package/lib/util/make-link.js.map +1 -1
  205. package/lib/util/nice-grpc.d.ts +9 -0
  206. package/lib/util/nice-grpc.d.ts.map +1 -0
  207. package/lib/util/nice-grpc.js +119 -0
  208. package/lib/util/nice-grpc.js.map +1 -0
  209. package/lib/util/parse-workspace-id.d.ts.map +1 -1
  210. package/lib/util/parse-workspace-id.js +1 -2
  211. package/lib/util/parse-workspace-id.js.map +1 -1
  212. package/lib/util/parse-workspace-id.spec.d.ts.map +1 -1
  213. package/lib/util/parse-workspace-id.spec.js.map +1 -1
  214. package/lib/util/queue.spec.js +9 -6
  215. package/lib/util/queue.spec.js.map +1 -1
  216. package/lib/util/semaphore.d.ts.map +1 -1
  217. package/lib/util/semaphore.js.map +1 -1
  218. package/lib/util/skip-if.d.ts.map +1 -1
  219. package/lib/util/skip-if.js.map +1 -1
  220. package/lib/util/timeutil.d.ts +2 -0
  221. package/lib/util/timeutil.d.ts.map +1 -1
  222. package/lib/util/timeutil.js +15 -3
  223. package/lib/util/timeutil.js.map +1 -1
  224. package/lib/util/timeutil.spec.d.ts +2 -0
  225. package/lib/util/timeutil.spec.d.ts.map +1 -1
  226. package/lib/util/timeutil.spec.js +34 -0
  227. package/lib/util/timeutil.spec.js.map +1 -1
  228. package/lib/util/tracing.d.ts +6 -6
  229. package/lib/util/tracing.d.ts.map +1 -1
  230. package/lib/util/tracing.js +14 -16
  231. package/lib/util/tracing.js.map +1 -1
  232. package/lib/util/tracing.spec.js +3 -3
  233. package/lib/util/tracing.spec.js.map +1 -1
  234. package/lib/util/workspace-port-authentication.d.ts +7 -7
  235. package/lib/util/workspace-port-authentication.d.ts.map +1 -1
  236. package/lib/util/workspace-port-authentication.js +8 -11
  237. package/lib/util/workspace-port-authentication.js.map +1 -1
  238. package/lib/webhook-event.d.ts +44 -0
  239. package/lib/webhook-event.d.ts.map +1 -0
  240. package/lib/{theia-plugins.js → webhook-event.js} +2 -2
  241. package/lib/webhook-event.js.map +1 -0
  242. package/lib/workspace-class.d.ts +14 -0
  243. package/lib/workspace-class.d.ts.map +1 -0
  244. package/lib/workspace-class.js +8 -0
  245. package/lib/workspace-class.js.map +1 -0
  246. package/lib/workspace-cluster.d.ts +12 -13
  247. package/lib/workspace-cluster.d.ts.map +1 -1
  248. package/lib/workspace-cluster.js +2 -4
  249. package/lib/workspace-cluster.js.map +1 -1
  250. package/lib/workspace-instance.d.ts +20 -3
  251. package/lib/workspace-instance.d.ts.map +1 -1
  252. package/lib/wsready.d.ts +1 -1
  253. package/lib/wsready.d.ts.map +1 -1
  254. package/lib/wsready.js +2 -2
  255. package/package.json +14 -6
  256. package/pkg-yarn.lock +10 -5
  257. package/provenance-bundle.jsonl +3 -1
  258. package/src/accounting-protocol.ts +66 -51
  259. package/src/admin-protocol.ts +32 -20
  260. package/src/analytics.ts +21 -21
  261. package/src/attribution.ts +63 -0
  262. package/src/auth.ts +2 -2
  263. package/src/billing-mode.ts +84 -0
  264. package/src/blocked-repositories-protocol.ts +13 -0
  265. package/src/context-url.spec.ts +25 -11
  266. package/src/context-url.ts +80 -78
  267. package/src/encryption/container-module.ts +2 -3
  268. package/src/encryption/encryption-engine.spec.ts +9 -8
  269. package/src/encryption/encryption-engine.ts +20 -16
  270. package/src/encryption/encryption-service.ts +4 -5
  271. package/src/encryption/key-provider.ts +16 -19
  272. package/src/env.ts +0 -22
  273. package/src/experiments/always-default.ts +24 -0
  274. package/src/experiments/configcat-server.ts +41 -0
  275. package/src/experiments/configcat.ts +56 -0
  276. package/src/experiments/types.ts +34 -0
  277. package/src/gitpod-file-parser.spec.ts +55 -61
  278. package/src/gitpod-file-parser.ts +16 -17
  279. package/src/gitpod-service.ts +208 -132
  280. package/src/headless-workspace-log.ts +6 -4
  281. package/src/ide-frontend-service.ts +2 -2
  282. package/src/ide-protocol.ts +18 -8
  283. package/src/index.ts +16 -16
  284. package/src/installation-admin-protocol.ts +11 -8
  285. package/src/license-protocol.ts +12 -6
  286. package/src/messaging/browser/connection.ts +45 -47
  287. package/src/messaging/browser/window-connection.ts +39 -29
  288. package/src/messaging/client-call-metrics.ts +62 -82
  289. package/src/messaging/error.ts +23 -7
  290. package/src/messaging/handler.ts +6 -6
  291. package/src/messaging/node/connection.ts +8 -8
  292. package/src/messaging/proxy-factory.ts +23 -30
  293. package/src/oss-allowlist.ts +3 -3
  294. package/src/payment-protocol.ts +2 -2
  295. package/src/permission.ts +20 -31
  296. package/src/plans.ts +240 -189
  297. package/src/protocol.spec.ts +97 -0
  298. package/src/protocol.ts +545 -261
  299. package/src/snapshot-url.spec.ts +9 -7
  300. package/src/team-subscription-protocol.ts +59 -22
  301. package/src/teams-projects-protocol.ts +36 -11
  302. package/src/typings/globals.ts +4 -4
  303. package/src/usage.ts +71 -0
  304. package/src/util/analytics.ts +46 -24
  305. package/src/util/async-iterator.ts +4 -5
  306. package/src/util/cancelable.ts +3 -3
  307. package/src/util/date-time.ts +8 -8
  308. package/src/util/debug-app.ts +81 -0
  309. package/src/util/deferred.ts +6 -6
  310. package/src/util/disposable.ts +3 -6
  311. package/src/util/event.ts +9 -11
  312. package/src/util/garbage-collected-cache.ts +8 -6
  313. package/src/util/generate-workspace-id.spec.ts +26 -16
  314. package/src/util/generate-workspace-id.ts +460 -454
  315. package/src/util/gitpod-cookie.ts +8 -9
  316. package/src/util/gitpod-host-url.spec.ts +40 -13
  317. package/src/util/gitpod-host-url.ts +57 -33
  318. package/src/util/grpc.ts +90 -1
  319. package/src/util/jaeger-client-types.ts +2 -2
  320. package/src/util/logging.spec.ts +23 -0
  321. package/src/util/logging.ts +60 -42
  322. package/src/util/make-link.ts +6 -7
  323. package/src/util/nice-grpc.ts +93 -0
  324. package/src/util/parse-workspace-id.spec.ts +17 -8
  325. package/src/util/parse-workspace-id.ts +5 -6
  326. package/src/util/queue.spec.ts +27 -25
  327. package/src/util/repeat.ts +1 -1
  328. package/src/util/semaphore.ts +4 -6
  329. package/src/util/skip-if.ts +9 -6
  330. package/src/util/timeutil.spec.ts +40 -14
  331. package/src/util/timeutil.ts +27 -11
  332. package/src/util/tracing.spec.ts +28 -23
  333. package/src/util/tracing.ts +54 -51
  334. package/src/util/workspace-port-authentication.ts +10 -13
  335. package/src/webhook-event.ts +55 -0
  336. package/src/workspace-class.ts +14 -0
  337. package/src/workspace-cluster.ts +24 -18
  338. package/src/workspace-instance.ts +60 -24
  339. package/src/wsready.ts +3 -3
  340. package/data/builtin-theia-plugins.json +0 -372
  341. package/lib/email-protocol.d.ts +0 -49
  342. package/lib/email-protocol.d.ts.map +0 -1
  343. package/lib/email-protocol.js +0 -28
  344. package/lib/email-protocol.js.map +0 -1
  345. package/lib/theia-plugins.d.ts +0 -11
  346. package/lib/theia-plugins.d.ts.map +0 -1
  347. package/lib/theia-plugins.js.map +0 -1
  348. package/src/email-protocol.ts +0 -66
package/src/protocol.ts CHANGED
@@ -7,26 +7,28 @@
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";
11
+ import { AttributionId } from "./attribution";
10
12
 
11
13
  export interface UserInfo {
12
- name?: string
14
+ name?: string;
13
15
  }
14
16
 
15
17
  export interface User {
16
18
  /** The user id */
17
- id: string
19
+ id: string;
18
20
 
19
21
  /** The timestamp when the user entry was created */
20
- creationDate: string
22
+ creationDate: string;
21
23
 
22
- avatarUrl?: string
24
+ avatarUrl?: string;
23
25
 
24
- name?: string
26
+ name?: string;
25
27
 
26
28
  /** Optional for backwards compatibility */
27
- fullName?: string
29
+ fullName?: string;
28
30
 
29
- identities: Identity[]
31
+ identities: Identity[];
30
32
 
31
33
  /**
32
34
  * Whether the user has been blocked to use our service, because of TOS violation for example.
@@ -44,38 +46,54 @@ export interface User {
44
46
  markedDeleted?: boolean;
45
47
 
46
48
  additionalData?: AdditionalUserData;
49
+
50
+ // Identifies an explicit team or user ID to which all the user's workspace usage should be attributed to (e.g. for billing purposes)
51
+ usageAttributionId?: string;
52
+
53
+ // The last time this user got verified somehow. The user is not verified if this is empty.
54
+ lastVerificationTime?: string;
55
+
56
+ // The phone number used for the last phone verification.
57
+ verificationPhoneNumber?: string;
47
58
  }
48
59
 
49
60
  export namespace User {
50
61
  export function is(data: any): data is User {
51
- return data
52
- && data.hasOwnProperty('id')
53
- && data.hasOwnProperty('identities')
62
+ return data && data.hasOwnProperty("id") && data.hasOwnProperty("identities");
54
63
  }
55
64
  export function getIdentity(user: User, authProviderId: string): Identity | undefined {
56
- return user.identities.find(id => id.authProviderId === authProviderId);
65
+ return user.identities.find((id) => id.authProviderId === authProviderId);
57
66
  }
58
67
  export function censor(user: User): User {
59
68
  const res = { ...user };
60
- delete (res.additionalData);
61
- res.identities = res.identities.map(i => {
62
- delete (i.tokens);
69
+ delete res.additionalData;
70
+ res.identities = res.identities.map((i) => {
71
+ delete i.tokens;
63
72
 
64
73
  // The user field is not in the Identity shape, but actually exists on DBIdentity.
65
74
  // Trying to push this object out via JSON RPC will fail because of the cyclic nature
66
75
  // of this field.
67
- delete ((i as any).user);
76
+ delete (i as any).user;
68
77
  return i;
69
78
  });
70
79
  return res;
71
80
  }
72
- export function getPrimaryEmail(user: User): string {
73
- const identities = user.identities.filter(i => !!i.primaryEmail);
81
+
82
+ /**
83
+ * Returns the stored email or if it doesn't exist returns the primaryEmail of the first identity this user signed up with.
84
+ * @param user
85
+ * @returns A primaryEmail, or undefined if there is none.
86
+ */
87
+ export function getPrimaryEmail(user: User): string | undefined {
88
+ if (user.additionalData?.profile?.emailAddress) {
89
+ return user.additionalData?.profile?.emailAddress;
90
+ }
91
+ const identities = user.identities.filter((i) => !!i.primaryEmail);
74
92
  if (identities.length <= 0) {
75
- throw new Error(`No identity with primary email for user: ${user.id}!`);
93
+ return undefined;
76
94
  }
77
95
 
78
- return identities[0].primaryEmail!;
96
+ return identities[0].primaryEmail || undefined;
79
97
  }
80
98
  export function getName(user: User): string | undefined {
81
99
  const name = user.fullName || user.name;
@@ -90,6 +108,91 @@ export namespace User {
90
108
  }
91
109
  return undefined;
92
110
  }
111
+
112
+ export function hasPreferredIde(user: User) {
113
+ return (
114
+ typeof user?.additionalData?.ideSettings?.defaultIde !== "undefined" ||
115
+ typeof user?.additionalData?.ideSettings?.useLatestVersion !== "undefined"
116
+ );
117
+ }
118
+
119
+ export function isOnboardingUser(user: User) {
120
+ return !hasPreferredIde(user);
121
+ }
122
+
123
+ export function migrationIDESettings(user: User) {
124
+ if (
125
+ !user?.additionalData?.ideSettings ||
126
+ Object.keys(user.additionalData.ideSettings).length === 0 ||
127
+ user.additionalData.ideSettings.settingVersion === "2.0"
128
+ ) {
129
+ return;
130
+ }
131
+ const newIDESettings: IDESettings = {
132
+ settingVersion: "2.0",
133
+ };
134
+ const ideSettings = user.additionalData.ideSettings;
135
+ if (ideSettings.useDesktopIde) {
136
+ if (ideSettings.defaultDesktopIde === "code-desktop") {
137
+ newIDESettings.defaultIde = "code-desktop";
138
+ } else if (ideSettings.defaultDesktopIde === "code-desktop-insiders") {
139
+ newIDESettings.defaultIde = "code-desktop";
140
+ newIDESettings.useLatestVersion = true;
141
+ } else {
142
+ newIDESettings.defaultIde = ideSettings.defaultDesktopIde;
143
+ newIDESettings.useLatestVersion = ideSettings.useLatestVersion;
144
+ }
145
+ } else {
146
+ const useLatest = ideSettings.defaultIde === "code-latest";
147
+ newIDESettings.defaultIde = "code";
148
+ newIDESettings.useLatestVersion = useLatest;
149
+ }
150
+ user.additionalData.ideSettings = newIDESettings;
151
+ }
152
+
153
+ export function getProfile(user: User): Profile {
154
+ return {
155
+ name: User.getName(user!) || "",
156
+ email: User.getPrimaryEmail(user!) || "",
157
+ company: user?.additionalData?.profile?.companyName,
158
+ avatarURL: user?.avatarUrl,
159
+ };
160
+ }
161
+
162
+ export function setProfile(user: User, profile: Profile): User {
163
+ user.fullName = profile.name;
164
+ user.avatarUrl = profile.avatarURL;
165
+
166
+ if (!user.additionalData) {
167
+ user.additionalData = {};
168
+ }
169
+ if (!user.additionalData.profile) {
170
+ user.additionalData.profile = {};
171
+ }
172
+ user.additionalData.profile.emailAddress = profile.email;
173
+ user.additionalData.profile.companyName = profile.company;
174
+ user.additionalData.profile.lastUpdatedDetailsNudge = new Date().toISOString();
175
+
176
+ return user;
177
+ }
178
+
179
+ // The actual Profile of a User
180
+ export interface Profile {
181
+ name: string;
182
+ email: string;
183
+ company?: string;
184
+ avatarURL?: string;
185
+ }
186
+ export namespace Profile {
187
+ export function hasChanges(before: Profile, after: Profile) {
188
+ return (
189
+ before.name !== after.name ||
190
+ before.email !== after.email ||
191
+ before.company !== after.company ||
192
+ before.avatarURL !== after.avatarURL
193
+ );
194
+ }
195
+ }
93
196
  }
94
197
 
95
198
  export interface AdditionalUserData {
@@ -98,15 +201,42 @@ export interface AdditionalUserData {
98
201
  featurePreview?: boolean;
99
202
  ideSettings?: IDESettings;
100
203
  // key is the name of the news, string the iso date when it was seen
101
- whatsNewSeen?: { [key: string]: string }
204
+ whatsNewSeen?: { [key: string]: string };
102
205
  // key is the name of the OAuth client i.e. local app, string the iso date when it was approved
103
206
  // TODO(rl): provide a management UX to allow rescinding of approval
104
- oauthClientsApproved?: { [key: string]: string }
207
+ oauthClientsApproved?: { [key: string]: string };
105
208
  // to remember GH Orgs the user installed/updated the GH App for
106
209
  knownGitHubOrgs?: string[];
107
-
108
210
  // Git clone URL pointing to the user's dotfile repo
109
211
  dotfileRepo?: string;
212
+ // preferred workspace classes
213
+ workspaceClasses?: WorkspaceClasses;
214
+ // additional user profile data
215
+ profile?: ProfileDetails;
216
+ }
217
+ export namespace AdditionalUserData {
218
+ export function set(user: User, partialData: Partial<AdditionalUserData>): User {
219
+ if (!user.additionalData) {
220
+ user.additionalData = {
221
+ ...partialData,
222
+ };
223
+ } else {
224
+ user.additionalData = {
225
+ ...user.additionalData,
226
+ ...partialData,
227
+ };
228
+ }
229
+ return user;
230
+ }
231
+ }
232
+ // The format in which we store User Profiles in
233
+ export interface ProfileDetails {
234
+ // when was the last time the user updated their profile information or has been nudged to do so.
235
+ lastUpdatedDetailsNudge?: string;
236
+ // the user's company name
237
+ companyName?: string;
238
+ // the user's email
239
+ emailAddress?: string;
110
240
  }
111
241
 
112
242
  export interface EmailNotificationSettings {
@@ -116,10 +246,18 @@ export interface EmailNotificationSettings {
116
246
  }
117
247
 
118
248
  export type IDESettings = {
119
- defaultIde?: string
120
- useDesktopIde?: boolean
121
- defaultDesktopIde?: string
122
- useLatestVersion?: boolean
249
+ settingVersion?: string;
250
+ defaultIde?: string;
251
+ // DEPRECATED: Use defaultIde after `settingVersion: 2.0`, no more specialify desktop or browser.
252
+ useDesktopIde?: boolean;
253
+ // DEPRECATED: Same with useDesktopIde.
254
+ defaultDesktopIde?: string;
255
+ useLatestVersion?: boolean;
256
+ };
257
+
258
+ export interface WorkspaceClasses {
259
+ regular: string;
260
+ prebuild: string;
123
261
  }
124
262
 
125
263
  export interface UserPlatform {
@@ -148,12 +286,29 @@ export interface UserFeatureSettings {
148
286
  permanentWSFeatureFlags?: NamedWorkspaceFeatureFlag[];
149
287
  }
150
288
 
289
+ export type BillingTier = "paid" | "free";
290
+
151
291
  /**
152
292
  * The values of this type MUST MATCH enum values in WorkspaceFeatureFlag from ws-manager/client/core_pb.d.ts
153
293
  * If they don't we'll break things during workspace startup.
154
294
  */
155
- export const WorkspaceFeatureFlags = { "full_workspace_backup": undefined, "fixed_resources": undefined };
156
- export type NamedWorkspaceFeatureFlag = keyof (typeof WorkspaceFeatureFlags);
295
+ export const WorkspaceFeatureFlags = {
296
+ full_workspace_backup: undefined,
297
+ persistent_volume_claim: undefined,
298
+ workspace_class_limiting: undefined,
299
+ workspace_connection_limiting: undefined,
300
+ workspace_psi: undefined,
301
+ };
302
+ export type NamedWorkspaceFeatureFlag = keyof typeof WorkspaceFeatureFlags;
303
+ export namespace NamedWorkspaceFeatureFlag {
304
+ export const WORKSPACE_PERSISTED_FEATTURE_FLAGS: NamedWorkspaceFeatureFlag[] = [
305
+ "full_workspace_backup",
306
+ "persistent_volume_claim",
307
+ ];
308
+ export function isWorkspacePersisted(ff: NamedWorkspaceFeatureFlag): boolean {
309
+ return WORKSPACE_PERSISTED_FEATTURE_FLAGS.includes(ff);
310
+ }
311
+ }
157
312
 
158
313
  export interface EnvVarWithValue {
159
314
  name: string;
@@ -166,7 +321,7 @@ export interface ProjectEnvVarWithValue extends EnvVarWithValue {
166
321
  censored: boolean;
167
322
  }
168
323
 
169
- export type ProjectEnvVar = Omit<ProjectEnvVarWithValue, 'value'>;
324
+ export type ProjectEnvVar = Omit<ProjectEnvVarWithValue, "value">;
170
325
 
171
326
  export interface UserEnvVarValue extends EnvVarWithValue {
172
327
  id?: string;
@@ -179,6 +334,44 @@ export interface UserEnvVar extends UserEnvVarValue {
179
334
  }
180
335
 
181
336
  export namespace UserEnvVar {
337
+ /**
338
+ * @param variable
339
+ * @returns Either a string containing an error message or undefined.
340
+ */
341
+ export function validate(variable: UserEnvVarValue): string | undefined {
342
+ const name = variable.name;
343
+ const pattern = variable.repositoryPattern;
344
+ if (name.trim() === "") {
345
+ return "Name must not be empty.";
346
+ }
347
+ if (name.length > 255) {
348
+ return "Name too long. Maximum name length is 255 characters.";
349
+ }
350
+ if (!/^[a-zA-Z_]+[a-zA-Z0-9_]*$/.test(name)) {
351
+ return "Name must match /^[a-zA-Z_]+[a-zA-Z0-9_]*$/.";
352
+ }
353
+ if (variable.value.trim() === "") {
354
+ return "Value must not be empty.";
355
+ }
356
+ if (variable.value.length > 32767) {
357
+ return "Value too long. Maximum value length is 32767 characters.";
358
+ }
359
+ if (pattern.trim() === "") {
360
+ return "Scope must not be empty.";
361
+ }
362
+ const split = pattern.split("/");
363
+ if (split.length < 2) {
364
+ return "A scope must use the form 'organization/repo'.";
365
+ }
366
+ for (const name of split) {
367
+ if (name !== "*") {
368
+ if (!/^[a-zA-Z0-9_\-.\*]+$/.test(name)) {
369
+ return "Invalid scope segment. Only ASCII characters, numbers, -, _, . or * are allowed.";
370
+ }
371
+ }
372
+ }
373
+ return undefined;
374
+ }
182
375
 
183
376
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
184
377
  export function normalizeRepoPattern(pattern: string) {
@@ -199,7 +392,7 @@ export namespace UserEnvVar {
199
392
  if (repoPattern == "*") {
200
393
  score += 1;
201
394
  }
202
- if (ownerPattern == '*') {
395
+ if (ownerPattern == "*") {
203
396
  score += 2;
204
397
  }
205
398
  if (ownerPattern == "#" || repoPattern == "#") {
@@ -210,20 +403,20 @@ export namespace UserEnvVar {
210
403
 
211
404
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
212
405
  export function filter<T extends UserEnvVarValue>(vars: T[], owner: string, repo: string): T[] {
213
- let result = vars.filter(e => {
406
+ let result = vars.filter((e) => {
214
407
  const [ownerPattern, repoPattern] = splitRepositoryPattern(e.repositoryPattern);
215
- if (ownerPattern !== '*' && ownerPattern !== '#' && (!!owner && ownerPattern !== owner.toLocaleLowerCase())) {
408
+ if (ownerPattern !== "*" && ownerPattern !== "#" && !!owner && ownerPattern !== owner.toLocaleLowerCase()) {
216
409
  return false;
217
410
  }
218
- if (repoPattern !== '*' && repoPattern !== '#' && (!!repo && repoPattern !== repo.toLocaleLowerCase())) {
411
+ if (repoPattern !== "*" && repoPattern !== "#" && !!repo && repoPattern !== repo.toLocaleLowerCase()) {
219
412
  return false;
220
413
  }
221
414
  return true;
222
415
  });
223
416
 
224
417
  const resmap = new Map<string, T[]>();
225
- result.forEach(e => {
226
- const l = (resmap.get(e.name) || []);
418
+ result.forEach((e) => {
419
+ const l = resmap.get(e.name) || [];
227
420
  l.push(e);
228
421
  resmap.set(e.name, l);
229
422
  });
@@ -258,46 +451,107 @@ export namespace UserEnvVar {
258
451
 
259
452
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
260
453
  export function splitRepositoryPattern(repositoryPattern: string): string[] {
261
- const patterns = repositoryPattern.split('/');
262
- const repoPattern = patterns.slice(1).join('/')
454
+ const patterns = repositoryPattern.split("/");
455
+ const repoPattern = patterns.slice(1).join("/");
263
456
  const ownerPattern = patterns[0];
264
457
  return [ownerPattern, repoPattern];
265
458
  }
266
459
  }
267
460
 
268
- export interface GitpodToken {
461
+ export interface SSHPublicKeyValue {
462
+ name: string;
463
+ key: string;
464
+ }
465
+ export interface UserSSHPublicKey extends SSHPublicKeyValue {
466
+ id: string;
467
+ key: string;
468
+ userId: string;
469
+ fingerprint: string;
470
+ creationTime: string;
471
+ lastUsedTime?: string;
472
+ }
269
473
 
474
+ export type UserSSHPublicKeyValue = Omit<UserSSHPublicKey, "key" | "userId">;
475
+
476
+ export namespace SSHPublicKeyValue {
477
+ export function validate(value: SSHPublicKeyValue): string | undefined {
478
+ if (value.name.length === 0) {
479
+ return "Title must not be empty.";
480
+ }
481
+ if (value.name.length > 255) {
482
+ return "Title too long. Maximum value length is 255 characters.";
483
+ }
484
+ if (value.key.length === 0) {
485
+ return "Key must not be empty.";
486
+ }
487
+ try {
488
+ getData(value);
489
+ } catch (e) {
490
+ return "Key is invalid. You must supply a key in OpenSSH public key format.";
491
+ }
492
+ return;
493
+ }
494
+
495
+ export function getData(value: SSHPublicKeyValue) {
496
+ // Begins with 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'ssh-ed25519', 'sk-ecdsa-sha2-nistp256@openssh.com', or 'sk-ssh-ed25519@openssh.com'.
497
+ const regex =
498
+ /^(?<type>ssh-rsa|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521|ssh-ed25519|sk-ecdsa-sha2-nistp256@openssh\.com|sk-ssh-ed25519@openssh\.com) (?<key>.*?)( (?<email>.*?))?$/;
499
+ const resultGroup = regex.exec(value.key.trim());
500
+ if (!resultGroup) {
501
+ throw new Error("Key is invalid.");
502
+ }
503
+ return {
504
+ type: resultGroup.groups?.["type"] as string,
505
+ key: resultGroup.groups?.["key"] as string,
506
+ email: resultGroup.groups?.["email"] || undefined,
507
+ };
508
+ }
509
+
510
+ export function getFingerprint(value: SSHPublicKeyValue) {
511
+ const data = getData(value);
512
+ let buf = Buffer.from(data.key, "base64");
513
+ // gitlab style
514
+ // const hash = createHash("md5").update(buf).digest("hex");
515
+ // github style
516
+ const hash = createHash("sha256").update(buf).digest("base64");
517
+ return hash;
518
+ }
519
+
520
+ export const MAXIMUM_KEY_LENGTH = 5;
521
+ }
522
+
523
+ export interface GitpodToken {
270
524
  /** Hash value (SHA256) of the token (primary key). */
271
- tokenHash: string
525
+ tokenHash: string;
272
526
 
273
527
  /** Human readable name of the token */
274
- name?: string
528
+ name?: string;
275
529
 
276
530
  /** Token kind */
277
- type: GitpodTokenType
531
+ type: GitpodTokenType;
278
532
 
279
533
  /** The user the token belongs to. */
280
- user: User
534
+ user: User;
281
535
 
282
536
  /** Scopes (e.g. limition to read-only) */
283
- scopes: string[]
537
+ scopes: string[];
284
538
 
285
539
  /** Created timestamp */
286
- created: string
540
+ created: string;
287
541
 
288
542
  // token is deleted on the database and about to be collected by db-sync
289
- deleted?: boolean
543
+ deleted?: boolean;
290
544
  }
291
545
 
292
546
  export enum GitpodTokenType {
293
547
  API_AUTH_TOKEN = 0,
294
- MACHINE_AUTH_TOKEN = 1
548
+ MACHINE_AUTH_TOKEN = 1,
295
549
  }
296
550
 
297
551
  export interface OneTimeSecret {
298
- id: string
552
+ id: string;
299
553
 
300
- value: string
554
+ value: string;
301
555
 
302
556
  expirationTime: string;
303
557
 
@@ -329,13 +583,12 @@ export type IdentityLookup = Pick<Identity, "authProviderId" | "authId">;
329
583
 
330
584
  export namespace Identity {
331
585
  export function is(data: any): data is Identity {
332
- return data.hasOwnProperty('authProviderId')
333
- && data.hasOwnProperty('authId')
334
- && data.hasOwnProperty('authName')
586
+ return (
587
+ data.hasOwnProperty("authProviderId") && data.hasOwnProperty("authId") && data.hasOwnProperty("authName")
588
+ );
335
589
  }
336
590
  export function equals(id1: IdentityLookup, id2: IdentityLookup) {
337
- return id1.authProviderId === id2.authProviderId
338
- && id1.authId === id2.authId
591
+ return id1.authProviderId === id2.authProviderId && id1.authId === id2.authId;
339
592
  }
340
593
  }
341
594
 
@@ -386,6 +639,7 @@ export interface PendingGithubEvent {
386
639
  creationDate: Date;
387
640
  type: string;
388
641
  event: string;
642
+ deleted: boolean;
389
643
  }
390
644
 
391
645
  export interface Snapshot {
@@ -394,19 +648,24 @@ export interface Snapshot {
394
648
  availableTime?: string;
395
649
  originalWorkspaceId: string;
396
650
  bucketId: string;
397
- layoutData?: string;
398
651
  state: SnapshotState;
399
652
  message?: string;
400
653
  }
401
654
 
402
- export type SnapshotState = 'pending' | 'available' | 'error';
403
-
404
- export interface LayoutData {
655
+ export interface VolumeSnapshot {
656
+ id: string;
405
657
  workspaceId: string;
406
- lastUpdatedTime: string;
407
- layoutData: string;
658
+ creationTime: string;
659
+ volumeHandle: string;
408
660
  }
409
661
 
662
+ export interface VolumeSnapshotWithWSType {
663
+ vs: VolumeSnapshot;
664
+ wsType: WorkspaceType;
665
+ }
666
+
667
+ export type SnapshotState = "pending" | "available" | "error";
668
+
410
669
  export interface Workspace {
411
670
  id: string;
412
671
  creationTime: string;
@@ -428,13 +687,13 @@ export interface Workspace {
428
687
  * The resolved, fix name of the workspace image. We only use this
429
688
  * to access the logs during an image build.
430
689
  */
431
- imageNameResolved?: string
690
+ imageNameResolved?: string;
432
691
 
433
692
  /**
434
693
  * The resolved/built fixed named of the base image. This field is only set if the workspace
435
694
  * already has its base image built.
436
695
  */
437
- baseImageNameResolved?: string
696
+ baseImageNameResolved?: string;
438
697
 
439
698
  shareable?: boolean;
440
699
  pinned?: boolean;
@@ -468,20 +727,19 @@ export interface Workspace {
468
727
 
469
728
  export type WorkspaceSoftDeletion = "user" | "gc";
470
729
 
471
- export type WorkspaceType = "regular" | "prebuild" | "probe";
730
+ export type WorkspaceType = "regular" | "prebuild";
472
731
 
473
732
  export namespace Workspace {
474
-
475
733
  export function getFullRepositoryName(ws: Workspace): string | undefined {
476
734
  if (CommitContext.is(ws.context)) {
477
- return ws.context.repository.owner + '/' + ws.context.repository.name
735
+ return ws.context.repository.owner + "/" + ws.context.repository.name;
478
736
  }
479
737
  return undefined;
480
738
  }
481
739
 
482
740
  export function getFullRepositoryUrl(ws: Workspace): string | undefined {
483
741
  if (CommitContext.is(ws.context)) {
484
- return `https://${ws.context.repository.host}/${getFullRepositoryName(ws)}`
742
+ return `https://${ws.context.repository.host}/${getFullRepositoryName(ws)}`;
485
743
  }
486
744
  return undefined;
487
745
  }
@@ -515,59 +773,58 @@ export namespace Workspace {
515
773
  }
516
774
  }
517
775
 
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
776
  export interface GuessGitTokenScopesParams {
537
- host: string
538
- repoUrl: string
539
- gitCommand: string
540
- currentToken: GitToken
777
+ host: string;
778
+ repoUrl: string;
779
+ gitCommand: string;
780
+ currentToken: GitToken;
541
781
  }
542
782
 
543
783
  export interface GitToken {
544
- token: string
545
- user: string
546
- scopes: string[]
784
+ token: string;
785
+ user: string;
786
+ scopes: string[];
547
787
  }
548
788
 
549
789
  export interface GuessedGitTokenScopes {
550
- message?: string
551
- scopes?: string[]
790
+ message?: string;
791
+ scopes?: string[];
552
792
  }
553
793
 
554
- export type ResolvedPluginKind = 'user' | 'workspace' | 'builtin';
794
+ export interface VSCodeConfig {
795
+ extensions?: string[];
796
+ }
555
797
 
556
- export interface ResolvedPlugins {
557
- [pluginId: string]: ResolvedPlugin | undefined
798
+ export interface JetBrainsConfig {
799
+ intellij?: JetBrainsProductConfig;
800
+ goland?: JetBrainsProductConfig;
801
+ pycharm?: JetBrainsProductConfig;
802
+ phpstorm?: JetBrainsProductConfig;
803
+ rubymine?: JetBrainsProductConfig;
804
+ webstorm?: JetBrainsProductConfig;
805
+ }
806
+ export interface JetBrainsProductConfig {
807
+ prebuilds?: JetBrainsPrebuilds;
808
+ vmoptions?: string;
809
+ }
810
+ export interface JetBrainsPrebuilds {
811
+ version?: "stable" | "latest" | "both";
558
812
  }
559
813
 
560
- export interface ResolvedPlugin {
561
- fullPluginName: string;
814
+ export interface RepositoryCloneInformation {
562
815
  url: string;
563
- kind: ResolvedPluginKind;
816
+ checkoutLocation?: string;
564
817
  }
565
818
 
566
- export interface VSCodeConfig {
567
- extensions?: string[];
819
+ export interface CoreDumpConfig {
820
+ enabled?: boolean;
821
+ softLimit?: number;
822
+ hardLimit?: number;
568
823
  }
569
824
 
570
825
  export interface WorkspaceConfig {
826
+ mainConfiguration?: string;
827
+ additionalRepositories?: RepositoryCloneInformation[];
571
828
  image?: ImageConfig;
572
829
  ports?: PortConfig[];
573
830
  tasks?: TaskConfig[];
@@ -576,6 +833,8 @@ export interface WorkspaceConfig {
576
833
  gitConfig?: { [config: string]: string };
577
834
  github?: GithubAppConfig;
578
835
  vscode?: VSCodeConfig;
836
+ jetbrains?: JetBrainsConfig;
837
+ coreDump?: CoreDumpConfig;
579
838
 
580
839
  /** deprecated. Enabled by default **/
581
840
  experimentalNetwork?: boolean;
@@ -584,13 +843,12 @@ export interface WorkspaceConfig {
584
843
  * Where the config object originates from.
585
844
  *
586
845
  * repo - from the repository
587
- * project-db - from the "Project" stored in the database
588
846
  * definitly-gp - from github.com/gitpod-io/definitely-gp
589
847
  * derived - computed based on analyzing the repository
590
848
  * additional-content - config comes from additional content, usually provided through the project's configuration
591
849
  * default - our static catch-all default config
592
850
  */
593
- _origin?: 'repo' | 'project-db' | 'definitely-gp' | 'derived' | 'additional-content' | 'default';
851
+ _origin?: "repo" | "definitely-gp" | "derived" | "additional-content" | "default";
594
852
 
595
853
  /**
596
854
  * Set of automatically infered feature flags. That's not something the user can set, but
@@ -600,34 +858,33 @@ export interface WorkspaceConfig {
600
858
  }
601
859
 
602
860
  export interface GithubAppConfig {
603
- prebuilds?: GithubAppPrebuildConfig
861
+ prebuilds?: GithubAppPrebuildConfig;
604
862
  }
605
863
  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
864
+ master?: boolean;
865
+ branches?: boolean;
866
+ pullRequests?: boolean;
867
+ pullRequestsFromForks?: boolean;
868
+ addCheck?: boolean | "prevent-merge-on-error";
869
+ addBadge?: boolean;
870
+ addLabel?: boolean | string;
871
+ addComment?: boolean;
614
872
  }
615
873
  export namespace GithubAppPrebuildConfig {
616
874
  export function is(obj: boolean | GithubAppPrebuildConfig): obj is GithubAppPrebuildConfig {
617
- return !(typeof obj === 'boolean');
875
+ return !(typeof obj === "boolean");
618
876
  }
619
877
  }
620
878
 
621
879
  export type WorkspaceImageSource = WorkspaceImageSourceDocker | WorkspaceImageSourceReference;
622
880
  export interface WorkspaceImageSourceDocker {
623
- dockerFilePath: string
624
- dockerFileHash: string
625
- dockerFileSource?: Commit
881
+ dockerFilePath: string;
882
+ dockerFileHash: string;
883
+ dockerFileSource?: Commit;
626
884
  }
627
885
  export namespace WorkspaceImageSourceDocker {
628
886
  export function is(obj: object): obj is WorkspaceImageSourceDocker {
629
- return 'dockerFileHash' in obj
630
- && 'dockerFilePath' in obj;
887
+ return "dockerFileHash" in obj && "dockerFilePath" in obj;
631
888
  }
632
889
  }
633
890
  export interface WorkspaceImageSourceReference {
@@ -636,21 +893,23 @@ export interface WorkspaceImageSourceReference {
636
893
  }
637
894
  export namespace WorkspaceImageSourceReference {
638
895
  export function is(obj: object): obj is WorkspaceImageSourceReference {
639
- return 'baseImageResolved' in obj;
896
+ return "baseImageResolved" in obj;
640
897
  }
641
898
  }
642
899
 
643
- export type PrebuiltWorkspaceState
900
+ export type PrebuiltWorkspaceState =
644
901
  // the prebuild is queued and may start at anytime
645
- = "queued"
902
+ | "queued"
646
903
  // the workspace prebuild is currently running (i.e. there's a workspace pod deployed)
647
904
  | "building"
648
- // the prebuild failed due to some issue with the system (e.g. missed a message, could not start workspace)
905
+ // the prebuild was aborted
649
906
  | "aborted"
650
907
  // the prebuild timed out
651
908
  | "timeout"
652
- // the prebuild has finished and a snapshot is available
653
- | "available";
909
+ // the prebuild has finished (even if a headless task failed) and a snapshot is available
910
+ | "available"
911
+ // the prebuild (headless workspace) failed due to some system error
912
+ | "failed";
654
913
 
655
914
  export interface PrebuiltWorkspace {
656
915
  id: string;
@@ -661,13 +920,16 @@ export interface PrebuiltWorkspace {
661
920
  buildWorkspaceId: string;
662
921
  creationTime: string;
663
922
  state: PrebuiltWorkspaceState;
923
+ statusVersion: number;
664
924
  error?: string;
665
925
  snapshot?: string;
666
926
  }
667
927
 
668
928
  export namespace PrebuiltWorkspace {
669
929
  export function isDone(pws: PrebuiltWorkspace) {
670
- return pws.state === "available" || pws.state === "timeout" || pws.state === 'aborted';
930
+ return (
931
+ pws.state === "available" || pws.state === "timeout" || pws.state === "aborted" || pws.state === "failed"
932
+ );
671
933
  }
672
934
 
673
935
  export function isAvailable(pws: PrebuiltWorkspace) {
@@ -686,18 +948,22 @@ export interface PrebuiltWorkspaceUpdatable {
686
948
  repo: string;
687
949
  isResolved: boolean;
688
950
  installationId: string;
951
+ /**
952
+ * the commitSHA of the commit that triggered the prebuild
953
+ */
954
+ commitSHA?: string;
689
955
  issue?: string;
690
956
  contextUrl?: string;
691
957
  }
692
958
 
693
959
  export interface WhitelistedRepository {
694
- url: string
695
- name: string
696
- description?: string
697
- avatar?: string
960
+ url: string;
961
+ name: string;
962
+ description?: string;
963
+ avatar?: string;
698
964
  }
699
965
 
700
- export type PortOnOpen = 'open-browser' | 'open-preview' | 'notify' | 'ignore';
966
+ export type PortOnOpen = "open-browser" | "open-preview" | "notify" | "ignore";
701
967
 
702
968
  export interface PortConfig {
703
969
  port: number;
@@ -708,7 +974,7 @@ export interface PortConfig {
708
974
  }
709
975
  export namespace PortConfig {
710
976
  export function is(config: any): config is PortConfig {
711
- return config && ('port' in config) && (typeof config.port === 'number');
977
+ return config && "port" in config && typeof config.port === "number";
712
978
  }
713
979
  }
714
980
 
@@ -718,7 +984,7 @@ export interface PortRangeConfig {
718
984
  }
719
985
  export namespace PortRangeConfig {
720
986
  export function is(config: any): config is PortRangeConfig {
721
- return config && ('port' in config) && (typeof config.port === 'string' || config.port instanceof String);
987
+ return config && "port" in config && (typeof config.port === "string" || config.port instanceof String);
722
988
  }
723
989
  }
724
990
 
@@ -729,32 +995,31 @@ export interface TaskConfig {
729
995
  prebuild?: string;
730
996
  command?: string;
731
997
  env?: { [env: string]: any };
732
- openIn?: 'bottom' | 'main' | 'left' | 'right';
733
- openMode?: 'split-top' | 'split-left' | 'split-right' | 'split-bottom' | 'tab-before' | 'tab-after';
998
+ openIn?: "bottom" | "main" | "left" | "right";
999
+ openMode?: "split-top" | "split-left" | "split-right" | "split-bottom" | "tab-before" | "tab-after";
734
1000
  }
735
1001
 
736
1002
  export namespace TaskConfig {
737
1003
  export function is(config: any): config is TaskConfig {
738
- return config
739
- && ('command' in config || 'init' in config || 'before' in config);
1004
+ return config && ("command" in config || "init" in config || "before" in config);
740
1005
  }
741
1006
  }
742
1007
 
743
1008
  export namespace WorkspaceImageBuild {
744
- export type Phase = 'BaseImage' | 'GitpodLayer' | 'Error' | 'Done';
1009
+ export type Phase = "BaseImage" | "GitpodLayer" | "Error" | "Done";
745
1010
  export interface StateInfo {
746
- phase: Phase
747
- currentStep?: number
748
- maxSteps?: number
1011
+ phase: Phase;
1012
+ currentStep?: number;
1013
+ maxSteps?: number;
749
1014
  }
750
1015
  export interface LogContent {
751
- text: string
752
- upToLine?: number
753
- isDiff?: boolean
1016
+ text: string;
1017
+ upToLine?: number;
1018
+ isDiff?: boolean;
754
1019
  }
755
1020
  export type LogCallback = (info: StateInfo, content: LogContent | undefined) => void;
756
1021
  export namespace LogLine {
757
- export const DELIMITER = '\r\n';
1022
+ export const DELIMITER = "\r\n";
758
1023
  export const DELIMITER_REGEX = /\r?\n/;
759
1024
  }
760
1025
  }
@@ -763,20 +1028,18 @@ export type ImageConfig = ImageConfigString | ImageConfigFile;
763
1028
  export type ImageConfigString = string;
764
1029
  export namespace ImageConfigString {
765
1030
  export function is(config: ImageConfig | undefined): config is ImageConfigString {
766
- return typeof config === 'string';
1031
+ return typeof config === "string";
767
1032
  }
768
-
769
1033
  }
770
1034
  export interface ImageConfigFile {
771
1035
  // Path to the Dockerfile relative to repository root
772
- file: string,
1036
+ file: string;
773
1037
  // Path to the docker build context relative to repository root
774
- context?: string
1038
+ context?: string;
775
1039
  }
776
1040
  export namespace ImageConfigFile {
777
1041
  export function is(config: ImageConfig | undefined): config is ImageConfigFile {
778
- return typeof config === 'object'
779
- && 'file' in config;
1042
+ return typeof config === "object" && "file" in config;
780
1043
  }
781
1044
  }
782
1045
  export interface ExternalImageConfigFile extends ImageConfigFile {
@@ -784,14 +1047,13 @@ export interface ExternalImageConfigFile extends ImageConfigFile {
784
1047
  }
785
1048
  export namespace ExternalImageConfigFile {
786
1049
  export function is(config: any | undefined): config is ExternalImageConfigFile {
787
- return typeof config === 'object'
788
- && 'file' in config
789
- && 'externalSource' in config;
1050
+ return typeof config === "object" && "file" in config && "externalSource" in config;
790
1051
  }
791
1052
  }
792
1053
 
793
1054
  export interface WorkspaceContext {
794
1055
  title: string;
1056
+ ref?: string;
795
1057
  /** 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. */
796
1058
  normalizedContextURL?: string;
797
1059
  forceCreateNewWorkspace?: boolean;
@@ -800,8 +1062,7 @@ export interface WorkspaceContext {
800
1062
 
801
1063
  export namespace WorkspaceContext {
802
1064
  export function is(context: any): context is WorkspaceContext {
803
- return context
804
- && 'title' in context;
1065
+ return context && "title" in context;
805
1066
  }
806
1067
  }
807
1068
 
@@ -810,8 +1071,7 @@ export interface WithSnapshot {
810
1071
  }
811
1072
  export namespace WithSnapshot {
812
1073
  export function is(context: any): context is WithSnapshot {
813
- return context
814
- && 'snapshotBucketId' in context;
1074
+ return context && "snapshotBucketId" in context;
815
1075
  }
816
1076
  }
817
1077
 
@@ -821,10 +1081,7 @@ export interface WithPrebuild extends WithSnapshot {
821
1081
  }
822
1082
  export namespace WithPrebuild {
823
1083
  export function is(context: any): context is WithPrebuild {
824
- return context
825
- && WithSnapshot.is(context)
826
- && 'prebuildWorkspaceId' in context
827
- && 'wasPrebuilt' in context;
1084
+ return context && WithSnapshot.is(context) && "prebuildWorkspaceId" in context && "wasPrebuilt" in context;
828
1085
  }
829
1086
  }
830
1087
 
@@ -838,16 +1095,14 @@ export interface WithDefaultConfig {
838
1095
 
839
1096
  export namespace WithDefaultConfig {
840
1097
  export function is(context: any): context is WithDefaultConfig {
841
- return context
842
- && 'withDefaultConfig' in context
843
- && context.withDefaultConfig;
1098
+ return context && "withDefaultConfig" in context && context.withDefaultConfig;
844
1099
  }
845
1100
 
846
1101
  export function mark(ctx: WorkspaceContext): WorkspaceContext & WithDefaultConfig {
847
1102
  return {
848
1103
  ...ctx,
849
- withDefaultConfig: true
850
- }
1104
+ withDefaultConfig: true,
1105
+ };
851
1106
  }
852
1107
  }
853
1108
 
@@ -857,23 +1112,27 @@ export interface SnapshotContext extends WorkspaceContext, WithSnapshot {
857
1112
 
858
1113
  export namespace SnapshotContext {
859
1114
  export function is(context: any): context is SnapshotContext {
860
- return context
861
- && WithSnapshot.is(context)
862
- && 'snapshotId' in context;
1115
+ return context && WithSnapshot.is(context) && "snapshotId" in context;
863
1116
  }
864
1117
  }
865
1118
 
866
- export interface StartPrebuildContext extends WorkspaceContext {
867
- actual: WorkspaceContext;
1119
+ export interface WithCommitHistory {
868
1120
  commitHistory?: string[];
1121
+ additionalRepositoryCommitHistories?: {
1122
+ cloneUrl: string;
1123
+ commitHistory: string[];
1124
+ }[];
1125
+ }
1126
+
1127
+ export interface StartPrebuildContext extends WorkspaceContext, WithCommitHistory {
1128
+ actual: WorkspaceContext;
869
1129
  project?: Project;
870
1130
  branch?: string;
871
1131
  }
872
1132
 
873
1133
  export namespace StartPrebuildContext {
874
1134
  export function is(context: any): context is StartPrebuildContext {
875
- return context
876
- && 'actual' in context;
1135
+ return context && "actual" in context;
877
1136
  }
878
1137
  }
879
1138
 
@@ -885,21 +1144,18 @@ export interface PrebuiltWorkspaceContext extends WorkspaceContext {
885
1144
 
886
1145
  export namespace PrebuiltWorkspaceContext {
887
1146
  export function is(context: any): context is PrebuiltWorkspaceContext {
888
- return context
889
- && 'originalContext' in context
890
- && 'prebuiltWorkspace' in context;
1147
+ return context && "originalContext" in context && "prebuiltWorkspace" in context;
891
1148
  }
892
1149
  }
893
1150
 
894
1151
  export interface WithReferrerContext extends WorkspaceContext {
895
- referrer: string
896
- referrerIde?: string
1152
+ referrer: string;
1153
+ referrerIde?: string;
897
1154
  }
898
1155
 
899
1156
  export namespace WithReferrerContext {
900
1157
  export function is(context: any): context is WithReferrerContext {
901
- return context
902
- && 'referrer' in context;
1158
+ return context && "referrer" in context;
903
1159
  }
904
1160
  }
905
1161
 
@@ -909,21 +1165,7 @@ export interface WithEnvvarsContext extends WorkspaceContext {
909
1165
 
910
1166
  export namespace WithEnvvarsContext {
911
1167
  export function is(context: any): context is WithEnvvarsContext {
912
- return context
913
- && 'envvars' in context
914
- }
915
- }
916
-
917
- export interface WorkspaceProbeContext extends WorkspaceContext {
918
- responseURL: string
919
- responseToken: string
920
- }
921
-
922
- export namespace WorkspaceProbeContext {
923
- export function is(context: any): context is WorkspaceProbeContext {
924
- return context
925
- && 'responseURL' in context
926
- && 'responseToken' in context;
1168
+ return context && "envvars" in context;
927
1169
  }
928
1170
  }
929
1171
 
@@ -935,32 +1177,30 @@ export namespace RefType {
935
1177
  }
936
1178
  // This fallback is meant to handle the cases where (for historic reasons) ref is present but refType is missing
937
1179
  return commit.refType || "branch";
938
- }
1180
+ };
939
1181
  }
940
1182
 
941
1183
  export interface Commit {
942
- repository: Repository
943
- revision: string
1184
+ repository: Repository;
1185
+ revision: string;
944
1186
 
945
1187
  // Might contain either a branch or a tag (determined by refType)
946
- ref?: string
1188
+ ref?: string;
947
1189
 
948
1190
  // refType is only set if ref is present (and not for old workspaces, before this feature was added)
949
- refType?: RefType
1191
+ refType?: RefType;
950
1192
  }
951
1193
 
952
1194
  export interface AdditionalContentContext extends WorkspaceContext {
953
-
954
1195
  /**
955
1196
  * utf-8 encoded contents that will be copied on top of the workspace's filesystem
956
1197
  */
957
- additionalFiles: {[filePath: string]: string};
958
-
1198
+ additionalFiles: { [filePath: string]: string };
959
1199
  }
960
1200
 
961
1201
  export namespace AdditionalContentContext {
962
1202
  export function is(ctx: any): ctx is AdditionalContentContext {
963
- return 'additionalFiles' in ctx;
1203
+ return "additionalFiles" in ctx;
964
1204
  }
965
1205
 
966
1206
  export function hasDockerConfig(ctx: any, config: WorkspaceConfig): boolean {
@@ -968,16 +1208,59 @@ export namespace AdditionalContentContext {
968
1208
  }
969
1209
  }
970
1210
 
971
- export interface CommitContext extends WorkspaceContext, Commit {
1211
+ export interface OpenPrebuildContext extends WorkspaceContext {
1212
+ openPrebuildID: string;
1213
+ }
1214
+
1215
+ export namespace OpenPrebuildContext {
1216
+ export function is(ctx: any): ctx is OpenPrebuildContext {
1217
+ return "openPrebuildID" in ctx;
1218
+ }
1219
+ }
1220
+
1221
+ export interface CommitContext extends WorkspaceContext, GitCheckoutInfo {
972
1222
  /** @deprecated Moved to .repository.cloneUrl, left here for backwards-compatibility for old workspace contextes in the DB */
973
- cloneUrl?: string
1223
+ cloneUrl?: string;
1224
+
1225
+ /**
1226
+ * The clone and checkout information for additional repositories in case of multi-repo projects.
1227
+ */
1228
+ additionalRepositoryCheckoutInfo?: GitCheckoutInfo[];
1229
+ }
1230
+
1231
+ export namespace CommitContext {
1232
+ /**
1233
+ * Creates a hash for all the commits of the CommitContext and all sub-repo commit infos.
1234
+ * The hash is max 255 chars long.
1235
+ * @param commitContext
1236
+ * @returns hash for commitcontext
1237
+ */
1238
+ export function computeHash(commitContext: CommitContext): string {
1239
+ // for single commits we use the revision to be backward compatible.
1240
+ if (
1241
+ !commitContext.additionalRepositoryCheckoutInfo ||
1242
+ commitContext.additionalRepositoryCheckoutInfo.length === 0
1243
+ ) {
1244
+ return commitContext.revision;
1245
+ }
1246
+ const hasher = createHash("sha256");
1247
+ hasher.update(commitContext.revision);
1248
+ for (const info of commitContext.additionalRepositoryCheckoutInfo) {
1249
+ hasher.update(info.revision);
1250
+ }
1251
+ return hasher.digest("hex");
1252
+ }
1253
+ }
1254
+
1255
+ export interface GitCheckoutInfo extends Commit {
1256
+ checkoutLocation?: string;
1257
+ upstreamRemoteURI?: string;
1258
+ localBranch?: string;
974
1259
  }
975
1260
 
976
1261
  export namespace CommitContext {
977
1262
  export function is(commit: any): commit is CommitContext {
978
- return WorkspaceContext.is(commit)
979
- && 'repository' in commit
980
- && 'revision' in commit
1263
+ return WorkspaceContext.is(commit) && "repository" in commit && "revision" in commit;
981
1264
  }
982
1265
  }
983
1266
 
@@ -985,17 +1268,14 @@ export interface PullRequestContext extends CommitContext {
985
1268
  nr: number;
986
1269
  ref: string;
987
1270
  base: {
988
- repository: Repository
989
- ref: string
990
- }
1271
+ repository: Repository;
1272
+ ref: string;
1273
+ };
991
1274
  }
992
1275
 
993
1276
  export namespace PullRequestContext {
994
1277
  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
1278
+ return CommitContext.is(ctx) && "nr" in ctx && "ref" in ctx && "base" in ctx;
999
1279
  }
1000
1280
  }
1001
1281
 
@@ -1007,10 +1287,7 @@ export interface IssueContext extends CommitContext {
1007
1287
 
1008
1288
  export namespace IssueContext {
1009
1289
  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
1290
+ return CommitContext.is(ctx) && "nr" in ctx && "ref" in ctx && "localBranch" in ctx;
1014
1291
  }
1015
1292
  }
1016
1293
 
@@ -1021,9 +1298,7 @@ export interface NavigatorContext extends CommitContext {
1021
1298
 
1022
1299
  export namespace NavigatorContext {
1023
1300
  export function is(ctx: any): ctx is NavigatorContext {
1024
- return CommitContext.is(ctx)
1025
- && 'path' in ctx
1026
- && 'isFile' in ctx
1301
+ return CommitContext.is(ctx) && "path" in ctx && "isFile" in ctx;
1027
1302
  }
1028
1303
  }
1029
1304
 
@@ -1032,6 +1307,8 @@ export interface Repository {
1032
1307
  owner: string;
1033
1308
  name: string;
1034
1309
  cloneUrl: string;
1310
+ /* Optional kind to differentiate between repositories of orgs/groups/projects and personal repos. */
1311
+ repoKind?: string;
1035
1312
  description?: string;
1036
1313
  avatarUrl?: string;
1037
1314
  webUrl?: string;
@@ -1040,8 +1317,8 @@ export interface Repository {
1040
1317
  private?: boolean;
1041
1318
  fork?: {
1042
1319
  // The direct parent of this fork
1043
- parent: Repository
1044
- }
1320
+ parent: Repository;
1321
+ };
1045
1322
  }
1046
1323
  export interface Branch {
1047
1324
  name: string;
@@ -1066,21 +1343,19 @@ export namespace Repository {
1066
1343
  export interface WorkspaceInstancePortsChangedEvent {
1067
1344
  type: "PortsChanged";
1068
1345
  instanceID: string;
1069
- portsOpened: number[]
1070
- portsClosed: number[]
1346
+ portsOpened: number[];
1347
+ portsClosed: number[];
1071
1348
  }
1072
1349
 
1073
1350
  export namespace WorkspaceInstancePortsChangedEvent {
1074
-
1075
1351
  export function is(data: any): data is WorkspaceInstancePortsChangedEvent {
1076
1352
  return data && data.type == "PortsChanged";
1077
1353
  }
1078
-
1079
1354
  }
1080
1355
 
1081
1356
  export interface WorkspaceInfo {
1082
- workspace: Workspace
1083
- latestInstance?: WorkspaceInstance
1357
+ workspace: Workspace;
1358
+ latestInstance?: WorkspaceInstance;
1084
1359
  }
1085
1360
 
1086
1361
  export namespace WorkspaceInfo {
@@ -1096,35 +1371,25 @@ export interface WorkspaceCreationResult {
1096
1371
  workspaceURL?: string;
1097
1372
  existingWorkspaces?: WorkspaceInfo[];
1098
1373
  runningWorkspacePrebuild?: {
1099
- prebuildID: string
1100
- workspaceID: string
1101
- instanceID: string
1102
- starting: RunningWorkspacePrebuildStarting
1103
- sameCluster: boolean
1104
- }
1374
+ prebuildID: string;
1375
+ workspaceID: string;
1376
+ instanceID: string;
1377
+ starting: RunningWorkspacePrebuildStarting;
1378
+ sameCluster: boolean;
1379
+ };
1105
1380
  runningPrebuildWorkspaceID?: string;
1106
1381
  }
1107
- export type RunningWorkspacePrebuildStarting = 'queued' | 'starting' | 'running';
1108
-
1109
- export enum CreateWorkspaceMode {
1110
- // Default returns a running prebuild if there is any, otherwise creates a new workspace (using a prebuild if one is available)
1111
- Default = 'default',
1112
- // 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',
1114
- // 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',
1116
- // 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',
1118
- }
1382
+ export type RunningWorkspacePrebuildStarting = "queued" | "starting" | "running";
1119
1383
 
1120
1384
  export namespace WorkspaceCreationResult {
1121
1385
  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
- )
1386
+ return (
1387
+ data &&
1388
+ ("createdWorkspaceId" in data ||
1389
+ "existingWorkspaces" in data ||
1390
+ "runningWorkspacePrebuild" in data ||
1391
+ "runningPrebuildWorkspaceID" in data)
1392
+ );
1128
1393
  }
1129
1394
  }
1130
1395
 
@@ -1158,7 +1423,7 @@ export interface AuthProviderInfo {
1158
1423
  readonly default: string[];
1159
1424
  readonly publicRepo: string[];
1160
1425
  readonly privateRepo: string[];
1161
- }
1426
+ };
1162
1427
  }
1163
1428
 
1164
1429
  export interface AuthProviderEntry {
@@ -1184,23 +1449,27 @@ export interface OAuth2Config {
1184
1449
  readonly scopeSeparator?: string;
1185
1450
 
1186
1451
  readonly settingsUrl?: string;
1187
- readonly authorizationParams?: { [key: string]: string }
1452
+ readonly authorizationParams?: { [key: string]: string };
1188
1453
  readonly configURL?: string;
1189
1454
  }
1190
1455
 
1191
1456
  export namespace AuthProviderEntry {
1192
1457
  export type Type = "GitHub" | "GitLab" | string;
1193
1458
  export type Status = "pending" | "verified";
1194
- export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type"> & { clientId?: string, clientSecret?: string };
1195
- export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> & Pick<OAuth2Config, "clientId" | "clientSecret">;
1459
+ export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type"> & {
1460
+ clientId?: string;
1461
+ clientSecret?: string;
1462
+ };
1463
+ export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> &
1464
+ Pick<OAuth2Config, "clientId" | "clientSecret">;
1196
1465
  export function redact(entry: AuthProviderEntry): AuthProviderEntry {
1197
1466
  return {
1198
1467
  ...entry,
1199
1468
  oauth: {
1200
1469
  ...entry.oauth,
1201
- clientSecret: "redacted"
1202
- }
1203
- }
1470
+ clientSecret: "redacted",
1471
+ },
1472
+ };
1204
1473
  }
1205
1474
  }
1206
1475
 
@@ -1244,3 +1513,18 @@ export interface Terms {
1244
1513
  readonly content: string;
1245
1514
  readonly formElements?: object;
1246
1515
  }
1516
+
1517
+ export interface StripeConfig {
1518
+ individualUsagePriceIds: { [currency: string]: string };
1519
+ teamUsagePriceIds: { [currency: string]: string };
1520
+ }
1521
+
1522
+ export type BillingStrategy = "other" | "stripe";
1523
+ export interface CostCenter {
1524
+ readonly id: AttributionId;
1525
+ /**
1526
+ * Unit: credits
1527
+ */
1528
+ spendingLimit: number;
1529
+ billingStrategy: BillingStrategy;
1530
+ }