@gitpod/gitpod-protocol 0.1.5-sje-installer-fun.1 → 0.1.5-sje-kots-node-reqs.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/lib/admin-protocol.d.ts +4 -0
  2. package/lib/admin-protocol.d.ts.map +1 -1
  3. package/lib/admin-protocol.js.map +1 -1
  4. package/lib/attribution.d.ts +20 -0
  5. package/lib/attribution.d.ts.map +1 -0
  6. package/lib/attribution.js +40 -0
  7. package/lib/attribution.js.map +1 -0
  8. package/lib/experiments/configcat-server.d.ts.map +1 -1
  9. package/lib/experiments/configcat-server.js +1 -0
  10. package/lib/experiments/configcat-server.js.map +1 -1
  11. package/lib/experiments/configcat.d.ts +3 -2
  12. package/lib/experiments/configcat.d.ts.map +1 -1
  13. package/lib/experiments/configcat.js +9 -3
  14. package/lib/experiments/configcat.js.map +1 -1
  15. package/lib/experiments/types.d.ts +7 -3
  16. package/lib/experiments/types.d.ts.map +1 -1
  17. package/lib/experiments/types.js +2 -0
  18. package/lib/experiments/types.js.map +1 -1
  19. package/lib/gitpod-service.d.ts +9 -2
  20. package/lib/gitpod-service.d.ts.map +1 -1
  21. package/lib/gitpod-service.js +1 -1
  22. package/lib/gitpod-service.js.map +1 -1
  23. package/lib/index.d.ts +1 -0
  24. package/lib/index.d.ts.map +1 -1
  25. package/lib/index.js +1 -0
  26. package/lib/index.js.map +1 -1
  27. package/lib/protocol.d.ts +47 -1
  28. package/lib/protocol.d.ts.map +1 -1
  29. package/lib/protocol.js +90 -2
  30. package/lib/protocol.js.map +1 -1
  31. package/lib/protocol.spec.d.ts +7 -0
  32. package/lib/protocol.spec.d.ts.map +1 -0
  33. package/lib/protocol.spec.js +127 -0
  34. package/lib/protocol.spec.js.map +1 -0
  35. package/lib/teams-projects-protocol.d.ts +12 -0
  36. package/lib/teams-projects-protocol.d.ts.map +1 -1
  37. package/lib/teams-projects-protocol.js.map +1 -1
  38. package/lib/usage.d.ts +22 -0
  39. package/lib/usage.d.ts.map +1 -0
  40. package/lib/usage.js +115 -0
  41. package/lib/usage.js.map +1 -0
  42. package/lib/webhook-event.d.ts +44 -0
  43. package/lib/webhook-event.d.ts.map +1 -0
  44. package/lib/webhook-event.js +8 -0
  45. package/lib/webhook-event.js.map +1 -0
  46. package/lib/workspace-cluster.d.ts +5 -7
  47. package/lib/workspace-cluster.d.ts.map +1 -1
  48. package/lib/workspace-cluster.js.map +1 -1
  49. package/lib/workspace-instance.d.ts +1 -0
  50. package/lib/workspace-instance.d.ts.map +1 -1
  51. package/package.json +1 -1
  52. package/pkg-yarn.lock +1 -1
  53. package/provenance-bundle.jsonl +1 -1
  54. package/src/admin-protocol.ts +7 -0
  55. package/src/attribution.ts +48 -0
  56. package/src/experiments/configcat-server.ts +1 -0
  57. package/src/experiments/configcat.ts +10 -5
  58. package/src/experiments/types.ts +10 -7
  59. package/src/gitpod-service.ts +14 -1
  60. package/src/index.ts +1 -0
  61. package/src/protocol.spec.ts +97 -0
  62. package/src/protocol.ts +131 -2
  63. package/src/teams-projects-protocol.ts +13 -0
  64. package/src/usage.ts +146 -0
  65. package/src/webhook-event.ts +55 -0
  66. package/src/workspace-cluster.ts +2 -4
  67. package/src/workspace-instance.ts +5 -0
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Copyright (c) 2020 Gitpod GmbH. All rights reserved.
3
+ * Licensed under the GNU Affero General Public License (AGPL).
4
+ * See License-AGPL.txt in the project root for license information.
5
+ */
6
+
7
+ import { suite, test } from "mocha-typescript";
8
+ import * as chai from "chai";
9
+ import { SSHPublicKeyValue } from ".";
10
+
11
+ const expect = chai.expect;
12
+
13
+ @suite
14
+ class TestSSHPublicKeyValue {
15
+ private key =
16
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDCnrN9UdK1bNGPmZfenTWXLuYYDjlYvZE8S+WOfP08WpR1GETzX5ZvgYOEZGwEE8KUPHC9cge4Hvo/ydIS9aqbZ5MiVGJ8cAIq1Ic89SjlDWU6fl8TwIqOPCi2imAASlEDP4q8vMLK1N6UOW1EVbxyL3uybGd10ysC1t1FxFPveIGNsYE/MOQeuEWS16AplpXYXIfVRSlgAskeBft2w8Ud3B4gNe8ECLA/FXu96UpvZkdtOarA3JZ9Z27GveNJg9Mtmmw0+US0KXiO9x9NyH7G8+mqVDwDY+nNvaFA5gtQxkkl/uY2oz9k/B4Rjlj3jOiUXe5uQs3XUm5m8g9a9fh62DabLpA2fEvtfg+a/VqNe52dNa5YjupwvBd6Inb5uMW/TYjNl6bNHPlXFKw/nwLOVzukpkjxMZUKS6+4BGkpoasj6y2rTU/wkpbdD8J7yjI1p6J9aKkC6KksIWgN7xGmHkv2PCGDqMHTNbnQyowtNKMgA/667vAYJ0qW7HAHBFXJRs6uRi/DI3+c1QV2s4wPCpEHDIYApovQ0fbON4WDPoGMyHd7kPh9xB/bX7Dj0uMXImu1pdTd62fQ/1XXX64+vjAAXS/P9RSCD0RCRt/K3LPKl2m7GPI3y1niaE52XhxZw+ms9ays6NasNVMw/ZC+f02Ti+L5FBEVf8230RVVRQ== notfound@gitpod.io";
17
+
18
+ @test public testValidate() {
19
+ const key = this.key;
20
+ const [t, k, e] = key.split(" ");
21
+ expect(
22
+ SSHPublicKeyValue.getData({
23
+ key,
24
+ name: "NiceName",
25
+ }),
26
+ ).to.deep.equal({ type: t, key: k, email: e });
27
+ }
28
+
29
+ @test public testValidateWithDiffType() {
30
+ const key = this.key;
31
+ const [_, k, e] = key.split(" ");
32
+ expect(
33
+ SSHPublicKeyValue.getData({
34
+ key: key.replace("ssh-rsa", "sk-ecdsa-sha2-nistp256@openssh.com"),
35
+ name: "NiceName",
36
+ }),
37
+ ).to.deep.equal({ type: "sk-ecdsa-sha2-nistp256@openssh.com", key: k, email: e });
38
+ }
39
+
40
+ @test public testValidateWithoutEmail() {
41
+ const key = this.key;
42
+ const [t, k, _] = key.split(" ");
43
+ expect(
44
+ SSHPublicKeyValue.getData({
45
+ key: key.replace(" notfound@gitpod.io", ""),
46
+ name: "NiceName",
47
+ }),
48
+ ).to.deep.equal({ type: t, key: k, email: undefined });
49
+ }
50
+
51
+ @test public testValidateWithoutEmailButEndsWithSpaces() {
52
+ const key = this.key;
53
+ const [t, k, _] = key.split(" ");
54
+ expect(
55
+ SSHPublicKeyValue.getData({
56
+ key: key.replace("notfound@gitpod.io", " "),
57
+ name: "NiceName",
58
+ }),
59
+ ).to.deep.equal({ type: t, key: k, email: undefined });
60
+ }
61
+
62
+ @test public testValidateWithError() {
63
+ expect(() =>
64
+ SSHPublicKeyValue.getData({
65
+ key: "Hello World",
66
+ name: "NiceName",
67
+ }),
68
+ ).throw("Key is invalid");
69
+
70
+ expect(() =>
71
+ SSHPublicKeyValue.getData({
72
+ key: "",
73
+ name: "NiceName",
74
+ }),
75
+ ).throw("Key is invalid");
76
+ }
77
+
78
+ @test public testGetFingerprint() {
79
+ const key = this.key;
80
+ expect(
81
+ SSHPublicKeyValue.getFingerprint({
82
+ key,
83
+ name: "NiceName",
84
+ }),
85
+ ).to.equal("ykjP/b5aqoa3envmXzWpPMCGgEFMu3QvubfSTNrJCMA=");
86
+ }
87
+
88
+ @test public testGetFingerprintWithIncorrectPublicKey() {
89
+ expect(() =>
90
+ SSHPublicKeyValue.getFingerprint({
91
+ key: "Hello World",
92
+ name: "NiceName",
93
+ }),
94
+ ).to.throw("Key is invalid");
95
+ }
96
+ }
97
+ module.exports = new TestSSHPublicKeyValue(); // Only to circumvent no usage warning :-/
package/src/protocol.ts CHANGED
@@ -70,11 +70,14 @@ export namespace User {
70
70
  }
