@gitpod/gitpod-protocol 0.1.5-update-ovsx.0 → 0.1.5-update-yarnlock.0

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 (455) hide show
  1. package/data/gitpod-schema.json +159 -25
  2. package/lib/accounting-protocol.d.ts +165 -0
  3. package/lib/accounting-protocol.d.ts.map +1 -0
  4. package/lib/accounting-protocol.js +120 -0
  5. package/lib/accounting-protocol.js.map +1 -0
  6. package/lib/admin-protocol.d.ts +51 -6
  7. package/lib/admin-protocol.d.ts.map +1 -1
  8. package/lib/admin-protocol.js +17 -2
  9. package/lib/admin-protocol.js.map +1 -1
  10. package/lib/analytics.d.ts +44 -0
  11. package/lib/analytics.d.ts.map +1 -0
  12. package/lib/analytics.js +10 -0
  13. package/lib/analytics.js.map +1 -0
  14. package/lib/attribution.d.ts +25 -0
  15. package/lib/attribution.d.ts.map +1 -0
  16. package/lib/attribution.js +58 -0
  17. package/lib/attribution.js.map +1 -0
  18. package/lib/auth.d.ts +25 -0
  19. package/lib/auth.d.ts.map +1 -0
  20. package/lib/auth.js +16 -0
  21. package/lib/auth.js.map +1 -0
  22. package/lib/billing-mode.d.ts +45 -0
  23. package/lib/billing-mode.d.ts.map +1 -0
  24. package/lib/billing-mode.js +44 -0
  25. package/lib/billing-mode.js.map +1 -0
  26. package/lib/blocked-repositories-protocol.d.ts +13 -0
  27. package/lib/blocked-repositories-protocol.d.ts.map +1 -0
  28. package/lib/blocked-repositories-protocol.js +8 -0
  29. package/lib/blocked-repositories-protocol.js.map +1 -0
  30. package/lib/context-url.d.ts +30 -0
  31. package/lib/context-url.d.ts.map +1 -0
  32. package/lib/context-url.js +100 -0
  33. package/lib/context-url.js.map +1 -0
  34. package/lib/context-url.spec.d.ts +12 -0
  35. package/lib/context-url.spec.d.ts.map +1 -0
  36. package/lib/context-url.spec.js +81 -0
  37. package/lib/context-url.spec.js.map +1 -0
  38. package/lib/encryption/container-module.d.ts +2 -2
  39. package/lib/encryption/container-module.d.ts.map +1 -1
  40. package/lib/encryption/container-module.js +8 -6
  41. package/lib/encryption/container-module.js.map +1 -1
  42. package/lib/encryption/encryption-engine.d.ts +2 -2
  43. package/lib/encryption/encryption-engine.d.ts.map +1 -1
  44. package/lib/encryption/encryption-engine.js +28 -28
  45. package/lib/encryption/encryption-engine.js.map +1 -1
  46. package/lib/encryption/encryption-engine.spec.d.ts +3 -3
  47. package/lib/encryption/encryption-engine.spec.d.ts.map +1 -1
  48. package/lib/encryption/encryption-engine.spec.js +32 -39
  49. package/lib/encryption/encryption-engine.spec.js.map +1 -1
  50. package/lib/encryption/encryption-service.d.ts +2 -2
  51. package/lib/encryption/encryption-service.d.ts.map +1 -1
  52. package/lib/encryption/encryption-service.js +33 -46
  53. package/lib/encryption/encryption-service.js.map +1 -1
  54. package/lib/encryption/key-provider.d.ts +3 -3
  55. package/lib/encryption/key-provider.d.ts.map +1 -1
  56. package/lib/encryption/key-provider.js +34 -40
  57. package/lib/encryption/key-provider.js.map +1 -1
  58. package/lib/env.d.ts +2 -8
  59. package/lib/env.d.ts.map +1 -1
  60. package/lib/env.js +10 -29
  61. package/lib/env.js.map +1 -1
  62. package/lib/experiments/always-default.d.ts +8 -0
  63. package/lib/experiments/always-default.d.ts.map +1 -0
  64. package/lib/experiments/always-default.js +20 -0
  65. package/lib/experiments/always-default.js.map +1 -0
  66. package/lib/experiments/configcat-server.d.ts +10 -0
  67. package/lib/experiments/configcat-server.d.ts.map +1 -0
  68. package/lib/experiments/configcat-server.js +37 -0
  69. package/lib/experiments/configcat-server.js.map +1 -0
  70. package/lib/experiments/configcat.d.ts +21 -0
  71. package/lib/experiments/configcat.d.ts.map +1 -0
  72. package/lib/experiments/configcat.js +51 -0
  73. package/lib/experiments/configcat.js.map +1 -0
  74. package/lib/experiments/types.d.ts +22 -0
  75. package/lib/experiments/types.d.ts.map +1 -0
  76. package/lib/experiments/types.js +10 -0
  77. package/lib/experiments/types.js.map +1 -0
  78. package/lib/frontend-dashboard-service.d.ts +99 -0
  79. package/lib/frontend-dashboard-service.d.ts.map +1 -0
  80. package/lib/frontend-dashboard-service.js +55 -0
  81. package/lib/frontend-dashboard-service.js.map +1 -0
  82. package/lib/gitpod-file-parser.d.ts +2 -2
  83. package/lib/gitpod-file-parser.d.ts.map +1 -1
  84. package/lib/gitpod-file-parser.js +29 -44
  85. package/lib/gitpod-file-parser.js.map +1 -1
  86. package/lib/gitpod-file-parser.spec.d.ts +2 -2
  87. package/lib/gitpod-file-parser.spec.js +147 -144
  88. package/lib/gitpod-file-parser.spec.js.map +1 -1
  89. package/lib/gitpod-service.d.ts +290 -50
  90. package/lib/gitpod-service.d.ts.map +1 -1
  91. package/lib/gitpod-service.js +288 -123
  92. package/lib/gitpod-service.js.map +1 -1
  93. package/lib/headless-workspace-log.d.ts +11 -13
  94. package/lib/headless-workspace-log.d.ts.map +1 -1
  95. package/lib/headless-workspace-log.js +8 -9
  96. package/lib/headless-workspace-log.js.map +1 -1
  97. package/lib/ide-frontend-service.d.ts +26 -0
  98. package/lib/ide-frontend-service.d.ts.map +1 -0
  99. package/lib/ide-frontend-service.js +8 -0
  100. package/lib/ide-frontend-service.js.map +1 -0
  101. package/lib/ide-protocol.d.ts +126 -0
  102. package/lib/ide-protocol.d.ts.map +1 -0
  103. package/lib/ide-protocol.js +18 -0
  104. package/lib/ide-protocol.js.map +1 -0
  105. package/lib/index.d.ts +18 -12
  106. package/lib/index.d.ts.map +1 -1
  107. package/lib/index.js +28 -13
  108. package/lib/index.js.map +1 -1
  109. package/lib/installation-admin-protocol.d.ts +30 -0
  110. package/lib/installation-admin-protocol.d.ts.map +1 -0
  111. package/lib/installation-admin-protocol.js +31 -0
  112. package/lib/installation-admin-protocol.js.map +1 -0
  113. package/lib/license-protocol.d.ts +9 -2
  114. package/lib/license-protocol.d.ts.map +1 -1
  115. package/lib/license-protocol.js +3 -2
  116. package/lib/license-protocol.js.map +1 -1
  117. package/lib/messaging/browser/connection.d.ts +6 -4
  118. package/lib/messaging/browser/connection.d.ts.map +1 -1
  119. package/lib/messaging/browser/connection.js +188 -48
  120. package/lib/messaging/browser/connection.js.map +1 -1
  121. package/lib/messaging/browser/window-connection.d.ts +9 -4
  122. package/lib/messaging/browser/window-connection.d.ts.map +1 -1
  123. package/lib/messaging/browser/window-connection.js +48 -59
  124. package/lib/messaging/browser/window-connection.js.map +1 -1
  125. package/lib/messaging/client-call-metrics.d.ts +21 -0
  126. package/lib/messaging/client-call-metrics.d.ts.map +1 -0
  127. package/lib/messaging/client-call-metrics.js +95 -0
  128. package/lib/messaging/client-call-metrics.js.map +1 -0
  129. package/lib/messaging/error.d.ts +18 -4
  130. package/lib/messaging/error.d.ts.map +1 -1
  131. package/lib/messaging/error.js +38 -7
  132. package/lib/messaging/error.js.map +1 -1
  133. package/lib/messaging/handler.d.ts +10 -0
  134. package/lib/messaging/handler.d.ts.map +1 -1
  135. package/lib/messaging/handler.js +2 -1
  136. package/lib/messaging/handler.js.map +1 -1
  137. package/lib/messaging/node/connection.d.ts +1 -17
  138. package/lib/messaging/node/connection.d.ts.map +1 -1
  139. package/lib/messaging/node/connection.js +24 -59
  140. package/lib/messaging/node/connection.js.map +1 -1
  141. package/lib/messaging/proxy-factory.d.ts +3 -1
  142. package/lib/messaging/proxy-factory.d.ts.map +1 -1
  143. package/lib/messaging/proxy-factory.js +76 -162
  144. package/lib/messaging/proxy-factory.js.map +1 -1
  145. package/lib/oss-allowlist.d.ts +14 -0
  146. package/lib/oss-allowlist.d.ts.map +1 -0
  147. package/lib/oss-allowlist.js +8 -0
  148. package/lib/oss-allowlist.js.map +1 -0
  149. package/lib/payment-protocol.d.ts +18 -0
  150. package/lib/payment-protocol.d.ts.map +1 -0
  151. package/lib/payment-protocol.js +13 -0
  152. package/lib/payment-protocol.js.map +1 -0
  153. package/lib/permission.d.ts +26 -15
  154. package/lib/permission.d.ts.map +1 -1
  155. package/lib/permission.js +50 -36
  156. package/lib/permission.js.map +1 -1
  157. package/lib/plans.d.ts +213 -0
  158. package/lib/plans.d.ts.map +1 -0
  159. package/lib/plans.js +625 -0
  160. package/lib/plans.js.map +1 -0
  161. package/lib/protocol.d.ts +338 -111
  162. package/lib/protocol.d.ts.map +1 -1
  163. package/lib/protocol.js +422 -201
  164. package/lib/protocol.js.map +1 -1
  165. package/lib/protocol.spec.d.ts +7 -0
  166. package/lib/protocol.spec.d.ts.map +1 -0
  167. package/lib/protocol.spec.js +127 -0
  168. package/lib/protocol.spec.js.map +1 -0
  169. package/lib/snapshot-url.d.ts +14 -0
  170. package/lib/snapshot-url.d.ts.map +1 -0
  171. package/lib/snapshot-url.js +26 -0
  172. package/lib/snapshot-url.js.map +1 -0
  173. package/lib/snapshot-url.spec.d.ts +7 -0
  174. package/lib/snapshot-url.spec.d.ts.map +1 -0
  175. package/lib/snapshot-url.spec.js +41 -0
  176. package/lib/snapshot-url.spec.js.map +1 -0
  177. package/lib/team-subscription-protocol.d.ts +93 -0
  178. package/lib/team-subscription-protocol.d.ts.map +1 -0
  179. package/lib/team-subscription-protocol.js +82 -0
  180. package/lib/team-subscription-protocol.js.map +1 -0
  181. package/lib/teams-projects-protocol.d.ts +136 -0
  182. package/lib/teams-projects-protocol.d.ts.map +1 -0
  183. package/lib/teams-projects-protocol.js +41 -0
  184. package/lib/teams-projects-protocol.js.map +1 -0
  185. package/lib/typings/globals.d.ts +8 -3
  186. package/lib/typings/globals.d.ts.map +1 -1
  187. package/lib/typings/globals.js +2 -2
  188. package/lib/usage.d.ts +73 -0
  189. package/lib/usage.d.ts.map +1 -0
  190. package/lib/usage.js +20 -0
  191. package/lib/usage.js.map +1 -0
  192. package/lib/util/analytics.d.ts +8 -0
  193. package/lib/util/analytics.d.ts.map +1 -0
  194. package/lib/util/analytics.js +88 -0
  195. package/lib/util/analytics.js.map +1 -0
  196. package/lib/util/async-iterator.d.ts +2 -2
  197. package/lib/util/async-iterator.d.ts.map +1 -1
  198. package/lib/util/async-iterator.js +60 -137
  199. package/lib/util/async-iterator.js.map +1 -1
  200. package/lib/util/cancelable.d.ts +2 -2
  201. package/lib/util/cancelable.js +20 -61
  202. package/lib/util/cancelable.js.map +1 -1
  203. package/lib/util/date-time.d.ts +2 -2
  204. package/lib/util/date-time.js +14 -13
  205. package/lib/util/date-time.js.map +1 -1
  206. package/lib/util/debug-app.d.ts +25 -0
  207. package/lib/util/debug-app.d.ts.map +1 -0
  208. package/lib/util/debug-app.js +100 -0
  209. package/lib/util/debug-app.js.map +1 -0
  210. package/lib/util/deep-partial.d.ts +2 -2
  211. package/lib/util/deep-partial.js +2 -2
  212. package/lib/util/deferred.d.ts +2 -2
  213. package/lib/util/deferred.js +13 -14
  214. package/lib/util/deferred.js.map +1 -1
  215. package/lib/util/disposable.d.ts +2 -2
  216. package/lib/util/disposable.d.ts.map +1 -1
  217. package/lib/util/disposable.js +28 -40
  218. package/lib/util/disposable.js.map +1 -1
  219. package/lib/util/event.d.ts +1 -1
  220. package/lib/util/event.d.ts.map +1 -1
  221. package/lib/util/event.js +64 -77
  222. package/lib/util/event.js.map +1 -1
  223. package/lib/util/garbage-collected-cache.d.ts +3 -2
  224. package/lib/util/garbage-collected-cache.d.ts.map +1 -1
  225. package/lib/util/garbage-collected-cache.js +35 -49
  226. package/lib/util/garbage-collected-cache.js.map +1 -1
  227. package/lib/util/generate-workspace-id.d.ts +9 -0
  228. package/lib/util/generate-workspace-id.d.ts.map +1 -0
  229. package/lib/util/generate-workspace-id.js +491 -0
  230. package/lib/util/generate-workspace-id.js.map +1 -0
  231. package/lib/util/generate-workspace-id.spec.d.ts +7 -0
  232. package/lib/util/generate-workspace-id.spec.d.ts.map +1 -0
  233. package/lib/util/generate-workspace-id.spec.js +98 -0
  234. package/lib/util/generate-workspace-id.spec.js.map +1 -0
  235. package/lib/util/gitpod-cookie.d.ts +20 -0
  236. package/lib/util/gitpod-cookie.d.ts.map +1 -0
  237. package/lib/util/gitpod-cookie.js +41 -0
  238. package/lib/util/gitpod-cookie.js.map +1 -0
  239. package/lib/util/gitpod-host-url.d.ts +20 -8
  240. package/lib/util/gitpod-host-url.d.ts.map +1 -1
  241. package/lib/util/gitpod-host-url.js +143 -85
  242. package/lib/util/gitpod-host-url.js.map +1 -1
  243. package/lib/util/gitpod-host-url.spec.d.ts +16 -0
  244. package/lib/util/gitpod-host-url.spec.d.ts.map +1 -0
  245. package/lib/util/gitpod-host-url.spec.js +134 -0
  246. package/lib/util/gitpod-host-url.spec.js.map +1 -0
  247. package/lib/util/grpc.d.ts +35 -0
  248. package/lib/util/grpc.d.ts.map +1 -0
  249. package/lib/util/grpc.js +90 -0
  250. package/lib/util/grpc.js.map +1 -0
  251. package/lib/util/jaeger-client-types.d.ts +68 -0
  252. package/lib/util/jaeger-client-types.d.ts.map +1 -0
  253. package/lib/util/jaeger-client-types.js +8 -0
  254. package/lib/util/jaeger-client-types.js.map +1 -0
  255. package/lib/util/logging.d.ts +58 -35
  256. package/lib/util/logging.d.ts.map +1 -1
  257. package/lib/util/logging.js +144 -129
  258. package/lib/util/logging.js.map +1 -1
  259. package/lib/util/logging.spec.d.ts +7 -0
  260. package/lib/util/logging.spec.d.ts.map +1 -0
  261. package/lib/util/logging.spec.js +52 -0
  262. package/lib/util/logging.spec.js.map +1 -0
  263. package/lib/util/make-link.d.ts +2 -2
  264. package/lib/util/make-link.js +8 -7
  265. package/lib/util/make-link.js.map +1 -1
  266. package/lib/util/nice-grpc.d.ts +9 -0
  267. package/lib/util/nice-grpc.d.ts.map +1 -0
  268. package/lib/util/nice-grpc.js +121 -0
  269. package/lib/util/nice-grpc.js.map +1 -0
  270. package/lib/util/parse-workspace-id.d.ts +15 -5
  271. package/lib/util/parse-workspace-id.d.ts.map +1 -1
  272. package/lib/util/parse-workspace-id.js +39 -9
  273. package/lib/util/parse-workspace-id.js.map +1 -1
  274. package/lib/util/parse-workspace-id.spec.d.ts +10 -2
  275. package/lib/util/parse-workspace-id.spec.d.ts.map +1 -1
  276. package/lib/util/parse-workspace-id.spec.js +130 -49
  277. package/lib/util/parse-workspace-id.spec.js.map +1 -1
  278. package/lib/util/queue.d.ts +2 -2
  279. package/lib/util/queue.js +19 -57
  280. package/lib/util/queue.js.map +1 -1
  281. package/lib/util/queue.spec.d.ts +2 -2
  282. package/lib/util/queue.spec.js +149 -288
  283. package/lib/util/queue.spec.js.map +1 -1
  284. package/lib/util/repeat.d.ts +15 -0
  285. package/lib/util/repeat.d.ts.map +1 -0
  286. package/lib/util/repeat.js +55 -0
  287. package/lib/util/repeat.js.map +1 -0
  288. package/lib/util/semaphore.d.ts +2 -2
  289. package/lib/util/semaphore.d.ts.map +1 -1
  290. package/lib/util/semaphore.js +18 -48
  291. package/lib/util/semaphore.js.map +1 -1
  292. package/lib/util/skip-if.d.ts +2 -2
  293. package/lib/util/skip-if.d.ts.map +1 -1
  294. package/lib/util/skip-if.js +9 -8
  295. package/lib/util/skip-if.js.map +1 -1
  296. package/lib/util/timeutil.d.ts +4 -2
  297. package/lib/util/timeutil.d.ts.map +1 -1
  298. package/lib/util/timeutil.js +43 -18
  299. package/lib/util/timeutil.js.map +1 -1
  300. package/lib/util/timeutil.spec.d.ts +4 -2
  301. package/lib/util/timeutil.spec.d.ts.map +1 -1
  302. package/lib/util/timeutil.spec.js +57 -25
  303. package/lib/util/timeutil.spec.js.map +1 -1
  304. package/lib/util/tracing.d.ts +55 -8
  305. package/lib/util/tracing.d.ts.map +1 -1
  306. package/lib/util/tracing.js +210 -66
  307. package/lib/util/tracing.js.map +1 -1
  308. package/lib/util/tracing.spec.d.ts +7 -0
  309. package/lib/util/tracing.spec.d.ts.map +1 -0
  310. package/lib/util/tracing.spec.js +121 -0
  311. package/lib/util/tracing.spec.js.map +1 -0
  312. package/lib/util/workspace-port-authentication.d.ts +9 -9
  313. package/lib/util/workspace-port-authentication.d.ts.map +1 -1
  314. package/lib/util/workspace-port-authentication.js +13 -14
  315. package/lib/util/workspace-port-authentication.js.map +1 -1
  316. package/lib/webhook-event.d.ts +44 -0
  317. package/lib/webhook-event.d.ts.map +1 -0
  318. package/lib/webhook-event.js +8 -0
  319. package/lib/webhook-event.js.map +1 -0
  320. package/lib/workspace-class.d.ts +14 -0
  321. package/lib/workspace-class.d.ts.map +1 -0
  322. package/lib/workspace-class.js +8 -0
  323. package/lib/workspace-class.js.map +1 -0
  324. package/lib/workspace-cluster.d.ts +80 -0
  325. package/lib/workspace-cluster.d.ts.map +1 -0
  326. package/lib/workspace-cluster.js +36 -0
  327. package/lib/workspace-cluster.js.map +1 -0
  328. package/lib/workspace-instance.d.ts +51 -8
  329. package/lib/workspace-instance.d.ts.map +1 -1
  330. package/lib/workspace-instance.js +2 -2
  331. package/lib/wsready.d.ts +8 -2
  332. package/lib/wsready.d.ts.map +1 -1
  333. package/lib/wsready.js +4 -3
  334. package/lib/wsready.js.map +1 -1
  335. package/package.json +42 -18
  336. package/pkg-yarn.lock +24 -10
  337. package/provenance-bundle.jsonl +2 -0
  338. package/src/accounting-protocol.ts +253 -0
  339. package/src/admin-protocol.ts +96 -21
  340. package/src/analytics.ts +52 -0
  341. package/src/attribution.ts +67 -0
  342. package/src/auth.ts +27 -0
  343. package/src/billing-mode.ts +84 -0
  344. package/src/blocked-repositories-protocol.ts +13 -0
  345. package/src/context-url.spec.ts +49 -0
  346. package/src/context-url.ts +107 -0
  347. package/src/encryption/container-module.ts +4 -5
  348. package/src/encryption/encryption-engine.spec.ts +11 -10
  349. package/src/encryption/encryption-engine.ts +22 -18
  350. package/src/encryption/encryption-service.ts +6 -7
  351. package/src/encryption/key-provider.ts +18 -21
  352. package/src/env.ts +3 -26
  353. package/src/experiments/always-default.ts +24 -0
  354. package/src/experiments/configcat-server.ts +42 -0
  355. package/src/experiments/configcat.ts +56 -0
  356. package/src/experiments/types.ts +34 -0
  357. package/src/frontend-dashboard-service.ts +148 -0
  358. package/src/gitpod-file-parser.spec.ts +57 -63
  359. package/src/gitpod-file-parser.ts +18 -19
  360. package/src/gitpod-service.ts +602 -99
  361. package/src/headless-workspace-log.ts +14 -16
  362. package/src/ide-frontend-service.ts +28 -0
  363. package/src/ide-protocol.ts +147 -0
  364. package/src/index.ts +18 -12
  365. package/src/installation-admin-protocol.ts +45 -0
  366. package/src/license-protocol.ts +14 -8
  367. package/src/messaging/browser/connection.ts +202 -26
  368. package/src/messaging/browser/window-connection.ts +45 -29
  369. package/src/messaging/client-call-metrics.ts +94 -0
  370. package/src/messaging/error.ts +51 -10
  371. package/src/messaging/handler.ts +13 -1
  372. package/src/messaging/node/connection.ts +23 -70
  373. package/src/messaging/proxy-factory.ts +35 -34
  374. package/src/oss-allowlist.ts +15 -0
  375. package/src/payment-protocol.ts +20 -0
  376. package/src/permission.ts +53 -40
  377. package/src/plans.ts +699 -0
  378. package/src/protocol.spec.ts +97 -0
  379. package/src/protocol.ts +790 -302
  380. package/src/snapshot-url.spec.ts +27 -0
  381. package/src/snapshot-url.ts +27 -0
  382. package/src/team-subscription-protocol.ts +153 -0
  383. package/src/teams-projects-protocol.ts +180 -0
  384. package/src/typings/globals.ts +13 -5
  385. package/src/usage.ts +85 -0
  386. package/src/util/analytics.ts +109 -0
  387. package/src/util/async-iterator.ts +6 -7
  388. package/src/util/cancelable.ts +5 -5
  389. package/src/util/date-time.ts +10 -10
  390. package/src/util/debug-app.ts +81 -0
  391. package/src/util/deep-partial.ts +2 -2
  392. package/src/util/deferred.ts +8 -8
  393. package/src/util/disposable.ts +3 -6
  394. package/src/util/event.ts +9 -11
  395. package/src/util/garbage-collected-cache.ts +18 -10
  396. package/src/util/generate-workspace-id.spec.ts +58 -0
  397. package/src/util/generate-workspace-id.ts +481 -0
  398. package/src/util/gitpod-cookie.ts +38 -0
  399. package/src/util/gitpod-host-url.spec.ts +76 -0
  400. package/src/util/gitpod-host-url.ts +119 -40
  401. package/src/util/grpc.ts +107 -0
  402. package/src/util/jaeger-client-types.ts +102 -0
  403. package/src/util/logging.spec.ts +23 -0
  404. package/src/util/logging.ts +163 -73
  405. package/src/util/make-link.ts +8 -9
  406. package/src/util/nice-grpc.ts +96 -0
  407. package/src/util/parse-workspace-id.spec.ts +62 -12
  408. package/src/util/parse-workspace-id.ts +40 -10
  409. package/src/util/queue.spec.ts +30 -28
  410. package/src/util/queue.ts +2 -2
  411. package/src/util/repeat.ts +45 -0
  412. package/src/util/semaphore.ts +8 -10
  413. package/src/util/skip-if.ts +12 -9
  414. package/src/util/timeutil.spec.ts +42 -16
  415. package/src/util/timeutil.ts +33 -17
  416. package/src/util/tracing.spec.ts +88 -0
  417. package/src/util/tracing.ts +211 -33
  418. package/src/util/workspace-port-authentication.ts +12 -15
  419. package/src/webhook-event.ts +55 -0
  420. package/src/workspace-class.ts +14 -0
  421. package/src/workspace-cluster.ts +121 -0
  422. package/src/workspace-instance.ts +120 -36
  423. package/src/wsready.ts +11 -4
  424. package/data/builtin-theia-plugins.json +0 -362
  425. package/lib/email-protocol.d.ts +0 -49
  426. package/lib/email-protocol.d.ts.map +0 -1
  427. package/lib/email-protocol.js +0 -27
  428. package/lib/email-protocol.js.map +0 -1
  429. package/lib/messaging/connection-error-handler.d.ts +0 -27
  430. package/lib/messaging/connection-error-handler.d.ts.map +0 -1
  431. package/lib/messaging/connection-error-handler.js +0 -45
  432. package/lib/messaging/connection-error-handler.js.map +0 -1
  433. package/lib/theia-plugins.d.ts +0 -11
  434. package/lib/theia-plugins.d.ts.map +0 -1
  435. package/lib/theia-plugins.js +0 -8
  436. package/lib/theia-plugins.js.map +0 -1
  437. package/lib/util/repeater.d.ts +0 -22
  438. package/lib/util/repeater.d.ts.map +0 -1
  439. package/lib/util/repeater.js +0 -117
  440. package/lib/util/repeater.js.map +0 -1
  441. package/lib/util/safe-promise.d.ts +0 -11
  442. package/lib/util/safe-promise.d.ts.map +0 -1
  443. package/lib/util/safe-promise.js +0 -33
  444. package/lib/util/safe-promise.js.map +0 -1
  445. package/lib/util/without.d.ts +0 -7
  446. package/lib/util/without.d.ts.map +0 -1
  447. package/lib/util/without.js +0 -8
  448. package/lib/util/without.js.map +0 -1
  449. package/src/email-protocol.ts +0 -67
  450. package/src/messaging/connection-error-handler.ts +0 -62
  451. package/src/theia-plugins.ts +0 -11
  452. package/src/util/jaeger-client.d.ts +0 -105
  453. package/src/util/repeater.ts +0 -49
  454. package/src/util/safe-promise.ts +0 -26
  455. package/src/util/without.ts +0 -8
