@gitpod/gitpod-protocol 0.1.5-sje-kots-node-reqs.1 → 0.1.5-sje-no-log-envvars.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 (147) hide show
  1. package/data/gitpod-schema.json +71 -129
  2. package/lib/accounting-protocol.d.ts +1 -0
  3. package/lib/accounting-protocol.d.ts.map +1 -1
  4. package/lib/accounting-protocol.js +4 -0
  5. package/lib/accounting-protocol.js.map +1 -1
  6. package/lib/admin-protocol.d.ts +4 -1
  7. package/lib/admin-protocol.d.ts.map +1 -1
  8. package/lib/admin-protocol.js.map +1 -1
  9. package/lib/attribution.d.ts +3 -0
  10. package/lib/attribution.d.ts.map +1 -1
  11. package/lib/attribution.js +10 -0
  12. package/lib/attribution.js.map +1 -1
  13. package/lib/billing-mode.d.ts +41 -0
  14. package/lib/billing-mode.d.ts.map +1 -0
  15. package/lib/billing-mode.js +44 -0
  16. package/lib/billing-mode.js.map +1 -0
  17. package/lib/encryption/encryption-engine.d.ts.map +1 -1
  18. package/lib/encryption/encryption-engine.js +3 -3
  19. package/lib/encryption/encryption-engine.js.map +1 -1
  20. package/lib/encryption/encryption-engine.spec.js +1 -1
  21. package/lib/encryption/encryption-engine.spec.js.map +1 -1
  22. package/lib/encryption/key-provider.js +1 -1
  23. package/lib/encryption/key-provider.js.map +1 -1
  24. package/lib/experiments/configcat-server.d.ts +2 -0
  25. package/lib/experiments/configcat-server.d.ts.map +1 -1
  26. package/lib/experiments/configcat-server.js +2 -1
  27. package/lib/experiments/configcat-server.js.map +1 -1
  28. package/lib/experiments/configcat.d.ts +1 -1
  29. package/lib/experiments/configcat.d.ts.map +1 -1
  30. package/lib/experiments/configcat.js +4 -5
  31. package/lib/experiments/configcat.js.map +1 -1
  32. package/lib/experiments/types.d.ts +2 -3
  33. package/lib/experiments/types.d.ts.map +1 -1
  34. package/lib/experiments/types.js.map +1 -1
  35. package/lib/gitpod-service.d.ts +23 -24
  36. package/lib/gitpod-service.d.ts.map +1 -1
  37. package/lib/gitpod-service.js +12 -0
  38. package/lib/gitpod-service.js.map +1 -1
  39. package/lib/ide-protocol.d.ts +8 -0
  40. package/lib/ide-protocol.d.ts.map +1 -1
  41. package/lib/index.d.ts +0 -1
  42. package/lib/index.d.ts.map +1 -1
  43. package/lib/index.js +0 -1
  44. package/lib/index.js.map +1 -1
  45. package/lib/messaging/client-call-metrics.d.ts +1 -17
  46. package/lib/messaging/client-call-metrics.d.ts.map +1 -1
  47. package/lib/messaging/client-call-metrics.js +1 -2
  48. package/lib/messaging/client-call-metrics.js.map +1 -1
  49. package/lib/messaging/error.d.ts +5 -1
  50. package/lib/messaging/error.d.ts.map +1 -1
  51. package/lib/messaging/error.js +11 -3
  52. package/lib/messaging/error.js.map +1 -1
  53. package/lib/plans.d.ts +1 -0
  54. package/lib/plans.d.ts.map +1 -1
  55. package/lib/plans.js +6 -2
  56. package/lib/plans.js.map +1 -1
  57. package/lib/protocol.d.ts +48 -18
  58. package/lib/protocol.d.ts.map +1 -1
  59. package/lib/protocol.js +34 -9
  60. package/lib/protocol.js.map +1 -1
  61. package/lib/team-subscription-protocol.d.ts +1 -0
  62. package/lib/team-subscription-protocol.d.ts.map +1 -1
  63. package/lib/team-subscription-protocol.js +4 -0
  64. package/lib/team-subscription-protocol.js.map +1 -1
  65. package/lib/teams-projects-protocol.d.ts +0 -1
  66. package/lib/teams-projects-protocol.d.ts.map +1 -1
  67. package/lib/teams-projects-protocol.js.map +1 -1
  68. package/lib/usage.d.ts +49 -10
  69. package/lib/usage.d.ts.map +1 -1
  70. package/lib/usage.js +6 -107
  71. package/lib/usage.js.map +1 -1
  72. package/lib/util/garbage-collected-cache.d.ts.map +1 -1
  73. package/lib/util/garbage-collected-cache.js +5 -0
  74. package/lib/util/garbage-collected-cache.js.map +1 -1
  75. package/lib/util/gitpod-host-url.d.ts +3 -0
  76. package/lib/util/gitpod-host-url.d.ts.map +1 -1
  77. package/lib/util/gitpod-host-url.js +18 -0
  78. package/lib/util/gitpod-host-url.js.map +1 -1
  79. package/lib/util/grpc.d.ts +19 -0
  80. package/lib/util/grpc.d.ts.map +1 -1
  81. package/lib/util/grpc.js +73 -1
  82. package/lib/util/grpc.js.map +1 -1
  83. package/lib/util/logging.spec.d.ts +7 -0
  84. package/lib/util/logging.spec.d.ts.map +1 -0
  85. package/lib/util/logging.spec.js +52 -0
  86. package/lib/util/logging.spec.js.map +1 -0
  87. package/lib/util/nice-grpc.d.ts +9 -0
  88. package/lib/util/nice-grpc.d.ts.map +1 -0
  89. package/lib/util/nice-grpc.js +119 -0
  90. package/lib/util/nice-grpc.js.map +1 -0
  91. package/lib/util/timeutil.d.ts +1 -0
  92. package/lib/util/timeutil.d.ts.map +1 -1
  93. package/lib/util/timeutil.js +7 -1
  94. package/lib/util/timeutil.js.map +1 -1
  95. package/lib/util/timeutil.spec.d.ts +2 -0
  96. package/lib/util/timeutil.spec.d.ts.map +1 -1
  97. package/lib/util/timeutil.spec.js +34 -0
  98. package/lib/util/timeutil.spec.js.map +1 -1
  99. package/lib/workspace-class.d.ts +14 -0
  100. package/lib/workspace-class.d.ts.map +1 -0
  101. package/lib/workspace-class.js +8 -0
  102. package/lib/workspace-class.js.map +1 -0
  103. package/lib/workspace-cluster.d.ts +1 -0
  104. package/lib/workspace-cluster.d.ts.map +1 -1
  105. package/lib/workspace-cluster.js.map +1 -1
  106. package/lib/workspace-instance.d.ts +1 -0
  107. package/lib/workspace-instance.d.ts.map +1 -1
  108. package/lib/wsready.js +1 -1
  109. package/package.json +7 -2
  110. package/pkg-yarn.lock +5 -2
  111. package/provenance-bundle.jsonl +1 -1
  112. package/src/accounting-protocol.ts +3 -0
  113. package/src/admin-protocol.ts +4 -1
  114. package/src/attribution.ts +11 -0
  115. package/src/billing-mode.ts +77 -0
  116. package/src/encryption/encryption-engine.spec.ts +1 -1
  117. package/src/encryption/encryption-engine.ts +7 -3
  118. package/src/encryption/key-provider.ts +1 -1
  119. package/src/experiments/configcat-server.ts +3 -0
  120. package/src/experiments/configcat.ts +3 -4
  121. package/src/experiments/types.ts +4 -5
  122. package/src/gitpod-service.ts +39 -26
  123. package/src/ide-protocol.ts +10 -0
  124. package/src/index.ts +0 -1
  125. package/src/messaging/client-call-metrics.ts +1 -20
  126. package/src/messaging/error.ts +16 -4
  127. package/src/plans.ts +6 -2
  128. package/src/protocol.ts +75 -25
  129. package/src/team-subscription-protocol.ts +3 -0
  130. package/src/teams-projects-protocol.ts +0 -1
  131. package/src/usage.ts +53 -128
  132. package/src/util/garbage-collected-cache.ts +5 -0
  133. package/src/util/gitpod-host-url.ts +21 -0
  134. package/src/util/grpc.ts +89 -0
  135. package/src/util/logging.spec.ts +23 -0
  136. package/src/util/nice-grpc.ts +93 -0
  137. package/src/util/timeutil.spec.ts +28 -1
  138. package/src/util/timeutil.ts +6 -0
  139. package/src/workspace-class.ts +14 -0
  140. package/src/workspace-cluster.ts +4 -0
  141. package/src/workspace-instance.ts +3 -0
  142. package/src/wsready.ts +1 -1
  143. package/lib/email-protocol.d.ts +0 -49
  144. package/lib/email-protocol.d.ts.map +0 -1
  145. package/lib/email-protocol.js +0 -28
  146. package/lib/email-protocol.js.map +0 -1
  147. package/src/email-protocol.ts +0 -65