71
71
 
72
72
  /**
73
- * Tries to return the primaryEmail of the first identity this user signed up with.
73
+ * Returns the stored email or if it doesn't exist returns the primaryEmail of the first identity this user signed up with.
74
74
  * @param user
75
75
  * @returns A primaryEmail, or undefined if there is none.
76
76
  */
77
77
  export function getPrimaryEmail(user: User): string | undefined {
78
+ if (user.additionalData?.profile?.emailAddress) {
79
+ return user.additionalData?.profile?.emailAddress;
80
+ }
78
81
  const identities = user.identities.filter((i) => !!i.primaryEmail);
79
82
  if (identities.length <= 0) {
80
83
  return undefined;
@@ -136,6 +139,50 @@ export namespace User {
136
139
  }
137
140
  user.additionalData.ideSettings = newIDESettings;
138
141
  }
142
+
143
+ export function getProfile(user: User): Profile {
144
+ return {
145
+ name: User.getName(user!) || "",
146
+ email: User.getPrimaryEmail(user!) || "",
147
+ company: user?.additionalData?.profile?.companyName,
148
+ avatarURL: user?.avatarUrl,
149
+ };
150
+ }
151
+
152
+ export function setProfile(user: User, profile: Profile): User {
153
+ user.fullName = profile.name;
154
+ user.avatarUrl = profile.avatarURL;
155
+
156
+ if (!user.additionalData) {
157
+ user.additionalData = {};
158
+ }
159
+ if (!user.additionalData.profile) {
160
+ user.additionalData.profile = {};
161
+ }
162
+ user.additionalData.profile.emailAddress = profile.email;
163
+ user.additionalData.profile.companyName = profile.company;
164
+ user.additionalData.profile.lastUpdatedDetailsNudge = new Date().toISOString();
165
+
166
+ return user;
167
+ }
168
+
169
+ // The actual Profile of a User
170
+ export interface Profile {
171
+ name: string;
172
+ email: string;
173
+ company?: string;
174
+ avatarURL?: string;
175
+ }
176
+ export namespace Profile {
177
+ export function hasChanges(before: Profile, after: Profile) {
178
+ return (
179
+ before.name !== after.name ||
180
+ before.email !== after.email ||
181
+ before.company !== after.company ||
182
+ before.avatarURL !== after.avatarURL
183
+ );
184
+ }
185
+ }
139
186
  }
