@gitpod/gitpod-protocol 0.1.5-patch-2-fork.0 → 0.1.5-pd-del-private-repo-check-fork.2
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.
- package/data/gitpod-schema.json +8 -22
- package/lib/accounting-protocol.d.ts +3 -6
- package/lib/accounting-protocol.d.ts.map +1 -1
- package/lib/accounting-protocol.js +10 -16
- package/lib/accounting-protocol.js.map +1 -1
- package/lib/admin-protocol.d.ts +15 -4
- package/lib/admin-protocol.d.ts.map +1 -1
- package/lib/admin-protocol.js +15 -0
- package/lib/admin-protocol.js.map +1 -1
- package/lib/analytics.d.ts +45 -0
- package/lib/analytics.d.ts.map +1 -0
- package/lib/{util/without.js → analytics.js} +4 -2
- package/lib/analytics.js.map +1 -0
- package/lib/context-url.d.ts +18 -0
- package/lib/context-url.d.ts.map +1 -0
- package/lib/context-url.js +49 -0
- package/lib/context-url.js.map +1 -0
- package/lib/{util/context-url.spec.d.ts → context-url.spec.d.ts} +3 -1
- package/lib/context-url.spec.d.ts.map +1 -0
- package/lib/context-url.spec.js +73 -0
- package/lib/context-url.spec.js.map +1 -0
- package/lib/email-protocol.d.ts +1 -2
- package/lib/email-protocol.d.ts.map +1 -1
- package/lib/email-protocol.js +4 -4
- package/lib/email-protocol.js.map +1 -1
- package/lib/encryption/container-module.js +5 -4
- package/lib/encryption/container-module.js.map +1 -1
- package/lib/encryption/encryption-engine.js +19 -20
- package/lib/encryption/encryption-engine.js.map +1 -1
- package/lib/encryption/encryption-engine.spec.js +29 -36
- package/lib/encryption/encryption-engine.spec.js.map +1 -1
- package/lib/encryption/encryption-service.js +29 -43
- package/lib/encryption/encryption-service.js.map +1 -1
- package/lib/encryption/key-provider.js +25 -30
- package/lib/encryption/key-provider.js.map +1 -1
- package/lib/env.d.ts +1 -2
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +20 -21
- package/lib/env.js.map +1 -1
- package/lib/gitpod-file-parser.js +25 -41
- package/lib/gitpod-file-parser.js.map +1 -1
- package/lib/gitpod-file-parser.spec.js +116 -116
- package/lib/gitpod-file-parser.spec.js.map +1 -1
- package/lib/gitpod-service.d.ts +95 -20
- package/lib/gitpod-service.d.ts.map +1 -1
- package/lib/gitpod-service.js +167 -278
- package/lib/gitpod-service.js.map +1 -1
- package/lib/headless-workspace-log.d.ts +8 -11
- package/lib/headless-workspace-log.d.ts.map +1 -1
- package/lib/headless-workspace-log.js +4 -7
- package/lib/headless-workspace-log.js.map +1 -1
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -1
- package/lib/index.js.map +1 -1
- package/lib/messaging/browser/connection.d.ts +5 -3
- package/lib/messaging/browser/connection.d.ts.map +1 -1
- package/lib/messaging/browser/connection.js +183 -33
- package/lib/messaging/browser/connection.js.map +1 -1
- package/lib/messaging/browser/window-connection.js +35 -55
- package/lib/messaging/browser/window-connection.js.map +1 -1
- package/lib/messaging/client-call-metrics.d.ts +35 -0
- package/lib/messaging/client-call-metrics.d.ts.map +1 -0
- package/lib/messaging/client-call-metrics.js +83 -0
- package/lib/messaging/client-call-metrics.js.map +1 -0
- package/lib/messaging/connection-error-handler.js +11 -23
- package/lib/messaging/connection-error-handler.js.map +1 -1
- package/lib/messaging/error.d.ts +2 -1
- package/lib/messaging/error.d.ts.map +1 -1
- package/lib/messaging/error.js +4 -2
- package/lib/messaging/error.js.map +1 -1
- package/lib/messaging/handler.d.ts +10 -0
- package/lib/messaging/handler.d.ts.map +1 -1
- package/lib/messaging/node/connection.js +22 -22
- package/lib/messaging/node/connection.js.map +1 -1
- package/lib/messaging/proxy-factory.d.ts +2 -0
- package/lib/messaging/proxy-factory.d.ts.map +1 -1
- package/lib/messaging/proxy-factory.js +74 -159
- package/lib/messaging/proxy-factory.js.map +1 -1
- package/lib/permission.d.ts +2 -1
- package/lib/permission.d.ts.map +1 -1
- package/lib/permission.js +14 -13
- package/lib/permission.js.map +1 -1
- package/lib/plans.d.ts +210 -0
- package/lib/plans.d.ts.map +1 -0
- package/lib/plans.js +570 -0
- package/lib/plans.js.map +1 -0
- package/lib/protocol.d.ts +93 -15
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +104 -130
- package/lib/protocol.js.map +1 -1
- package/lib/snapshot-url.d.ts +14 -0
- package/lib/snapshot-url.d.ts.map +1 -0
- package/lib/snapshot-url.js +26 -0
- package/lib/snapshot-url.js.map +1 -0
- package/{src/util/without.ts → lib/snapshot-url.spec.d.ts} +2 -3
- package/lib/snapshot-url.spec.d.ts.map +1 -0
- package/lib/snapshot-url.spec.js +41 -0
- package/lib/snapshot-url.spec.js.map +1 -0
- package/lib/team-subscription-protocol.d.ts +4 -4
- package/lib/team-subscription-protocol.d.ts.map +1 -1
- package/lib/team-subscription-protocol.js +15 -12
- package/lib/team-subscription-protocol.js.map +1 -1
- package/lib/teams-projects-protocol.d.ts +103 -0
- package/lib/teams-projects-protocol.d.ts.map +1 -0
- package/lib/teams-projects-protocol.js +23 -0
- package/lib/teams-projects-protocol.js.map +1 -0
- package/lib/util/analytics.d.ts +8 -0
- package/lib/util/analytics.d.ts.map +1 -0
- package/lib/util/analytics.js +79 -0
- package/lib/util/analytics.js.map +1 -0
- package/lib/util/async-iterator.js +55 -133
- package/lib/util/async-iterator.js.map +1 -1
- package/lib/util/cancelable.js +17 -59
- package/lib/util/cancelable.js.map +1 -1
- package/lib/util/date-time.js +8 -8
- package/lib/util/date-time.js.map +1 -1
- package/lib/util/deferred.js +10 -12
- package/lib/util/deferred.js.map +1 -1
- package/lib/util/disposable.js +26 -39
- package/lib/util/disposable.js.map +1 -1
- package/lib/util/event.js +58 -74
- package/lib/util/event.js.map +1 -1
- package/lib/util/garbage-collected-cache.js +22 -46
- package/lib/util/garbage-collected-cache.js.map +1 -1
- package/lib/util/generate-workspace-id.d.ts.map +1 -1
- package/lib/util/generate-workspace-id.js +13 -67
- package/lib/util/generate-workspace-id.js.map +1 -1
- package/lib/util/generate-workspace-id.spec.js +34 -79
- package/lib/util/generate-workspace-id.spec.js.map +1 -1
- package/lib/util/gitpod-cookie.d.ts +20 -0
- package/lib/util/gitpod-cookie.d.ts.map +1 -0
- package/lib/util/gitpod-cookie.js +44 -0
- package/lib/util/gitpod-cookie.js.map +1 -0
- package/lib/util/gitpod-host-url.d.ts +0 -1
- package/lib/util/gitpod-host-url.d.ts.map +1 -1
- package/lib/util/gitpod-host-url.js +95 -98
- package/lib/util/gitpod-host-url.js.map +1 -1
- package/lib/util/gitpod-host-url.spec.d.ts +7 -1
- package/lib/util/gitpod-host-url.spec.d.ts.map +1 -1
- package/lib/util/gitpod-host-url.spec.js +103 -31
- package/lib/util/gitpod-host-url.spec.js.map +1 -1
- package/lib/util/grpc.d.ts +15 -0
- package/lib/util/grpc.d.ts.map +1 -0
- package/lib/util/grpc.js +18 -0
- package/lib/util/grpc.js.map +1 -0
- package/lib/util/logging.d.ts +49 -33
- package/lib/util/logging.d.ts.map +1 -1
- package/lib/util/logging.js +107 -110
- package/lib/util/logging.js.map +1 -1
- package/lib/util/make-link.js +2 -2
- package/lib/util/make-link.js.map +1 -1
- package/lib/util/parse-workspace-id.d.ts +10 -0
- package/lib/util/parse-workspace-id.d.ts.map +1 -1
- package/lib/util/parse-workspace-id.js +32 -7
- package/lib/util/parse-workspace-id.js.map +1 -1
- package/lib/util/parse-workspace-id.spec.d.ts +4 -0
- package/lib/util/parse-workspace-id.spec.d.ts.map +1 -1
- package/lib/util/parse-workspace-id.spec.js +123 -84
- package/lib/util/parse-workspace-id.spec.js.map +1 -1
- package/lib/util/queue.js +16 -55
- package/lib/util/queue.js.map +1 -1
- package/lib/util/queue.spec.js +144 -288
- package/lib/util/queue.spec.js.map +1 -1
- package/lib/util/repeater.js +35 -88
- package/lib/util/repeater.js.map +1 -1
- package/lib/util/safe-promise.js +9 -12
- package/lib/util/safe-promise.js.map +1 -1
- package/lib/util/semaphore.js +15 -46
- package/lib/util/semaphore.js.map +1 -1
- package/lib/util/skip-if.js +6 -6
- package/lib/util/skip-if.js.map +1 -1
- package/lib/util/timeutil.js +28 -16
- package/lib/util/timeutil.js.map +1 -1
- package/lib/util/timeutil.spec.js +21 -24
- package/lib/util/timeutil.spec.js.map +1 -1
- package/lib/util/tracing.js +43 -47
- package/lib/util/tracing.js.map +1 -1
- package/lib/util/workspace-port-authentication.js +3 -2
- package/lib/util/workspace-port-authentication.js.map +1 -1
- package/lib/workspace-cluster.d.ts +74 -0
- package/lib/workspace-cluster.d.ts.map +1 -0
- package/lib/workspace-cluster.js +16 -0
- package/lib/workspace-cluster.js.map +1 -0
- package/lib/workspace-instance.d.ts +4 -2
- package/lib/workspace-instance.d.ts.map +1 -1
- package/lib/wsready.d.ts +1 -1
- package/lib/wsready.js +2 -2
- package/package.json +28 -16
- package/pkg-yarn.lock +17 -9
- package/src/accounting-protocol.ts +4 -10
- package/src/admin-protocol.ts +33 -5
- package/src/analytics.ts +54 -0
- package/src/context-url.spec.ts +39 -0
- package/src/context-url.ts +51 -0
- package/src/email-protocol.ts +2 -3
- package/src/env.ts +10 -10
- package/src/gitpod-service.ts +145 -39
- package/src/headless-workspace-log.ts +7 -11
- package/src/index.ts +5 -1
- package/src/messaging/browser/connection.ts +195 -14
- package/src/messaging/client-call-metrics.ts +97 -0
- package/src/messaging/error.ts +5 -2
- package/src/messaging/handler.ts +12 -0
- package/src/messaging/node/connection.ts +2 -2
- package/src/messaging/proxy-factory.ts +14 -6
- package/src/permission.ts +2 -1
- package/src/plans.ts +632 -0
- package/src/protocol.ts +152 -43
- package/src/snapshot-url.spec.ts +25 -0
- package/src/snapshot-url.ts +27 -0
- package/src/team-subscription-protocol.ts +7 -5
- package/src/teams-projects-protocol.ts +132 -0
- package/src/util/analytics.ts +87 -0
- package/src/util/deferred.ts +1 -1
- package/src/util/garbage-collected-cache.ts +2 -2
- package/src/util/generate-workspace-id.spec.ts +3 -3
- package/src/util/generate-workspace-id.ts +2 -0
- package/src/util/gitpod-cookie.ts +39 -0
- package/src/util/gitpod-host-url.spec.ts +25 -1
- package/src/util/gitpod-host-url.ts +19 -10
- package/src/util/grpc.ts +15 -0
- package/src/util/logging.ts +102 -38
- package/src/util/parse-workspace-id.spec.ts +21 -1
- package/src/util/parse-workspace-id.ts +32 -6
- package/src/util/queue.spec.ts +1 -1
- package/src/util/semaphore.ts +2 -2
- package/src/util/skip-if.ts +1 -1
- package/src/util/timeutil.ts +4 -4
- package/src/workspace-cluster.ts +96 -0
- package/src/workspace-instance.ts +22 -13
- package/src/wsready.ts +2 -2
- package/lib/util/context-url.d.ts +0 -13
- package/lib/util/context-url.d.ts.map +0 -1
- package/lib/util/context-url.js +0 -26
- package/lib/util/context-url.js.map +0 -1
- package/lib/util/context-url.spec.d.ts.map +0 -1
- package/lib/util/context-url.spec.js +0 -52
- package/lib/util/context-url.spec.js.map +0 -1
- package/lib/util/without.d.ts +0 -7
- package/lib/util/without.d.ts.map +0 -1
- package/lib/util/without.js.map +0 -1
- package/src/util/context-url.spec.ts +0 -25
- package/src/util/context-url.ts +0 -23
package/src/protocol.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { WorkspaceInstance, PortVisibility } from "./workspace-instance";
|
|
8
8
|
import { RoleOrPermission } from "./permission";
|
|
9
|
+
import { Project } from "./teams-projects-protocol";
|
|
9
10
|
|
|
10
11
|
export interface UserInfo {
|
|
11
12
|
name?: string
|
|
@@ -27,8 +28,6 @@ export interface User {
|
|
|
27
28
|
|
|
28
29
|
identities: Identity[]
|
|
29
30
|
|
|
30
|
-
allowsMarketingCommunication: boolean;
|
|
31
|
-
|
|
32
31
|
/**
|
|
33
32
|
* Whether the user has been blocked to use our service, because of TOS violation for example.
|
|
34
33
|
* Optional for backwards compatibility.
|
|
@@ -98,14 +97,25 @@ export interface AdditionalUserData {
|
|
|
98
97
|
emailNotificationSettings?: EmailNotificationSettings;
|
|
99
98
|
featurePreview?: boolean;
|
|
100
99
|
ideSettings?: IDESettings;
|
|
100
|
+
// key is the name of the news, string the iso date when it was seen
|
|
101
|
+
whatsNewSeen?: { [key: string]: string }
|
|
102
|
+
// key is the name of the OAuth client i.e. local app, string the iso date when it was approved
|
|
103
|
+
// TODO(rl): provide a management UX to allow rescinding of approval
|
|
104
|
+
oauthClientsApproved?: { [key: string]: string }
|
|
105
|
+
// to remember GH Orgs the user installed/updated the GH App for
|
|
106
|
+
knownGitHubOrgs?: string[];
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
export interface EmailNotificationSettings {
|
|
104
|
-
|
|
110
|
+
allowsChangelogMail?: boolean;
|
|
111
|
+
allowsDevXMail?: boolean;
|
|
112
|
+
allowsOnboardingMail?: boolean;
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
export type IDESettings = {
|
|
108
116
|
defaultIde?: string
|
|
117
|
+
useDesktopIde?: boolean
|
|
118
|
+
defaultDesktopIde?: string
|
|
109
119
|
}
|
|
110
120
|
|
|
111
121
|
export interface UserPlatform {
|
|
@@ -127,14 +137,6 @@ export interface UserPlatform {
|
|
|
127
137
|
}
|
|
128
138
|
|
|
129
139
|
export interface UserFeatureSettings {
|
|
130
|
-
/**
|
|
131
|
-
* This field is used as marker to grant users a free trial for using private repositories,
|
|
132
|
-
* independent of any subscription or Chargebee.
|
|
133
|
-
* - it is set when the user uses their first private repo
|
|
134
|
-
* - whether the trial is expired or not is juged by the UserService
|
|
135
|
-
*/
|
|
136
|
-
privateRepoTrialStartDate?: string;
|
|
137
|
-
|
|
138
140
|
/**
|
|
139
141
|
* Permanent feature flags are added to each and every workspace instance
|
|
140
142
|
* this user starts.
|
|
@@ -146,7 +148,7 @@ export interface UserFeatureSettings {
|
|
|
146
148
|
* The values of this type MUST MATCH enum values in WorkspaceFeatureFlag from ws-manager/client/core_pb.d.ts
|
|
147
149
|
* If they don't we'll break things during workspace startup.
|
|
148
150
|
*/
|
|
149
|
-
export const WorkspaceFeatureFlags = { "full_workspace_backup": undefined, "fixed_resources": undefined
|
|
151
|
+
export const WorkspaceFeatureFlags = { "full_workspace_backup": undefined, "fixed_resources": undefined };
|
|
150
152
|
export type NamedWorkspaceFeatureFlag = keyof (typeof WorkspaceFeatureFlags);
|
|
151
153
|
|
|
152
154
|
export interface UserEnvVarValue {
|
|
@@ -167,6 +169,28 @@ export namespace UserEnvVar {
|
|
|
167
169
|
return pattern.toLocaleLowerCase();
|
|
168
170
|
}
|
|
169
171
|
|
|
172
|
+
export function score(value: UserEnvVarValue): number {
|
|
173
|
+
// We use a score to enforce precedence:
|
|
174
|
+
// value/value = 0
|
|
175
|
+
// value/* = 1
|
|
176
|
+
// */value = 2
|
|
177
|
+
// */* = 3
|
|
178
|
+
// #/# = 4 (used for env vars passed through the URL)
|
|
179
|
+
// the lower the score, the higher the precedence.
|
|
180
|
+
const [ownerPattern, repoPattern] = splitRepositoryPattern(value.repositoryPattern);
|
|
181
|
+
let score = 0;
|
|
182
|
+
if (repoPattern == "*") {
|
|
183
|
+
score += 1;
|
|
184
|
+
}
|
|
185
|
+
if (ownerPattern == '*') {
|
|
186
|
+
score += 2;
|
|
187
|
+
}
|
|
188
|
+
if (ownerPattern == "#" || repoPattern == "#") {
|
|
189
|
+
score = 4;
|
|
190
|
+
}
|
|
191
|
+
return score;
|
|
192
|
+
}
|
|
193
|
+
|
|
170
194
|
export function filter<T extends UserEnvVarValue>(vars: T[], owner: string, repo: string): T[] {
|
|
171
195
|
let result = vars.filter(e => {
|
|
172
196
|
const [ownerPattern, repoPattern] = splitRepositoryPattern(e.repositoryPattern);
|
|
@@ -202,25 +226,7 @@ export namespace UserEnvVar {
|
|
|
202
226
|
let minscore = 10;
|
|
203
227
|
let bestCandidate: T | undefined;
|
|
204
228
|
for (const e of candidates) {
|
|
205
|
-
|
|
206
|
-
// value/value = 0
|
|
207
|
-
// value/* = 1
|
|
208
|
-
// */value = 2
|
|
209
|
-
// */* = 3
|
|
210
|
-
// #/# = 4 (used for env vars passed through the URL)
|
|
211
|
-
// the lower the score, the higher the precedence.
|
|
212
|
-
const [ownerPattern, repoPattern] = splitRepositoryPattern(e.repositoryPattern);
|
|
213
|
-
let score = 0;
|
|
214
|
-
if (repoPattern == "*") {
|
|
215
|
-
score += 1;
|
|
216
|
-
}
|
|
217
|
-
if (ownerPattern == '*') {
|
|
218
|
-
score += 2;
|
|
219
|
-
}
|
|
220
|
-
if (ownerPattern == "#" || repoPattern == "#") {
|
|
221
|
-
score = 4;
|
|
222
|
-
}
|
|
223
|
-
|
|
229
|
+
const score = UserEnvVar.score(e);
|
|
224
230
|
if (!bestCandidate || score < minscore) {
|
|
225
231
|
minscore = score;
|
|
226
232
|
bestCandidate = e;
|
|
@@ -232,7 +238,7 @@ export namespace UserEnvVar {
|
|
|
232
238
|
return result;
|
|
233
239
|
}
|
|
234
240
|
|
|
235
|
-
function splitRepositoryPattern(repositoryPattern: string): string[] {
|
|
241
|
+
export function splitRepositoryPattern(repositoryPattern: string): string[] {
|
|
236
242
|
const patterns = repositoryPattern.split('/');
|
|
237
243
|
const repoPattern = patterns.pop() || "";
|
|
238
244
|
const ownerPattern = patterns.join('/');
|
|
@@ -366,11 +372,16 @@ export interface PendingGithubEvent {
|
|
|
366
372
|
export interface Snapshot {
|
|
367
373
|
id: string;
|
|
368
374
|
creationTime: string;
|
|
375
|
+
availableTime?: string;
|
|
369
376
|
originalWorkspaceId: string;
|
|
370
377
|
bucketId: string;
|
|
371
378
|
layoutData?: string;
|
|
379
|
+
state: SnapshotState;
|
|
380
|
+
message?: string;
|
|
372
381
|
}
|
|
373
382
|
|
|
383
|
+
export type SnapshotState = 'pending' | 'available' | 'error';
|
|
384
|
+
|
|
374
385
|
export interface LayoutData {
|
|
375
386
|
workspaceId: string;
|
|
376
387
|
lastUpdatedTime: string;
|
|
@@ -383,6 +394,7 @@ export interface Workspace {
|
|
|
383
394
|
contextURL: string;
|
|
384
395
|
description: string;
|
|
385
396
|
ownerId: string;
|
|
397
|
+
projectId?: string;
|
|
386
398
|
context: WorkspaceContext;
|
|
387
399
|
config: WorkspaceConfig;
|
|
388
400
|
|
|
@@ -502,6 +514,24 @@ export interface UninstallPluginParams {
|
|
|
502
514
|
pluginId: string;
|
|
503
515
|
}
|
|
504
516
|
|
|
517
|
+
export interface GuessGitTokenScopesParams {
|
|
518
|
+
host: string
|
|
519
|
+
repoUrl: string
|
|
520
|
+
gitCommand: string
|
|
521
|
+
currentToken: GitToken
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export interface GitToken {
|
|
525
|
+
token: string
|
|
526
|
+
user: string
|
|
527
|
+
scopes: string[]
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
export interface GuessedGitTokenScopes {
|
|
531
|
+
message?: string
|
|
532
|
+
scopes?: string[]
|
|
533
|
+
}
|
|
534
|
+
|
|
505
535
|
export type ResolvedPluginKind = 'user' | 'workspace' | 'builtin';
|
|
506
536
|
|
|
507
537
|
export interface ResolvedPlugins {
|
|
@@ -527,16 +557,21 @@ export interface WorkspaceConfig {
|
|
|
527
557
|
gitConfig?: { [config: string]: string };
|
|
528
558
|
github?: GithubAppConfig;
|
|
529
559
|
vscode?: VSCodeConfig;
|
|
530
|
-
|
|
560
|
+
|
|
561
|
+
/** tailscale demo */
|
|
562
|
+
experimentalNetwork?: boolean;
|
|
563
|
+
|
|
531
564
|
/**
|
|
532
565
|
* Where the config object originates from.
|
|
533
|
-
*
|
|
566
|
+
*
|
|
534
567
|
* repo - from the repository
|
|
568
|
+
* project-db - from the "Project" stored in the database
|
|
535
569
|
* definitly-gp - from github.com/gitpod-io/definitely-gp
|
|
536
570
|
* derived - computed based on analyzing the repository
|
|
571
|
+
* additional-content - config comes from additional content, usually provided through the project's configuration
|
|
537
572
|
* default - our static catch-all default config
|
|
538
573
|
*/
|
|
539
|
-
_origin?: 'repo' | 'definitely-gp' | 'derived' | 'default';
|
|
574
|
+
_origin?: 'repo' | 'project-db' | 'definitely-gp' | 'derived' | 'additional-content' | 'default';
|
|
540
575
|
|
|
541
576
|
/**
|
|
542
577
|
* Set of automatically infered feature flags. That's not something the user can set, but
|
|
@@ -566,16 +601,13 @@ export namespace GithubAppPrebuildConfig {
|
|
|
566
601
|
|
|
567
602
|
export type WorkspaceImageSource = WorkspaceImageSourceDocker | WorkspaceImageSourceReference;
|
|
568
603
|
export interface WorkspaceImageSourceDocker {
|
|
569
|
-
// TODO: clean this up. We should have the commit and an ImageSource in here, not duplicate the whole thing again.
|
|
570
|
-
// We have a ton of those objects in the database, thus cleaning this up means lengthy DB migrations. Yuck.
|
|
571
|
-
dockerFileHash: string
|
|
572
|
-
dockerFileSource: Commit
|
|
573
604
|
dockerFilePath: string
|
|
605
|
+
dockerFileHash: string
|
|
606
|
+
dockerFileSource?: Commit
|
|
574
607
|
}
|
|
575
608
|
export namespace WorkspaceImageSourceDocker {
|
|
576
609
|
export function is(obj: object): obj is WorkspaceImageSourceDocker {
|
|
577
610
|
return 'dockerFileHash' in obj
|
|
578
|
-
&& 'dockerFileSource' in obj
|
|
579
611
|
&& 'dockerFilePath' in obj;
|
|
580
612
|
}
|
|
581
613
|
}
|
|
@@ -604,6 +636,8 @@ export type PrebuiltWorkspaceState
|
|
|
604
636
|
export interface PrebuiltWorkspace {
|
|
605
637
|
id: string;
|
|
606
638
|
cloneURL: string;
|
|
639
|
+
branch?: string;
|
|
640
|
+
projectId?: string;
|
|
607
641
|
commit: string;
|
|
608
642
|
buildWorkspaceId: string;
|
|
609
643
|
creationTime: string;
|
|
@@ -614,7 +648,7 @@ export interface PrebuiltWorkspace {
|
|
|
614
648
|
|
|
615
649
|
export namespace PrebuiltWorkspace {
|
|
616
650
|
export function isDone(pws: PrebuiltWorkspace) {
|
|
617
|
-
return pws.state === "available" || pws.state === "timeout" ||
|
|
651
|
+
return pws.state === "available" || pws.state === "timeout" || pws.state === 'aborted';
|
|
618
652
|
}
|
|
619
653
|
|
|
620
654
|
export function isAvailable(pws: PrebuiltWorkspace) {
|
|
@@ -673,7 +707,7 @@ export interface TaskConfig {
|
|
|
673
707
|
init?: string;
|
|
674
708
|
prebuild?: string;
|
|
675
709
|
command?: string;
|
|
676
|
-
env?: { [env: string]:
|
|
710
|
+
env?: { [env: string]: any };
|
|
677
711
|
openIn?: 'bottom' | 'main' | 'left' | 'right';
|
|
678
712
|
openMode?: 'split-top' | 'split-left' | 'split-right' | 'split-bottom' | 'tab-before' | 'tab-after';
|
|
679
713
|
}
|
|
@@ -739,6 +773,7 @@ export interface WorkspaceContext {
|
|
|
739
773
|
title: string;
|
|
740
774
|
normalizedContextURL?: string;
|
|
741
775
|
forceCreateNewWorkspace?: boolean;
|
|
776
|
+
forceImageBuild?: boolean;
|
|
742
777
|
}
|
|
743
778
|
|
|
744
779
|
export namespace WorkspaceContext {
|
|
@@ -772,6 +807,29 @@ export namespace WithPrebuild {
|
|
|
772
807
|
}
|
|
773
808
|
}
|
|
774
809
|
|
|
810
|
+
/**
|
|
811
|
+
* WithDefaultConfig contexts disable the download of the gitpod.yml from the repository
|
|
812
|
+
* and fall back to the built-in configuration.
|
|
813
|
+
*/
|
|
814
|
+
export interface WithDefaultConfig {
|
|
815
|
+
withDefaultConfig: true;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
export namespace WithDefaultConfig {
|
|
819
|
+
export function is(context: any): context is WithDefaultConfig {
|
|
820
|
+
return context
|
|
821
|
+
&& 'withDefaultConfig' in context
|
|
822
|
+
&& context.withDefaultConfig;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
export function mark(ctx: WorkspaceContext): WorkspaceContext & WithDefaultConfig {
|
|
826
|
+
return {
|
|
827
|
+
...ctx,
|
|
828
|
+
withDefaultConfig: true
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
775
833
|
export interface SnapshotContext extends WorkspaceContext, WithSnapshot {
|
|
776
834
|
snapshotId: string;
|
|
777
835
|
}
|
|
@@ -786,6 +844,9 @@ export namespace SnapshotContext {
|
|
|
786
844
|
|
|
787
845
|
export interface StartPrebuildContext extends WorkspaceContext {
|
|
788
846
|
actual: WorkspaceContext;
|
|
847
|
+
commitHistory?: string[];
|
|
848
|
+
project?: Project;
|
|
849
|
+
branch?: string;
|
|
789
850
|
}
|
|
790
851
|
|
|
791
852
|
export namespace StartPrebuildContext {
|
|
@@ -855,6 +916,25 @@ export interface Commit {
|
|
|
855
916
|
refType?: RefType
|
|
856
917
|
}
|
|
857
918
|
|
|
919
|
+
export interface AdditionalContentContext extends WorkspaceContext {
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* utf-8 encoded contents that will be copied on top of the workspace's filesystem
|
|
923
|
+
*/
|
|
924
|
+
additionalFiles: {[filePath: string]: string};
|
|
925
|
+
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
export namespace AdditionalContentContext {
|
|
929
|
+
export function is(ctx: any): ctx is AdditionalContentContext {
|
|
930
|
+
return 'additionalFiles' in ctx;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
export function hasDockerConfig(ctx: any, config: WorkspaceConfig): boolean {
|
|
934
|
+
return is(ctx) && ImageConfigFile.is(config.image) && !!ctx.additionalFiles[config.image.file];
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
858
938
|
export interface CommitContext extends WorkspaceContext, Commit {
|
|
859
939
|
/** @deprecated Moved to .repository.cloneUrl, left here for backwards-compatibility for old workspace contextes in the DB */
|
|
860
940
|
cloneUrl?: string
|
|
@@ -930,6 +1010,19 @@ export interface Repository {
|
|
|
930
1010
|
parent: Repository
|
|
931
1011
|
}
|
|
932
1012
|
}
|
|
1013
|
+
export interface Branch {
|
|
1014
|
+
name: string;
|
|
1015
|
+
commit: CommitInfo;
|
|
1016
|
+
htmlUrl: string;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
export interface CommitInfo {
|
|
1020
|
+
author: string;
|
|
1021
|
+
sha: string;
|
|
1022
|
+
commitMessage: string;
|
|
1023
|
+
authorAvatarUrl?: string;
|
|
1024
|
+
authorDate?: string;
|
|
1025
|
+
}
|
|
933
1026
|
|
|
934
1027
|
export namespace Repository {
|
|
935
1028
|
export function fullRepoName(repo: Repository): string {
|
|
@@ -957,6 +1050,12 @@ export interface WorkspaceInfo {
|
|
|
957
1050
|
latestInstance?: WorkspaceInstance
|
|
958
1051
|
}
|
|
959
1052
|
|
|
1053
|
+
export namespace WorkspaceInfo {
|
|
1054
|
+
export function lastActiveISODate(info: WorkspaceInfo): string {
|
|
1055
|
+
return info.latestInstance?.creationTime || info.workspace.creationTime;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
960
1059
|
export type RunningWorkspaceInfo = WorkspaceInfo & { latestInstance: WorkspaceInstance };
|
|
961
1060
|
|
|
962
1061
|
export interface WorkspaceCreationResult {
|
|
@@ -966,6 +1065,7 @@ export interface WorkspaceCreationResult {
|
|
|
966
1065
|
runningWorkspacePrebuild?: {
|
|
967
1066
|
prebuildID: string
|
|
968
1067
|
workspaceID: string
|
|
1068
|
+
instanceID: string
|
|
969
1069
|
starting: RunningWorkspacePrebuildStarting
|
|
970
1070
|
sameCluster: boolean
|
|
971
1071
|
}
|
|
@@ -1056,8 +1156,17 @@ export interface OAuth2Config {
|
|
|
1056
1156
|
export namespace AuthProviderEntry {
|
|
1057
1157
|
export type Type = "GitHub" | "GitLab" | string;
|
|
1058
1158
|
export type Status = "pending" | "verified";
|
|
1059
|
-
export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type"
|
|
1159
|
+
export type NewEntry = Pick<AuthProviderEntry, "ownerId" | "host" | "type"> & { clientId?: string, clientSecret?: string };
|
|
1060
1160
|
export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> & Pick<OAuth2Config, "clientId" | "clientSecret">;
|
|
1161
|
+
export function redact(entry: AuthProviderEntry): AuthProviderEntry {
|
|
1162
|
+
return {
|
|
1163
|
+
...entry,
|
|
1164
|
+
oauth: {
|
|
1165
|
+
...entry.oauth,
|
|
1166
|
+
clientSecret: "redacted"
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1061
1170
|
}
|
|
1062
1171
|
|
|
1063
1172
|
export interface Branding {
|
|
@@ -0,0 +1,25 @@
|
|
|
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 { SnapshotUrl } from ".";
|
|
10
|
+
|
|
11
|
+
const expect = chai.expect
|
|
12
|
+
|
|
13
|
+
@suite class TestSnapshotUrlParser {
|
|
14
|
+
|
|
15
|
+
@test public testPositive() {
|
|
16
|
+
const actual = SnapshotUrl.parse("workspaces/c362d434-6faa-4ce0-9ad4-91b4a87c4abe/3f0556f7-4afa-11e9-98d5-52f8983b9279.tar@gitpod-prodcopy-user-e1e28f18-0354-4a5d-b6b4-8879a2ff73fd");
|
|
17
|
+
|
|
18
|
+
expect(actual).to.deep.equal(<SnapshotUrl>{
|
|
19
|
+
bucketId: "gitpod-prodcopy-user-e1e28f18-0354-4a5d-b6b4-8879a2ff73fd",
|
|
20
|
+
filename: "3f0556f7-4afa-11e9-98d5-52f8983b9279.tar",
|
|
21
|
+
fullPath: "workspaces/c362d434-6faa-4ce0-9ad4-91b4a87c4abe/3f0556f7-4afa-11e9-98d5-52f8983b9279.tar",
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
module.exports = new TestSnapshotUrlParser() // Only to circumvent no usage warning :-/
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
export interface SnapshotUrl {
|
|
8
|
+
bucketId: string;
|
|
9
|
+
fullPath: string;
|
|
10
|
+
filename: string;
|
|
11
|
+
}
|
|
12
|
+
export namespace SnapshotUrl {
|
|
13
|
+
export function parse(url: string): SnapshotUrl {
|
|
14
|
+
const parts = url.split("@");
|
|
15
|
+
if (parts.length !== 2) {
|
|
16
|
+
throw new Error(`cannot parse snapshot URL: ${url}`);
|
|
17
|
+
}
|
|
18
|
+
const [fullPath, bucketId] = parts;
|
|
19
|
+
|
|
20
|
+
const pathParts = fullPath.split("/");
|
|
21
|
+
if (pathParts.length < 1) {
|
|
22
|
+
throw new Error(`cannot parse snapshot URL: ${url}`);
|
|
23
|
+
}
|
|
24
|
+
const filename = pathParts[pathParts.length - 1];
|
|
25
|
+
return { bucketId, fullPath, filename };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* See License-AGPL.txt in the project root for license information.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import uuidv4 = require("uuid/v4");
|
|
7
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
9
8
|
import { Subscription } from "./accounting-protocol";
|
|
10
9
|
|
|
11
10
|
export interface TeamSubscription {
|
|
@@ -22,7 +21,7 @@ export interface TeamSubscription {
|
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
export namespace TeamSubscription {
|
|
25
|
-
export const create = (ts:
|
|
24
|
+
export const create = (ts: Omit<TeamSubscription, 'id'>): TeamSubscription => {
|
|
26
25
|
const withId = ts as TeamSubscription;
|
|
27
26
|
withId.id = uuidv4();
|
|
28
27
|
return withId;
|
|
@@ -49,7 +48,7 @@ export type TeamSubscriptionSlotAssigned = TeamSubscriptionSlot & TeamSubscripti
|
|
|
49
48
|
export type TeamSubscriptionSlotState = 'unassigned' | 'assigned' | 'deactivated' | 'cancelled';
|
|
50
49
|
|
|
51
50
|
export namespace TeamSubscriptionSlot {
|
|
52
|
-
export const create = (ts:
|
|
51
|
+
export const create = (ts: Omit<TeamSubscriptionSlot, 'id'>): TeamSubscriptionSlot => {
|
|
53
52
|
const withId = ts as TeamSubscriptionSlot;
|
|
54
53
|
withId.id = uuidv4();
|
|
55
54
|
return withId;
|
|
@@ -63,7 +62,7 @@ export namespace TeamSubscriptionSlot {
|
|
|
63
62
|
slot.subscriptionId = undefined;
|
|
64
63
|
slot.cancellationDate = cancellationDate;
|
|
65
64
|
}
|
|
66
|
-
export const reactivate = (slot: TeamSubscriptionSlot, subscriptionId
|
|
65
|
+
export const reactivate = (slot: TeamSubscriptionSlot, subscriptionId?: string) => {
|
|
67
66
|
slot.subscriptionId = subscriptionId;
|
|
68
67
|
slot.cancellationDate = undefined;
|
|
69
68
|
}
|
|
@@ -83,6 +82,9 @@ export namespace TeamSubscriptionSlot {
|
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
}
|
|
85
|
+
export const isActive = (slot: TeamSubscriptionSlot): boolean => {
|
|
86
|
+
return !slot.cancellationDate;
|
|
87
|
+
}
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
/**
|
|
@@ -0,0 +1,132 @@
|
|
|
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 { PrebuiltWorkspaceState } from "./protocol";
|
|
8
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
9
|
+
|
|
10
|
+
export interface ProjectConfig {
|
|
11
|
+
'.gitpod.yml': string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Project {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
slug?: string;
|
|
18
|
+
cloneUrl: string;
|
|
19
|
+
teamId?: string;
|
|
20
|
+
userId?: string;
|
|
21
|
+
appInstallationId: string;
|
|
22
|
+
config?: ProjectConfig;
|
|
23
|
+
creationTime: string;
|
|
24
|
+
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
25
|
+
deleted?: boolean;
|
|
26
|
+
markedDeleted?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export namespace Project {
|
|
30
|
+
export const create = (project: Omit<Project, 'id' | 'creationTime'>): Project => {
|
|
31
|
+
return {
|
|
32
|
+
...project,
|
|
33
|
+
id: uuidv4(),
|
|
34
|
+
creationTime: new Date().toISOString()
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface Overview {
|
|
39
|
+
branches: BranchDetails[]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface BranchDetails {
|
|
43
|
+
name: string;
|
|
44
|
+
url: string;
|
|
45
|
+
isDefault: boolean;
|
|
46
|
+
|
|
47
|
+
// Latest commit
|
|
48
|
+
changeTitle: string;
|
|
49
|
+
changeDate?: string;
|
|
50
|
+
changeAuthor?: string;
|
|
51
|
+
changeAuthorAvatar?: string;
|
|
52
|
+
changePR?: string;
|
|
53
|
+
changeUrl?: string;
|
|
54
|
+
changeHash: string;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface PrebuildWithStatus {
|
|
59
|
+
info: PrebuildInfo;
|
|
60
|
+
status: PrebuiltWorkspaceState;
|
|
61
|
+
error?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface PrebuildInfo {
|
|
65
|
+
id: string;
|
|
66
|
+
buildWorkspaceId: string;
|
|
67
|
+
|
|
68
|
+
teamId?: string;
|
|
69
|
+
userId?: string;
|
|
70
|
+
|
|
71
|
+
projectId: string;
|
|
72
|
+
projectName: string;
|
|
73
|
+
|
|
74
|
+
cloneUrl: string;
|
|
75
|
+
branch: string;
|
|
76
|
+
|
|
77
|
+
startedAt: string;
|
|
78
|
+
startedBy: string;
|
|
79
|
+
startedByAvatar?: string;
|
|
80
|
+
|
|
81
|
+
changeTitle: string;
|
|
82
|
+
changeDate: string;
|
|
83
|
+
changeAuthor: string;
|
|
84
|
+
changeAuthorAvatar?: string;
|
|
85
|
+
changePR?: string;
|
|
86
|
+
changeUrl?: string;
|
|
87
|
+
changeHash: string;
|
|
88
|
+
}
|
|
89
|
+
export namespace PrebuildInfo {
|
|
90
|
+
export function is(data?: any): data is PrebuildInfo {
|
|
91
|
+
return typeof data === "object" && ["id", "buildWorkspaceId", "projectId", "branch"].every(p => p in data);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface StartPrebuildResult {
|
|
96
|
+
prebuildId: string;
|
|
97
|
+
wsid: string;
|
|
98
|
+
done: boolean;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface Team {
|
|
102
|
+
id: string;
|
|
103
|
+
name: string;
|
|
104
|
+
slug: string;
|
|
105
|
+
creationTime: string;
|
|
106
|
+
markedDeleted?: boolean;
|
|
107
|
+
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
108
|
+
deleted?: boolean;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type TeamMemberRole = "owner" | "member";
|
|
112
|
+
|
|
113
|
+
export interface TeamMemberInfo {
|
|
114
|
+
userId: string;
|
|
115
|
+
fullName?: string;
|
|
116
|
+
primaryEmail?: string;
|
|
117
|
+
avatarUrl?: string;
|
|
118
|
+
role: TeamMemberRole;
|
|
119
|
+
memberSince: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface TeamMembershipInvite {
|
|
123
|
+
id: string;
|
|
124
|
+
teamId: string;
|
|
125
|
+
role: TeamMemberRole;
|
|
126
|
+
creationTime: string;
|
|
127
|
+
invalidationTime: string;
|
|
128
|
+
invitedEmail?: string;
|
|
129
|
+
|
|
130
|
+
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
131
|
+
deleted?: boolean;
|
|
132
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
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 Analytics = require("analytics-node");
|
|
8
|
+
import { IAnalyticsWriter, IdentifyMessage, TrackMessage, PageMessage } from "../analytics";
|
|
9
|
+
import { log } from './logging';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
export function newAnalyticsWriterFromEnv(): IAnalyticsWriter {
|
|
13
|
+
switch (process.env.GITPOD_ANALYTICS_WRITER) {
|
|
14
|
+
case "segment":
|
|
15
|
+
return new SegmentAnalyticsWriter(process.env.GITPOD_ANALYTICS_SEGMENT_KEY || "");
|
|
16
|
+
case "log":
|
|
17
|
+
return new LogAnalyticsWriter();
|
|
18
|
+
default:
|
|
19
|
+
return new NoAnalyticsWriter();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class SegmentAnalyticsWriter implements IAnalyticsWriter {
|
|
24
|
+
|
|
25
|
+
protected readonly analytics: Analytics;
|
|
26
|
+
|
|
27
|
+
constructor(writeKey: string) {
|
|
28
|
+
this.analytics = new Analytics(writeKey);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
identify(msg: IdentifyMessage) {
|
|
32
|
+
try {
|
|
33
|
+
this.analytics.identify(msg, (err: Error) => {
|
|
34
|
+
if (err) {
|
|
35
|
+
log.warn("analytics.identify failed", err);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
} catch (err) {
|
|
39
|
+
log.warn("analytics.identify failed", err);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
track(msg: TrackMessage) {
|
|
44
|
+
try {
|
|
45
|
+
this.analytics.track(msg, (err: Error) => {
|
|
46
|
+
if (err) {
|
|
47
|
+
log.warn("analytics.track failed", err);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
} catch (err) {
|
|
51
|
+
log.warn("analytics.track failed", err);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
page(msg: PageMessage) {
|
|
56
|
+
try{
|
|
57
|
+
this.analytics.page(msg, (err: Error) => {
|
|
58
|
+
if (err) {
|
|
59
|
+
log.warn("analytics.page failed", err);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
} catch (err) {
|
|
63
|
+
log.warn("analytics.page failed", err);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class LogAnalyticsWriter implements IAnalyticsWriter {
|
|
70
|
+
|
|
71
|
+
identify(msg: IdentifyMessage): void {
|
|
72
|
+
log.debug("analytics identify", msg);
|
|
73
|
+
}
|
|
74
|
+
track(msg: TrackMessage): void {
|
|
75
|
+
log.debug("analytics track", msg);
|
|
76
|
+
}
|
|
77
|
+
page(msg: PageMessage): void {
|
|
78
|
+
log.debug("analytics page", msg);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
class NoAnalyticsWriter implements IAnalyticsWriter {
|
|
84
|
+
identify(msg: IdentifyMessage): void {}
|
|
85
|
+
track(msg: TrackMessage): void {}
|
|
86
|
+
page(msg: PageMessage): void {}
|
|
87
|
+
}
|