package/src/protocol.ts CHANGED
@@ -1,33 +1,37 @@
1
1
  /**
2
- * Copyright (c) 2020 TypeFox GmbH. All rights reserved.
2
+ * Copyright (c) 2020 Gitpod GmbH. All rights reserved.
3
3
  * Licensed under the GNU Affero General Public License (AGPL).
4
- * See License-AGPL.txt in the project root for license information.
4
+ * See License.AGPL.txt in the project root for license information.
5
5
  */
6
6
 
7
7
  import { WorkspaceInstance, PortVisibility } from "./workspace-instance";
8
8
  import { RoleOrPermission } from "./permission";
9
+ import { Project } from "./teams-projects-protocol";
10
+ import { createHash } from "crypto";
11
+ import { AttributionId } from "./attribution";
9
12
 
10
- export interface UserInfo {
11
- name?: string
13
+ export interface UserInfo {
14
+ name?: string;
12
15
  }
13
16
 
14
17
  export interface User {
15
18
  /** The user id */
16
- id: string
19
+ id: string;
20
+
21
+ /** The ID of the Organization this user is owned by. If undefined, the user is owned by the installation */
22
+ organizationId?: string;
17
23
 
18
24
  /** The timestamp when the user entry was created */
19
- creationDate: string
25
+ creationDate: string;
20
26
 
21
- avatarUrl?: string
27
+ avatarUrl?: string;
22
28
 
23
- name?: string
29
+ name?: string;
24
30
 
25
31
  /** Optional for backwards compatibility */
26
- fullName?: string
27
-
28
- identities: Identity[]
32
+ fullName?: string;
29
33
 
30
- allowsMarketingCommunication: boolean;
34
+ identities: Identity[];
31
35
 
32
36
  /**
33
37
  * Whether the user has been blocked to use our service, because of TOS violation for example.
@@ -35,11 +39,6 @@ export interface User {
35
39
  */
36
40
  blocked?: boolean;
37
41
 
38
- /**
39
- * whether this user can run workspaces in privileged mode
40
- */
41
- privileged?: boolean;
42
-
43
42
  /** A map of random settings that alter the behaviour of Gitpod on a per-user basis */
44
43
  featureFlags?: UserFeatureSettings;
45
44
 
@@ -50,31 +49,61 @@ export interface User {
50
49
  markedDeleted?: boolean;
51
50
 
52
51
  additionalData?: AdditionalUserData;
52
+
53
+ // Identifies an explicit team or user ID to which all the user's workspace usage should be attributed to (e.g. for billing purposes)
54
+ usageAttributionId?: string;
55
+
56
+ // The last time this user got verified somehow. The user is not verified if this is empty.
57
+ lastVerificationTime?: string;
58
+
59
+ // The phone number used for the last phone verification.
60
+ verificationPhoneNumber?: string;
53
61
  }
54
62
 
55
63
  export namespace User {
56
64
  export function is(data: any): data is User {
57
- return data
58
- && data.hasOwnProperty('id')
59
- && data.hasOwnProperty('identities')
65
+ return data && data.hasOwnProperty("id") && data.hasOwnProperty("identities");
60
66
  }
61
67
  export function getIdentity(user: User, authProviderId: string): Identity | undefined {
62
- return user.identities.find(id => id.authProviderId === authProviderId);
68
+ return user.identities.find((id) => id.authProviderId === authProviderId);
69
+ }
70
+ export function censor(user: User): User {
71
+ const res = { ...user };
72
+ delete res.additionalData;
73
+ res.identities = res.identities.map((i) => {
74
+ delete i.tokens;
75
+
76
+ // The user field is not in the Identity shape, but actually exists on DBIdentity.
77
+ // Trying to push this object out via JSON RPC will fail because of the cyclic nature
78
+ // of this field.
79
+ delete (i as any).user;
80
+ return i;
81
+ });
82
+ return res;
63
83
  }
64
- export function getPrimaryEmail(user: User): string {
65
- const identities = user.identities.filter(i => !!i.primaryEmail);
84
+
85
+ /**
86
+ * Returns the stored email or if it doesn't exist returns the primaryEmail of the first identity this user signed up with.
87
+ * @param user
88
+ * @returns A primaryEmail, or undefined if there is none.
89
+ */
90
+ export function getPrimaryEmail(user: User): string | undefined {
91
+ if (user.additionalData?.profile?.emailAddress) {
92
+ return user.additionalData?.profile?.emailAddress;
93
+ }
94
+ const identities = user.identities.filter((i) => !!i.primaryEmail);
66
95
  if (identities.length <= 0) {
67
- throw new Error(`No identity with primary email for user: ${user.id}!`);
96
+ return undefined;
68
97
  }
69
98
 
70
- return identities[0].primaryEmail!;
99
+ return identities[0].primaryEmail || undefined;
71
100
  }
72
101
  export function getName(user: User): string | undefined {
73
102
  const name = user.fullName || user.name;
74
103
  if (name) {
75
104
  return name;
76
105
  }
77
-
106
+
78
107
  for (const id of user.identities) {
79
108
  if (id.authName !== "") {
80
109
  return id.authName;
@@ -82,15 +111,220 @@ export namespace User {
82
111
  }
83
112
  return undefined;
84
113
  }
114
+
115
+ export function hasPreferredIde(user: User) {
116
+ return (
117
+ typeof user?.additionalData?.ideSettings?.defaultIde !== "undefined" ||
118
+ typeof user?.additionalData?.ideSettings?.useLatestVersion !== "undefined"
119
+ );
120
+ }
121
+
122
+ export function isOnboardingUser(user: User) {
123
+ return !hasPreferredIde(user);
124
+ }
125
+
126
+ export function migrationIDESettings(user: User) {
127
+ if (
128
+ !user?.additionalData?.ideSettings ||
129
+ Object.keys(user.additionalData.ideSettings).length === 0 ||
130
+ user.additionalData.ideSettings.settingVersion === "2.0"
131
+ ) {
132
+ return;
133
+ }
134
+ const newIDESettings: IDESettings = {
135
+ settingVersion: "2.0",
136
+ };
137
+ const ideSettings = user.additionalData.ideSettings;
138
+ if (ideSettings.useDesktopIde) {
139
+ if (ideSettings.defaultDesktopIde === "code-desktop") {
140
+ newIDESettings.defaultIde = "code-desktop";
141
+ } else if (ideSettings.defaultDesktopIde === "code-desktop-insiders") {
142
+ newIDESettings.defaultIde = "code-desktop";
143
+ newIDESettings.useLatestVersion = true;
144
+ } else {
145
+ newIDESettings.defaultIde = ideSettings.defaultDesktopIde;
146
+ newIDESettings.useLatestVersion = ideSettings.useLatestVersion;
147
+ }
148
+ } else {
149
+ const useLatest = ideSettings.defaultIde === "code-latest";
150
+ newIDESettings.defaultIde = "code";
151
+ newIDESettings.useLatestVersion = useLatest;
152
+ }
153
+ user.additionalData.ideSettings = newIDESettings;
154
+ }
155
+
156
+ // TODO: make it more explicit that these field names are relied for our tracking purposes
157
+ // and decouple frontend from relying on them - instead use user.additionalData.profile object directly in FE
158
+ export function getProfile(user: User): Profile {
159
+ return {
160
+ name: User.getName(user!) || "",
161
+ email: User.getPrimaryEmail(user!) || "",
162
+ company: user?.additionalData?.profile?.companyName,
163
+ avatarURL: user?.avatarUrl,
164
+ companyWebsite: user?.additionalData?.profile?.companyWebsite,
165
+ jobRole: user?.additionalData?.profile?.jobRole,
166
+ jobRoleOther: user?.additionalData?.profile?.jobRoleOther,
167
+ explorationReasons: user?.additionalData?.profile?.explorationReasons,
168
+ signupGoals: user?.additionalData?.profile?.signupGoals,
169
+ signupGoalsOther: user?.additionalData?.profile?.signupGoalsOther,
170
+ companySize: user?.additionalData?.profile?.companySize,
171
+ onboardedTimestamp: user?.additionalData?.profile?.onboardedTimestamp,
172
+ };
173
+ }
174
+
175
+ export function setProfile(user: User, profile: Profile): User {
176
+ user.fullName = profile.name;
177
+ user.avatarUrl = profile.avatarURL;
178
+
179
+ if (!user.additionalData) {
180
+ user.additionalData = {};
181
+ }
182
+ if (!user.additionalData.profile) {
183
+ user.additionalData.profile = {};
184
+ }
185
+ user.additionalData.profile.emailAddress = profile.email;
186
+ user.additionalData.profile.companyName = profile.company;
187
+ user.additionalData.profile.lastUpdatedDetailsNudge = new Date().toISOString();
188
+
189
+ return user;
190
+ }
191
+
192
+ export function getDefaultAttributionId(user: User): AttributionId {
193
+ if (user.usageAttributionId) {
194
+ const result = AttributionId.parse(user.usageAttributionId);
195
+ if (!result) {
196
+ throw new Error("Invalid attribution ID: " + user.usageAttributionId);
197
+ }
198
+ return result;
199
+ }
200
+ return AttributionId.create(user);
201
+ }
202
+
203
+ // TODO: refactor where this is referenced so it's more clearly tied to just analytics-tracking
204
+ // Let other places rely on the ProfileDetails type since that's what we store
205
+ // This is the profile data we send to our Segment analytics tracking pipeline
206
+ export interface Profile {
207
+ name: string;
208
+ email: string;
209
+ company?: string;
210
+ avatarURL?: string;
211
+ companyWebsite?: string;
212
+ jobRole?: string;
213
+ jobRoleOther?: string;
214
+ explorationReasons?: string[];
215
+ signupGoals?: string[];
216
+ signupGoalsOther?: string;
217
+ onboardedTimestamp?: string;
218
+ companySize?: string;
219
+ }
220
+ export namespace Profile {
221
+ export function hasChanges(before: Profile, after: Profile) {
222
+ return (
223
+ before.name !== after.name ||
224
+ before.email !== after.email ||
225
+ before.company !== after.company ||
226
+ before.avatarURL !== after.avatarURL ||
227
+ before.companyWebsite !== after.companyWebsite ||
228
+ before.jobRole !== after.jobRole ||
229
+ before.jobRoleOther !== after.jobRoleOther ||
230
+ // not checking explorationReasons or signupGoals atm as it's an array - need to check deep equality
231
+ before.signupGoalsOther !== after.signupGoalsOther ||
232
+ before.onboardedTimestamp !== after.onboardedTimestamp ||
233
+ before.companySize !== after.companySize
234
+ );
235
+ }
236
+ }
237
+ }
238
+
239
+ export interface WorkspaceTimeoutSetting {
240
+ // user globol workspace timeout
241
+ workspaceTimeout: string;
242
+ // control whether to enable the closed timeout of a workspace, i.e. close web ide, disconnect ssh connection
243
+ disabledClosedTimeout: boolean;
85
244
  }
86
245
 
87
- export interface AdditionalUserData {
246
+ export interface AdditionalUserData extends Partial<WorkspaceTimeoutSetting> {
88
247
  platforms?: UserPlatform[];
89
248
  emailNotificationSettings?: EmailNotificationSettings;
249
+ featurePreview?: boolean;
250
+ ideSettings?: IDESettings;
251
+ // key is the name of the news, string the iso date when it was seen
252
+ whatsNewSeen?: { [key: string]: string };
253
+ // key is the name of the OAuth client i.e. local app, string the iso date when it was approved
254
+ // TODO(rl): provide a management UX to allow rescinding of approval
255
+ oauthClientsApproved?: { [key: string]: string };
256
+ // to remember GH Orgs the user installed/updated the GH App for
257
+ knownGitHubOrgs?: string[];
258
+ // Git clone URL pointing to the user's dotfile repo
259
+ dotfileRepo?: string;
260
+ // preferred workspace classes
261
+ workspaceClasses?: WorkspaceClasses;
262
+ // additional user profile data
263
+ profile?: ProfileDetails;
264
+ // whether the user has been migrated to team attribution.
265
+ // a corresponding feature flag (team_only_attribution) triggers the migration.
266
+ isMigratedToTeamOnlyAttribution?: boolean;
267
+ }
268
+ export namespace AdditionalUserData {
269
+ export function set(user: User, partialData: Partial<AdditionalUserData>): User {
270
+ if (!user.additionalData) {
271
+ user.additionalData = {
272
+ ...partialData,
273
+ };
274
+ } else {
275
+ user.additionalData = {
276
+ ...user.additionalData,
277
+ ...partialData,
278
+ };
279
+ }
280
+ return user;
281
+ }
282
+ }
283
+ // The format in which we store User Profiles in
284
+ export interface ProfileDetails {
285
+ // when was the last time the user updated their profile information or has been nudged to do so.
286
+ lastUpdatedDetailsNudge?: string;
287
+ // the user's company name
288
+ companyName?: string;
289
+ // the user's email
290
+ emailAddress?: string;
291
+ // the user's company website
292
+ companyWebsite?: string;
293
+ // type of role user has in their job
294
+ jobRole?: string;
295
+ // freeform entry for job role user works in (when jobRole is "other")
296
+ jobRoleOther?: string;
297
+ // Reasons user is exploring Gitpod when they signed up
298
+ explorationReasons?: string[];
299
+ // what user hopes to accomplish when they signed up
300
+ signupGoals?: string[];
301
+ // freeform entry for signup goals (when signupGoals is "other")
302
+ signupGoalsOther?: string;
303
+ // Set after a user completes the onboarding flow
304
+ onboardedTimestamp?: string;
305
+ // Onboarding question about a user's company size
306
+ companySize?: string;
90
307
  }
91
308
 
92
309
  export interface EmailNotificationSettings {
93
- disallowTransactionalEmails?: boolean;
310
+ allowsChangelogMail?: boolean;
311
+ allowsDevXMail?: boolean;
312
+ allowsOnboardingMail?: boolean;
313
+ }
314
+
315
+ export type IDESettings = {
316
+ settingVersion?: string;
317
+ defaultIde?: string;
318
+ // DEPRECATED: Use defaultIde after `settingVersion: 2.0`, no more specialify desktop or browser.
319
+ useDesktopIde?: boolean;
320
+ // DEPRECATED: Same with useDesktopIde.
321
+ defaultDesktopIde?: string;
322
+ useLatestVersion?: boolean;
323
+ };
324
+
325
+ export interface WorkspaceClasses {
326
+ regular?: string;
327
+ prebuild?: string;
94
328
  }
95
329
 
96
330
  export interface UserPlatform {
@@ -104,7 +338,7 @@ export interface UserPlatform {
104
338
  * Since when does the user have the browser extension installe don this device.
105
339
  */
106
340
  browserExtensionInstalledSince?: string;
107
-
341
+
108
342
  /**
109
343
  * Since when does the user not have the browser extension installed anymore (but previously had).
110
344
  */
@@ -112,14 +346,6 @@ export interface UserPlatform {
112
346
  }
113
347
 
114
348
  export interface UserFeatureSettings {
115
- /**
116
- * This field is used as marker to grant users a free trial for using private repositories,
117
- * independent of any subscription or Chargebee.
118
- * - it is set when the user uses their first private repo
119
- * - whether the trial is expired or not is juged by the UserService
120
- */
121
- privateRepoTrialStartDate?: string;
122
-
123
349
  /**
124
350
  * Permanent feature flags are added to each and every workspace instance
125
351
  * this user starts.
@@ -127,19 +353,45 @@ export interface UserFeatureSettings {
127
353
  permanentWSFeatureFlags?: NamedWorkspaceFeatureFlag[];
128
354
  }
129
355
 
356
+ export type BillingTier = "paid" | "free";
357
+
130
358
  /**
131
359
  * The values of this type MUST MATCH enum values in WorkspaceFeatureFlag from ws-manager/client/core_pb.d.ts
132
360
  * If they don't we'll break things during workspace startup.
133
361
  */
134
- export const WorkspaceFeatureFlags = { "privileged": undefined, "registry_facade": undefined, "full_workspace_backup": undefined, "fixed_resources": undefined };
135
- export type NamedWorkspaceFeatureFlag = keyof(typeof WorkspaceFeatureFlags);
362
+ export const WorkspaceFeatureFlags = {
363
+ full_workspace_backup: undefined,
364
+ workspace_class_limiting: undefined,
365
+ workspace_connection_limiting: undefined,
366
+ workspace_psi: undefined,
367
+ };
368
+ export type NamedWorkspaceFeatureFlag = keyof typeof WorkspaceFeatureFlags;
369
+ export namespace NamedWorkspaceFeatureFlag {
370
+ export const WORKSPACE_PERSISTED_FEATTURE_FLAGS: NamedWorkspaceFeatureFlag[] = ["full_workspace_backup"];
371
+ export function isWorkspacePersisted(ff: NamedWorkspaceFeatureFlag): boolean {
372
+ return WORKSPACE_PERSISTED_FEATTURE_FLAGS.includes(ff);
373
+ }
374
+ }
136
375
 
137
- export interface UserEnvVarValue {
138
- id?: string;
376
+ export type EnvVar = UserEnvVar | ProjectEnvVarWithValue | EnvVarWithValue;
377
+
378
+ export interface EnvVarWithValue {
139
379
  name: string;
140
- repositoryPattern: string;
141
380
  value: string;
142
381
  }
382
+
383
+ export interface ProjectEnvVarWithValue extends EnvVarWithValue {
384
+ id: string;
385
+ projectId: string;
386
+ censored: boolean;
387
+ }
388
+
389
+ export type ProjectEnvVar = Omit<ProjectEnvVarWithValue, "value">;
390
+
391
+ export interface UserEnvVarValue extends EnvVarWithValue {
392
+ id?: string;
393
+ repositoryPattern: string; // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
394
+ }
143
395
  export interface UserEnvVar extends UserEnvVarValue {
144
396
  id: string;
145
397
  userId: string;
@@ -147,26 +399,89 @@ export interface UserEnvVar extends UserEnvVarValue {
147
399
  }
148
400
 
149
401
  export namespace UserEnvVar {
402
+ /**
403
+ * @param variable
404
+ * @returns Either a string containing an error message or undefined.
405
+ */
406
+ export function validate(variable: UserEnvVarValue): string | undefined {
407
+ const name = variable.name;
408
+ const pattern = variable.repositoryPattern;
409
+ if (name.trim() === "") {
410
+ return "Name must not be empty.";
411
+ }
412
+ if (name.length > 255) {
413
+ return "Name too long. Maximum name length is 255 characters.";
414
+ }
415
+ if (!/^[a-zA-Z_]+[a-zA-Z0-9_]*$/.test(name)) {
416
+ return "Name must match /^[a-zA-Z_]+[a-zA-Z0-9_]*$/.";
417
+ }
418
+ if (variable.value.trim() === "") {
419
+ return "Value must not be empty.";
420
+ }
421
+ if (variable.value.length > 32767) {
422
+ return "Value too long. Maximum value length is 32767 characters.";
423
+ }
424
+ if (pattern.trim() === "") {
425
+ return "Scope must not be empty.";
426
+ }
427
+ const split = pattern.split("/");
428
+ if (split.length < 2) {
429
+ return "A scope must use the form 'organization/repo'.";
430
+ }
431
+ for (const name of split) {
432
+ if (name !== "*") {
433
+ if (!/^[a-zA-Z0-9_\-.\*]+$/.test(name)) {
434
+ return "Invalid scope segment. Only ASCII characters, numbers, -, _, . or * are allowed.";
435
+ }
436
+ }
437
+ }
438
+ return undefined;
439
+ }
150
440
 
441
+ // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
151
442
  export function normalizeRepoPattern(pattern: string) {
152
443
  return pattern.toLocaleLowerCase();
153
444
  }
154
445
 
446
+ // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
447
+ export function score(value: UserEnvVarValue): number {
448
+ // We use a score to enforce precedence:
449
+ // value/value = 0
450
+ // value/* = 1
451
+ // */value = 2
452
+ // */* = 3
453
+ // #/# = 4 (used for env vars passed through the URL)
454
+ // the lower the score, the higher the precedence.
455
+ const [ownerPattern, repoPattern] = splitRepositoryPattern(value.repositoryPattern);
456
+ let score = 0;
457
+ if (repoPattern == "*") {
458
+ score += 1;
459
+ }
460
+ if (ownerPattern == "*") {
461
+ score += 2;
462
+ }
463
+ if (ownerPattern == "#" || repoPattern == "#") {
464
+ score = 4;
465
+ }
466
+ return score;
467
+ }
468
+
469
+ // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
155
470
  export function filter<T extends UserEnvVarValue>(vars: T[], owner: string, repo: string): T[] {
156
- let result = vars.filter(e => {
471
+ let result = vars.filter((e) => {
157
472
  const [ownerPattern, repoPattern] = splitRepositoryPattern(e.repositoryPattern);
158
- if (ownerPattern !== '*' && ownerPattern !== '#' && (!!owner && ownerPattern !== owner.toLocaleLowerCase())) {
473
+ if (ownerPattern !== "*" && ownerPattern !== "#" && !!owner && ownerPattern !== owner.toLocaleLowerCase()) {
159
474
  return false;
160
475
  }
161
- if (repoPattern !== '*' && repoPattern !== '#' && (!!repo && repoPattern !== repo.toLocaleLowerCase())) {
476
+ if (repoPattern !== "*" && repoPattern !== "#" && !!repo && repoPattern !== repo.toLocaleLowerCase()) {
162
477
  return false;
163
478
  }
164
479
  return true;
165
480
  });
166
481
 
167
482
  const resmap = new Map<string, T[]>();
168
- result.forEach(e => {
169
- const l = (resmap.get(e.name) || []);
483
+ result.forEach((e) => {
484
+ const l = resmap.get(e.name) || [];
170
485
  l.push(e);
171
486
  resmap.set(e.name, l);
172
487
  });
@@ -187,25 +502,7 @@ export namespace UserEnvVar {
187
502
  let minscore = 10;
188
503
  let bestCandidate: T | undefined;
189
504
  for (const e of candidates) {
190
- // We use a score to enforce precedence:
191
- // value/value = 0
192
- // value/* = 1
193
- // */value = 2
194
- // */* = 3
195
- // #/# = 4 (used for env vars passed through the URL)
196
- // the lower the score, the higher the precedence.
197
- const [ownerPattern, repoPattern] = splitRepositoryPattern(e.repositoryPattern);
198
- let score = 0;
199
- if (repoPattern == "*") {
200
- score += 1;
201
- }
202
- if (ownerPattern == '*') {
203
- score += 2;
204
- }
205
- if (ownerPattern == "#" || repoPattern == "#") {
206
- score = 4;
207
- }
208
-
505
+ const score = UserEnvVar.score(e);
209
506
  if (!bestCandidate || score < minscore) {
210
507
  minscore = score;
211
508
  bestCandidate = e;
@@ -217,47 +514,109 @@ export namespace UserEnvVar {
217
514
  return result;
218
515
  }
219
516
 
220
- function splitRepositoryPattern(repositoryPattern: string): string[] {
221
- const patterns = repositoryPattern.split('/');
222
- const repoPattern = patterns.pop() || "";
223
- const ownerPattern = patterns.join('/');
517
+ // DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
518
+ export function splitRepositoryPattern(repositoryPattern: string): string[] {
519
+ const patterns = repositoryPattern.split("/");
520
+ const repoPattern = patterns.slice(1).join("/");
521
+ const ownerPattern = patterns[0];
224
522
  return [ownerPattern, repoPattern];
225
523
  }
226
524
  }
227
525
 
228
- export interface GitpodToken {
526
+ export interface SSHPublicKeyValue {
527
+ name: string;
528
+ key: string;
529
+ }
530
+ export interface UserSSHPublicKey extends SSHPublicKeyValue {
531
+ id: string;
532
+ key: string;
533
+ userId: string;
534
+ fingerprint: string;
535
+ creationTime: string;
536
+ lastUsedTime?: string;
537
+ }
538
+
539
+ export type UserSSHPublicKeyValue = Omit<UserSSHPublicKey, "userId">;
540
+
541
+ export namespace SSHPublicKeyValue {
542
+ export function validate(value: SSHPublicKeyValue): string | undefined {
543
+ if (value.name.length === 0) {
544
+ return "Title must not be empty.";
545
+ }
546
+ if (value.name.length > 255) {
547
+ return "Title too long. Maximum value length is 255 characters.";
548
+ }
549
+ if (value.key.length === 0) {
550
+ return "Key must not be empty.";
551
+ }
552
+ try {
553
+ getData(value);
554
+ } catch (e) {
555
+ return "Key is invalid. You must supply a key in OpenSSH public key format.";
556
+ }
557
+ return;
558
+ }
559
+
560
+ export function getData(value: SSHPublicKeyValue) {
561
+ // 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'.
562
+ const regex =
563
+ /^(?<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>.*?))?$/;
564
+ const resultGroup = regex.exec(value.key.trim());
565
+ if (!resultGroup) {
566
+ throw new Error("Key is invalid.");
567
+ }
568
+ return {
569
+ type: resultGroup.groups?.["type"] as string,
570
+ key: resultGroup.groups?.["key"] as string,
571
+ email: resultGroup.groups?.["email"] || undefined,
572
+ };
573
+ }
574
+
575
+ export function getFingerprint(value: SSHPublicKeyValue) {
576
+ const data = getData(value);
577
+ let buf = Buffer.from(data.key, "base64");
578
+ // gitlab style
579
+ // const hash = createHash("md5").update(buf).digest("hex");
580
+ // github style
581
+ const hash = createHash("sha256").update(buf).digest("base64");
582
+ return hash;
583
+ }
584
+
585
+ export const MAXIMUM_KEY_LENGTH = 5;
586
+ }
229
587
 
588
+ export interface GitpodToken {
230
589
  /** Hash value (SHA256) of the token (primary key). */
231
- tokenHash: string
590
+ tokenHash: string;
232
591
 
233
592
  /** Human readable name of the token */
234
- name?: string
593
+ name?: string;
235
594
 
236
595
  /** Token kind */
237
- type: GitpodTokenType
596
+ type: GitpodTokenType;
238
597
 
239
598
  /** The user the token belongs to. */
240
- user: User
241
-
599
+ user: User;
600
+
242
601
  /** Scopes (e.g. limition to read-only) */
243
- scopes: string[]
602
+ scopes: string[];
244
603
 
245
604
  /** Created timestamp */
246
- created: string
247
-
248
- // token is deleted on the database and about to be collected by db-sync
249
- deleted?: boolean
605
+ created: string;
606
+
607
+ // token is deleted on the database and about to be collected by periodic deleter
608
+ deleted?: boolean;
250
609
  }
251
610
 
252
611
  export enum GitpodTokenType {
253
612
  API_AUTH_TOKEN = 0,
254
- MACHINE_AUTH_TOKEN = 1
613
+ MACHINE_AUTH_TOKEN = 1,
255
614
  }
256
615
 
257
616
  export interface OneTimeSecret {
258
- id: string
617
+ id: string;
259
618
 
260
- value: string
619
+ value: string;
261
620
 
262
621
  expirationTime: string;
263
622
 
@@ -289,13 +648,12 @@ export type IdentityLookup = Pick<Identity, "authProviderId" | "authId">;
289
648
 
290
649
  export namespace Identity {
291
650
  export function is(data: any): data is Identity {
292
- return data.hasOwnProperty('authProviderId')
293
- && data.hasOwnProperty('authId')
294
- && data.hasOwnProperty('authName')
651
+ return (
652
+ data.hasOwnProperty("authProviderId") && data.hasOwnProperty("authId") && data.hasOwnProperty("authName")
653
+ );
295
654
  }
296
655
  export function equals(id1: IdentityLookup, id2: IdentityLookup) {
297
- return id1.authProviderId === id2.authProviderId
298
- && id1.authId === id2.authId
656
+ return id1.authProviderId === id2.authProviderId && id1.authId === id2.authId;
299
657
  }
300
658
  }
301
659
 
@@ -346,31 +704,35 @@ export interface PendingGithubEvent {
346
704
  creationDate: Date;
347
705
  type: string;
348
706
  event: string;
707
+ deleted: boolean;
349
708
  }
350
709
 
351
710
  export interface Snapshot {
352
711
  id: string;
353
712
  creationTime: string;
713
+ availableTime?: string;
354
714
  originalWorkspaceId: string;
355
715
  bucketId: string;
356
- layoutData?: string;
716
+ state: SnapshotState;
717
+ message?: string;
357
718
  }
358
719
 
359
- export interface LayoutData {
360
- workspaceId: string;
361
- lastUpdatedTime: string;
362
- layoutData: string;
363
- }
720
+ export type SnapshotState = "pending" | "available" | "error";
364
721
 
365
722
  export interface Workspace {
366
723
  id: string;
367
724
  creationTime: string;
725
+ /**
726
+ * undefined means it is owned by the user (legacy mode, soon to be removed)
727
+ */
728
+ organizationId?: string;
368
729
  contextURL: string;
369
730
  description: string;
370
731
  ownerId: string;
732
+ projectId?: string;
371
733
  context: WorkspaceContext;
372
734
  config: WorkspaceConfig;
373
-
735
+
374
736
  /**
375
737
  * The source where to get the workspace base image from. This source is resolved
376
738
  * during workspace creation. Once a base image has been built the information in here
@@ -382,18 +744,18 @@ export interface Workspace {
382
744
  * The resolved, fix name of the workspace image. We only use this
383
745
  * to access the logs during an image build.
384
746
  */
385
- imageNameResolved?: string
747
+ imageNameResolved?: string;
386
748
 
387
749
  /**
388
750
  * The resolved/built fixed named of the base image. This field is only set if the workspace
389
751
  * already has its base image built.
390
752
  */
391
- baseImageNameResolved?: string
753
+ baseImageNameResolved?: string;
392
754
 
393
755
  shareable?: boolean;
394
756
  pinned?: boolean;
395
757
 
396
- // workspace is hard-deleted on the database and about to be collected by db-sync
758
+ // workspace is hard-deleted on the database and about to be collected by periodic deleter
397
759
  readonly deleted?: boolean;
398
760
 
399
761
  /**
@@ -422,20 +784,19 @@ export interface Workspace {
422
784
 
423
785
  export type WorkspaceSoftDeletion = "user" | "gc";
424
786
 
425
- export type WorkspaceType = "regular" | "prebuild" | "probe";
787
+ export type WorkspaceType = "regular" | "prebuild";
426
788
 
427
789
  export namespace Workspace {
428
-
429
790
  export function getFullRepositoryName(ws: Workspace): string | undefined {
430
791
  if (CommitContext.is(ws.context)) {
431
- return ws.context.repository.owner + '/' + ws.context.repository.name
792
+ return ws.context.repository.owner + "/" + ws.context.repository.name;
432
793
  }
433
794
  return undefined;
434
795
  }
435
796
 
436
797
  export function getFullRepositoryUrl(ws: Workspace): string | undefined {
437
798
  if (CommitContext.is(ws.context)) {
438
- return `https://${ws.context.repository.host}/${getFullRepositoryName(ws)}`
799
+ return `https://${ws.context.repository.host}/${getFullRepositoryName(ws)}`;
439
800
  }
440
801
  return undefined;
441
802
  }
@@ -469,60 +830,85 @@ export namespace Workspace {
469
830
  }
470
831
  }
471
832
 
472
- export interface PreparePluginUploadParams {
473
- fullPluginName: string;
833
+ export interface GuessGitTokenScopesParams {
834
+ host: string;
835
+ repoUrl: string;
836
+ gitCommand: string;
837
+ currentToken: GitToken;
474
838
  }
475
839
 
476
- export interface ResolvePluginsParams {
477
- config?: WorkspaceConfig
478
- builtins?: ResolvedPlugins
840
+ export interface GitToken {
841
+ token: string;
842
+ user: string;
843
+ scopes: string[];
479
844
  }
480
845
 
481
- export interface InstallPluginsParams {
482
- pluginIds: string[]
846
+ export interface GuessedGitTokenScopes {
847
+ message?: string;
848
+ scopes?: string[];
483
849
  }
484
850
 
485
- export interface UninstallPluginParams {
486
- pluginId: string;
851
+ export interface VSCodeConfig {
852
+ extensions?: string[];
487
853
  }
488
854
 
489
- export type ResolvedPluginKind = 'user' | 'workspace' | 'builtin';
490
-
491
- export interface ResolvedPlugins {
492
- [pluginId: string]: ResolvedPlugin | undefined
855
+ export interface JetBrainsConfig {
856
+ intellij?: JetBrainsProductConfig;
857
+ goland?: JetBrainsProductConfig;
858
+ pycharm?: JetBrainsProductConfig;
859
+ phpstorm?: JetBrainsProductConfig;
860
+ rubymine?: JetBrainsProductConfig;
861
+ webstorm?: JetBrainsProductConfig;
862
+ rider?: JetBrainsProductConfig;
863
+ clion?: JetBrainsProductConfig;
864
+ }
865
+ export interface JetBrainsProductConfig {
866
+ prebuilds?: JetBrainsPrebuilds;
867
+ vmoptions?: string;
868
+ }
869
+ export interface JetBrainsPrebuilds {
870
+ version?: "stable" | "latest" | "both";
493
871
  }
494
872
 
495
- export interface ResolvedPlugin {
496
- fullPluginName: string;
873
+ export interface RepositoryCloneInformation {
497
874
  url: string;
498
- kind: ResolvedPluginKind;
875
+ checkoutLocation?: string;
499
876
  }
500
877
 
501
- export interface VSCodeConfig {
502
- extensions?: string[];
878
+ export interface CoreDumpConfig {
879
+ enabled?: boolean;
880
+ softLimit?: number;
881
+ hardLimit?: number;
503
882
  }
504
883
 
505
884
  export interface WorkspaceConfig {
885
+ mainConfiguration?: string;
886
+ additionalRepositories?: RepositoryCloneInformation[];
506
887
  image?: ImageConfig;
507
888
  ports?: PortConfig[];
508
889
  tasks?: TaskConfig[];
509
890
  checkoutLocation?: string;
510
891
  workspaceLocation?: string;
511
- privileged?: boolean;
512
892
  gitConfig?: { [config: string]: string };
513
893
  github?: GithubAppConfig;
514
894
  vscode?: VSCodeConfig;
515
- ide?: 'theia' | 'code' | string;
895
+ jetbrains?: JetBrainsConfig;
896
+ coreDump?: CoreDumpConfig;
897
+ ideCredentials?: string;
898
+
899
+ /** deprecated. Enabled by default **/
900
+ experimentalNetwork?: boolean;
516
901
 
517
902
  /**
518
903
  * Where the config object originates from.
519
- *
904
+ *
520
905
  * repo - from the repository
521
906
  * definitly-gp - from github.com/gitpod-io/definitely-gp
522
907
  * derived - computed based on analyzing the repository
908
+ * additional-content - config comes from additional content, usually provided through the project's configuration
523
909
  * default - our static catch-all default config
524
910
  */
525
- _origin?: 'repo' | 'definitely-gp' | 'derived' | 'default';
911
+ _origin?: "repo" | "definitely-gp" | "derived" | "additional-content" | "default";
526
912
 
527
913
  /**
528
914
  * Set of automatically infered feature flags. That's not something the user can set, but
@@ -532,37 +918,33 @@ export interface WorkspaceConfig {
532
918
  }
533
919
 
534
920
  export interface GithubAppConfig {
535
- prebuilds?: GithubAppPrebuildConfig
921
+ prebuilds?: GithubAppPrebuildConfig;
536
922
  }
537
923
  export interface GithubAppPrebuildConfig {
538
- master?: boolean
539
- branches?: boolean
540
- pullRequests?: boolean
541
- pullRequestsFromForks?: boolean
542
- addCheck?: boolean
543
- addBadge?: boolean
544
- addLabel?: boolean | string
545
- addComment?: boolean
924
+ master?: boolean;
925
+ branches?: boolean;
926
+ pullRequests?: boolean;
927
+ pullRequestsFromForks?: boolean;
928
+ addCheck?: boolean | "prevent-merge-on-error";
929
+ addBadge?: boolean;
930
+ addLabel?: boolean | string;
931
+ addComment?: boolean;
546
932
  }
547
933
  export namespace GithubAppPrebuildConfig {
548
934
  export function is(obj: boolean | GithubAppPrebuildConfig): obj is GithubAppPrebuildConfig {
549
- return !(typeof obj === 'boolean');
935
+ return !(typeof obj === "boolean");
550
936
  }
551
937
  }
552
938
 
553
939
  export type WorkspaceImageSource = WorkspaceImageSourceDocker | WorkspaceImageSourceReference;
554
940
  export interface WorkspaceImageSourceDocker {
555
- // TODO: clean this up. We should have the commit and an ImageSource in here, not duplicate the whole thing again.
556
- // We have a ton of those objects in the database, thus cleaning this up means lengthy DB migrations. Yuck.
557
- dockerFileHash: string
558
- dockerFileSource: Commit
559
- dockerFilePath: string
941
+ dockerFilePath: string;
942
+ dockerFileHash: string;
943
+ dockerFileSource?: Commit;
560
944
  }
561
945
  export namespace WorkspaceImageSourceDocker {
562
946
  export function is(obj: object): obj is WorkspaceImageSourceDocker {
563
- return 'dockerFileHash' in obj
564
- && 'dockerFileSource' in obj
565
- && 'dockerFilePath' in obj;
947
+ return "dockerFileHash" in obj && "dockerFilePath" in obj;
566
948
  }
567
949
  }
568
950
  export interface WorkspaceImageSourceReference {
@@ -571,34 +953,45 @@ export interface WorkspaceImageSourceReference {
571
953
  }
572
954
  export namespace WorkspaceImageSourceReference {
573
955
  export function is(obj: object): obj is WorkspaceImageSourceReference {
574
- return 'baseImageResolved' in obj;
956
+ return "baseImageResolved" in obj;
575
957
  }
576
958
  }
577
959
 
578
- export type PrebuiltWorkspaceState
960
+ export type PrebuiltWorkspaceState =
579
961
  // the prebuild is queued and may start at anytime
580
- = "queued"
962
+ | "queued"
581
963
  // the workspace prebuild is currently running (i.e. there's a workspace pod deployed)
582
964
  | "building"
583
- // the prebuild failed due to some issue with the system (e.g. missed a message, could not start workspace)
965
+ // the prebuild was aborted
584
966
  | "aborted"
585
967
  // the prebuild timed out
586
968
  | "timeout"
587
- // the prebuild has finished and a snapshot is available
588
- | "available";
969
+ // the prebuild has finished (even if a headless task failed) and a snapshot is available
970
+ | "available"
971
+ // the prebuild (headless workspace) failed due to some system error
972
+ | "failed";
589
973
 
590
974
  export interface PrebuiltWorkspace {
591
975
  id: string;
592
976
  cloneURL: string;
977
+ branch?: string;
978
+ projectId?: string;
593
979
  commit: string;
594
980
  buildWorkspaceId: string;
595
981
  creationTime: string;
596
982
  state: PrebuiltWorkspaceState;
983
+ statusVersion: number;
597
984
  error?: string;
598
985
  snapshot?: string;
599
986
  }
600
987
 
601
988
  export namespace PrebuiltWorkspace {
989
+ export function isDone(pws: PrebuiltWorkspace) {
990
+ return (
991
+ pws.state === "available" || pws.state === "timeout" || pws.state === "aborted" || pws.state === "failed"
992
+ );
993
+ }
994
+
602
995
  export function isAvailable(pws: PrebuiltWorkspace) {
603
996
  return pws.state === "available" && !!pws.snapshot;
604
997
  }
@@ -615,27 +1008,33 @@ export interface PrebuiltWorkspaceUpdatable {
615
1008
  repo: string;
616
1009
  isResolved: boolean;
617
1010
  installationId: string;
1011
+ /**
1012
+ * the commitSHA of the commit that triggered the prebuild
1013
+ */
1014
+ commitSHA?: string;
618
1015
  issue?: string;
619
1016
  contextUrl?: string;
620
1017
  }
621
1018
 
622
1019
  export interface WhitelistedRepository {
623
- url: string
624
- name: string
625
- description?: string
626
- avatar?: string
1020
+ url: string;
1021
+ name: string;
1022
+ description?: string;
1023
+ avatar?: string;
627
1024
  }
628
1025
 
629
- export type PortOnOpen = 'open-browser' | 'open-preview' | 'notify' | 'ignore';
1026
+ export type PortOnOpen = "open-browser" | "open-preview" | "notify" | "ignore";
630
1027
 
631
1028
  export interface PortConfig {
632
1029
  port: number;
633
1030
  onOpen?: PortOnOpen;
634
1031
  visibility?: PortVisibility;
1032
+ description?: string;
1033
+ name?: string;
635
1034
  }
636
1035
  export namespace PortConfig {
637
1036
  export function is(config: any): config is PortConfig {
638
- return config && ('port' in config) && (typeof config.port === 'number');
1037
+ return config && "port" in config && typeof config.port === "number";
639
1038
  }
640
1039
  }
641
1040
 
@@ -645,7 +1044,7 @@ export interface PortRangeConfig {
645
1044
  }
646
1045
  export namespace PortRangeConfig {
647
1046
  export function is(config: any): config is PortRangeConfig {
648
- return config && ('port' in config) && (typeof config.port === 'string' || config.port instanceof String);
1047
+ return config && "port" in config && (typeof config.port === "string" || config.port instanceof String);
649
1048
  }
650
1049
  }
651
1050
 
@@ -655,33 +1054,32 @@ export interface TaskConfig {
655
1054
  init?: string;
656
1055
  prebuild?: string;
657
1056
  command?: string;
658
- env?: { [env: string]: string };
659
- openIn?: 'bottom' | 'main' | 'left' | 'right';
660
- openMode?: 'split-top' | 'split-left' | 'split-right' | 'split-bottom' | 'tab-before' | 'tab-after';
1057
+ env?: { [env: string]: any };
1058
+ openIn?: "bottom" | "main" | "left" | "right";
1059
+ openMode?: "split-top" | "split-left" | "split-right" | "split-bottom" | "tab-before" | "tab-after";
661
1060
  }
662
1061
 
663
1062
  export namespace TaskConfig {
664
1063
  export function is(config: any): config is TaskConfig {
665
- return config
666
- && ('command' in config || 'init' in config || 'before' in config);
1064
+ return config && ("command" in config || "init" in config || "before" in config);
667
1065
  }
668
1066
  }
669
1067
 
670
1068
  export namespace WorkspaceImageBuild {
671
- export type Phase = 'BaseImage' | 'GitpodLayer' | 'Error' | 'Done';
1069
+ export type Phase = "BaseImage" | "GitpodLayer" | "Error" | "Done";
672
1070
  export interface StateInfo {
673
- phase: Phase
674
- currentStep?: number
675
- maxSteps?: number
1071
+ phase: Phase;
1072
+ currentStep?: number;
1073
+ maxSteps?: number;
676
1074
  }
677
1075
  export interface LogContent {
678
- text: string
679
- upToLine?: number
680
- isDiff?: boolean
1076
+ text: string;
1077
+ upToLine?: number;
1078
+ isDiff?: boolean;
681
1079
  }
682
1080
  export type LogCallback = (info: StateInfo, content: LogContent | undefined) => void;
683
1081
  export namespace LogLine {
684
- export const DELIMITER = '\r\n';
1082
+ export const DELIMITER = "\r\n";
685
1083
  export const DELIMITER_REGEX = /\r?\n/;
686
1084
  }
687
1085
  }
@@ -690,20 +1088,18 @@ export type ImageConfig = ImageConfigString | ImageConfigFile;
690
1088
  export type ImageConfigString = string;
691
1089
  export namespace ImageConfigString {
692
1090
  export function is(config: ImageConfig | undefined): config is ImageConfigString {
693
- return typeof config === 'string';
1091
+ return typeof config === "string";
694
1092
  }
695
-
696
1093
  }
697
1094
  export interface ImageConfigFile {
698
1095
  // Path to the Dockerfile relative to repository root
699
- file: string,
1096
+ file: string;
700
1097
  // Path to the docker build context relative to repository root
701
- context?: string
1098
+ context?: string;
702
1099
  }
703
1100
  export namespace ImageConfigFile {
704
1101
  export function is(config: ImageConfig | undefined): config is ImageConfigFile {
705
- return typeof config === 'object'
706
- && 'file' in config;
1102
+ return typeof config === "object" && "file" in config;
707
1103
  }
708
1104
  }
709
1105
  export interface ExternalImageConfigFile extends ImageConfigFile {
@@ -711,22 +1107,22 @@ export interface ExternalImageConfigFile extends ImageConfigFile {
711
1107
  }
712
1108
  export namespace ExternalImageConfigFile {
713
1109
  export function is(config: any | undefined): config is ExternalImageConfigFile {
714
- return typeof config === 'object'
715
- && 'file' in config
716
- && 'externalSource' in config;
1110
+ return typeof config === "object" && "file" in config && "externalSource" in config;
717
1111
  }
718
1112
  }
719
1113
 
720
1114
  export interface WorkspaceContext {
721
1115
  title: string;
1116
+ ref?: string;
1117
+ /** 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. */
722
1118
  normalizedContextURL?: string;
723
1119
  forceCreateNewWorkspace?: boolean;
1120
+ forceImageBuild?: boolean;
724
1121
  }
725
1122
 
726
1123
  export namespace WorkspaceContext {
727
1124
  export function is(context: any): context is WorkspaceContext {
728
- return context
729
- && 'title' in context;
1125
+ return context && "title" in context;
730
1126
  }
731
1127
  }
732
1128
 
@@ -735,22 +1131,38 @@ export interface WithSnapshot {
735
1131
  }
736
1132
  export namespace WithSnapshot {
737
1133
  export function is(context: any): context is WithSnapshot {
738
- return context
739
- && 'snapshotBucketId' in context;
1134
+ return context && "snapshotBucketId" in context;
740
1135
  }
741
1136
  }
742
1137
 
743
- export interface WithPrebuild {
744
- snapshotBucketId: string;
1138
+ export interface WithPrebuild extends WithSnapshot {
745
1139
  prebuildWorkspaceId: string;
746
1140
  wasPrebuilt: true;
747
1141
  }
748
1142
  export namespace WithPrebuild {
749
1143
  export function is(context: any): context is WithPrebuild {
750
- return context
751
- && 'snapshotBucketId' in context
752
- && 'prebuildWorkspaceId' in context
753
- && 'wasPrebuilt' in context;
1144
+ return context && WithSnapshot.is(context) && "prebuildWorkspaceId" in context && "wasPrebuilt" in context;
1145
+ }
1146
+ }
1147
+
1148
+ /**
1149
+ * WithDefaultConfig contexts disable the download of the gitpod.yml from the repository
1150
+ * and fall back to the built-in configuration.
1151
+ */
1152
+ export interface WithDefaultConfig {
1153
+ withDefaultConfig: true;
1154
+ }
1155
+
1156
+ export namespace WithDefaultConfig {
1157
+ export function is(context: any): context is WithDefaultConfig {
1158
+ return context && "withDefaultConfig" in context && context.withDefaultConfig;
1159
+ }
1160
+
1161
+ export function mark(ctx: WorkspaceContext): WorkspaceContext & WithDefaultConfig {
1162
+ return {
1163
+ ...ctx,
1164
+ withDefaultConfig: true,
1165
+ };
754
1166
  }
755
1167
  }
756
1168
 
@@ -760,20 +1172,27 @@ export interface SnapshotContext extends WorkspaceContext, WithSnapshot {
760
1172
 
761
1173
  export namespace SnapshotContext {
762
1174
  export function is(context: any): context is SnapshotContext {
763
- return context
764
- && WithSnapshot.is(context)
765
- && 'snapshotId' in context;
1175
+ return context && WithSnapshot.is(context) && "snapshotId" in context;
766
1176
  }
767
1177
  }
768
1178
 
769
- export interface StartPrebuildContext extends WorkspaceContext {
1179
+ export interface WithCommitHistory {
1180
+ commitHistory?: string[];
1181
+ additionalRepositoryCommitHistories?: {
1182
+ cloneUrl: string;
1183
+ commitHistory: string[];
1184
+ }[];
1185
+ }
1186
+
1187
+ export interface StartPrebuildContext extends WorkspaceContext, WithCommitHistory {
770
1188
  actual: WorkspaceContext;
1189
+ project: Project;
1190
+ branch?: string;
771
1191
  }
772
1192
 
773
1193
  export namespace StartPrebuildContext {
774
1194
  export function is(context: any): context is StartPrebuildContext {
775
- return context
776
- && 'actual' in context;
1195
+ return context && "actual" in context;
777
1196
  }
778
1197
  }
779
1198
 
@@ -785,33 +1204,28 @@ export interface PrebuiltWorkspaceContext extends WorkspaceContext {
785
1204
 
786
1205
  export namespace PrebuiltWorkspaceContext {
787
1206
  export function is(context: any): context is PrebuiltWorkspaceContext {
788
- return context
789
- && 'originalContext' in context
790
- && 'prebuiltWorkspace' in context;
1207
+ return context && "originalContext" in context && "prebuiltWorkspace" in context;
791
1208
  }
792
1209
  }
793
1210
 
794
- export interface WithEnvvarsContext extends WorkspaceContext {
795
- envvars: UserEnvVarValue[];
1211
+ export interface WithReferrerContext extends WorkspaceContext {
1212
+ referrer: string;
1213
+ referrerIde?: string;
796
1214
  }
797
1215
 
798
- export namespace WithEnvvarsContext {
799
- export function is(context: any): context is WithEnvvarsContext {
800
- return context
801
- && 'envvars' in context
1216
+ export namespace WithReferrerContext {
1217
+ export function is(context: any): context is WithReferrerContext {
1218
+ return context && "referrer" in context;
802
1219
  }
803
1220
  }
804
1221
 
805
- export interface WorkspaceProbeContext extends WorkspaceContext {
806
- responseURL: string
807
- responseToken: string
1222
+ export interface WithEnvvarsContext extends WorkspaceContext {
1223
+ envvars: EnvVarWithValue[];
808
1224
  }
809
1225
 
810
- export namespace WorkspaceProbeContext {
811
- export function is(context: any): context is WorkspaceProbeContext {
812
- return context
813
- && 'responseURL' in context
814
- && 'responseToken' in context;
1226
+ export namespace WithEnvvarsContext {
1227
+ export function is(context: any): context is WithEnvvarsContext {
1228
+ return context && "envvars" in context;
815
1229
  }
816
1230
  }
817
1231
 
@@ -823,30 +1237,90 @@ export namespace RefType {
823
1237
  }
824
1238
  // This fallback is meant to handle the cases where (for historic reasons) ref is present but refType is missing
825
1239
  return commit.refType || "branch";
826
- }
1240
+ };
827
1241
  }
828
1242
 
829
1243
  export interface Commit {
830
- repository: Repository
831
- revision: string
1244
+ repository: Repository;
1245
+ revision: string;
832
1246
 
833
1247
  // Might contain either a branch or a tag (determined by refType)
834
- ref?: string
1248
+ ref?: string;
835
1249
 
836
1250
  // refType is only set if ref is present (and not for old workspaces, before this feature was added)
837
- refType?: RefType
1251
+ refType?: RefType;
838
1252
  }
839
1253
 
840
- export interface CommitContext extends WorkspaceContext, Commit {
1254
+ export interface AdditionalContentContext extends WorkspaceContext {
1255
+ /**
1256
+ * utf-8 encoded contents that will be copied on top of the workspace's filesystem
1257
+ */
1258
+ additionalFiles: { [filePath: string]: string };
1259
+ }
1260
+
1261
+ export namespace AdditionalContentContext {
1262
+ export function is(ctx: any): ctx is AdditionalContentContext {
1263
+ return "additionalFiles" in ctx;
1264
+ }
1265
+
1266
+ export function hasDockerConfig(ctx: any, config: WorkspaceConfig): boolean {
1267
+ return is(ctx) && ImageConfigFile.is(config.image) && !!ctx.additionalFiles[config.image.file];
1268
+ }
1269
+ }
1270
+
1271
+ export interface OpenPrebuildContext extends WorkspaceContext {
1272
+ openPrebuildID: string;
1273
+ }
1274
+
1275
+ export namespace OpenPrebuildContext {
1276
+ export function is(ctx: any): ctx is OpenPrebuildContext {
1277
+ return "openPrebuildID" in ctx;
1278
+ }
1279
+ }
1280
+
1281
+ export interface CommitContext extends WorkspaceContext, GitCheckoutInfo {
841
1282
  /** @deprecated Moved to .repository.cloneUrl, left here for backwards-compatibility for old workspace contextes in the DB */
842
- cloneUrl?: string
1283
+ cloneUrl?: string;
1284
+
1285
+ /**
1286
+ * The clone and checkout information for additional repositories in case of multi-repo projects.
1287
+ */
1288
+ additionalRepositoryCheckoutInfo?: GitCheckoutInfo[];
1289
+ }
1290
+
1291
+ export namespace CommitContext {
1292
+ /**
1293
+ * Creates a hash for all the commits of the CommitContext and all sub-repo commit infos.
1294
+ * The hash is max 255 chars long.
1295
+ * @param commitContext
1296
+ * @returns hash for commitcontext
1297
+ */
1298
+ export function computeHash(commitContext: CommitContext): string {
1299
+ // for single commits we use the revision to be backward compatible.
1300
+ if (
1301
+ !commitContext.additionalRepositoryCheckoutInfo ||
1302
+ commitContext.additionalRepositoryCheckoutInfo.length === 0
1303
+ ) {
1304
+ return commitContext.revision;
1305
+ }
1306
+ const hasher = createHash("sha256");
1307
+ hasher.update(commitContext.revision);
1308
+ for (const info of commitContext.additionalRepositoryCheckoutInfo) {
1309
+ hasher.update(info.revision);
1310
+ }
1311
+ return hasher.digest("hex");
1312
+ }
1313
+ }
1314
+
1315
+ export interface GitCheckoutInfo extends Commit {
1316
+ checkoutLocation?: string;
1317
+ upstreamRemoteURI?: string;
1318
+ localBranch?: string;
843
1319
  }
844
1320
 
845
1321
  export namespace CommitContext {
846
1322
  export function is(commit: any): commit is CommitContext {
847
- return WorkspaceContext.is(commit)
848
- && 'repository' in commit
849
- && 'revision' in commit
1323
+ return WorkspaceContext.is(commit) && "repository" in commit && "revision" in commit;
850
1324
  }
851
1325
  }
852
1326
 
@@ -854,17 +1328,14 @@ export interface PullRequestContext extends CommitContext {
854
1328
  nr: number;
855
1329
  ref: string;
856
1330
  base: {
857
- repository: Repository
858
- ref: string
859
- }
1331
+ repository: Repository;
1332
+ ref: string;
1333
+ };
860
1334
  }
861
1335
 
862
1336
  export namespace PullRequestContext {
863
1337
  export function is(ctx: any): ctx is PullRequestContext {
864
- return CommitContext.is(ctx)
865
- && 'nr' in ctx
866
- && 'ref' in ctx
867
- && 'base' in ctx
1338
+ return CommitContext.is(ctx) && "nr" in ctx && "ref" in ctx && "base" in ctx;
868
1339
  }
869
1340
  }
870
1341
 
@@ -876,10 +1347,7 @@ export interface IssueContext extends CommitContext {
876
1347
 
877
1348
  export namespace IssueContext {
878
1349
  export function is(ctx: any): ctx is IssueContext {
879
- return CommitContext.is(ctx)
880
- && 'nr' in ctx
881
- && 'ref' in ctx
882
- && 'localBranch' in ctx
1350
+ return CommitContext.is(ctx) && "nr" in ctx && "ref" in ctx && "localBranch" in ctx;
883
1351
  }
884
1352
  }
885
1353
 
@@ -890,9 +1358,7 @@ export interface NavigatorContext extends CommitContext {
890
1358
 
891
1359
  export namespace NavigatorContext {
892
1360
  export function is(ctx: any): ctx is NavigatorContext {
893
- return CommitContext.is(ctx)
894
- && 'path' in ctx
895
- && 'isFile' in ctx
1361
+ return CommitContext.is(ctx) && "path" in ctx && "isFile" in ctx;
896
1362
  }
897
1363
  }
898
1364
 
@@ -901,6 +1367,8 @@ export interface Repository {
901
1367
  owner: string;
902
1368
  name: string;
903
1369
  cloneUrl: string;
1370
+ /* Optional kind to differentiate between repositories of orgs/groups/projects and personal repos. */
1371
+ repoKind?: string;
904
1372
  description?: string;
905
1373
  avatarUrl?: string;
906
1374
  webUrl?: string;
@@ -909,8 +1377,21 @@ export interface Repository {
909
1377
  private?: boolean;
910
1378
  fork?: {
911
1379
  // The direct parent of this fork
912
- parent: Repository
913
- }
1380
+ parent: Repository;
1381
+ };
1382
+ }
1383
+ export interface Branch {
1384
+ name: string;
1385
+ commit: CommitInfo;
1386
+ htmlUrl: string;
1387
+ }
1388
+
1389
+ export interface CommitInfo {
1390
+ author: string;
1391
+ sha: string;
1392
+ commitMessage: string;
1393
+ authorAvatarUrl?: string;
1394
+ authorDate?: string;
914
1395
  }
915
1396
 
916
1397
  export namespace Repository {
@@ -922,21 +1403,25 @@ export namespace Repository {
922
1403
  export interface WorkspaceInstancePortsChangedEvent {
923
1404
  type: "PortsChanged";
924
1405
  instanceID: string;
925
- portsOpened: number[]
926
- portsClosed: number[]
1406
+ portsOpened: number[];
1407
+ portsClosed: number[];
927
1408
  }
928
1409
 
929
1410
  export namespace WorkspaceInstancePortsChangedEvent {
930
-
931
1411
  export function is(data: any): data is WorkspaceInstancePortsChangedEvent {
932
1412
  return data && data.type == "PortsChanged";
933
1413
  }
934
-
935
1414
  }
936
1415
 
937
1416
  export interface WorkspaceInfo {
938
- workspace: Workspace
939
- latestInstance?: WorkspaceInstance
1417
+ workspace: Workspace;
1418
+ latestInstance?: WorkspaceInstance;
1419
+ }
1420
+
1421
+ export namespace WorkspaceInfo {
1422
+ export function lastActiveISODate(info: WorkspaceInfo): string {
1423
+ return info.latestInstance?.creationTime || info.workspace.creationTime;
1424
+ }
940
1425
  }
941
1426
 
942
1427
  export type RunningWorkspaceInfo = WorkspaceInfo & { latestInstance: WorkspaceInstance };
@@ -946,34 +1431,25 @@ export interface WorkspaceCreationResult {
946
1431
  workspaceURL?: string;
947
1432
  existingWorkspaces?: WorkspaceInfo[];
948
1433
  runningWorkspacePrebuild?: {
949
- prebuildID: string
950
- workspaceID: string
951
- starting: RunningWorkspacePrebuildStarting
952
- sameCluster: boolean
953
- }
1434
+ prebuildID: string;
1435
+ workspaceID: string;
1436
+ instanceID: string;
1437
+ starting: RunningWorkspacePrebuildStarting;
1438
+ sameCluster: boolean;
1439
+ };
954
1440
  runningPrebuildWorkspaceID?: string;
955
1441
  }
956
- export type RunningWorkspacePrebuildStarting = 'queued' | 'starting' | 'running';
957
-
958
- export enum CreateWorkspaceMode {
959
- // Default returns a running prebuild if there is any, otherwise creates a new workspace (using a prebuild if one is available)
960
- Default = 'default',
961
- // 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.
962
- ForceNew = 'force-new',
963
- // UsePrebuild polls the database waiting for a currently running prebuild to become available. This mode exists to handle the db-sync delay.
964
- UsePrebuild = 'use-prebuild',
965
- // SelectIfRunning returns a list of currently running workspaces for the context URL if there are any, otherwise falls back to Default mode
966
- SelectIfRunning = 'select-if-running',
967
- }
1442
+ export type RunningWorkspacePrebuildStarting = "queued" | "starting" | "running";
968
1443
 
969
1444
  export namespace WorkspaceCreationResult {
970
1445
  export function is(data: any): data is WorkspaceCreationResult {
971
- return data && (
972
- 'createdWorkspaceId' in data
973
- || 'existingWorkspaces' in data
974
- || 'runningWorkspacePrebuild' in data
975
- || 'runningPrebuildWorkspaceID' in data
976
- )
1446
+ return (
1447
+ data &&
1448
+ ("createdWorkspaceId" in data ||
1449
+ "existingWorkspaces" in data ||
1450
+ "runningWorkspacePrebuild" in data ||
1451
+ "runningPrebuildWorkspaceID" in data)
1452
+ );
977
1453
  }
978
1454
  }
979
1455
 
@@ -993,6 +1469,7 @@ export interface AuthProviderInfo {
993
1469
  readonly authProviderType: string;
994
1470
  readonly host: string;
995
1471
  readonly ownerId?: string;
1472
+ readonly organizationId?: string;
996
1473
  readonly verified: boolean;
997
1474
  readonly isReadonly?: boolean;
998
1475
  readonly hiddenOnDashboard?: boolean;
@@ -1007,7 +1484,7 @@ export interface AuthProviderInfo {
1007
1484
  readonly default: string[];
1008
1485
  readonly publicRepo: string[];
1009
1486
  readonly privateRepo: string[];
1010
- }
1487
+ };
1011
1488
  }
1012
1489
 
1013
1490
  export interface AuthProviderEntry {
@@ -1015,10 +1492,13 @@ export interface AuthProviderEntry {
1015
1492
  readonly type: AuthProviderEntry.Type;
1016
1493
  readonly host: string;
1017
1494
  readonly ownerId: string;
1495
+ readonly organizationId?: string;
1018
1496
 
1019
1497
  readonly status: AuthProviderEntry.Status;
1020
1498
 
1021
1499
  readonly oauth: OAuth2Config;
1500
+ /** A random string that is to change whenever oauth changes (enforced on DB level) */
1501
+ readonly oauthRevision?: string;
1022
1502
  }
1023
1503
 
1024
1504
  export interface OAuth2Config {
@@ -1031,47 +1511,35 @@ export interface OAuth2Config {
1031
1511
  readonly scopeSeparator?: string;
1032
1512
 
1033
1513
  readonly settingsUrl?: string;
1034
- readonly authorizationParams?: { [key: string]: string }
1514
+ readonly authorizationParams?: { [key: string]: string };
1035
1515
  readonly configURL?: string;
1036
1516
  }
1037
1517
 
1038
1518
  export namespace AuthProviderEntry {
1039
1519
  export type Type = "GitHub" | "GitLab" | string;
1040
1520
  export type Status = "pending" | "verified";
1041
- export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type">;
1042
- export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> & Pick<OAuth2Config, "clientId" | "clientSecret">;
1043
- }
1044
-
1045
- export interface Branding {
1046
- readonly name: string;
1047
- readonly favicon?: string;
1048
- /** Either including domain OR absolute path (interpreted relative to host URL) */
1049
- readonly logo: string;
1050
- readonly startupLogo: string;
1051
- readonly showProductivityTips: boolean;
1052
- readonly redirectUrlIfNotAuthenticated?: string;
1053
- readonly redirectUrlAfterLogout?: string;
1054
- readonly homepage: string;
1055
- readonly ide?: {
1056
- readonly logo: string;
1057
- readonly showReleaseNotes: boolean;
1058
- readonly helpMenu: Branding.Link[];
1059
- }
1060
- readonly links: {
1061
- readonly header: Branding.Link[];
1062
- readonly footer: Branding.Link[];
1063
- readonly social: Branding.SocialLink[];
1064
- readonly legal: Branding.Link[];
1065
- }
1066
- }
1067
- export namespace Branding {
1068
- export interface Link {
1069
- readonly name: string;
1070
- readonly url: string;
1071
- }
1072
- export interface SocialLink {
1073
- readonly type: string;
1074
- readonly url: string;
1521
+ export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type"> & {
1522
+ clientId?: string;
1523
+ clientSecret?: string;
1524
+ };
1525
+ export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> &
1526
+ Pick<OAuth2Config, "clientId" | "clientSecret">;
1527
+ export type NewOrgEntry = NewEntry & {
1528
+ organizationId: string;
1529
+ };
1530
+ export type UpdateOrgEntry = Pick<AuthProviderEntry, "id"> & {
1531
+ clientId: string;
1532
+ clientSecret: string;
1533
+ organizationId: string;
1534
+ };
1535
+ export function redact(entry: AuthProviderEntry): AuthProviderEntry {
1536
+ return {
1537
+ ...entry,
1538
+ oauth: {
1539
+ ...entry.oauth,
1540
+ clientSecret: "redacted",
1541
+ },
1542
+ };
1075
1543
  }
1076
1544
  }
1077
1545
 
@@ -1100,3 +1568,23 @@ export namespace TheiaPlugin {
1100
1568
  CheckinFailed = "checkin-failed",
1101
1569
  }
1102
1570
  }
1571
+
1572
+ export interface TermsAcceptanceEntry {
1573
+ readonly userId: string;
1574
+ readonly termsRevision: string;
1575
+ readonly acceptionTime: string;
1576
+ }
1577
+
1578
+ export interface Terms {
1579
+ readonly revision: string;
1580
+ readonly activeSince: string;
1581
+ readonly adminOnlyTerms: boolean;
1582
+ readonly updateMessage: string;
1583
+ readonly content: string;
1584
+ readonly formElements?: object;
1585
+ }
1586
+
1587
+ export interface StripeConfig {
1588
+ individualUsagePriceIds: { [currency: string]: string };
1589
+ teamUsagePriceIds: { [currency: string]: string };
1590
+ }