@gitpod/gitpod-protocol 0.1.5-pd-workspacekit.3 → 0.1.5-pd-proto-ide.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 (47) hide show
  1. package/lib/billing-mode.js +2 -2
  2. package/lib/billing-mode.js.map +1 -1
  3. package/lib/frontend-dashboard-service.d.ts +90 -0
  4. package/lib/frontend-dashboard-service.d.ts.map +1 -0
  5. package/lib/frontend-dashboard-service.js +49 -0
  6. package/lib/frontend-dashboard-service.js.map +1 -0
  7. package/lib/gitpod-service.d.ts +29 -10
  8. package/lib/gitpod-service.d.ts.map +1 -1
  9. package/lib/gitpod-service.js +25 -11
  10. package/lib/gitpod-service.js.map +1 -1
  11. package/lib/permission.d.ts +4 -1
  12. package/lib/permission.d.ts.map +1 -1
  13. package/lib/permission.js +3 -0
  14. package/lib/permission.js.map +1 -1
  15. package/lib/protocol.d.ts +16 -0
  16. package/lib/protocol.d.ts.map +1 -1
  17. package/lib/protocol.js.map +1 -1
  18. package/lib/teams-projects-protocol.d.ts +4 -1
  19. package/lib/teams-projects-protocol.d.ts.map +1 -1
  20. package/lib/teams-projects-protocol.js +12 -1
  21. package/lib/teams-projects-protocol.js.map +1 -1
  22. package/lib/typings/globals.d.ts +2 -1
  23. package/lib/typings/globals.d.ts.map +1 -1
  24. package/lib/util/gitpod-host-url.d.ts +7 -13
  25. package/lib/util/gitpod-host-url.d.ts.map +1 -1
  26. package/lib/util/gitpod-host-url.js +22 -38
  27. package/lib/util/gitpod-host-url.js.map +1 -1
  28. package/lib/util/tracing.d.ts +1 -0
  29. package/lib/util/tracing.d.ts.map +1 -1
  30. package/lib/util/tracing.js +10 -0
  31. package/lib/util/tracing.js.map +1 -1
  32. package/lib/workspace-cluster.d.ts +1 -0
  33. package/lib/workspace-cluster.d.ts.map +1 -1
  34. package/lib/workspace-cluster.js.map +1 -1
  35. package/package.json +1 -1
  36. package/pkg-yarn.lock +1 -1
  37. package/provenance-bundle.jsonl +1 -1
  38. package/src/billing-mode.ts +2 -2
  39. package/src/frontend-dashboard-service.ts +125 -0
  40. package/src/gitpod-service.ts +50 -15
  41. package/src/permission.ts +4 -0
  42. package/src/protocol.ts +19 -0
  43. package/src/teams-projects-protocol.ts +10 -1
  44. package/src/typings/globals.ts +4 -1
  45. package/src/util/gitpod-host-url.ts +25 -45
  46. package/src/util/tracing.ts +9 -0
  47. package/src/workspace-cluster.ts +4 -0
@@ -128,7 +128,6 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
128
128
  deleteWorkspace(id: string): Promise<void>;
129
129
  setWorkspaceDescription(id: string, desc: string): Promise<void>;
130
130
  controlAdmission(id: string, level: GitpodServer.AdmissionLevel): Promise<void>;
131
- restartRing1(workspaceId: string, type: number): Promise<void>;
132
131
 
133
132
  updateWorkspaceUserPin(id: string, action: GitpodServer.PinAction): Promise<void>;
134
133
  sendHeartBeat(options: GitpodServer.SendHeartBeatOptions): Promise<void>;
@@ -166,6 +165,7 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
166
165
 
167
166
  // Teams
168
167
  getTeam(teamId: string): Promise<Team>;
168
+ updateTeam(teamId: string, team: Pick<Team, "name">): Promise<Team>;
169
169
  getTeams(): Promise<Team[]>;
170
170
  getTeamMembers(teamId: string): Promise<TeamMemberInfo[]>;
171
171
  createTeam(name: string): Promise<Team>;
@@ -175,6 +175,10 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
175
175
  getGenericInvite(teamId: string): Promise<TeamMembershipInvite>;
176
176
  resetGenericInvite(inviteId: string): Promise<TeamMembershipInvite>;
177
177
  deleteTeam(teamId: string): Promise<void>;