package/src/usage.ts CHANGED
@@ -6,141 +6,66 @@
6
6
 
7
7
  import { WorkspaceType } from "./protocol";
8
8
 
9
- export interface BillableSession {
10
- // The id of the one paying the bill
9
+ // types below are copied over from components/usage-api/typescript/src/usage/v1/usage_pb.d.ts
10
+ export interface ListUsageRequest {
11
11
  attributionId: string;
12
+ from?: number;
13
+ to?: number;
14
+ order: Ordering;
15
+ pagination?: PaginationRequest;
16
+ }
12
17
 
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;
18
+ export enum Ordering {
19
+ ORDERING_DESCENDING = 0,
20
+ ORDERING_ASCENDING = 1,
21
+ }
22
22
 
23
- // "standard" or "XL"
24
- workspaceClass: string;
23
+ export interface PaginationRequest {
24
+ perPage: number;
25
+ page: number;
26
+ }
25
27
 
26
- // When the workspace started
27
- startTime: string;
28
+ export interface ListUsageResponse {
29
+ usageEntriesList: Usage[];
30
+ pagination?: PaginationResponse;
31
+ creditsUsed: number;
32
+ }
28
33
 
29
- // When the workspace ended
30
- endTime: string;
34
+ export interface PaginationResponse {
35
+ perPage: number;
36
+ totalPages: number;
37
+ total: number;
38
+ page: number;
39
+ }
31
40
 
32
- // The credits used for this session
41
+ export type UsageKind = "workspaceinstance" | "invoice";
42
+ export interface Usage {
43
+ id: string;
44
+ attributionId: string;
45
+ description: string;
33
46
  credits: number;
34
-
35
- // TODO - maybe
36
- projectId?: string;
47
+ effectiveTime?: number;
48
+ kind: UsageKind;
49
+ workspaceInstanceId: string;
50
+ draft: boolean;
51
+ metadata: WorkspaceInstanceUsageData | InvoiceUsageData;
37
52
  }
38
53
 
39
- export type BillableWorkspaceType = WorkspaceType;
54
+ // the equivalent golang shape is maintained in `/workspace/gitpod/`components/usage/pkg/db/usage.go`
55
+ export interface WorkspaceInstanceUsageData {
56
+ workspaceId: string;
57
+ workspaceType: WorkspaceType;
58
+ workspaceClass: string;
59
+ contextURL: string;
60
+ startTime: string;
61
+ endTime?: string;
62
+ userId: string;
63
+ userName: string;
64
+ userAvatarURL: string;
65
+ }
40
66
 
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
- ];
67
+ export interface InvoiceUsageData {
68
+ invoiceId: string;
69
+ startDate: string;
70
+ endDate: string;
71
+ }
@@ -37,6 +37,11 @@ export class GarbageCollectedCache<T> {
37
37
  if (!entry) {
38
38
  return undefined;
39
39
  }
40
+ // Still valid?
41
+ if (entry.expiryDate < Date.now()) {
42
+ this.store.delete(entry.key);
43
+ return undefined;
44
+ }
40
45
  return entry.value;
41
46
  }