140
187
 
141
188
  export interface AdditionalUserData {
@@ -154,6 +201,20 @@ export interface AdditionalUserData {
154
201
  dotfileRepo?: string;
155
202
  // Identifies an explicit team or user ID to which all the user's workspace usage should be attributed to (e.g. for billing purposes)
156
203
  usageAttributionId?: string;
204
+ // preferred workspace classes
205
+ workspaceClasses?: WorkspaceClasses;
206
+ // additional user profile data
207
+ profile?: ProfileDetails;
208
+ }
209
+
210
+ // The format in which we store User Profiles in
211
+ export interface ProfileDetails {
212
+ // when was the last time the user updated their profile information or has been nudged to do so.
213
+ lastUpdatedDetailsNudge?: string;
214
+ // the user's company name
215
+ companyName?: string;
216
+ // the user's email
217
+ emailAddress?: string;
157
218
  }
158
219
 
159
220
  export interface EmailNotificationSettings {
@@ -172,6 +233,11 @@ export type IDESettings = {
172
233
  useLatestVersion?: boolean;
173
234
  };
174
235
 
236
+ export interface WorkspaceClasses {
237
+ regular: string;
238
+ prebuild: string;
239
+ }
240
+
175
241
  export interface UserPlatform {
176
242
  uid: string;
177
243
  userAgent: string;
@@ -206,6 +272,7 @@ export const WorkspaceFeatureFlags = {
206
272
  full_workspace_backup: undefined,
207
273
  fixed_resources: undefined,
208
274
  persistent_volume_claim: undefined,
275
+ protected_secrets: undefined,
209
276
  };
210
277
  export type NamedWorkspaceFeatureFlag = keyof typeof WorkspaceFeatureFlags;
211
278
 
@@ -357,6 +424,68 @@ export namespace UserEnvVar {
357
424
  }
358
425
  }
359
426
 
427
+ export interface SSHPublicKeyValue {
428
+ name: string;
429
+ key: string;
430
+ }
431
+ export interface UserSSHPublicKey extends SSHPublicKeyValue {
432
+ id: string;
433
+ key: string;
434
+ userId: string;
435
+ fingerprint: string;
436
+ creationTime: string;
437
+ lastUsedTime?: string;
438
+ }
439
+
440
+ export type UserSSHPublicKeyValue = Omit<UserSSHPublicKey, "key" | "userId">;
441
+
442
+ export namespace SSHPublicKeyValue {
443
+ export function validate(value: SSHPublicKeyValue): string | undefined {
444
+ if (value.name.length === 0) {
445
+ return "Title must not be empty.";
446
+ }
447
+ if (value.name.length > 255) {
448
+ return "Title too long. Maximum value length is 255 characters.";
449
+ }
450
+ if (value.key.length === 0) {
451
+ return "Key must not be empty.";
452
+ }
453
+ try {
454
+ getData(value);
455
+ } catch (e) {
456
+ return "Key is invalid. You must supply a key in OpenSSH public key format.";
457
+ }
458
+ return;
459
+ }
460
+
461
+ export function getData(value: SSHPublicKeyValue) {
462
+ // 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'.
463
+ const regex =
464
+ /^(?<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>.*?))?$/;
465
+ const resultGroup = regex.exec(value.key.trim());
466
+ if (!resultGroup) {
467
+ throw new Error("Key is invalid.");
468
+ }
469
+ return {
470
+ type: resultGroup.groups?.["type"] as string,
471
+ key: resultGroup.groups?.["key"] as string,
472
+ email: resultGroup.groups?.["email"] || undefined,
473
+ };
474
+ }
475
+
476
+ export function getFingerprint(value: SSHPublicKeyValue) {
477
+ const data = getData(value);
478
+ let buf = Buffer.from(data.key, "base64");
479
+ // gitlab style
480
+ // const hash = createHash("md5").update(buf).digest("hex");
481
+ // github style
482
+ const hash = createHash("sha256").update(buf).digest("base64");
483
+ return hash;
484
+ }
485
+
486
+ export const MAXIMUM_KEY_LENGTH = 5;
487
+ }
488
+
360
489
  export interface GitpodToken {
361
490
  /** Hash value (SHA256) of the token (primary key). */
362
491
  tokenHash: string;
@@ -565,7 +694,7 @@ export interface Workspace {
565
694
 
566
695
  export type WorkspaceSoftDeletion = "user" | "gc";
567
696
 
568
- export type WorkspaceType = "regular" | "prebuild" | "probe";
697
+ export type WorkspaceType = "regular" | "prebuild" | "probe"; // TODO(gpl) Removed prove here
569
698
 
570
699
  export namespace Workspace {
571
700
  export function getFullRepositoryName(ws: Workspace): string | undefined {
@@ -7,6 +7,7 @@
7
7
  import { PrebuiltWorkspaceState } from "./protocol";
8
8
  import { v4 as uuidv4 } from "uuid";
9
9
  import { DeepPartial } from "./util/deep-partial";
10
+ import { WebhookEvent } from "./webhook-event";
10
11
 
11
12
  export interface ProjectConfig {
12
13
  ".gitpod.yml": string;
@@ -152,3 +153,15 @@ export interface TeamMembershipInvite {
152
153
  /** This is a flag that triggers the HARD DELETION of this entity */
153
154
  deleted?: boolean;
154
155
  }
156
+
157
+ export interface PrebuildEvent {
158
+ id: string;
159
+ creationTime: string;
160
+ status: WebhookEvent.Status | WebhookEvent.PrebuildStatus;
161
+ message?: string;
162
+ prebuildId?: string;
163
+ projectId?: string;
164
+ cloneUrl?: string;
165
+ branch?: string;
166
+ commit?: string;
167
+ }
package/src/usage.ts ADDED
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3
+ * Licensed under the GNU Affero General Public License (AGPL).
4
+ * See License-AGPL.txt in the project root for license information.
5
+ */
6
+
7
+ import { WorkspaceType } from "./protocol";
8
+
9
+ export interface BillableSession {
10
+ // The id of the one paying the bill
11
+ attributionId: string;
12
+
13
+ // Relevant for workspace type. When prebuild, shows "prebuild"
14
+ userId?: string;
15
+ teamId?: string;
16
+
17
+ instanceId: string;
18
+
19
+ workspaceId: string;
20
+
21
+ workspaceType: BillableWorkspaceType;
22
+
23
+ // "standard" or "XL"
24
+ workspaceClass: string;
25
+
26
+ // When the workspace started
27
+ startTime: string;
28
+
29
+ // When the workspace ended
30
+ endTime: string;
31
+
32
+ // The credits used for this session
33
+ credits: number;
34
+
35
+ // TODO - maybe
36
+ projectId?: string;
37
+ }
38
+
39
+ export type BillableWorkspaceType = WorkspaceType;
40
+
41
+ export const billableSessionDummyData: BillableSession[] = [
42
+ {
43
+ attributionId: "some-attribution-id",
44
+ userId: "prebuild",
45
+ teamId: "prebuild",
46
+ instanceId: "some-instance-id",
47
+ workspaceId: "some-workspace-id",
48
+ workspaceType: "prebuild",
49
+ workspaceClass: "XL",
50
+ startTime: new Date(Date.now() + -3 * 24 * 3600 * 1000).toISOString(), // 3 days ago
51
+ endTime: new Date().toISOString(),
52
+ credits: 320,
53
+ projectId: "project-123",
54
+ },
55
+ {
56
+ attributionId: "some-attribution-id2",
57
+ userId: "some-user",
58
+ teamId: "some-team",
59
+ instanceId: "some-instance-id2",
60
+ workspaceId: "some-workspace-id2",
61
+ workspaceType: "regular",
62
+ workspaceClass: "standard",
63
+ startTime: new Date(Date.now() + -5 * 24 * 3600 * 1000).toISOString(),
64
+ endTime: new Date().toISOString(),
65
+ credits: 130,
66
+ projectId: "project-123",
67
+ },
68
+ {
69
+ attributionId: "some-attribution-id3",
70
+ userId: "some-other-user",
71
+ teamId: "some-other-team",
72
+ instanceId: "some-instance-id3",
73
+ workspaceId: "some-workspace-id3",
74
+ workspaceType: "regular",
75
+ workspaceClass: "XL",
76
+ startTime: new Date(Date.now() + -5 * 24 * 3600 * 1000).toISOString(),
77
+ endTime: new Date(Date.now() + -4 * 24 * 3600 * 1000).toISOString(),
78
+ credits: 150,
79
+ projectId: "project-134",
80
+ },
81
+ {
82
+ attributionId: "some-attribution-id4",
83
+ userId: "some-other-user2",
84
+ teamId: "some-other-team2",
85
+ instanceId: "some-instance-id4",
86
+ workspaceId: "some-workspace-id4",
87
+ workspaceType: "regular",
88
+ workspaceClass: "standard",
89
+ startTime: new Date(Date.now() + -10 * 24 * 3600 * 1000).toISOString(),
90
+ endTime: new Date(Date.now() + -9 * 24 * 3600 * 1000).toISOString(),
91
+ credits: 330,
92
+ projectId: "project-137",
93
+ },
94
+ {
95
+ attributionId: "some-attribution-id5",
96
+ userId: "some-other-user3",
97
+ teamId: "some-other-team3",
98
+ instanceId: "some-instance-id5",
99
+ workspaceId: "some-workspace-id5",
100
+ workspaceType: "regular",
101
+ workspaceClass: "XL",
102
+ startTime: new Date(Date.now() + -2 * 24 * 3600 * 1000).toISOString(),
103
+ endTime: new Date().toISOString(),
104
+ credits: 222,
105
+ projectId: "project-138",
106
+ },
107
+ {
108
+ attributionId: "some-attribution-id6",
109
+ userId: "some-other-user4",
110
+ teamId: "some-other-team4",
111
+ instanceId: "some-instance-id6",
112
+ workspaceId: "some-workspace-id3",
113
+ workspaceType: "regular",
114
+ workspaceClass: "XL",
115
+ startTime: new Date(Date.now() + -7 * 24 * 3600 * 1000).toISOString(),
116
+ endTime: new Date(Date.now() + -6 * 24 * 3600 * 1000).toISOString(),
117
+ credits: 300,
118
+ projectId: "project-134",
119
+ },
120
+ {
121
+ attributionId: "some-attribution-id8",
122
+ userId: "some-other-user5",
123
+ teamId: "some-other-team5",
124
+ instanceId: "some-instance-id8",
125
+ workspaceId: "some-workspace-id3",
126
+ workspaceType: "regular",
127
+ workspaceClass: "standard",
128
+ startTime: new Date(Date.now() + -1 * 24 * 3600 * 1000).toISOString(),
129
+ endTime: new Date().toISOString(),
130
+ credits: 100,
131
+ projectId: "project-567",
132
+ },
133
+ {
134
+ attributionId: "some-attribution-id7",
135
+ userId: "prebuild",
136
+ teamId: "some-other-team7",
137
+ instanceId: "some-instance-id7",
138
+ workspaceId: "some-workspace-id7",
139
+ workspaceType: "prebuild",
140
+ workspaceClass: "XL",
141
+ startTime: new Date(Date.now() + -1 * 24 * 3600 * 1000).toISOString(),
142
+ endTime: new Date().toISOString(),
143
+ credits: 200,
144
+ projectId: "project-345",
145
+ },
146
+ ];
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3
+ * Licensed under the GNU Affero General Public License (AGPL).
4
+ * See License-AGPL.txt in the project root for license information.
5
+ */
6
+
7
+ export interface WebhookEvent {
8
+ id: string;
9
+ creationTime: string;
10
+ type: "push" | string;
11
+
12
+ /**
13
+ * Typically the webhook installer is referenced here.
14
+ */
15
+ authorizedUserId?: string;
16
+
17
+ /**
18
+ * webhook event's payload
19
+ */
20
+ rawEvent: string;
21
+
22
+ /**
23
+ * The general status of the received webhook event.
24
+ */
25
+ status: WebhookEvent.Status;
26
+
27
+ /**
28
+ * Optional message to help understand errors with handling events.
29
+ */
30
+ message?: string;
31
+
32
+ /**
33
+ * If the webhook event is considered to trigger a prebuild, the `prebuildStatus`
34
+ * contains a more specific status.
35
+ */
36
+ prebuildStatus?: WebhookEvent.PrebuildStatus;
37
+
38
+ /**
39
+ * If `prebuildStatus` is `prebuild_triggered` this points to a prebuild.
40
+ */
41
+ prebuildId?: string;
42
+
43
+ projectId?: string;
44
+
45
+ cloneUrl?: string;
46
+
47
+ branch?: string;
48
+
49
+ commit?: string;
50
+ }
51
+
52
+ export namespace WebhookEvent {
53
+ export type Status = "received" | "dismissed_unauthorized" | "ignored" | "processed";
54
+ export type PrebuildStatus = "ignored_unconfigured" | "prebuild_trigger_failed" | "prebuild_triggered";
55
+ }
@@ -56,12 +56,10 @@ export type WorkspaceManagerConnectionInfo = Pick<WorkspaceCluster, "name" | "ur
56
56
  export type AdmissionConstraint =
57
57
  | AdmissionConstraintFeaturePreview
58
58
  | AdmissionConstraintHasPermission
59
- | AdmissionConstraintHasUserLevel
60
- | AdmissionConstraintHasMoreResources;
59
+ | AdmissionConstraintHasClass;
61
60
  export type AdmissionConstraintFeaturePreview = { type: "has-feature-preview" };
62
61
  export type AdmissionConstraintHasPermission = { type: "has-permission"; permission: PermissionName };
63
- export type AdmissionConstraintHasUserLevel = { type: "has-user-level"; level: string };
64
- export type AdmissionConstraintHasMoreResources = { type: "has-more-resources" };
62
+ export type AdmissionConstraintHasClass = { type: "has-class"; id: string; displayName: string };
65
63
 
66
64
  export namespace AdmissionConstraint {
67
65
  export function is(o: any): o is AdmissionConstraint {
@@ -72,6 +72,11 @@ export interface WorkspaceInstance {
72
72
 
73
73
  // WorkspaceInstanceStatus describes the current state of a workspace instance
74
74
  export interface WorkspaceInstanceStatus {
75
+ // version is the current version of the workspace instance status
76
+ // Note: consider this value opague. The only guarantee given is that it imposes
77
+ // a partial order on status updates, i.e. a.version > b.version -> a newer than b.
78
+ version?: number;
79
+
75
80
  // phase describes a high-level state of the workspace instance
76
81
  phase: WorkspaceInstancePhase;
77
82