178
+ createOrgAuthProvider(params: GitpodServer.CreateOrgAuthProviderParams): Promise<AuthProviderEntry>;
179
+ updateOrgAuthProvider(params: GitpodServer.UpdateOrgAuthProviderParams): Promise<AuthProviderEntry>;
180
+ getOrgAuthProviders(params: GitpodServer.GetOrgAuthProviderParams): Promise<AuthProviderEntry[]>;
181
+ deleteOrgAuthProvider(params: GitpodServer.DeleteOrgAuthProviderParams): Promise<void>;
178
182
 
179
183
  // Projects
180
184
  getProviderRepositoriesForUser(params: GetProviderRepositoriesParams): Promise<ProviderRepository[]>;
@@ -273,6 +277,7 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
273
277
  getStripePublishableKey(): Promise<string>;
274
278
  getStripeSetupIntentClientSecret(): Promise<string>;
275
279
  findStripeSubscriptionId(attributionId: string): Promise<string | undefined>;
280
+ getPriceInformation(attributionId: string): Promise<string | undefined>;
276
281
  createStripeCustomerIfNeeded(attributionId: string, currency: string): Promise<void>;
277
282
  subscribeToStripe(attributionId: string, setupIntentId: string, usageLimit: number): Promise<number | undefined>;
278
283
  getStripePortalUrl(attributionId: string): Promise<string>;
@@ -353,16 +358,33 @@ export interface ClientHeaderFields {
353
358
  clientRegion?: string;
354
359
  }
355
360
 
356
- export const WORKSPACE_TIMEOUT_DEFAULT_SHORT = "short";
357
- export const WORKSPACE_TIMEOUT_DEFAULT_LONG = "long";
358
- export const WORKSPACE_TIMEOUT_EXTENDED = "extended";
359
- export const WORKSPACE_TIMEOUT_EXTENDED_ALT = "180m"; // for backwards compatibility since the IDE uses this
360
- export const WorkspaceTimeoutValues = [
361
- WORKSPACE_TIMEOUT_DEFAULT_SHORT,
362
- WORKSPACE_TIMEOUT_DEFAULT_LONG,
363
- WORKSPACE_TIMEOUT_EXTENDED,
364
- WORKSPACE_TIMEOUT_EXTENDED_ALT,
365
- ] as const;
361
+ const WORKSPACE_MAXIMUM_TIMEOUT_HOURS = 24;
362
+
363
+ export type WorkspaceTimeoutDuration = string;
364
+ export namespace WorkspaceTimeoutDuration {
365
+ export function validate(duration: string): WorkspaceTimeoutDuration {
366
+ duration = duration.toLowerCase();
367
+ const unit = duration.slice(-1);
368
+ if (!["m", "h"].includes(unit)) {
369
+ throw new Error(`Invalid timeout unit: ${unit}`);
370
+ }
371
+ const value = parseInt(duration.slice(0, -1), 10);
372
+ if (isNaN(value) || value <= 0) {
373
+ throw new Error(`Invalid timeout value: ${duration}`);
374
+ }
375
+ if (
376
+ (unit === "h" && value > WORKSPACE_MAXIMUM_TIMEOUT_HOURS) ||
377
+ (unit === "m" && value > WORKSPACE_MAXIMUM_TIMEOUT_HOURS * 60)
378
+ ) {
379
+ throw new Error("Workspace inactivity timeout cannot exceed 24h");
380
+ }
381
+ return duration;
382
+ }
383
+ }
384
+
385
+ export const WORKSPACE_TIMEOUT_DEFAULT_SHORT: WorkspaceTimeoutDuration = "30m";
386
+ export const WORKSPACE_TIMEOUT_DEFAULT_LONG: WorkspaceTimeoutDuration = "60m";
387
+ export const WORKSPACE_TIMEOUT_EXTENDED: WorkspaceTimeoutDuration = "180m";
366
388
 
367
389
  export const createServiceMock = function <C extends GitpodClient, S extends GitpodServer>(
368
390
  methods: Partial<JsonRpcProxy<S>>,
@@ -387,17 +409,15 @@ export const createServerMock = function <C extends GitpodClient, S extends Gitp
387
409
  });
388
410
  };
389
411
 
390
- type WorkspaceTimeoutDurationTuple = typeof WorkspaceTimeoutValues;
391
- export type WorkspaceTimeoutDuration = WorkspaceTimeoutDurationTuple[number];
392
-
393
412
  export interface SetWorkspaceTimeoutResult {
394
413
  resetTimeoutOnWorkspaces: string[];
414
+ humanReadableDuration: string;
395
415
  }
396
416
 
397
417
  export interface GetWorkspaceTimeoutResult {
398
418
  duration: WorkspaceTimeoutDuration;
399
- durationRaw: string;
400
419
  canChange: boolean;
420
+ humanReadableDuration: string;
401
421
  }
