@gitpod/gitpod-protocol 0.1.5-to-code-reading.1 → 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 (361) 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 +19 -0
  7. package/lib/admin-protocol.d.ts.map +1 -1
  8. package/lib/admin-protocol.js.map +1 -1
  9. package/lib/analytics.d.ts +4 -5
  10. package/lib/analytics.d.ts.map +1 -1
  11. package/lib/analytics.js.map +1 -1
  12. package/lib/attribution.d.ts +24 -0
  13. package/lib/attribution.d.ts.map +1 -0
  14. package/lib/attribution.js +54 -0
  15. package/lib/attribution.js.map +1 -0
  16. package/lib/auth.d.ts.map +1 -1
  17. package/lib/billing-mode.d.ts +45 -0
  18. package/lib/billing-mode.d.ts.map +1 -0
  19. package/lib/billing-mode.js +44 -0
  20. package/lib/billing-mode.js.map +1 -0
  21. package/lib/blocked-repositories-protocol.d.ts +13 -0
  22. package/lib/blocked-repositories-protocol.d.ts.map +1 -0
  23. package/lib/blocked-repositories-protocol.js +8 -0
  24. package/lib/blocked-repositories-protocol.js.map +1 -0
  25. package/lib/context-url.d.ts +18 -5
  26. package/lib/context-url.d.ts.map +1 -1
  27. package/lib/context-url.js +59 -6
  28. package/lib/context-url.js.map +1 -1
  29. package/lib/context-url.spec.d.ts +2 -0
  30. package/lib/context-url.spec.d.ts.map +1 -1
  31. package/lib/context-url.spec.js +40 -4
  32. package/lib/context-url.spec.js.map +1 -1
  33. package/lib/encryption/container-module.d.ts.map +1 -1
  34. package/lib/encryption/container-module.js +1 -1
  35. package/lib/encryption/container-module.js.map +1 -1
  36. package/lib/encryption/encryption-engine.d.ts.map +1 -1
  37. package/lib/encryption/encryption-engine.js +9 -9
  38. package/lib/encryption/encryption-engine.js.map +1 -1
  39. package/lib/encryption/encryption-engine.spec.d.ts.map +1 -1
  40. package/lib/encryption/encryption-engine.spec.js +2 -3
  41. package/lib/encryption/encryption-engine.spec.js.map +1 -1
  42. package/lib/encryption/encryption-service.d.ts.map +1 -1
  43. package/lib/encryption/encryption-service.js +1 -1
  44. package/lib/encryption/encryption-service.js.map +1 -1
  45. package/lib/encryption/key-provider.d.ts.map +1 -1
  46. package/lib/encryption/key-provider.js +7 -9
  47. package/lib/encryption/key-provider.js.map +1 -1
  48. package/lib/env.d.ts +0 -5
  49. package/lib/env.d.ts.map +1 -1
  50. package/lib/env.js +1 -20
  51. package/lib/env.js.map +1 -1
  52. package/lib/experiments/always-default.d.ts +8 -0
  53. package/lib/experiments/always-default.d.ts.map +1 -0
  54. package/lib/experiments/always-default.js +20 -0
  55. package/lib/experiments/always-default.js.map +1 -0
  56. package/lib/experiments/configcat-server.d.ts +10 -0
  57. package/lib/experiments/configcat-server.d.ts.map +1 -0
  58. package/lib/experiments/configcat-server.js +36 -0
  59. package/lib/experiments/configcat-server.js.map +1 -0
  60. package/lib/experiments/configcat.d.ts +21 -0
  61. package/lib/experiments/configcat.d.ts.map +1 -0
  62. package/lib/experiments/configcat.js +51 -0
  63. package/lib/experiments/configcat.js.map +1 -0
  64. package/lib/experiments/types.d.ts +22 -0
  65. package/lib/experiments/types.d.ts.map +1 -0
  66. package/lib/experiments/types.js +10 -0
  67. package/lib/experiments/types.js.map +1 -0
  68. package/lib/gitpod-file-parser.d.ts.map +1 -1
  69. package/lib/gitpod-file-parser.js +6 -6
  70. package/lib/gitpod-file-parser.js.map +1 -1
  71. package/lib/gitpod-file-parser.spec.js +42 -39
  72. package/lib/gitpod-file-parser.spec.js.map +1 -1
  73. package/lib/gitpod-service.d.ts +83 -45
  74. package/lib/gitpod-service.d.ts.map +1 -1
  75. package/lib/gitpod-service.js +52 -33
  76. package/lib/gitpod-service.js.map +1 -1
  77. package/lib/headless-workspace-log.d.ts +1 -0
  78. package/lib/headless-workspace-log.d.ts.map +1 -1
  79. package/lib/headless-workspace-log.js +2 -1
  80. package/lib/headless-workspace-log.js.map +1 -1
  81. package/lib/ide-frontend-service.d.ts +1 -1
  82. package/lib/ide-protocol.d.ts +38 -6
  83. package/lib/ide-protocol.d.ts.map +1 -1
  84. package/lib/index.d.ts +16 -15
  85. package/lib/index.d.ts.map +1 -1
  86. package/lib/index.js +2 -1
  87. package/lib/index.js.map +1 -1
  88. package/lib/installation-admin-protocol.d.ts +30 -0
  89. package/lib/installation-admin-protocol.d.ts.map +1 -0
  90. package/lib/installation-admin-protocol.js +31 -0
  91. package/lib/installation-admin-protocol.js.map +1 -0
  92. package/lib/license-protocol.d.ts +7 -0
  93. package/lib/license-protocol.d.ts.map +1 -1
  94. package/lib/license-protocol.js.map +1 -1
  95. package/lib/messaging/browser/connection.d.ts +1 -1
  96. package/lib/messaging/browser/connection.d.ts.map +1 -1
  97. package/lib/messaging/browser/connection.js +19 -19
  98. package/lib/messaging/browser/connection.js.map +1 -1
  99. package/lib/messaging/browser/window-connection.d.ts +4 -4
  100. package/lib/messaging/browser/window-connection.d.ts.map +1 -1
  101. package/lib/messaging/browser/window-connection.js +9 -6
  102. package/lib/messaging/browser/window-connection.js.map +1 -1
  103. package/lib/messaging/client-call-metrics.d.ts +2 -18
  104. package/lib/messaging/client-call-metrics.d.ts.map +1 -1
  105. package/lib/messaging/client-call-metrics.js +21 -22
  106. package/lib/messaging/client-call-metrics.js.map +1 -1
  107. package/lib/messaging/error.d.ts +8 -1
  108. package/lib/messaging/error.d.ts.map +1 -1
  109. package/lib/messaging/error.js +17 -3
  110. package/lib/messaging/error.js.map +1 -1
  111. package/lib/messaging/handler.d.ts.map +1 -1
  112. package/lib/messaging/handler.js +1 -1
  113. package/lib/messaging/node/connection.js +8 -8
  114. package/lib/messaging/node/connection.js.map +1 -1
  115. package/lib/messaging/proxy-factory.d.ts +1 -1
  116. package/lib/messaging/proxy-factory.d.ts.map +1 -1
  117. package/lib/messaging/proxy-factory.js +7 -9
  118. package/lib/messaging/proxy-factory.js.map +1 -1
  119. package/lib/payment-protocol.d.ts.map +1 -1
  120. package/lib/payment-protocol.js +1 -1
  121. package/lib/payment-protocol.js.map +1 -1
  122. package/lib/permission.d.ts +9 -3
  123. package/lib/permission.d.ts.map +1 -1
  124. package/lib/permission.js +34 -25
  125. package/lib/permission.js.map +1 -1
  126. package/lib/plans.d.ts +4 -3
  127. package/lib/plans.d.ts.map +1 -1
  128. package/lib/plans.js +210 -171
  129. package/lib/plans.js.map +1 -1
  130. package/lib/protocol.d.ts +192 -59
  131. package/lib/protocol.d.ts.map +1 -1
  132. package/lib/protocol.js +292 -104
  133. package/lib/protocol.js.map +1 -1
  134. package/{src/theia-plugins.ts → lib/protocol.spec.d.ts} +2 -6
  135. package/lib/protocol.spec.d.ts.map +1 -0
  136. package/lib/protocol.spec.js +127 -0
  137. package/lib/protocol.spec.js.map +1 -0
  138. package/lib/snapshot-url.spec.js.map +1 -1
  139. package/lib/team-subscription-protocol.d.ts +22 -3
  140. package/lib/team-subscription-protocol.d.ts.map +1 -1
  141. package/lib/team-subscription-protocol.js +20 -5
  142. package/lib/team-subscription-protocol.js.map +1 -1
  143. package/lib/teams-projects-protocol.d.ts +29 -5
  144. package/lib/teams-projects-protocol.d.ts.map +1 -1
  145. package/lib/teams-projects-protocol.js +8 -1
  146. package/lib/teams-projects-protocol.js.map +1 -1
  147. package/lib/typings/globals.d.ts +2 -2
  148. package/lib/typings/globals.d.ts.map +1 -1
  149. package/lib/usage.d.ts +61 -0
  150. package/lib/usage.d.ts.map +1 -0
  151. package/lib/usage.js +14 -0
  152. package/lib/usage.js.map +1 -0
  153. package/lib/util/analytics.d.ts.map +1 -1
  154. package/lib/util/analytics.js +12 -3
  155. package/lib/util/analytics.js.map +1 -1
  156. package/lib/util/async-iterator.d.ts.map +1 -1
  157. package/lib/util/async-iterator.js +3 -3
  158. package/lib/util/async-iterator.js.map +1 -1
  159. package/lib/util/cancelable.js.map +1 -1
  160. package/lib/util/date-time.js +6 -6
  161. package/lib/util/date-time.js.map +1 -1
  162. package/lib/util/debug-app.d.ts +25 -0
  163. package/lib/util/debug-app.d.ts.map +1 -0
  164. package/lib/util/debug-app.js +100 -0
  165. package/lib/util/debug-app.js.map +1 -0
  166. package/lib/util/deferred.js.map +1 -1
  167. package/lib/util/disposable.d.ts.map +1 -1
  168. package/lib/util/disposable.js +2 -2
  169. package/lib/util/disposable.js.map +1 -1
  170. package/lib/util/event.d.ts.map +1 -1
  171. package/lib/util/event.js +5 -3
  172. package/lib/util/event.js.map +1 -1
  173. package/lib/util/garbage-collected-cache.d.ts.map +1 -1
  174. package/lib/util/garbage-collected-cache.js +6 -1
  175. package/lib/util/garbage-collected-cache.js.map +1 -1
  176. package/lib/util/generate-workspace-id.d.ts +5 -0
  177. package/lib/util/generate-workspace-id.d.ts.map +1 -1
  178. package/lib/util/generate-workspace-id.js +446 -442
  179. package/lib/util/generate-workspace-id.js.map +1 -1
  180. package/lib/util/generate-workspace-id.spec.js +18 -7
  181. package/lib/util/generate-workspace-id.spec.js.map +1 -1
  182. package/lib/util/gitpod-cookie.d.ts +1 -1
  183. package/lib/util/gitpod-cookie.d.ts.map +1 -1
  184. package/lib/util/gitpod-cookie.js +0 -3
  185. package/lib/util/gitpod-cookie.js.map +1 -1
  186. package/lib/util/gitpod-host-url.d.ts +3 -0
  187. package/lib/util/gitpod-host-url.d.ts.map +1 -1
  188. package/lib/util/gitpod-host-url.js +49 -29
  189. package/lib/util/gitpod-host-url.js.map +1 -1
  190. package/lib/util/gitpod-host-url.spec.d.ts.map +1 -1
  191. package/lib/util/gitpod-host-url.spec.js +15 -5
  192. package/lib/util/gitpod-host-url.spec.js.map +1 -1
  193. package/lib/util/grpc.d.ts +19 -0
  194. package/lib/util/grpc.d.ts.map +1 -1
  195. package/lib/util/grpc.js +73 -1
  196. package/lib/util/grpc.js.map +1 -1
  197. package/lib/util/jaeger-client-types.d.ts.map +1 -1
  198. package/lib/util/logging.d.ts +1 -1
  199. package/lib/util/logging.d.ts.map +1 -1
  200. package/lib/util/logging.js +31 -25
  201. package/lib/util/logging.js.map +1 -1
  202. package/lib/util/logging.spec.d.ts +7 -0
  203. package/lib/util/logging.spec.d.ts.map +1 -0
  204. package/lib/util/logging.spec.js +52 -0
  205. package/lib/util/logging.spec.js.map +1 -0
  206. package/lib/util/make-link.js +5 -5
  207. package/lib/util/make-link.js.map +1 -1
  208. package/lib/util/nice-grpc.d.ts +9 -0
  209. package/lib/util/nice-grpc.d.ts.map +1 -0
  210. package/lib/util/nice-grpc.js +119 -0
  211. package/lib/util/nice-grpc.js.map +1 -0
  212. package/lib/util/parse-workspace-id.d.ts.map +1 -1
  213. package/lib/util/parse-workspace-id.js +1 -2
  214. package/lib/util/parse-workspace-id.js.map +1 -1
  215. package/lib/util/parse-workspace-id.spec.d.ts.map +1 -1
  216. package/lib/util/parse-workspace-id.spec.js.map +1 -1
  217. package/lib/util/queue.spec.js +9 -6
  218. package/lib/util/queue.spec.js.map +1 -1
  219. package/lib/util/semaphore.d.ts.map +1 -1
  220. package/lib/util/semaphore.js.map +1 -1
  221. package/lib/util/skip-if.d.ts.map +1 -1
  222. package/lib/util/skip-if.js.map +1 -1
  223. package/lib/util/timeutil.d.ts +2 -0
  224. package/lib/util/timeutil.d.ts.map +1 -1
  225. package/lib/util/timeutil.js +15 -3
  226. package/lib/util/timeutil.js.map +1 -1
  227. package/lib/util/timeutil.spec.d.ts +2 -0
  228. package/lib/util/timeutil.spec.d.ts.map +1 -1
  229. package/lib/util/timeutil.spec.js +34 -0
  230. package/lib/util/timeutil.spec.js.map +1 -1
  231. package/lib/util/tracing.d.ts +8 -8
  232. package/lib/util/tracing.d.ts.map +1 -1
  233. package/lib/util/tracing.js +19 -20
  234. package/lib/util/tracing.js.map +1 -1
  235. package/lib/util/tracing.spec.js +3 -3
  236. package/lib/util/tracing.spec.js.map +1 -1
  237. package/lib/util/workspace-port-authentication.d.ts +7 -7
  238. package/lib/util/workspace-port-authentication.d.ts.map +1 -1
  239. package/lib/util/workspace-port-authentication.js +8 -11
  240. package/lib/util/workspace-port-authentication.js.map +1 -1
  241. package/lib/webhook-event.d.ts +44 -0
  242. package/lib/webhook-event.d.ts.map +1 -0
  243. package/lib/{theia-plugins.js → webhook-event.js} +2 -2
  244. package/lib/webhook-event.js.map +1 -0
  245. package/lib/workspace-class.d.ts +14 -0
  246. package/lib/workspace-class.d.ts.map +1 -0
  247. package/lib/workspace-class.js +8 -0
  248. package/lib/workspace-class.js.map +1 -0
  249. package/lib/workspace-cluster.d.ts +18 -17
  250. package/lib/workspace-cluster.d.ts.map +1 -1
  251. package/lib/workspace-cluster.js +16 -1
  252. package/lib/workspace-cluster.js.map +1 -1
  253. package/lib/workspace-instance.d.ts +39 -3
  254. package/lib/workspace-instance.d.ts.map +1 -1
  255. package/lib/wsready.d.ts +1 -1
  256. package/lib/wsready.d.ts.map +1 -1
  257. package/lib/wsready.js +2 -2
  258. package/package.json +15 -7
  259. package/pkg-yarn.lock +11 -6
  260. package/provenance-bundle.jsonl +3 -1
  261. package/src/accounting-protocol.ts +66 -51
  262. package/src/admin-protocol.ts +45 -18
  263. package/src/analytics.ts +26 -28
  264. package/src/attribution.ts +63 -0
  265. package/src/auth.ts +2 -2
  266. package/src/billing-mode.ts +84 -0
  267. package/src/blocked-repositories-protocol.ts +13 -0
  268. package/src/context-url.spec.ts +37 -9
  269. package/src/context-url.ts +94 -36
  270. package/src/encryption/container-module.ts +2 -3
  271. package/src/encryption/encryption-engine.spec.ts +9 -8
  272. package/src/encryption/encryption-engine.ts +20 -16
  273. package/src/encryption/encryption-service.ts +4 -5
  274. package/src/encryption/key-provider.ts +16 -19
  275. package/src/env.ts +0 -22
  276. package/src/experiments/always-default.ts +24 -0
  277. package/src/experiments/configcat-server.ts +41 -0
  278. package/src/experiments/configcat.ts +56 -0
  279. package/src/experiments/types.ts +34 -0
  280. package/src/gitpod-file-parser.spec.ts +55 -61
  281. package/src/gitpod-file-parser.ts +16 -17
  282. package/src/gitpod-service.ts +228 -129
  283. package/src/headless-workspace-log.ts +6 -4
  284. package/src/ide-frontend-service.ts +2 -2
  285. package/src/ide-protocol.ts +43 -6
  286. package/src/index.ts +16 -15
  287. package/src/installation-admin-protocol.ts +45 -0
  288. package/src/license-protocol.ts +12 -6
  289. package/src/messaging/browser/connection.ts +45 -47
  290. package/src/messaging/browser/window-connection.ts +39 -29
  291. package/src/messaging/client-call-metrics.ts +62 -82
  292. package/src/messaging/error.ts +26 -7
  293. package/src/messaging/handler.ts +6 -6
  294. package/src/messaging/node/connection.ts +8 -8
  295. package/src/messaging/proxy-factory.ts +23 -30
  296. package/src/oss-allowlist.ts +3 -3
  297. package/src/payment-protocol.ts +2 -2
  298. package/src/permission.ts +40 -32
  299. package/src/plans.ts +240 -189
  300. package/src/protocol.spec.ts +97 -0
  301. package/src/protocol.ts +556 -258
  302. package/src/snapshot-url.spec.ts +9 -7
  303. package/src/team-subscription-protocol.ts +59 -22
  304. package/src/teams-projects-protocol.ts +43 -12
  305. package/src/typings/globals.ts +4 -4
  306. package/src/usage.ts +71 -0
  307. package/src/util/analytics.ts +46 -24
  308. package/src/util/async-iterator.ts +4 -5
  309. package/src/util/cancelable.ts +3 -3
  310. package/src/util/date-time.ts +8 -8
  311. package/src/util/debug-app.ts +81 -0
  312. package/src/util/deferred.ts +6 -6
  313. package/src/util/disposable.ts +3 -6
  314. package/src/util/event.ts +9 -11
  315. package/src/util/garbage-collected-cache.ts +8 -6
  316. package/src/util/generate-workspace-id.spec.ts +26 -16
  317. package/src/util/generate-workspace-id.ts +460 -454
  318. package/src/util/gitpod-cookie.ts +8 -9
  319. package/src/util/gitpod-host-url.spec.ts +40 -13
  320. package/src/util/gitpod-host-url.ts +57 -33
  321. package/src/util/grpc.ts +90 -1
  322. package/src/util/jaeger-client-types.ts +2 -2
  323. package/src/util/logging.spec.ts +23 -0
  324. package/src/util/logging.ts +60 -42
  325. package/src/util/make-link.ts +6 -7
  326. package/src/util/nice-grpc.ts +93 -0
  327. package/src/util/parse-workspace-id.spec.ts +17 -8
  328. package/src/util/parse-workspace-id.ts +5 -6
  329. package/src/util/queue.spec.ts +27 -25
  330. package/src/util/repeat.ts +1 -1
  331. package/src/util/semaphore.ts +4 -6
  332. package/src/util/skip-if.ts +9 -6
  333. package/src/util/timeutil.spec.ts +40 -14
  334. package/src/util/timeutil.ts +27 -11
  335. package/src/util/tracing.spec.ts +28 -23
  336. package/src/util/tracing.ts +58 -54
  337. package/src/util/workspace-port-authentication.ts +10 -13
  338. package/src/webhook-event.ts +55 -0
  339. package/src/workspace-class.ts +14 -0
  340. package/src/workspace-cluster.ts +34 -20
  341. package/src/workspace-instance.ts +76 -20
  342. package/src/wsready.ts +3 -3
  343. package/data/builtin-theia-plugins.json +0 -372
  344. package/lib/email-protocol.d.ts +0 -49
  345. package/lib/email-protocol.d.ts.map +0 -1
  346. package/lib/email-protocol.js +0 -28
  347. package/lib/email-protocol.js.map +0 -1
  348. package/lib/messaging/connection-error-handler.d.ts +0 -27
  349. package/lib/messaging/connection-error-handler.d.ts.map +0 -1
  350. package/lib/messaging/connection-error-handler.js +0 -34
  351. package/lib/messaging/connection-error-handler.js.map +0 -1
  352. package/lib/theia-plugins.d.ts +0 -11
  353. package/lib/theia-plugins.d.ts.map +0 -1
  354. package/lib/theia-plugins.js.map +0 -1
  355. package/lib/util/safe-promise.d.ts +0 -11
  356. package/lib/util/safe-promise.d.ts.map +0 -1
  357. package/lib/util/safe-promise.js +0 -31
  358. package/lib/util/safe-promise.js.map +0 -1
  359. package/src/email-protocol.ts +0 -66
  360. package/src/messaging/connection-error-handler.ts +0 -62
  361. package/src/util/safe-promise.ts +0 -26
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,9 +246,18 @@ export interface EmailNotificationSettings {
116
246
  }