42
47
 
@@ -85,6 +85,10 @@ export class GitpodHostUrl {
85
85
  return this.with((url) => ({ protocol: url.protocol === "https:" ? "wss:" : "ws:" }));
86
86
  }
87
87
 
88
+ asWorkspacePage(): GitpodHostUrl {
89
+ return this.with((url) => ({ pathname: "/workspaces" }));
90
+ }
91
+
88
92
  asDashboard(): GitpodHostUrl {
89
93
  return this.with((url) => ({ pathname: "/" }));
90
94
  }
@@ -171,4 +175,21 @@ export class GitpodHostUrl {
171
175
  asApiLogout(): GitpodHostUrl {
172
176
  return this.withApi((url) => ({ pathname: "/logout/" }));
173
177
  }
178
+
179
+ asIDEProxy(): GitpodHostUrl {
180
+ const hostSegments = this.url.host.split(".");
181
+ if (hostSegments[0] === "ide") {
182
+ return this;
183
+ }
184
+ return this.with((url) => ({ host: "ide." + url.host }));
185
+ }
186
+
187
+ asIDEMetrics(): GitpodHostUrl {
188
+ let newUrl: GitpodHostUrl = this;
189
+ const hostSegments = this.url.host.split(".");
190
+ if (hostSegments[0] !== "ide") {
191
+ newUrl = newUrl.asIDEProxy();
192
+ }
193
+ return newUrl.with((url) => ({ pathname: "/metrics-api" }));
194
+ }
174
195
  }