402
422
 
403
423
  export interface StartWorkspaceResult {
@@ -430,6 +450,7 @@ export namespace GitpodServer {
430
450
  forceDefaultImage?: boolean;
431
451
  workspaceClass?: string;
432
452
  ideSettings?: IDESettings;
453
+ region?: string;
433
454
  }
434
455
  export interface TakeSnapshotOptions {
435
456
  workspaceId: string;
@@ -457,6 +478,20 @@ export namespace GitpodServer {
457
478
  export interface DeleteOwnAuthProviderParams {
458
479
  readonly id: string;
459
480
  }
481
+ export interface CreateOrgAuthProviderParams {
482
+ // ownerId is automatically set to the authenticated user
483
+ readonly entry: Omit<AuthProviderEntry.NewOrgEntry, "ownerId">;
484
+ }
485
+ export interface UpdateOrgAuthProviderParams {
486
+ readonly entry: AuthProviderEntry.UpdateOrgEntry;
487
+ }
488
+ export interface GetOrgAuthProviderParams {
489
+ readonly organizationId: string;
490
+ }
491
+ export interface DeleteOrgAuthProviderParams {
492
+ readonly id: string;
493
+ readonly organizationId: string;
494
+ }
460
495
  export type AdmissionLevel = "owner" | "everyone";
461
496
  export type PinAction = "pin" | "unpin" | "toggle";
462
497
  export interface GenerateNewGitpodTokenOptions {
package/src/permission.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  // see below for explanation
8
8
  export const Permissions = {
9
9
  monitor: undefined,
10
+ developer: undefined,
10
11
  enforcement: undefined,
11
12
  "privileged-ws": undefined,
12
13
  "registry-access": undefined,
@@ -53,6 +54,9 @@ export namespace Permission {
53
54
  /** The permission to monitor the (live) state of a Gitpod installation */
54
55
  export const MONITOR: PermissionName = "monitor";
55
56
 
57
+ /** The permission to develop on this running Gitpod installation */
58
+ export const DEVELOPER: PermissionName = "developer";
59
+
56
60
  /** The permission for actions like block user, stop workspace, etc. */
57
61
  export const ENFORCEMENT: PermissionName = "enforcement";
58
62
 
package/src/protocol.ts CHANGED
@@ -17,6 +17,9 @@ export interface User {
17
17
  /** The user id */
18
18
  id: string;
19
19
 
20
+ /** The ID of the Organization this user is owned by. If undefined, the user is owned by the installation */
21
+ organizationId?: string;
22
+
20
23
  /** The timestamp when the user entry was created */
21
24
  creationDate: string;
22
25
 
@@ -212,6 +215,9 @@ export interface AdditionalUserData {
212
215
  workspaceClasses?: WorkspaceClasses;
213
216
  // additional user profile data
214
217
  profile?: ProfileDetails;
218
+ // whether the user has been migrated to team attribution.
219
+ // a corresponding feature flag (team_only_attribution) triggers the migration.
220
+ isMigratedToTeamOnlyAttribution?: boolean;
215
221
  }
216
222
  export namespace AdditionalUserData {
217
223
  export function set(user: User, partialData: Partial<AdditionalUserData>): User {
@@ -652,6 +658,10 @@ export type SnapshotState = "pending" | "available" | "error";
652
658
  export interface Workspace {
653
659
  id: string;
654
660
  creationTime: string;
661
+ /**
662
+ * undefined means it is owned by the user (legacy mode, soon to be removed)
663
+ */
664
+ organizationId?: string;
655
665
  contextURL: string;
656
666
  description: string;
657
667
  ownerId: string;
@@ -1416,6 +1426,7 @@ export interface AuthProviderEntry {
1416
1426
  readonly type: AuthProviderEntry.Type;
1417
1427
  readonly host: string;
1418
1428
  readonly ownerId: string;
1429
+ readonly organizationId?: string;
1419
1430
 
1420
1431
  readonly status: AuthProviderEntry.Status;
1421
1432
 
@@ -1447,6 +1458,14 @@ export namespace AuthProviderEntry {
1447
1458
  };
1448
1459
  export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> &
1449
1460
  Pick<OAuth2Config, "clientId" | "clientSecret">;
1461
+ export type NewOrgEntry = NewEntry & {
1462
+ organizationId: string;
1463
+ };
1464
+ export type UpdateOrgEntry = Pick<AuthProviderEntry, "id"> & {
1465
+ clientId: string;
1466
+ clientSecret: string;
1467
+ organizationId: string;
1468
+ };
1450
1469
  export function redact(entry: AuthProviderEntry): AuthProviderEntry {
1451
1470
  return {
1452
1471
  ...entry,
@@ -48,6 +48,10 @@ export namespace Project {
48
48
  };
49
49
  };
50
50
 
51
+ export function slug(p: Project): string {
52
+ return p.slug || p.name || p.id;
53
+ }
54
+
51
55
  export interface Overview {
52
56
  branches: BranchDetails[];
53
57
  isConsideredInactive?: boolean;
@@ -128,7 +132,6 @@ export interface StartPrebuildResult {
128
132
  export interface Team {
129
133
  id: string;
130
134
  name: string;
131
- slug: string;
132
135
  creationTime: string;
133
136
  markedDeleted?: boolean;
134
137
  /** This is a flag that triggers the HARD DELETION of this entity */
@@ -137,6 +140,12 @@ export interface Team {
137
140
 
138
141
  export type TeamMemberRole = "owner" | "member";
139
142
 
143
+ export namespace TeamMemberRole {
144
+ export function isValid(role: any): role is TeamMemberRole {
145
+ return role === "owner" || role === "member";
146
+ }
147
+ }
148
+
140
149
  export interface TeamMemberInfo {
141
150
  userId: string;
142
151
  fullName?: string;
@@ -5,8 +5,11 @@
5
5
  */
6
6
 
7
7
  interface Window {
8
+ // gitpod is used by supervisor/frontend and vscode browser https://github.com/gitpod-io/openvscode-server/blob/dadd40deda5959c0efdaa0c7d02ab64b6f8b5ad0/src/vs/gitpod/browser/workbench/workbench.ts#L7
8
9
  gitpod: {
9
- service: import("../gitpod-service").GitpodService;
10
10
  ideService?: import("../ide-frontend-service").IDEFrontendService;
11
+ loggedUserID?: string;
12
+
13
+ openDesktopIDE(url: string): void;
11
14
  };
12
15
  }
@@ -16,16 +16,10 @@ const baseWorkspaceIDRegex =
16
16
  "(([a-f][0-9a-f]{7}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})|([0-9a-z]{2,16}-[0-9a-z]{2,16}-[0-9a-z]{8,11}))";
17
17
 
18
18
  // this pattern matches v4 UUIDs as well as the new generated workspace ids (e.g. pink-panda-ns35kd21)
19
- const workspaceIDRegex = RegExp(`^${baseWorkspaceIDRegex}$`);
19
+ const workspaceIDRegex = RegExp(`^(?:debug-)?${baseWorkspaceIDRegex}$`);
20
20
 
21
21
  // this pattern matches URL prefixes of workspaces
22
- const workspaceUrlPrefixRegex = RegExp(`^([0-9]{4,6}-)?${baseWorkspaceIDRegex}\\.`);
23
-
24
- export namespace StartOptions {
25
- export const WORKSPACE_CLASS = "workspaceClass";
26
- export const EDITOR = "editor";
27
- export const USE_LATEST_EDITOR = "useLatestEditor";
28
- }
22
+ const workspaceUrlPrefixRegex = RegExp(`^(([0-9]{4,6}|debug)-)?${baseWorkspaceIDRegex}\\.`);
29
23
 
30
24
  export class GitpodHostUrl {
31
25
  readonly url: URL;
@@ -83,8 +77,15 @@ export class GitpodHostUrl {
83
77
  return updated.with((url) => ({ pathname: `/api${url.pathname}` }));
84
78
  }
85
79
 
86
- withContext(contextUrl: string) {
87
- return this.with((url) => ({ hash: contextUrl }));
80
+ withContext(
81
+ contextUrl: string,
82
+ startOptions?: { showOptions?: boolean; editor?: string; workspaceClass?: string },
83
+ ) {
84
+ const searchParams = new URLSearchParams();
85
+ if (startOptions?.showOptions) {
86
+ searchParams.append("showOptions", "true");
87
+ }
88
+ return this.with((url) => ({ hash: contextUrl, search: searchParams.toString() }));
88
89
  }
89
90
 
90
91
  asWebsocket(): GitpodHostUrl {
@@ -100,27 +101,23 @@ export class GitpodHostUrl {
100
101
  }
101
102
 
102
103
  asBilling(): GitpodHostUrl {
103
- return this.with((url) => ({ pathname: "/billing" }));
104
+ return this.with((url) => ({ pathname: "/user/billing" }));
104
105
  }
105
106
 
106
107
  asLogin(): GitpodHostUrl {
107
108
  return this.with((url) => ({ pathname: "/login" }));
108
109
  }
109
110
 
110
- asUpgradeSubscription(): GitpodHostUrl {
111
- return this.with((url) => ({ pathname: "/plans" }));
112
- }
113
-
114
111
  asAccessControl(): GitpodHostUrl {
115
112
  return this.with((url) => ({ pathname: "/integrations" }));
116
113
  }
117
114
 
118
115
  asSettings(): GitpodHostUrl {
119
- return this.with((url) => ({ pathname: "/settings" }));
116
+ return this.with((url) => ({ pathname: "/user/account" }));
120
117
  }
121
118
 
122
119
  asPreferences(): GitpodHostUrl {
123
- return this.with((url) => ({ pathname: "/preferences" }));
120
+ return this.with((url) => ({ pathname: "/user/preferences" }));
124
121
  }
125
122
 
126
123
  asStart(workspaceId = this.workspaceId): GitpodHostUrl {
@@ -130,35 +127,9 @@ export class GitpodHostUrl {
130
127
  });
131
128
  }
132
129
 
133
- asCreateWorkspace(
134
- contextUrl: string,
135
- o?: {
136
- workspaceClass?: string;
137
- editor?: string;
138
- useLatestEditor?: boolean;
139
- },
140
- ): GitpodHostUrl {
141
- const searchParams: URLSearchParams = new URLSearchParams();
142
- if (o?.workspaceClass && o?.workspaceClass.length > 0) {
143
- searchParams.append(StartOptions.WORKSPACE_CLASS, o.workspaceClass);
144
- }
145
- if (o?.editor && o?.editor?.length > 0) {
146
- searchParams.append(StartOptions.EDITOR, o.editor);
147
- }
148
- if (o?.useLatestEditor !== undefined) {
149
- searchParams.append(StartOptions.USE_LATEST_EDITOR, o.useLatestEditor.toString());
150
- }
151
- return this.withoutWorkspacePrefix().with({
152
- pathname: "/",
153
- search: searchParams.toString(),
154
- hash: "#" + contextUrl,
155
- });
156
- }
157
-
158
- asWorkspaceAuth(instanceID: string, redirect?: boolean): GitpodHostUrl {
130
+ asWorkspaceAuth(instanceID: string): GitpodHostUrl {
159
131
  return this.with((url) => ({
160
132
  pathname: `/api/auth/workspace-cookie/${instanceID}`,
161
- search: redirect ? "redirect" : "",
162
133
  }));
163
134
  }
164
135
 
@@ -174,6 +145,10 @@ export class GitpodHostUrl {
174
145
  return result;
175
146
  }
176
147
 
148
+ get debugWorkspace(): boolean {
149
+ return this.url.host.match(workspaceUrlPrefixRegex)?.[2] === "debug";
150
+ }
151
+
177
152
  get workspaceId(): string | undefined {
178
153
  const hostSegs = this.url.host.split(".");
179
154
  if (hostSegs.length > 1) {
@@ -181,7 +156,7 @@ export class GitpodHostUrl {
181
156
  if (matchResults) {
182
157
  // URL has a workspace prefix
183
158
  // port prefixes are excluded
184
- return matchResults[0];
159
+ return matchResults[1];
185
160
  }
186
161
  }
187
162
 
@@ -190,6 +165,11 @@ export class GitpodHostUrl {
190
165
  return pathSegs[2];
191
166
  }
192
167
 
168
+ const cleanHash = this.url.hash.replace(/^#/, "");
169
+ if (this.url.pathname == "/start/" && cleanHash.match(workspaceIDRegex)) {
170
+ return cleanHash;
171
+ }
172
+
193
173
  return undefined;
194
174
  }
195
175
 
@@ -186,6 +186,15 @@ export namespace TraceContext {
186
186
  context: owi,
187
187
  });
188
188
  }
189
+
190
+ export function finishOnce(span: opentracing.Span): () => void {
191
+ let done = false;
192
+ return () => {
193
+ if (done) return;
194
+ span.finish();
195
+ done = true;
196
+ };
197
+ }
189
198
  }
190
199
 
191
200
  @injectable()
@@ -19,6 +19,10 @@ export interface WorkspaceCluster {
19
19
  // The name can be at most 60 characters.
20
20
  applicationCluster: string;
21
21
 
22
+ // The name of the region this cluster belongs to. E.g. us-west1 or europe-west1
23
+ // The name can be at most 60 characters.
24
+ region: string;
25
+
22
26
  // URL of the cluster's ws-manager API
23
27
  url: string;
24
28