117
247
 
118
248
  export type IDESettings = {
119
- defaultIde?: string
120
- useDesktopIde?: boolean
121
- defaultDesktopIde?: string
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;
122
261
  }
123
262
 
124
263
  export interface UserPlatform {
@@ -147,12 +286,29 @@ export interface UserFeatureSettings {
147
286
  permanentWSFeatureFlags?: NamedWorkspaceFeatureFlag[];
148
287
  }
149
288
 
289
+ export type BillingTier = "paid" | "free";
290
+
150
291
  /**
151
292
  * The values of this type MUST MATCH enum values in WorkspaceFeatureFlag from ws-manager/client/core_pb.d.ts
152
293
  * If they don't we'll break things during workspace startup.
153
294
  */
154
- export const WorkspaceFeatureFlags = { "full_workspace_backup": undefined, "fixed_resources": undefined };
155
- 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
+ }
156
312
 
157
313
  export interface EnvVarWithValue {
158
314
  name: string;
@@ -165,7 +321,7 @@ export interface ProjectEnvVarWithValue extends EnvVarWithValue {
165
321
  censored: boolean;
166
322
  }
167
323
 
168
- export type ProjectEnvVar = Omit<ProjectEnvVarWithValue, 'value'>;
324
+ export type ProjectEnvVar = Omit<ProjectEnvVarWithValue, "value">;
169
325
 
170
326
  export interface UserEnvVarValue extends EnvVarWithValue {
171
327
  id?: string;
@@ -178,6 +334,44 @@ export interface UserEnvVar extends UserEnvVarValue {
178
334
  }
179
335
 
180
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
+ }
181
375
 
182
376
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
183
377
  export function normalizeRepoPattern(pattern: string) {
@@ -198,7 +392,7 @@ export namespace UserEnvVar {
198
392
  if (repoPattern == "*") {
199
393
  score += 1;
200
394
  }
201
- if (ownerPattern == '*') {
395
+ if (ownerPattern == "*") {
202
396
  score += 2;
203
397
  }
204
398
  if (ownerPattern == "#" || repoPattern == "#") {
@@ -209,20 +403,20 @@ export namespace UserEnvVar {
209
403
 
210
404
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
211
405
  export function filter<T extends UserEnvVarValue>(vars: T[], owner: string, repo: string): T[] {
212
- let result = vars.filter(e => {
406
+ let result = vars.filter((e) => {
213
407
  const [ownerPattern, repoPattern] = splitRepositoryPattern(e.repositoryPattern);
214
- if (ownerPattern !== '*' && ownerPattern !== '#' && (!!owner && ownerPattern !== owner.toLocaleLowerCase())) {
408
+ if (ownerPattern !== "*" && ownerPattern !== "#" && !!owner && ownerPattern !== owner.toLocaleLowerCase()) {
215
409
  return false;
216
410
  }
217
- if (repoPattern !== '*' && repoPattern !== '#' && (!!repo && repoPattern !== repo.toLocaleLowerCase())) {
411
+ if (repoPattern !== "*" && repoPattern !== "#" && !!repo && repoPattern !== repo.toLocaleLowerCase()) {
218
412
  return false;
219
413
  }
220
414
  return true;
221
415
  });
222
416
 
223
417
  const resmap = new Map<string, T[]>();
224
- result.forEach(e => {
225
- const l = (resmap.get(e.name) || []);
418
+ result.forEach((e) => {
419
+ const l = resmap.get(e.name) || [];
226
420
  l.push(e);
227
421
  resmap.set(e.name, l);
228
422
  });
@@ -257,46 +451,107 @@ export namespace UserEnvVar {
257
451
 
258
452
  // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
259
453
  export function splitRepositoryPattern(repositoryPattern: string): string[] {
260
- const patterns = repositoryPattern.split('/');
261
- const repoPattern = patterns.pop() || "";
262
- const ownerPattern = patterns.join('/');
454
+ const patterns = repositoryPattern.split("/");
455
+ const repoPattern = patterns.slice(1).join("/");
456
+ const ownerPattern = patterns[0];
263
457
  return [ownerPattern, repoPattern];
264
458
  }
265
459
  }
266
460
 
267
- 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
+ }
473
+
474
+ export type UserSSHPublicKeyValue = Omit<UserSSHPublicKey, "key" | "userId">;
268
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 {
269
524
  /** Hash value (SHA256) of the token (primary key). */
270
- tokenHash: string
525
+ tokenHash: string;
271
526
 
272
527
  /** Human readable name of the token */
273
- name?: string
528
+ name?: string;
274
529
 
275
530
  /** Token kind */
276
- type: GitpodTokenType
531
+ type: GitpodTokenType;
277
532
 
278
533
  /** The user the token belongs to. */
279
- user: User
534
+ user: User;
280
535
 
281
536
  /** Scopes (e.g. limition to read-only) */
282
- scopes: string[]
537
+ scopes: string[];
283
538
 
284
539
  /** Created timestamp */
285
- created: string
540
+ created: string;
286
541
 
287
542
  // token is deleted on the database and about to be collected by db-sync
288
- deleted?: boolean
543
+ deleted?: boolean;
289
544
  }
290
545
 
291
546
  export enum GitpodTokenType {
292
547
  API_AUTH_TOKEN = 0,
293
- MACHINE_AUTH_TOKEN = 1
548
+ MACHINE_AUTH_TOKEN = 1,
294
549
  }
295
550
 
296
551
  export interface OneTimeSecret {
297
- id: string
552
+ id: string;
298
553
 
299
- value: string
554
+ value: string;
300
555
 
301
556
  expirationTime: string;
302
557
 
@@ -328,13 +583,12 @@ export type IdentityLookup = Pick<Identity, "authProviderId" | "authId">;
328
583
 
329
584
  export namespace Identity {
330
585
  export function is(data: any): data is Identity {
331
- return data.hasOwnProperty('authProviderId')
332
- && data.hasOwnProperty('authId')
333
- && data.hasOwnProperty('authName')
586
+ return (
587
+ data.hasOwnProperty("authProviderId") && data.hasOwnProperty("authId") && data.hasOwnProperty("authName")
588
+ );
334
589
  }
335
590
  export function equals(id1: IdentityLookup, id2: IdentityLookup) {
336
- return id1.authProviderId === id2.authProviderId
337
- && id1.authId === id2.authId
591
+ return id1.authProviderId === id2.authProviderId && id1.authId === id2.authId;
338
592
  }
339
593
  }
340
594
 
@@ -385,6 +639,7 @@ export interface PendingGithubEvent {
385
639
  creationDate: Date;
386
640
  type: string;
387
641
  event: string;
642
+ deleted: boolean;
388
643
  }
389
644
 
390
645
  export interface Snapshot {
@@ -393,19 +648,24 @@ export interface Snapshot {
393
648
  availableTime?: string;
394
649
  originalWorkspaceId: string;
395
650
  bucketId: string;
396
- layoutData?: string;
397
651
  state: SnapshotState;
398
652
  message?: string;
399
653
  }
400
654
 
401
- export type SnapshotState = 'pending' | 'available' | 'error';
402
-
403
- export interface LayoutData {
655
+ export interface VolumeSnapshot {
656
+ id: string;
404
657
  workspaceId: string;
405
- lastUpdatedTime: string;
406
- layoutData: string;
658
+ creationTime: string;
659
+ volumeHandle: string;
407
660
  }
408
661
 
662
+ export interface VolumeSnapshotWithWSType {
663
+ vs: VolumeSnapshot;
664
+ wsType: WorkspaceType;
665
+ }
666
+
667
+ export type SnapshotState = "pending" | "available" | "error";
668
+
409
669
  export interface Workspace {
410
670
  id: string;
411
671
  creationTime: string;
@@ -427,13 +687,13 @@ export interface Workspace {
427
687
  * The resolved, fix name of the workspace image. We only use this
428
688
  * to access the logs during an image build.
429
689
  */
430
- imageNameResolved?: string
690
+ imageNameResolved?: string;
431
691
 
432
692
  /**
433
693
  * The resolved/built fixed named of the base image. This field is only set if the workspace
434
694
  * already has its base image built.
435
695
  */
436
- baseImageNameResolved?: string
696
+ baseImageNameResolved?: string;
437
697
 
438
698
  shareable?: boolean;
439
699
  pinned?: boolean;
@@ -467,20 +727,19 @@ export interface Workspace {
467
727
 
468
728
  export type WorkspaceSoftDeletion = "user" | "gc";
469
729
 
470
- export type WorkspaceType = "regular" | "prebuild" | "probe";
730
+ export type WorkspaceType = "regular" | "prebuild";
471
731
 
472
732
  export namespace Workspace {
473
-
474
733
  export function getFullRepositoryName(ws: Workspace): string | undefined {
475
734
  if (CommitContext.is(ws.context)) {
476
- return ws.context.repository.owner + '/' + ws.context.repository.name
735
+ return ws.context.repository.owner + "/" + ws.context.repository.name;
477
736
  }
478
737
  return undefined;
479
738
  }
480
739
 
481
740
  export function getFullRepositoryUrl(ws: Workspace): string | undefined {
482
741
  if (CommitContext.is(ws.context)) {
483
- return `https://${ws.context.repository.host}/${getFullRepositoryName(ws)}`
742
+ return `https://${ws.context.repository.host}/${getFullRepositoryName(ws)}`;
484
743
  }
485
744
  return undefined;
486
745
  }
@@ -514,59 +773,58 @@ export namespace Workspace {
514
773
  }
515
774
  }
516
775
 
517
- export interface PreparePluginUploadParams {
518
- fullPluginName: string;
519
- }
520
-
521
- export interface ResolvePluginsParams {
522
- config?: WorkspaceConfig
523
- builtins?: ResolvedPlugins
524
- vsxRegistryUrl?: string
525
- }
526
-
527
- export interface InstallPluginsParams {
528
- pluginIds: string[]
529
- }
530
-
531
- export interface UninstallPluginParams {
532
- pluginId: string;
533
- }
534
-
535
776
  export interface GuessGitTokenScopesParams {
536
- host: string
537
- repoUrl: string
538
- gitCommand: string
539
- currentToken: GitToken
777
+ host: string;
778
+ repoUrl: string;
779
+ gitCommand: string;
780
+ currentToken: GitToken;
540
781
  }
541
782
 
542
783
  export interface GitToken {
543
- token: string
544
- user: string
545
- scopes: string[]
784
+ token: string;
785
+ user: string;
786
+ scopes: string[];
546
787
  }
547
788
 
548
789
  export interface GuessedGitTokenScopes {
549
- message?: string
550
- scopes?: string[]
790
+ message?: string;
791
+ scopes?: string[];
551
792
  }
552
793
 
553
- export type ResolvedPluginKind = 'user' | 'workspace' | 'builtin';
794
+ export interface VSCodeConfig {
795
+ extensions?: string[];
796
+ }
554
797
 
555
- export interface ResolvedPlugins {
556
- [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";
557
812
  }
558
813
 
559
- export interface ResolvedPlugin {
560
- fullPluginName: string;
814
+ export interface RepositoryCloneInformation {
561
815
  url: string;
562
- kind: ResolvedPluginKind;
816
+ checkoutLocation?: string;
563
817
  }
564
818
 
565
- export interface VSCodeConfig {
566
- extensions?: string[];
819
+ export interface CoreDumpConfig {
820
+ enabled?: boolean;
821
+ softLimit?: number;
822
+ hardLimit?: number;
567
823
  }
568
824
 
569
825
  export interface WorkspaceConfig {
826
+ mainConfiguration?: string;
827
+ additionalRepositories?: RepositoryCloneInformation[];
570
828
  image?: ImageConfig;
571
829
  ports?: PortConfig[];
572
830
  tasks?: TaskConfig[];
@@ -575,6 +833,8 @@ export interface WorkspaceConfig {
575
833
  gitConfig?: { [config: string]: string };
576
834
  github?: GithubAppConfig;
577
835
  vscode?: VSCodeConfig;
836
+ jetbrains?: JetBrainsConfig;
837
+ coreDump?: CoreDumpConfig;
578
838
 
579
839
  /** deprecated. Enabled by default **/
580
840
  experimentalNetwork?: boolean;
@@ -583,13 +843,12 @@ export interface WorkspaceConfig {
583
843
  * Where the config object originates from.
584
844
  *
585
845
  * repo - from the repository
586
- * project-db - from the "Project" stored in the database
587
846
  * definitly-gp - from github.com/gitpod-io/definitely-gp
588
847
  * derived - computed based on analyzing the repository
589
848
  * additional-content - config comes from additional content, usually provided through the project's configuration
590
849
  * default - our static catch-all default config
591
850
  */
592
- _origin?: 'repo' | 'project-db' | 'definitely-gp' | 'derived' | 'additional-content' | 'default';
851
+ _origin?: "repo" | "definitely-gp" | "derived" | "additional-content" | "default";
593
852
 
594
853
  /**
595
854
  * Set of automatically infered feature flags. That's not something the user can set, but
@@ -599,34 +858,33 @@ export interface WorkspaceConfig {
599
858
  }
600
859
 
601
860
  export interface GithubAppConfig {
602
- prebuilds?: GithubAppPrebuildConfig
861
+ prebuilds?: GithubAppPrebuildConfig;
603
862
  }
604
863
  export interface GithubAppPrebuildConfig {
605
- master?: boolean
606
- branches?: boolean
607
- pullRequests?: boolean
608
- pullRequestsFromForks?: boolean
609
- addCheck?: boolean | 'prevent-merge-on-error'
610
- addBadge?: boolean
611
- addLabel?: boolean | string
612
- addComment?: boolean
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;
613
872
  }
614
873
  export namespace GithubAppPrebuildConfig {
615
874
  export function is(obj: boolean | GithubAppPrebuildConfig): obj is GithubAppPrebuildConfig {
616
- return !(typeof obj === 'boolean');
875
+ return !(typeof obj === "boolean");
617
876
  }
618
877
  }
619
878
 
620
879
  export type WorkspaceImageSource = WorkspaceImageSourceDocker | WorkspaceImageSourceReference;
621
880
  export interface WorkspaceImageSourceDocker {
622
- dockerFilePath: string
623
- dockerFileHash: string
624
- dockerFileSource?: Commit
881
+ dockerFilePath: string;
882
+ dockerFileHash: string;
883
+ dockerFileSource?: Commit;
625
884
  }
626
885
  export namespace WorkspaceImageSourceDocker {
627
886
  export function is(obj: object): obj is WorkspaceImageSourceDocker {
628
- return 'dockerFileHash' in obj
629
- && 'dockerFilePath' in obj;
887
+ return "dockerFileHash" in obj && "dockerFilePath" in obj;
630
888
  }
631
889
  }
632
890
  export interface WorkspaceImageSourceReference {
@@ -635,21 +893,23 @@ export interface WorkspaceImageSourceReference {
635
893
  }
636
894
  export namespace WorkspaceImageSourceReference {
637
895
  export function is(obj: object): obj is WorkspaceImageSourceReference {
638
- return 'baseImageResolved' in obj;
896
+ return "baseImageResolved" in obj;
639
897
  }
640
898
  }
641
899
 
642
- export type PrebuiltWorkspaceState
900
+ export type PrebuiltWorkspaceState =
643
901
  // the prebuild is queued and may start at anytime
644
- = "queued"
902
+ | "queued"
645
903
  // the workspace prebuild is currently running (i.e. there's a workspace pod deployed)
646
904
  | "building"
647
- // the prebuild failed due to some issue with the system (e.g. missed a message, could not start workspace)
905
+ // the prebuild was aborted
648
906
  | "aborted"
649
907
  // the prebuild timed out
650
908
  | "timeout"
651
- // the prebuild has finished and a snapshot is available
652
- | "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";
653
913
 
654
914
  export interface PrebuiltWorkspace {
655
915
  id: string;
@@ -660,13 +920,16 @@ export interface PrebuiltWorkspace {
660
920
  buildWorkspaceId: string;
661
921
  creationTime: string;
662
922
  state: PrebuiltWorkspaceState;
923
+ statusVersion: number;
663
924
  error?: string;
664
925
  snapshot?: string;
665
926
  }
666
927
 
667
928
  export namespace PrebuiltWorkspace {
668
929
  export function isDone(pws: PrebuiltWorkspace) {
669
- 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
+ );
670
933
  }
671
934
 
672
935
  export function isAvailable(pws: PrebuiltWorkspace) {
@@ -685,18 +948,22 @@ export interface PrebuiltWorkspaceUpdatable {
685
948
  repo: string;
686
949
  isResolved: boolean;
687
950
  installationId: string;
951
+ /**
952
+ * the commitSHA of the commit that triggered the prebuild
953
+ */
954
+ commitSHA?: string;
688
955
  issue?: string;
689
956
  contextUrl?: string;
690
957
  }
691
958
 
692
959
  export interface WhitelistedRepository {
693
- url: string
694
- name: string
695
- description?: string
696
- avatar?: string
960
+ url: string;
961
+ name: string;
962
+ description?: string;
963
+ avatar?: string;
697
964
  }
698
965
 
699
- export type PortOnOpen = 'open-browser' | 'open-preview' | 'notify' | 'ignore';
966
+ export type PortOnOpen = "open-browser" | "open-preview" | "notify" | "ignore";
700
967
 
701
968
  export interface PortConfig {
702
969
  port: number;
@@ -707,7 +974,7 @@ export interface PortConfig {
707
974
  }
708
975
  export namespace PortConfig {
709
976
  export function is(config: any): config is PortConfig {
710
- return config && ('port' in config) && (typeof config.port === 'number');
977
+ return config && "port" in config && typeof config.port === "number";
711
978
  }
712
979
  }
713
980
 
@@ -717,7 +984,7 @@ export interface PortRangeConfig {
717
984
  }
718
985
  export namespace PortRangeConfig {
719
986
  export function is(config: any): config is PortRangeConfig {
720
- 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);
721
988
  }
722
989
  }
723
990
 
@@ -728,32 +995,31 @@ export interface TaskConfig {
728
995
  prebuild?: string;
729
996
  command?: string;
730
997
  env?: { [env: string]: any };
731
- openIn?: 'bottom' | 'main' | 'left' | 'right';
732
- 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";
733
1000
  }
734
1001
 
735
1002
  export namespace TaskConfig {
736
1003
  export function is(config: any): config is TaskConfig {
737
- return config
738
- && ('command' in config || 'init' in config || 'before' in config);
1004
+ return config && ("command" in config || "init" in config || "before" in config);
739
1005
  }
740
1006
  }
741
1007
 
742
1008
  export namespace WorkspaceImageBuild {
743
- export type Phase = 'BaseImage' | 'GitpodLayer' | 'Error' | 'Done';
1009
+ export type Phase = "BaseImage" | "GitpodLayer" | "Error" | "Done";
744
1010
  export interface StateInfo {
745
- phase: Phase
746
- currentStep?: number
747
- maxSteps?: number
1011
+ phase: Phase;
1012
+ currentStep?: number;
1013
+ maxSteps?: number;
748
1014
  }
749
1015
  export interface LogContent {
750
- text: string
751
- upToLine?: number
752
- isDiff?: boolean
1016
+ text: string;
1017
+ upToLine?: number;
1018
+ isDiff?: boolean;
753
1019
  }
754
1020
  export type LogCallback = (info: StateInfo, content: LogContent | undefined) => void;
755
1021
  export namespace LogLine {
756
- export const DELIMITER = '\r\n';
1022
+ export const DELIMITER = "\r\n";
757
1023
  export const DELIMITER_REGEX = /\r?\n/;
758
1024
  }
759
1025
  }
@@ -762,20 +1028,18 @@ export type ImageConfig = ImageConfigString | ImageConfigFile;
762
1028
  export type ImageConfigString = string;
763
1029
  export namespace ImageConfigString {
764
1030
  export function is(config: ImageConfig | undefined): config is ImageConfigString {
765
- return typeof config === 'string';
1031
+ return typeof config === "string";
766
1032
  }
767
-
768
1033
  }
769
1034
  export interface ImageConfigFile {
770
1035
  // Path to the Dockerfile relative to repository root
771
- file: string,
1036
+ file: string;
772
1037
  // Path to the docker build context relative to repository root
773
- context?: string
1038
+ context?: string;
774
1039
  }
775
1040
  export namespace ImageConfigFile {
776
1041
  export function is(config: ImageConfig | undefined): config is ImageConfigFile {
777
- return typeof config === 'object'
778
- && 'file' in config;
1042
+ return typeof config === "object" && "file" in config;
779
1043
  }
780
1044
  }
781
1045
  export interface ExternalImageConfigFile extends ImageConfigFile {
@@ -783,14 +1047,13 @@ export interface ExternalImageConfigFile extends ImageConfigFile {
783
1047
  }
784
1048
  export namespace ExternalImageConfigFile {
785
1049
  export function is(config: any | undefined): config is ExternalImageConfigFile {
786
- return typeof config === 'object'
787
- && 'file' in config
788
- && 'externalSource' in config;
1050
+ return typeof config === "object" && "file" in config && "externalSource" in config;
789
1051
  }
790
1052
  }
791
1053
 
792
1054
  export interface WorkspaceContext {
793
1055
  title: string;
1056
+ ref?: string;
794
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. */
795
1058
  normalizedContextURL?: string;
796
1059
  forceCreateNewWorkspace?: boolean;
@@ -799,8 +1062,7 @@ export interface WorkspaceContext {
799
1062
 
800
1063
  export namespace WorkspaceContext {
801
1064
  export function is(context: any): context is WorkspaceContext {
802
- return context
803
- && 'title' in context;
1065
+ return context && "title" in context;
804
1066
  }
805
1067
  }
806
1068
 
@@ -809,22 +1071,17 @@ export interface WithSnapshot {
809
1071
  }
810
1072
  export namespace WithSnapshot {
811
1073
  export function is(context: any): context is WithSnapshot {
812
- return context
813
- && 'snapshotBucketId' in context;
1074
+ return context && "snapshotBucketId" in context;
814
1075
  }
815
1076
  }
816
1077
 
817
- export interface WithPrebuild {
818
- snapshotBucketId: string;
1078
+ export interface WithPrebuild extends WithSnapshot {
819
1079
  prebuildWorkspaceId: string;
820
1080
  wasPrebuilt: true;
821
1081
  }
822
1082
  export namespace WithPrebuild {
823
1083
  export function is(context: any): context is WithPrebuild {
824
- return context
825
- && 'snapshotBucketId' in 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,33 +1144,28 @@ 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
- export interface WithEnvvarsContext extends WorkspaceContext {
895
- envvars: EnvVarWithValue[];
1151
+ export interface WithReferrerContext extends WorkspaceContext {
1152
+ referrer: string;
1153
+ referrerIde?: string;
896
1154
  }
897
1155
 
898
- export namespace WithEnvvarsContext {
899
- export function is(context: any): context is WithEnvvarsContext {
900
- return context
901
- && 'envvars' in context
1156
+ export namespace WithReferrerContext {
1157
+ export function is(context: any): context is WithReferrerContext {
1158
+ return context && "referrer" in context;
902
1159
  }
903
1160
  }
904
1161
 
905
- export interface WorkspaceProbeContext extends WorkspaceContext {
906
- responseURL: string
907
- responseToken: string
1162
+ export interface WithEnvvarsContext extends WorkspaceContext {
1163
+ envvars: EnvVarWithValue[];
908
1164
  }
909
1165
 
910
- export namespace WorkspaceProbeContext {
911
- export function is(context: any): context is WorkspaceProbeContext {
912
- return context
913
- && 'responseURL' in context
914
- && 'responseToken' in context;
1166
+ export namespace WithEnvvarsContext {
1167
+ export function is(context: any): context is WithEnvvarsContext {
1168
+ return context && "envvars" in context;
915
1169
  }
916
1170
  }
917
1171
 
@@ -923,32 +1177,30 @@ export namespace RefType {
923
1177
  }
924
1178
  // This fallback is meant to handle the cases where (for historic reasons) ref is present but refType is missing
925
1179
  return commit.refType || "branch";
926
- }
1180
+ };
927
1181
  }
928
1182
 
929
1183
  export interface Commit {
930
- repository: Repository
931
- revision: string
1184
+ repository: Repository;
1185
+ revision: string;
932
1186
 
933
1187
  // Might contain either a branch or a tag (determined by refType)
934
- ref?: string
1188
+ ref?: string;
935
1189
 
936
1190
  // refType is only set if ref is present (and not for old workspaces, before this feature was added)
937
- refType?: RefType
1191
+ refType?: RefType;
938
1192
  }
939
1193
 
940
1194
  export interface AdditionalContentContext extends WorkspaceContext {
941
-
942
1195
  /**
943
1196
  * utf-8 encoded contents that will be copied on top of the workspace's filesystem
944
1197
  */
945
- additionalFiles: {[filePath: string]: string};
946
-
1198
+ additionalFiles: { [filePath: string]: string };
947
1199
  }
948
1200
 
949
1201
  export namespace AdditionalContentContext {
950
1202
  export function is(ctx: any): ctx is AdditionalContentContext {
951
- return 'additionalFiles' in ctx;
1203
+ return "additionalFiles" in ctx;
952
1204
  }
953
1205
 
954
1206
  export function hasDockerConfig(ctx: any, config: WorkspaceConfig): boolean {
@@ -956,16 +1208,59 @@ export namespace AdditionalContentContext {
956
1208
  }
957
1209
  }
958
1210
 
959
- 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 {
960
1222
  /** @deprecated Moved to .repository.cloneUrl, left here for backwards-compatibility for old workspace contextes in the DB */
961
- 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;
962
1259
  }
963
1260
 
964
1261
  export namespace CommitContext {
965
1262
  export function is(commit: any): commit is CommitContext {
966
- return WorkspaceContext.is(commit)
967
- && 'repository' in commit
968
- && 'revision' in commit
1263
+ return WorkspaceContext.is(commit) && "repository" in commit && "revision" in commit;
969
1264
  }
970
1265
  }
971
1266
 
@@ -973,17 +1268,14 @@ export interface PullRequestContext extends CommitContext {
973
1268
  nr: number;
974
1269
  ref: string;
975
1270
  base: {
976
- repository: Repository
977
- ref: string
978
- }
1271
+ repository: Repository;
1272
+ ref: string;
1273
+ };
979
1274
  }
980
1275
 
981
1276
  export namespace PullRequestContext {
982
1277
  export function is(ctx: any): ctx is PullRequestContext {
983
- return CommitContext.is(ctx)
984
- && 'nr' in ctx
985
- && 'ref' in ctx
986
- && 'base' in ctx
1278
+ return CommitContext.is(ctx) && "nr" in ctx && "ref" in ctx && "base" in ctx;
987
1279
  }
988
1280
  }
989
1281
 
@@ -995,10 +1287,7 @@ export interface IssueContext extends CommitContext {
995
1287
 
996
1288
  export namespace IssueContext {
997
1289
  export function is(ctx: any): ctx is IssueContext {
998
- return CommitContext.is(ctx)
999
- && 'nr' in ctx
1000
- && 'ref' in ctx
1001
- && 'localBranch' in ctx
1290
+ return CommitContext.is(ctx) && "nr" in ctx && "ref" in ctx && "localBranch" in ctx;
1002
1291
  }
1003
1292
  }
1004
1293
 
@@ -1009,9 +1298,7 @@ export interface NavigatorContext extends CommitContext {
1009
1298
 
1010
1299
  export namespace NavigatorContext {
1011
1300
  export function is(ctx: any): ctx is NavigatorContext {
1012
- return CommitContext.is(ctx)
1013
- && 'path' in ctx
1014
- && 'isFile' in ctx
1301
+ return CommitContext.is(ctx) && "path" in ctx && "isFile" in ctx;
1015
1302
  }
1016
1303
  }
1017
1304
 
@@ -1020,6 +1307,8 @@ export interface Repository {
1020
1307
  owner: string;
1021
1308
  name: string;
1022
1309
  cloneUrl: string;
1310
+ /* Optional kind to differentiate between repositories of orgs/groups/projects and personal repos. */
1311
+ repoKind?: string;
1023
1312
  description?: string;
1024
1313
  avatarUrl?: string;
1025
1314
  webUrl?: string;
@@ -1028,8 +1317,8 @@ export interface Repository {
1028
1317
  private?: boolean;
1029
1318
  fork?: {
1030
1319
  // The direct parent of this fork
1031
- parent: Repository
1032
- }
1320
+ parent: Repository;
1321
+ };
1033
1322
  }
1034
1323
  export interface Branch {
1035
1324
  name: string;
@@ -1054,21 +1343,19 @@ export namespace Repository {
1054
1343
  export interface WorkspaceInstancePortsChangedEvent {
1055
1344
  type: "PortsChanged";
1056
1345
  instanceID: string;
1057
- portsOpened: number[]
1058
- portsClosed: number[]
1346
+ portsOpened: number[];
1347
+ portsClosed: number[];
1059
1348
  }
1060
1349
 
1061
1350
  export namespace WorkspaceInstancePortsChangedEvent {
1062
-
1063
1351
  export function is(data: any): data is WorkspaceInstancePortsChangedEvent {
1064
1352
  return data && data.type == "PortsChanged";
1065
1353
  }
1066
-
1067
1354
  }
1068
1355
 
1069
1356
  export interface WorkspaceInfo {
1070
- workspace: Workspace
1071
- latestInstance?: WorkspaceInstance
1357
+ workspace: Workspace;
1358
+ latestInstance?: WorkspaceInstance;
1072
1359
  }
1073
1360
 
1074
1361
  export namespace WorkspaceInfo {
@@ -1084,35 +1371,25 @@ export interface WorkspaceCreationResult {
1084
1371
  workspaceURL?: string;
1085
1372
  existingWorkspaces?: WorkspaceInfo[];
1086
1373
  runningWorkspacePrebuild?: {
1087
- prebuildID: string
1088
- workspaceID: string
1089
- instanceID: string
1090
- starting: RunningWorkspacePrebuildStarting
1091
- sameCluster: boolean
1092
- }
1374
+ prebuildID: string;
1375
+ workspaceID: string;
1376
+ instanceID: string;
1377
+ starting: RunningWorkspacePrebuildStarting;
1378
+ sameCluster: boolean;
1379
+ };
1093
1380
  runningPrebuildWorkspaceID?: string;
1094
1381
  }
1095
- export type RunningWorkspacePrebuildStarting = 'queued' | 'starting' | 'running';
1096
-
1097
- export enum CreateWorkspaceMode {
1098
- // Default returns a running prebuild if there is any, otherwise creates a new workspace (using a prebuild if one is available)
1099
- Default = 'default',
1100
- // 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.
1101
- ForceNew = 'force-new',
1102
- // UsePrebuild polls the database waiting for a currently running prebuild to become available. This mode exists to handle the db-sync delay.
1103
- UsePrebuild = 'use-prebuild',
1104
- // SelectIfRunning returns a list of currently running workspaces for the context URL if there are any, otherwise falls back to Default mode
1105
- SelectIfRunning = 'select-if-running',
1106
- }
1382
+ export type RunningWorkspacePrebuildStarting = "queued" | "starting" | "running";
1107
1383
 
1108
1384
  export namespace WorkspaceCreationResult {
1109
1385
  export function is(data: any): data is WorkspaceCreationResult {
1110
- return data && (
1111
- 'createdWorkspaceId' in data
1112
- || 'existingWorkspaces' in data
1113
- || 'runningWorkspacePrebuild' in data
1114
- || 'runningPrebuildWorkspaceID' in data
1115
- )
1386
+ return (
1387
+ data &&
1388
+ ("createdWorkspaceId" in data ||
1389
+ "existingWorkspaces" in data ||
1390
+ "runningWorkspacePrebuild" in data ||
1391
+ "runningPrebuildWorkspaceID" in data)
1392
+ );
1116
1393
  }
1117
1394
  }
1118
1395
 
@@ -1146,7 +1423,7 @@ export interface AuthProviderInfo {
1146
1423
  readonly default: string[];
1147
1424
  readonly publicRepo: string[];
1148
1425
  readonly privateRepo: string[];
1149
- }
1426
+ };
1150
1427
  }
1151
1428
 
1152
1429
  export interface AuthProviderEntry {
@@ -1158,6 +1435,8 @@ export interface AuthProviderEntry {
1158
1435
  readonly status: AuthProviderEntry.Status;
1159
1436
 
1160
1437
  readonly oauth: OAuth2Config;
1438
+ /** A random string that is to change whenever oauth changes (enforced on DB level) */
1439
+ readonly oauthRevision?: string;
1161
1440
  }
1162
1441
 
1163
1442
  export interface OAuth2Config {
@@ -1170,23 +1449,27 @@ export interface OAuth2Config {
1170
1449
  readonly scopeSeparator?: string;
1171
1450
 
1172
1451
  readonly settingsUrl?: string;
1173
- readonly authorizationParams?: { [key: string]: string }
1452
+ readonly authorizationParams?: { [key: string]: string };
1174
1453
  readonly configURL?: string;
1175
1454
  }
1176
1455
 
1177
1456
  export namespace AuthProviderEntry {
1178
1457
  export type Type = "GitHub" | "GitLab" | string;
1179
1458
  export type Status = "pending" | "verified";
1180
- export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type"> & { clientId?: string, clientSecret?: string };
1181
- 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">;
1182
1465
  export function redact(entry: AuthProviderEntry): AuthProviderEntry {
1183
1466
  return {
1184
1467
  ...entry,
1185
1468
  oauth: {
1186
1469
  ...entry.oauth,
1187
- clientSecret: "redacted"
1188
- }
1189
- }
1470
+ clientSecret: "redacted",
1471
+ },
1472
+ };
1190
1473
  }
1191
1474
  }
1192
1475
 
@@ -1230,3 +1513,18 @@ export interface Terms {
1230
1513
  readonly content: string;
1231
1514
  readonly formElements?: object;
1232
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
+ }