package/src/util/grpc.ts CHANGED
@@ -4,6 +4,9 @@
4
4
  * See License-AGPL.txt in the project root for license information.
5
5
  */
6
6
 
7
+ import * as grpc from "@grpc/grpc-js";
8
+ import { Status } from "@grpc/grpc-js/build/src/constants";
9
+
7
10
  export const defaultGRPCOptions = {
8
11
  "grpc.keepalive_timeout_ms": 10000,
9
12
  "grpc.keepalive_time_ms": 60000,
@@ -13,3 +16,89 @@ export const defaultGRPCOptions = {
13
16
  "grpc.max_reconnect_backoff_ms": 5000,
14
17
  "grpc.max_receive_message_length": 1024 * 1024 * 16,
15
18
  };
19
+
20
+ export type GrpcMethodType = "unary" | "client_stream" | "server_stream" | "bidi_stream";
21
+
22
+ export interface IGrpcCallMetricsLabels {
23
+ service: string;
24
+ method: string;
25
+ type: GrpcMethodType;
26
+ }
27
+
28
+ export interface IGrpcCallMetricsLabelsWithCode extends IGrpcCallMetricsLabels {
29
+ code: string;
30
+ }
31
+
32
+ export const IClientCallMetrics = Symbol("IClientCallMetrics");
33
+
34
+ export interface IClientCallMetrics {
35
+ started(labels: IGrpcCallMetricsLabels): void;
36
+ sent(labels: IGrpcCallMetricsLabels): void;
37
+ received(labels: IGrpcCallMetricsLabels): void;
38
+ handled(labels: IGrpcCallMetricsLabelsWithCode): void;
39
+ }
40
+
41
+ export function getGrpcMethodType(requestStream: boolean, responseStream: boolean): GrpcMethodType {
42
+ if (requestStream) {
43
+ if (responseStream) {
44
+ return "bidi_stream";
45
+ } else {
46
+ return "client_stream";
47
+ }
48
+ } else {
49
+ if (responseStream) {
50
+ return "server_stream";
51
+ } else {
52
+ return "unary";
53
+ }
54
+ }
55
+ }
56
+
57
+ export function createClientCallMetricsInterceptor(metrics: IClientCallMetrics): grpc.Interceptor {
58
+ return (options, nextCall): grpc.InterceptingCall => {
59
+ const methodDef = options.method_definition;
60
+ const method = methodDef.path.substring(methodDef.path.lastIndexOf("/") + 1);
61
+ const service = methodDef.path.substring(1, methodDef.path.length - method.length - 1);
62
+ const labels = {
63
+ service,
64
+ method,
65
+ type: getGrpcMethodType(options.method_definition.requestStream, options.method_definition.responseStream),
66
+ };
67
+ const requester = new grpc.RequesterBuilder()
68
+ .withStart((metadata, listener, next) => {
69
+ const newListener = new grpc.ListenerBuilder()
70
+ .withOnReceiveStatus((status, next) => {
71
+ try {
72
+ metrics.handled({
73
+ ...labels,
74
+ code: Status[status.code],
75
+ });
76
+ } finally {
77
+ next(status);
78
+ }
79
+ })
80
+ .withOnReceiveMessage((message, next) => {
81
+ try {
82
+ metrics.received(labels);
83
+ } finally {
84
+ next(message);
85
+ }
86
+ })
87
+ .build();
88
+ try {
89
+ metrics.started(labels);
90
+ } finally {
91
+ next(metadata, newListener);
92
+ }
93
+ })
94
+ .withSendMessage((message, next) => {
95
+ try {
96
+ metrics.sent(labels);
97
+ } finally {
98
+ next(message);
99
+ }
100
+ })
101
+ .build();
102
+ return new grpc.InterceptingCall(nextCall(options), requester);
103
+ };
104
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copyright (c) 2021 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 { log } from "./logging";
9
+
10
+ @suite
11
+ class TestLogging {
12
+ @test public async testLogInfo_output() {
13
+ const testObj = {
14
+ null: null,
15
+ undefined: undefined,
16
+ empty: "",
17
+ foo: "bar",
18
+ number: 0,
19
+ };
20
+ log.info("info logging test", testObj);
21
+ }
22
+ }
23
+ module.exports = new TestLogging();
@@ -0,0 +1,93 @@
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 { isAbortError } from "abort-controller-x";
8
+ import {
9
+ CallOptions,
10
+ ClientError,
11
+ ClientMiddleware,
12
+ ClientMiddlewareCall,
13
+ Status,
14
+ MethodDescriptor,
15
+ } from "nice-grpc-common";
16
+ import { GrpcMethodType, IClientCallMetrics } from "./grpc";
17
+
18
+ function getLabels(method: MethodDescriptor) {
19
+ const callType = method.requestStream
20
+ ? method.responseStream
21
+ ? "bidi_stream"
22
+ : "client_stream"
23
+ : method.responseStream
24
+ ? "server_stream"
25
+ : "unary";
26
+ const { path } = method;
27
+ const [serviceName, methodName] = path.split("/").slice(1);
28
+
29
+ return {
30
+ type: callType as GrpcMethodType,
31
+ service: serviceName,
32
+ method: methodName,
33
+ };
34
+ }
35
+
36
+ async function* incrementStreamMessagesCounter<T>(iterable: AsyncIterable<T>, callback: () => void): AsyncIterable<T> {
37
+ for await (const item of iterable) {
38
+ callback();
39
+ yield item;
40
+ }
41
+ }
42
+
43
+ export function prometheusClientMiddleware(metrics: IClientCallMetrics): ClientMiddleware {
44
+ return async function* prometheusClientMiddlewareGenerator<Request, Response>(
45
+ call: ClientMiddlewareCall<Request, Response>,
46
+ options: CallOptions,
47
+ ): AsyncGenerator<Response, Response | void, undefined> {
48
+ const labels = getLabels(call.method);
49
+
50
+ metrics.started(labels);
51
+
52
+ let settled = false;
53
+ let status: Status = Status.OK;
54
+
55
+ try {
56
+ let request;
57
+
58
+ if (!call.requestStream) {
59
+ request = call.request;
60
+ } else {
61
+ request = incrementStreamMessagesCounter(call.request, metrics.sent.bind(metrics, labels));
62
+ }
63
+
64
+ if (!call.responseStream) {
65
+ const response = yield* call.next(request, options);
66
+ settled = true;
67
+ return response;
68
+ } else {
69
+ yield* incrementStreamMessagesCounter(
70
+ call.next(request, options),
71
+ metrics.received.bind(metrics, labels),
72
+ );
73
+ settled = true;
74
+ return;
75
+ }
76
+ } catch (err) {
77
+ settled = true;
78
+ if (err instanceof ClientError) {
79
+ status = err.code;
80
+ } else if (isAbortError(err)) {
81
+ status = Status.CANCELLED;
82
+ } else {
83
+ status = Status.UNKNOWN;
84
+ }
85
+ throw err;
86
+ } finally {
87
+ if (!settled) {
88
+ status = Status.CANCELLED;
89
+ }
90
+ metrics.handled({ ...labels, code: Status[status] });
91
+ }
92
+ };
93
+ }
@@ -7,10 +7,16 @@
7
7
  import * as chai from "chai";
8
8
  const expect = chai.expect;
9
9
  import { suite, test } from "mocha-typescript";
10
- import { oneMonthLater } from "./timeutil";
10
+ import { daysBefore, hoursBefore, oneMonthLater } from "./timeutil";
11
11
 
12
12
  @suite()
13
13
  export class TimeutilSpec {
14
+ @test
15
+ testDaysBefore() {
16
+ const now = new Date().toISOString();
17
+ expect(daysBefore(now, 2)).to.be.eq(hoursBefore(now, 48));
18
+ }
19
+
14
20
  @test
15
21
  testTimeutil() {
16
22
  // targeting a 1st, 1th of Jan => 1st of Feb
@@ -39,4 +45,25 @@ export class TimeutilSpec {
39
45
  const later = oneMonthLater(from.toISOString(), day);
40
46
  expect(later, `expected ${later} to be equal ${expectation}`).to.be.equal(expectation.toISOString());
41
47
  }
48
+
49
+ @test
50
+ testDaysBefore2() {
51
+ const tests: { date: Date; daysEarlier: number; expectation: string }[] = [
52
+ {
53
+ date: new Date("2021-07-13T00:00:00.000Z"),
54
+ daysEarlier: 365,
55
+ expectation: "2020-07-13T00:00:00.000Z",
56
+ },
57
+ {
58
+ date: new Date("2019-02-01T00:00:00.000Z"),
59
+ daysEarlier: 365,
60
+ expectation: "2018-02-01T00:00:00.000Z",
61
+ },
62
+ ];
63
+
64
+ for (const t of tests) {
65
+ const actual = daysBefore(t.date.toISOString(), t.daysEarlier);
66
+ expect(actual).to.equal(t.expectation, `expected ${actual} to be equal ${t.expectation}`);
67
+ }
68
+ }
42
69
  }
@@ -47,6 +47,12 @@ export const orderAsc = (d1: string, d2: string): number => liftDate(d1, d2, (d1
47
47
  export const liftDate1 = <T>(d1: string, f: (d1: Date) => T): T => f(new Date(d1));
48
48
  export const liftDate = <T>(d1: string, d2: string, f: (d1: Date, d2: Date) => T): T => f(new Date(d1), new Date(d2));
49
49
 
50
+ export function daysBefore(date: string, days: number): string {
51
+ const result = new Date(date);
52
+ result.setDate(result.getDate() - days);
53
+ return result.toISOString();
54
+ }
55
+
50
56
  export function hoursBefore(date: string, hours: number): string {
51
57
  const result = new Date(date);
52
58
  result.setHours(result.getHours() - hours);
@@ -0,0 +1,14 @@
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 SupportedWorkspaceClass {
8
+ id: string;
9
+ category: string;
10
+ displayName: string;
11
+ description: string;
12
+ powerups: number;
13
+ isSelected: boolean;
14
+ }
@@ -15,6 +15,10 @@ export interface WorkspaceCluster {
15
15
  // Must be identical to the installationShortname of the cluster it represents!
16
16
  name: string;
17
17
 
18
+ // The name of the application cluster to which this cluster should be registered.
19
+ // The name can be at most 60 characters.
20
+ applicationCluster: string;
21
+
18
22
  // URL of the cluster's ws-manager API
19
23
  url: string;
20
24
 
@@ -246,6 +246,9 @@ export interface WorkspaceInstanceConfiguration {
246
246
  // desktopIdeImage is the ref of the desktop IDE image this instance uses.
247
247
  desktopIdeImage?: string;
248
248
 
249
+ // desktopIdePluginImage is the ref of the desktop IDE plugin image this instance uses.
250
+ desktopIdePluginImage?: string;
251
+
249
252
  // supervisorImage is the ref of the supervisor image this instance uses.
250
253
  supervisorImage?: string;
251
254
 
package/src/wsready.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * See License-AGPL.txt in the project root for license information.
5
5
  */
6
6
 
7
- // generated using github.com/32leaves/bel on 2022-05-18 18:19:49.011672619 +0000 UTC m=+0.006607361
7
+ // generated using github.com/32leaves/bel on 2022-10-10 21:41:56.018177383 +0000 UTC m=+0.010324839
8
8
  // DO NOT MODIFY
9
9
 
10
10
  export enum WorkspaceInitSource {
@@ -1,49 +0,0 @@
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
- export declare type EMailState = "scheduledInternal" | "scheduledSendgrid";
7
- export interface EMailStatus {
8
- /** The time the email entry was inserted into the DB */
9
- scheduledInternalTime: string;
10
- /** The time the email state transitioned to "scheduledSendgrid" */
11
- scheduledSendgridTime?: string;
12
- /** In case of any errors during sending with Sendgrid it gets noted here */
13
- error?: string;
14
- }
15
- export declare namespace EMailStatus {
16
- function getState(status: EMailStatus): EMailState;
17
- }
18
- export interface EmailAddress {
19
- name?: string;
20
- email: string;
21
- }
22
- export interface EMailParameters {
23
- /** undefined means default from template */
24
- subject?: string;
25
- /** The sender address */
26
- senderAddress: string | EmailAddress;
27
- /** The replyTo address */
28
- replyToAddress?: string | EmailAddress;
29
- /** The SendGrid template id */
30
- templateId: string;
31
- /** The parameters for the SendGrid template */
32
- templateParams: {};
33
- }
34
- export declare type EMail = {
35
- /** The unique id of this email (uuid/v4 for now) */
36
- uid: string;
37
- /** The id of the user this email was sent to */
38
- userId: string;
39
- /** The address this email was sent to */
40
- recipientAddress: string;
41
- /** Which campaign scheduled this email */
42
- campaignId: string;
43
- /** The parameters this email was sent with (template id, template params, etc) */
44
- params: EMailParameters;
45
- } & EMailStatus;
46
- export declare namespace EMail {
47
- const create: (ts: Omit<EMail, "uid">) => EMail;
48
- }
49
- //# sourceMappingURL=email-protocol.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-protocol.d.ts","sourceRoot":"","sources":["../src/email-protocol.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,oBAAY,UAAU,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEnE,MAAM,WAAW,WAAW;IACxB,wDAAwD;IACxD,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mEAAmE;IACnE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,yBAAiB,WAAW,CAAC;IACzB,SAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAKxD;CACJ;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC5B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,aAAa,EAAE,MAAM,GAAG,YAAY,CAAC;IACrC,0BAA0B;IAC1B,cAAc,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IACvC,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,cAAc,EAAE,EAAE,CAAC;CACtB;AAED,oBAAY,KAAK,GAAG;IAChB,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,MAAM,EAAE,eAAe,CAAC;CAC3B,GAAG,WAAW,CAAC;AAEhB,yBAAiB,KAAK,CAAC;IACZ,MAAM,MAAM,OAAQ,KAAK,KAAK,EAAE,KAAK,CAAC,KAAG,KAI/C,CAAC;CACL"}
@@ -1,28 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) 2020 Gitpod GmbH. All rights reserved.
4
- * Licensed under the GNU Affero General Public License (AGPL).
5
- * See License-AGPL.txt in the project root for license information.
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.EMail = exports.EMailStatus = void 0;
9
- const uuid_1 = require("uuid");
10
- var EMailStatus;
11
- (function (EMailStatus) {
12
- function getState(status) {
13
- if (status.scheduledSendgridTime) {
14
- return "scheduledSendgrid";
15
- }
16
- return "scheduledInternal";
17
- }
18
- EMailStatus.getState = getState;
19
- })(EMailStatus = exports.EMailStatus || (exports.EMailStatus = {}));
20
- var EMail;
21
- (function (EMail) {
22
- EMail.create = (ts) => {
23
- const withId = ts;
24
- withId.uid = (0, uuid_1.v4)();
25
- return withId;
26
- };
27
- })(EMail = exports.EMail || (exports.EMail = {}));
28
- //# sourceMappingURL=email-protocol.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-protocol.js","sourceRoot":"","sources":["../src/email-protocol.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,+BAAoC;AAYpC,IAAiB,WAAW,CAO3B;AAPD,WAAiB,WAAW;IACxB,SAAgB,QAAQ,CAAC,MAAmB;QACxC,IAAI,MAAM,CAAC,qBAAqB,EAAE;YAC9B,OAAO,mBAAmB,CAAC;SAC9B;QACD,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IALe,oBAAQ,WAKvB,CAAA;AACL,CAAC,EAPgB,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAO3B;AAiCD,IAAiB,KAAK,CAMrB;AAND,WAAiB,KAAK;IACL,YAAM,GAAG,CAAC,EAAsB,EAAS,EAAE;QACpD,MAAM,MAAM,GAAG,EAAW,CAAC;QAC3B,MAAM,CAAC,GAAG,GAAG,IAAA,SAAM,GAAE,CAAC;QACtB,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC,EANgB,KAAK,GAAL,aAAK,KAAL,aAAK,QAMrB"}