@slicemachine/manager 0.27.2-beta.2 → 0.27.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/dist/lib/decodeSliceMachineConfig.cjs +2 -1
- package/dist/lib/decodeSliceMachineConfig.cjs.map +1 -1
- package/dist/lib/decodeSliceMachineConfig.js +2 -1
- package/dist/lib/decodeSliceMachineConfig.js.map +1 -1
- package/dist/managers/telemetry/TelemetryManager.cjs +6 -2
- package/dist/managers/telemetry/TelemetryManager.cjs.map +1 -1
- package/dist/managers/telemetry/TelemetryManager.js +6 -2
- package/dist/managers/telemetry/TelemetryManager.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/package.json +3 -4
- package/src/lib/decodeSliceMachineConfig.ts +1 -0
- package/src/managers/telemetry/TelemetryManager.ts +7 -3
- package/src/types.ts +1 -0
|
@@ -40,7 +40,8 @@ const SliceMachineConfigCodec = t__namespace.intersection([
|
|
|
40
40
|
libraries: t__namespace.array(t__namespace.string),
|
|
41
41
|
localSliceSimulatorURL: t__namespace.string,
|
|
42
42
|
plugins: t__namespace.array(SliceMachineConfigPluginRegistrationCodec),
|
|
43
|
-
labs: t__namespace.partial({ legacySliceUpgrader: t__namespace.boolean })
|
|
43
|
+
labs: t__namespace.partial({ legacySliceUpgrader: t__namespace.boolean }),
|
|
44
|
+
starter: t__namespace.string
|
|
44
45
|
})
|
|
45
46
|
]);
|
|
46
47
|
const decodeSliceMachineConfig = (input) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decodeSliceMachineConfig.cjs","sources":["../../../src/lib/decodeSliceMachineConfig.ts"],"sourcesContent":["import * as t from \"io-ts\";\n\nimport { SliceMachineConfig } from \"../types\";\n\nimport { decode, DecodeReturnType } from \"./decode\";\n\nconst SliceMachineConfigPluginRegistrationCodec = t.union([\n\tt.string,\n\tt.intersection([\n\t\tt.type({\n\t\t\tresolve: t.string,\n\t\t}),\n\t\tt.partial({\n\t\t\toptions: t.UnknownRecord,\n\t\t}),\n\t]),\n]);\n\nconst SliceMachineConfigCodec = t.intersection([\n\tt.type({\n\t\trepositoryName: t.string,\n\t\tadapter: SliceMachineConfigPluginRegistrationCodec,\n\t}),\n\tt.partial({\n\t\tapiEndpoint: t.string,\n\t\tlibraries: t.array(t.string),\n\t\tlocalSliceSimulatorURL: t.string,\n\t\tplugins: t.array(SliceMachineConfigPluginRegistrationCodec),\n\t\tlabs: t.partial({ legacySliceUpgrader: t.boolean }),\n\t}),\n]);\n\n// TODO: Maybe rename \"decode\" to \"validate\". \"decode\" exposes the `io-ts`\n// internals.\nexport const decodeSliceMachineConfig = (\n\tinput: unknown,\n): DecodeReturnType<SliceMachineConfig, SliceMachineConfig, unknown> => {\n\treturn decode(SliceMachineConfigCodec, input);\n};\n"],"names":["t","decode"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAMA,MAAM,4CAA4CA,aAAE,MAAM;AAAA,EACzDA,aAAE;AAAA,EACFA,aAAE,aAAa;AAAA,IACdA,aAAE,KAAK;AAAA,MACN,SAASA,aAAE;AAAA,IAAA,CACX;AAAA,IACDA,aAAE,QAAQ;AAAA,MACT,SAASA,aAAE;AAAA,IAAA,CACX;AAAA,EAAA,CACD;AACD,CAAA;AAED,MAAM,0BAA0BA,aAAE,aAAa;AAAA,EAC9CA,aAAE,KAAK;AAAA,IACN,gBAAgBA,aAAE;AAAA,IAClB,SAAS;AAAA,EAAA,CACT;AAAA,EACDA,aAAE,QAAQ;AAAA,IACT,aAAaA,aAAE;AAAA,IACf,WAAWA,aAAE,MAAMA,aAAE,MAAM;AAAA,IAC3B,wBAAwBA,aAAE;AAAA,IAC1B,SAASA,aAAE,MAAM,yCAAyC;AAAA,IAC1D,MAAMA,aAAE,QAAQ,EAAE,qBAAqBA,aAAE,SAAS;AAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"decodeSliceMachineConfig.cjs","sources":["../../../src/lib/decodeSliceMachineConfig.ts"],"sourcesContent":["import * as t from \"io-ts\";\n\nimport { SliceMachineConfig } from \"../types\";\n\nimport { decode, DecodeReturnType } from \"./decode\";\n\nconst SliceMachineConfigPluginRegistrationCodec = t.union([\n\tt.string,\n\tt.intersection([\n\t\tt.type({\n\t\t\tresolve: t.string,\n\t\t}),\n\t\tt.partial({\n\t\t\toptions: t.UnknownRecord,\n\t\t}),\n\t]),\n]);\n\nconst SliceMachineConfigCodec = t.intersection([\n\tt.type({\n\t\trepositoryName: t.string,\n\t\tadapter: SliceMachineConfigPluginRegistrationCodec,\n\t}),\n\tt.partial({\n\t\tapiEndpoint: t.string,\n\t\tlibraries: t.array(t.string),\n\t\tlocalSliceSimulatorURL: t.string,\n\t\tplugins: t.array(SliceMachineConfigPluginRegistrationCodec),\n\t\tlabs: t.partial({ legacySliceUpgrader: t.boolean }),\n\t\tstarter: t.string,\n\t}),\n]);\n\n// TODO: Maybe rename \"decode\" to \"validate\". \"decode\" exposes the `io-ts`\n// internals.\nexport const decodeSliceMachineConfig = (\n\tinput: unknown,\n): DecodeReturnType<SliceMachineConfig, SliceMachineConfig, unknown> => {\n\treturn decode(SliceMachineConfigCodec, input);\n};\n"],"names":["t","decode"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAMA,MAAM,4CAA4CA,aAAE,MAAM;AAAA,EACzDA,aAAE;AAAA,EACFA,aAAE,aAAa;AAAA,IACdA,aAAE,KAAK;AAAA,MACN,SAASA,aAAE;AAAA,IAAA,CACX;AAAA,IACDA,aAAE,QAAQ;AAAA,MACT,SAASA,aAAE;AAAA,IAAA,CACX;AAAA,EAAA,CACD;AACD,CAAA;AAED,MAAM,0BAA0BA,aAAE,aAAa;AAAA,EAC9CA,aAAE,KAAK;AAAA,IACN,gBAAgBA,aAAE;AAAA,IAClB,SAAS;AAAA,EAAA,CACT;AAAA,EACDA,aAAE,QAAQ;AAAA,IACT,aAAaA,aAAE;AAAA,IACf,WAAWA,aAAE,MAAMA,aAAE,MAAM;AAAA,IAC3B,wBAAwBA,aAAE;AAAA,IAC1B,SAASA,aAAE,MAAM,yCAAyC;AAAA,IAC1D,MAAMA,aAAE,QAAQ,EAAE,qBAAqBA,aAAE,SAAS;AAAA,IAClD,SAASA,aAAE;AAAA,EAAA,CACX;AACD,CAAA;AAIM,MAAM,2BAA2B,CACvC,UACsE;AACtE,SAAOC,OAAAA,OAAO,yBAAyB,KAAK;AAC7C;;"}
|
|
@@ -21,7 +21,8 @@ const SliceMachineConfigCodec = t.intersection([
|
|
|
21
21
|
libraries: t.array(t.string),
|
|
22
22
|
localSliceSimulatorURL: t.string,
|
|
23
23
|
plugins: t.array(SliceMachineConfigPluginRegistrationCodec),
|
|
24
|
-
labs: t.partial({ legacySliceUpgrader: t.boolean })
|
|
24
|
+
labs: t.partial({ legacySliceUpgrader: t.boolean }),
|
|
25
|
+
starter: t.string
|
|
25
26
|
})
|
|
26
27
|
]);
|
|
27
28
|
const decodeSliceMachineConfig = (input) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decodeSliceMachineConfig.js","sources":["../../../src/lib/decodeSliceMachineConfig.ts"],"sourcesContent":["import * as t from \"io-ts\";\n\nimport { SliceMachineConfig } from \"../types\";\n\nimport { decode, DecodeReturnType } from \"./decode\";\n\nconst SliceMachineConfigPluginRegistrationCodec = t.union([\n\tt.string,\n\tt.intersection([\n\t\tt.type({\n\t\t\tresolve: t.string,\n\t\t}),\n\t\tt.partial({\n\t\t\toptions: t.UnknownRecord,\n\t\t}),\n\t]),\n]);\n\nconst SliceMachineConfigCodec = t.intersection([\n\tt.type({\n\t\trepositoryName: t.string,\n\t\tadapter: SliceMachineConfigPluginRegistrationCodec,\n\t}),\n\tt.partial({\n\t\tapiEndpoint: t.string,\n\t\tlibraries: t.array(t.string),\n\t\tlocalSliceSimulatorURL: t.string,\n\t\tplugins: t.array(SliceMachineConfigPluginRegistrationCodec),\n\t\tlabs: t.partial({ legacySliceUpgrader: t.boolean }),\n\t}),\n]);\n\n// TODO: Maybe rename \"decode\" to \"validate\". \"decode\" exposes the `io-ts`\n// internals.\nexport const decodeSliceMachineConfig = (\n\tinput: unknown,\n): DecodeReturnType<SliceMachineConfig, SliceMachineConfig, unknown> => {\n\treturn decode(SliceMachineConfigCodec, input);\n};\n"],"names":[],"mappings":";;AAMA,MAAM,4CAA4C,EAAE,MAAM;AAAA,EACzD,EAAE;AAAA,EACF,EAAE,aAAa;AAAA,IACd,EAAE,KAAK;AAAA,MACN,SAAS,EAAE;AAAA,IAAA,CACX;AAAA,IACD,EAAE,QAAQ;AAAA,MACT,SAAS,EAAE;AAAA,IAAA,CACX;AAAA,EAAA,CACD;AACD,CAAA;AAED,MAAM,0BAA0B,EAAE,aAAa;AAAA,EAC9C,EAAE,KAAK;AAAA,IACN,gBAAgB,EAAE;AAAA,IAClB,SAAS;AAAA,EAAA,CACT;AAAA,EACD,EAAE,QAAQ;AAAA,IACT,aAAa,EAAE;AAAA,IACf,WAAW,EAAE,MAAM,EAAE,MAAM;AAAA,IAC3B,wBAAwB,EAAE;AAAA,IAC1B,SAAS,EAAE,MAAM,yCAAyC;AAAA,IAC1D,MAAM,EAAE,QAAQ,EAAE,qBAAqB,EAAE,SAAS;AAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"decodeSliceMachineConfig.js","sources":["../../../src/lib/decodeSliceMachineConfig.ts"],"sourcesContent":["import * as t from \"io-ts\";\n\nimport { SliceMachineConfig } from \"../types\";\n\nimport { decode, DecodeReturnType } from \"./decode\";\n\nconst SliceMachineConfigPluginRegistrationCodec = t.union([\n\tt.string,\n\tt.intersection([\n\t\tt.type({\n\t\t\tresolve: t.string,\n\t\t}),\n\t\tt.partial({\n\t\t\toptions: t.UnknownRecord,\n\t\t}),\n\t]),\n]);\n\nconst SliceMachineConfigCodec = t.intersection([\n\tt.type({\n\t\trepositoryName: t.string,\n\t\tadapter: SliceMachineConfigPluginRegistrationCodec,\n\t}),\n\tt.partial({\n\t\tapiEndpoint: t.string,\n\t\tlibraries: t.array(t.string),\n\t\tlocalSliceSimulatorURL: t.string,\n\t\tplugins: t.array(SliceMachineConfigPluginRegistrationCodec),\n\t\tlabs: t.partial({ legacySliceUpgrader: t.boolean }),\n\t\tstarter: t.string,\n\t}),\n]);\n\n// TODO: Maybe rename \"decode\" to \"validate\". \"decode\" exposes the `io-ts`\n// internals.\nexport const decodeSliceMachineConfig = (\n\tinput: unknown,\n): DecodeReturnType<SliceMachineConfig, SliceMachineConfig, unknown> => {\n\treturn decode(SliceMachineConfigCodec, input);\n};\n"],"names":[],"mappings":";;AAMA,MAAM,4CAA4C,EAAE,MAAM;AAAA,EACzD,EAAE;AAAA,EACF,EAAE,aAAa;AAAA,IACd,EAAE,KAAK;AAAA,MACN,SAAS,EAAE;AAAA,IAAA,CACX;AAAA,IACD,EAAE,QAAQ;AAAA,MACT,SAAS,EAAE;AAAA,IAAA,CACX;AAAA,EAAA,CACD;AACD,CAAA;AAED,MAAM,0BAA0B,EAAE,aAAa;AAAA,EAC9C,EAAE,KAAK;AAAA,IACN,gBAAgB,EAAE;AAAA,IAClB,SAAS;AAAA,EAAA,CACT;AAAA,EACD,EAAE,QAAQ;AAAA,IACT,aAAa,EAAE;AAAA,IACf,WAAW,EAAE,MAAM,EAAE,MAAM;AAAA,IAC3B,wBAAwB,EAAE;AAAA,IAC1B,SAAS,EAAE,MAAM,yCAAyC;AAAA,IAC1D,MAAM,EAAE,QAAQ,EAAE,qBAAqB,EAAE,SAAS;AAAA,IAClD,SAAS,EAAE;AAAA,EAAA,CACX;AACD,CAAA;AAIM,MAAM,2BAA2B,CACvC,UACsE;AACtE,SAAO,OAAO,yBAAyB,KAAK;AAC7C;"}
|
|
@@ -51,10 +51,13 @@ class TelemetryManager extends BaseManager.BaseManager {
|
|
|
51
51
|
var _a;
|
|
52
52
|
const { event, repository, _includeEnvironmentKind, ...properties } = args;
|
|
53
53
|
let repositoryName = repository;
|
|
54
|
+
let starter;
|
|
54
55
|
if (repositoryName === void 0) {
|
|
55
56
|
try {
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
const config = await this.project.getSliceMachineConfig();
|
|
58
|
+
repositoryName = config.repositoryName;
|
|
59
|
+
starter = config.starter;
|
|
60
|
+
} catch {
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
let environmentKind = void 0;
|
|
@@ -79,6 +82,7 @@ class TelemetryManager extends BaseManager.BaseManager {
|
|
|
79
82
|
properties: {
|
|
80
83
|
nodeVersion: process.versions.node,
|
|
81
84
|
environmentKind,
|
|
85
|
+
starter,
|
|
82
86
|
...properties
|
|
83
87
|
},
|
|
84
88
|
context: { ...this._context }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TelemetryManager.cjs","sources":["../../../../src/managers/telemetry/TelemetryManager.ts"],"sourcesContent":["import {\n\tExperiment,\n\tRemoteEvaluationClient,\n\tVariant,\n} from \"@amplitude/experiment-node-server\";\nimport { randomUUID } from \"node:crypto\";\nimport { Analytics, GroupParams, TrackParams } from \"@segment/analytics-node\";\n\nimport { readPrismicrc } from \"../../lib/prismicrc\";\n\nimport { API_TOKENS } from \"../../constants/API_TOKENS\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport {\n\tHumanSegmentEventType,\n\tHumanSegmentEventTypes,\n\tSegmentEvents,\n} from \"./types\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype TelemetryManagerInitTelemetryArgs = {\n\tappName: string;\n\tappVersion: string;\n};\n\ntype TelemetryManagerTrackArgs = SegmentEvents & {\n\t_includeEnvironmentKind?: boolean;\n};\n\ntype TelemetryManagerIdentifyArgs = {\n\tuserID: string;\n\tintercomHash: string;\n};\n\ntype TelemetryManagerGroupArgs = {\n\tmanualLibsCount: number;\n\tdownloadedLibsCount: number;\n\tnpmLibsCount: number;\n\tdownloadedLibs: string[];\n};\n\ntype TelemetryManagerContext = {\n\tapp: {\n\t\tname: string;\n\t\tversion: string;\n\t};\n};\n\nfunction assertTelemetryInitialized(\n\tsegmentClient: (() => Analytics) | undefined,\n): asserts segmentClient is NonNullable<typeof segmentClient> {\n\tif (segmentClient === undefined) {\n\t\tthrow new Error(\n\t\t\t\"Telemetry has not been initialized. Run `SliceMachineManager.telemetry.prototype.initTelemetry()` before re-calling this method.\",\n\t\t);\n\t}\n}\n\nexport class TelemetryManager extends BaseManager {\n\tprivate _segmentClient: (() => Analytics) | undefined = undefined;\n\tprivate _anonymousID: string | undefined = undefined;\n\tprivate _userID: string | undefined = undefined;\n\tprivate _context: TelemetryManagerContext | undefined = undefined;\n\tprivate _experiment: RemoteEvaluationClient | undefined = undefined;\n\n\tasync initTelemetry(args: TelemetryManagerInitTelemetryArgs): Promise<void> {\n\t\tconst isTelemetryEnabled = await this.checkIsTelemetryEnabled();\n\n\t\tthis._segmentClient = () => {\n\t\t\tconst analytics = new Analytics({\n\t\t\t\twriteKey: API_TOKENS.SegmentKey,\n\t\t\t\t// Since it's a local app, we do not benefit from event batching the way a server would normally do, all tracking event will be awaited.\n\t\t\t\tmaxEventsInBatch: 1,\n\t\t\t\t// TODO: Verify that this actually does not send data to Segment when false.\n\t\t\t\tdisable: !isTelemetryEnabled,\n\t\t\t});\n\n\t\t\tanalytics.on(\"error\", (error) => {\n\t\t\t\t// noop - We don't care if the tracking event\n\t\t\t\t// failed. Some users or networks intentionally\n\t\t\t\t// block Segment, so we can't block the app if\n\t\t\t\t// a tracking event is unsuccessful.\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(`An error occurred with Segment`, error);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn analytics;\n\t\t};\n\n\t\tif (isTelemetryEnabled) {\n\t\t\tthis.initExperiment();\n\t\t}\n\n\t\tthis._anonymousID = randomUUID();\n\t\tthis._context = { app: { name: args.appName, version: args.appVersion } };\n\t}\n\n\t// TODO: Should `userId` be automatically populated by the logged in\n\t// user? We already have their info via UserRepository.\n\tasync track(args: TelemetryManagerTrackArgs): Promise<void> {\n\t\tconst { event, repository, _includeEnvironmentKind, ...properties } = args;\n\t\tlet repositoryName = repository;\n\n\t\tif (repositoryName === undefined) {\n\t\t\ttry {\n\t\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t\t} catch (error) {\n\t\t\t\t// noop, happen only when the user is not in a project\n\t\t\t}\n\t\t}\n\n\t\tlet environmentKind: Environment[\"kind\"] | \"_unknown\" | undefined =\n\t\t\tundefined;\n\t\tif (_includeEnvironmentKind) {\n\t\t\tif (this.project.checkSupportsEnvironments()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst activeEnvironmentResult =\n\t\t\t\t\t\tawait this.project.fetchActiveEnvironment();\n\n\t\t\t\t\tif (activeEnvironmentResult.type === \"ok\") {\n\t\t\t\t\t\tenvironmentKind = activeEnvironmentResult.activeEnvironment.kind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow activeEnvironmentResult.error;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tenvironmentKind = \"_unknown\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Assume only the production environment can be\n\t\t\t\t// used if the project's adapter does not\n\t\t\t\t// support environments.\n\t\t\t\tenvironmentKind = \"prod\";\n\t\t\t}\n\t\t}\n\n\t\tconst payload: {\n\t\t\tevent: HumanSegmentEventTypes;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\tproperties?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\tevent: HumanSegmentEventType[event],\n\t\t\tproperties: {\n\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\tenvironmentKind,\n\t\t\t\t...properties,\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().track(\n\t\t\t\tpayload as TrackParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`An error occurred during Segment tracking`,\n\t\t\t\t\t\t\tmaybeError,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t// TODO: Should `userID` and `intercomHash` be automatically populated\n\t// by the logged in user? We already have their info via\n\t// UserRepository.\n\tidentify(args: TelemetryManagerIdentifyArgs): Promise<void> {\n\t\tconst payload = {\n\t\t\tuserId: args.userID,\n\t\t\tanonymousId: this._anonymousID,\n\t\t\tintegrations: {\n\t\t\t\tIntercom: {\n\t\t\t\t\tuser_hash: args.intercomHash,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tthis._userID = args.userID;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().identify(payload, (maybeError?: unknown) => {\n\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\tconsole.warn(`An error occurred during Segment identify`, maybeError);\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync group(args: TelemetryManagerGroupArgs): Promise<void> {\n\t\tlet repositoryName;\n\n\t\ttry {\n\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t} catch (error) {\n\t\t\t// noop, happen only when the user is not in a project\n\t\t}\n\n\t\tconst payload: {\n\t\t\tgroupId?: string;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\ttraits?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\ttraits: args,\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.groupId = repositoryName;\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\tthis._segmentClient().group(\n\t\t\t\tpayload as GroupParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(`An error occurred during Segment group`, maybeError);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync checkIsTelemetryEnabled(): Promise<boolean> {\n\t\tlet root: string;\n\t\ttry {\n\t\t\troot = await this.project\n\t\t\t\t.getRoot()\n\t\t\t\t.catch(() => this.project.suggestRoot());\n\n\t\t\treturn readPrismicrc(root).telemetry !== false;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate initExperiment(): void {\n\t\ttry {\n\t\t\tthis._experiment = Experiment.initializeRemote(API_TOKENS.AmplitudeKey);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Error initializing experiment\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getExperimentVariant(variantKey: string): Promise<Variant | undefined> {\n\t\tif (this._experiment) {\n\t\t\ttry {\n\t\t\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\t\t\tconst variants = await this._experiment.fetchV2({\n\t\t\t\t\tuser_id: this._userID,\n\t\t\t\t\tuser_properties: {\n\t\t\t\t\t\tRepository: repositoryName,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst variantValue = variants[variantKey].value;\n\t\t\t\tif (variantValue) {\n\t\t\t\t\tawait this.track({\n\t\t\t\t\t\tevent: \"experiment:exposure\",\n\t\t\t\t\t\tflag_key: variantKey,\n\t\t\t\t\t\tvariant: variantValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn variants[variantKey];\n\t\t\t} catch (error) {\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(\"Error fetching experiment variant\", error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"],"names":["BaseManager","Analytics","API_TOKENS","randomUUID","HumanSegmentEventType","readPrismicrc","Experiment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TelemetryManager.cjs","sources":["../../../../src/managers/telemetry/TelemetryManager.ts"],"sourcesContent":["import {\n\tExperiment,\n\tRemoteEvaluationClient,\n\tVariant,\n} from \"@amplitude/experiment-node-server\";\nimport { randomUUID } from \"node:crypto\";\nimport { Analytics, GroupParams, TrackParams } from \"@segment/analytics-node\";\n\nimport { readPrismicrc } from \"../../lib/prismicrc\";\n\nimport { API_TOKENS } from \"../../constants/API_TOKENS\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport {\n\tHumanSegmentEventType,\n\tHumanSegmentEventTypes,\n\tSegmentEvents,\n} from \"./types\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype TelemetryManagerInitTelemetryArgs = {\n\tappName: string;\n\tappVersion: string;\n};\n\ntype TelemetryManagerTrackArgs = SegmentEvents & {\n\t_includeEnvironmentKind?: boolean;\n};\n\ntype TelemetryManagerIdentifyArgs = {\n\tuserID: string;\n\tintercomHash: string;\n};\n\ntype TelemetryManagerGroupArgs = {\n\tmanualLibsCount: number;\n\tdownloadedLibsCount: number;\n\tnpmLibsCount: number;\n\tdownloadedLibs: string[];\n};\n\ntype TelemetryManagerContext = {\n\tapp: {\n\t\tname: string;\n\t\tversion: string;\n\t};\n};\n\nfunction assertTelemetryInitialized(\n\tsegmentClient: (() => Analytics) | undefined,\n): asserts segmentClient is NonNullable<typeof segmentClient> {\n\tif (segmentClient === undefined) {\n\t\tthrow new Error(\n\t\t\t\"Telemetry has not been initialized. Run `SliceMachineManager.telemetry.prototype.initTelemetry()` before re-calling this method.\",\n\t\t);\n\t}\n}\n\nexport class TelemetryManager extends BaseManager {\n\tprivate _segmentClient: (() => Analytics) | undefined = undefined;\n\tprivate _anonymousID: string | undefined = undefined;\n\tprivate _userID: string | undefined = undefined;\n\tprivate _context: TelemetryManagerContext | undefined = undefined;\n\tprivate _experiment: RemoteEvaluationClient | undefined = undefined;\n\n\tasync initTelemetry(args: TelemetryManagerInitTelemetryArgs): Promise<void> {\n\t\tconst isTelemetryEnabled = await this.checkIsTelemetryEnabled();\n\n\t\tthis._segmentClient = () => {\n\t\t\tconst analytics = new Analytics({\n\t\t\t\twriteKey: API_TOKENS.SegmentKey,\n\t\t\t\t// Since it's a local app, we do not benefit from event batching the way a server would normally do, all tracking event will be awaited.\n\t\t\t\tmaxEventsInBatch: 1,\n\t\t\t\t// TODO: Verify that this actually does not send data to Segment when false.\n\t\t\t\tdisable: !isTelemetryEnabled,\n\t\t\t});\n\n\t\t\tanalytics.on(\"error\", (error) => {\n\t\t\t\t// noop - We don't care if the tracking event\n\t\t\t\t// failed. Some users or networks intentionally\n\t\t\t\t// block Segment, so we can't block the app if\n\t\t\t\t// a tracking event is unsuccessful.\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(`An error occurred with Segment`, error);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn analytics;\n\t\t};\n\n\t\tif (isTelemetryEnabled) {\n\t\t\tthis.initExperiment();\n\t\t}\n\n\t\tthis._anonymousID = randomUUID();\n\t\tthis._context = { app: { name: args.appName, version: args.appVersion } };\n\t}\n\n\t// TODO: Should `userId` be automatically populated by the logged in\n\t// user? We already have their info via UserRepository.\n\tasync track(args: TelemetryManagerTrackArgs): Promise<void> {\n\t\tconst { event, repository, _includeEnvironmentKind, ...properties } = args;\n\t\tlet repositoryName = repository;\n\t\tlet starter: string | undefined;\n\n\t\tif (repositoryName === undefined) {\n\t\t\ttry {\n\t\t\t\tconst config = await this.project.getSliceMachineConfig();\n\t\t\t\trepositoryName = config.repositoryName;\n\t\t\t\tstarter = config.starter;\n\t\t\t} catch {\n\t\t\t\t// noop, happens only when the user is not in a project\n\t\t\t}\n\t\t}\n\n\t\tlet environmentKind: Environment[\"kind\"] | \"_unknown\" | undefined =\n\t\t\tundefined;\n\t\tif (_includeEnvironmentKind) {\n\t\t\tif (this.project.checkSupportsEnvironments()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst activeEnvironmentResult =\n\t\t\t\t\t\tawait this.project.fetchActiveEnvironment();\n\n\t\t\t\t\tif (activeEnvironmentResult.type === \"ok\") {\n\t\t\t\t\t\tenvironmentKind = activeEnvironmentResult.activeEnvironment.kind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow activeEnvironmentResult.error;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tenvironmentKind = \"_unknown\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Assume only the production environment can be\n\t\t\t\t// used if the project's adapter does not\n\t\t\t\t// support environments.\n\t\t\t\tenvironmentKind = \"prod\";\n\t\t\t}\n\t\t}\n\n\t\tconst payload: {\n\t\t\tevent: HumanSegmentEventTypes;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\tproperties?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\tevent: HumanSegmentEventType[event],\n\t\t\tproperties: {\n\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\tenvironmentKind,\n\t\t\t\tstarter,\n\t\t\t\t...properties,\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().track(\n\t\t\t\tpayload as TrackParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`An error occurred during Segment tracking`,\n\t\t\t\t\t\t\tmaybeError,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t// TODO: Should `userID` and `intercomHash` be automatically populated\n\t// by the logged in user? We already have their info via\n\t// UserRepository.\n\tidentify(args: TelemetryManagerIdentifyArgs): Promise<void> {\n\t\tconst payload = {\n\t\t\tuserId: args.userID,\n\t\t\tanonymousId: this._anonymousID,\n\t\t\tintegrations: {\n\t\t\t\tIntercom: {\n\t\t\t\t\tuser_hash: args.intercomHash,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tthis._userID = args.userID;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().identify(payload, (maybeError?: unknown) => {\n\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\tconsole.warn(`An error occurred during Segment identify`, maybeError);\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync group(args: TelemetryManagerGroupArgs): Promise<void> {\n\t\tlet repositoryName;\n\n\t\ttry {\n\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t} catch (error) {\n\t\t\t// noop, happen only when the user is not in a project\n\t\t}\n\n\t\tconst payload: {\n\t\t\tgroupId?: string;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\ttraits?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\ttraits: args,\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.groupId = repositoryName;\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\tthis._segmentClient().group(\n\t\t\t\tpayload as GroupParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(`An error occurred during Segment group`, maybeError);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync checkIsTelemetryEnabled(): Promise<boolean> {\n\t\tlet root: string;\n\t\ttry {\n\t\t\troot = await this.project\n\t\t\t\t.getRoot()\n\t\t\t\t.catch(() => this.project.suggestRoot());\n\n\t\t\treturn readPrismicrc(root).telemetry !== false;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate initExperiment(): void {\n\t\ttry {\n\t\t\tthis._experiment = Experiment.initializeRemote(API_TOKENS.AmplitudeKey);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Error initializing experiment\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getExperimentVariant(variantKey: string): Promise<Variant | undefined> {\n\t\tif (this._experiment) {\n\t\t\ttry {\n\t\t\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\t\t\tconst variants = await this._experiment.fetchV2({\n\t\t\t\t\tuser_id: this._userID,\n\t\t\t\t\tuser_properties: {\n\t\t\t\t\t\tRepository: repositoryName,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst variantValue = variants[variantKey].value;\n\t\t\t\tif (variantValue) {\n\t\t\t\t\tawait this.track({\n\t\t\t\t\t\tevent: \"experiment:exposure\",\n\t\t\t\t\t\tflag_key: variantKey,\n\t\t\t\t\t\tvariant: variantValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn variants[variantKey];\n\t\t\t} catch (error) {\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(\"Error fetching experiment variant\", error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"],"names":["BaseManager","Analytics","API_TOKENS","randomUUID","HumanSegmentEventType","readPrismicrc","Experiment"],"mappings":"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"}
|
|
@@ -49,10 +49,13 @@ class TelemetryManager extends BaseManager {
|
|
|
49
49
|
var _a;
|
|
50
50
|
const { event, repository, _includeEnvironmentKind, ...properties } = args;
|
|
51
51
|
let repositoryName = repository;
|
|
52
|
+
let starter;
|
|
52
53
|
if (repositoryName === void 0) {
|
|
53
54
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
const config = await this.project.getSliceMachineConfig();
|
|
56
|
+
repositoryName = config.repositoryName;
|
|
57
|
+
starter = config.starter;
|
|
58
|
+
} catch {
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
let environmentKind = void 0;
|
|
@@ -77,6 +80,7 @@ class TelemetryManager extends BaseManager {
|
|
|
77
80
|
properties: {
|
|
78
81
|
nodeVersion: process.versions.node,
|
|
79
82
|
environmentKind,
|
|
83
|
+
starter,
|
|
80
84
|
...properties
|
|
81
85
|
},
|
|
82
86
|
context: { ...this._context }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TelemetryManager.js","sources":["../../../../src/managers/telemetry/TelemetryManager.ts"],"sourcesContent":["import {\n\tExperiment,\n\tRemoteEvaluationClient,\n\tVariant,\n} from \"@amplitude/experiment-node-server\";\nimport { randomUUID } from \"node:crypto\";\nimport { Analytics, GroupParams, TrackParams } from \"@segment/analytics-node\";\n\nimport { readPrismicrc } from \"../../lib/prismicrc\";\n\nimport { API_TOKENS } from \"../../constants/API_TOKENS\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport {\n\tHumanSegmentEventType,\n\tHumanSegmentEventTypes,\n\tSegmentEvents,\n} from \"./types\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype TelemetryManagerInitTelemetryArgs = {\n\tappName: string;\n\tappVersion: string;\n};\n\ntype TelemetryManagerTrackArgs = SegmentEvents & {\n\t_includeEnvironmentKind?: boolean;\n};\n\ntype TelemetryManagerIdentifyArgs = {\n\tuserID: string;\n\tintercomHash: string;\n};\n\ntype TelemetryManagerGroupArgs = {\n\tmanualLibsCount: number;\n\tdownloadedLibsCount: number;\n\tnpmLibsCount: number;\n\tdownloadedLibs: string[];\n};\n\ntype TelemetryManagerContext = {\n\tapp: {\n\t\tname: string;\n\t\tversion: string;\n\t};\n};\n\nfunction assertTelemetryInitialized(\n\tsegmentClient: (() => Analytics) | undefined,\n): asserts segmentClient is NonNullable<typeof segmentClient> {\n\tif (segmentClient === undefined) {\n\t\tthrow new Error(\n\t\t\t\"Telemetry has not been initialized. Run `SliceMachineManager.telemetry.prototype.initTelemetry()` before re-calling this method.\",\n\t\t);\n\t}\n}\n\nexport class TelemetryManager extends BaseManager {\n\tprivate _segmentClient: (() => Analytics) | undefined = undefined;\n\tprivate _anonymousID: string | undefined = undefined;\n\tprivate _userID: string | undefined = undefined;\n\tprivate _context: TelemetryManagerContext | undefined = undefined;\n\tprivate _experiment: RemoteEvaluationClient | undefined = undefined;\n\n\tasync initTelemetry(args: TelemetryManagerInitTelemetryArgs): Promise<void> {\n\t\tconst isTelemetryEnabled = await this.checkIsTelemetryEnabled();\n\n\t\tthis._segmentClient = () => {\n\t\t\tconst analytics = new Analytics({\n\t\t\t\twriteKey: API_TOKENS.SegmentKey,\n\t\t\t\t// Since it's a local app, we do not benefit from event batching the way a server would normally do, all tracking event will be awaited.\n\t\t\t\tmaxEventsInBatch: 1,\n\t\t\t\t// TODO: Verify that this actually does not send data to Segment when false.\n\t\t\t\tdisable: !isTelemetryEnabled,\n\t\t\t});\n\n\t\t\tanalytics.on(\"error\", (error) => {\n\t\t\t\t// noop - We don't care if the tracking event\n\t\t\t\t// failed. Some users or networks intentionally\n\t\t\t\t// block Segment, so we can't block the app if\n\t\t\t\t// a tracking event is unsuccessful.\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(`An error occurred with Segment`, error);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn analytics;\n\t\t};\n\n\t\tif (isTelemetryEnabled) {\n\t\t\tthis.initExperiment();\n\t\t}\n\n\t\tthis._anonymousID = randomUUID();\n\t\tthis._context = { app: { name: args.appName, version: args.appVersion } };\n\t}\n\n\t// TODO: Should `userId` be automatically populated by the logged in\n\t// user? We already have their info via UserRepository.\n\tasync track(args: TelemetryManagerTrackArgs): Promise<void> {\n\t\tconst { event, repository, _includeEnvironmentKind, ...properties } = args;\n\t\tlet repositoryName = repository;\n\n\t\tif (repositoryName === undefined) {\n\t\t\ttry {\n\t\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t\t} catch (error) {\n\t\t\t\t// noop, happen only when the user is not in a project\n\t\t\t}\n\t\t}\n\n\t\tlet environmentKind: Environment[\"kind\"] | \"_unknown\" | undefined =\n\t\t\tundefined;\n\t\tif (_includeEnvironmentKind) {\n\t\t\tif (this.project.checkSupportsEnvironments()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst activeEnvironmentResult =\n\t\t\t\t\t\tawait this.project.fetchActiveEnvironment();\n\n\t\t\t\t\tif (activeEnvironmentResult.type === \"ok\") {\n\t\t\t\t\t\tenvironmentKind = activeEnvironmentResult.activeEnvironment.kind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow activeEnvironmentResult.error;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tenvironmentKind = \"_unknown\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Assume only the production environment can be\n\t\t\t\t// used if the project's adapter does not\n\t\t\t\t// support environments.\n\t\t\t\tenvironmentKind = \"prod\";\n\t\t\t}\n\t\t}\n\n\t\tconst payload: {\n\t\t\tevent: HumanSegmentEventTypes;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\tproperties?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\tevent: HumanSegmentEventType[event],\n\t\t\tproperties: {\n\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\tenvironmentKind,\n\t\t\t\t...properties,\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().track(\n\t\t\t\tpayload as TrackParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`An error occurred during Segment tracking`,\n\t\t\t\t\t\t\tmaybeError,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t// TODO: Should `userID` and `intercomHash` be automatically populated\n\t// by the logged in user? We already have their info via\n\t// UserRepository.\n\tidentify(args: TelemetryManagerIdentifyArgs): Promise<void> {\n\t\tconst payload = {\n\t\t\tuserId: args.userID,\n\t\t\tanonymousId: this._anonymousID,\n\t\t\tintegrations: {\n\t\t\t\tIntercom: {\n\t\t\t\t\tuser_hash: args.intercomHash,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tthis._userID = args.userID;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().identify(payload, (maybeError?: unknown) => {\n\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\tconsole.warn(`An error occurred during Segment identify`, maybeError);\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync group(args: TelemetryManagerGroupArgs): Promise<void> {\n\t\tlet repositoryName;\n\n\t\ttry {\n\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t} catch (error) {\n\t\t\t// noop, happen only when the user is not in a project\n\t\t}\n\n\t\tconst payload: {\n\t\t\tgroupId?: string;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\ttraits?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\ttraits: args,\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.groupId = repositoryName;\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\tthis._segmentClient().group(\n\t\t\t\tpayload as GroupParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(`An error occurred during Segment group`, maybeError);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync checkIsTelemetryEnabled(): Promise<boolean> {\n\t\tlet root: string;\n\t\ttry {\n\t\t\troot = await this.project\n\t\t\t\t.getRoot()\n\t\t\t\t.catch(() => this.project.suggestRoot());\n\n\t\t\treturn readPrismicrc(root).telemetry !== false;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate initExperiment(): void {\n\t\ttry {\n\t\t\tthis._experiment = Experiment.initializeRemote(API_TOKENS.AmplitudeKey);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Error initializing experiment\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getExperimentVariant(variantKey: string): Promise<Variant | undefined> {\n\t\tif (this._experiment) {\n\t\t\ttry {\n\t\t\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\t\t\tconst variants = await this._experiment.fetchV2({\n\t\t\t\t\tuser_id: this._userID,\n\t\t\t\t\tuser_properties: {\n\t\t\t\t\t\tRepository: repositoryName,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst variantValue = variants[variantKey].value;\n\t\t\t\tif (variantValue) {\n\t\t\t\t\tawait this.track({\n\t\t\t\t\t\tevent: \"experiment:exposure\",\n\t\t\t\t\t\tflag_key: variantKey,\n\t\t\t\t\t\tvariant: variantValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn variants[variantKey];\n\t\t\t} catch (error) {\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(\"Error fetching experiment variant\", error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"],"names":["Experiment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TelemetryManager.js","sources":["../../../../src/managers/telemetry/TelemetryManager.ts"],"sourcesContent":["import {\n\tExperiment,\n\tRemoteEvaluationClient,\n\tVariant,\n} from \"@amplitude/experiment-node-server\";\nimport { randomUUID } from \"node:crypto\";\nimport { Analytics, GroupParams, TrackParams } from \"@segment/analytics-node\";\n\nimport { readPrismicrc } from \"../../lib/prismicrc\";\n\nimport { API_TOKENS } from \"../../constants/API_TOKENS\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport {\n\tHumanSegmentEventType,\n\tHumanSegmentEventTypes,\n\tSegmentEvents,\n} from \"./types\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype TelemetryManagerInitTelemetryArgs = {\n\tappName: string;\n\tappVersion: string;\n};\n\ntype TelemetryManagerTrackArgs = SegmentEvents & {\n\t_includeEnvironmentKind?: boolean;\n};\n\ntype TelemetryManagerIdentifyArgs = {\n\tuserID: string;\n\tintercomHash: string;\n};\n\ntype TelemetryManagerGroupArgs = {\n\tmanualLibsCount: number;\n\tdownloadedLibsCount: number;\n\tnpmLibsCount: number;\n\tdownloadedLibs: string[];\n};\n\ntype TelemetryManagerContext = {\n\tapp: {\n\t\tname: string;\n\t\tversion: string;\n\t};\n};\n\nfunction assertTelemetryInitialized(\n\tsegmentClient: (() => Analytics) | undefined,\n): asserts segmentClient is NonNullable<typeof segmentClient> {\n\tif (segmentClient === undefined) {\n\t\tthrow new Error(\n\t\t\t\"Telemetry has not been initialized. Run `SliceMachineManager.telemetry.prototype.initTelemetry()` before re-calling this method.\",\n\t\t);\n\t}\n}\n\nexport class TelemetryManager extends BaseManager {\n\tprivate _segmentClient: (() => Analytics) | undefined = undefined;\n\tprivate _anonymousID: string | undefined = undefined;\n\tprivate _userID: string | undefined = undefined;\n\tprivate _context: TelemetryManagerContext | undefined = undefined;\n\tprivate _experiment: RemoteEvaluationClient | undefined = undefined;\n\n\tasync initTelemetry(args: TelemetryManagerInitTelemetryArgs): Promise<void> {\n\t\tconst isTelemetryEnabled = await this.checkIsTelemetryEnabled();\n\n\t\tthis._segmentClient = () => {\n\t\t\tconst analytics = new Analytics({\n\t\t\t\twriteKey: API_TOKENS.SegmentKey,\n\t\t\t\t// Since it's a local app, we do not benefit from event batching the way a server would normally do, all tracking event will be awaited.\n\t\t\t\tmaxEventsInBatch: 1,\n\t\t\t\t// TODO: Verify that this actually does not send data to Segment when false.\n\t\t\t\tdisable: !isTelemetryEnabled,\n\t\t\t});\n\n\t\t\tanalytics.on(\"error\", (error) => {\n\t\t\t\t// noop - We don't care if the tracking event\n\t\t\t\t// failed. Some users or networks intentionally\n\t\t\t\t// block Segment, so we can't block the app if\n\t\t\t\t// a tracking event is unsuccessful.\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(`An error occurred with Segment`, error);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn analytics;\n\t\t};\n\n\t\tif (isTelemetryEnabled) {\n\t\t\tthis.initExperiment();\n\t\t}\n\n\t\tthis._anonymousID = randomUUID();\n\t\tthis._context = { app: { name: args.appName, version: args.appVersion } };\n\t}\n\n\t// TODO: Should `userId` be automatically populated by the logged in\n\t// user? We already have their info via UserRepository.\n\tasync track(args: TelemetryManagerTrackArgs): Promise<void> {\n\t\tconst { event, repository, _includeEnvironmentKind, ...properties } = args;\n\t\tlet repositoryName = repository;\n\t\tlet starter: string | undefined;\n\n\t\tif (repositoryName === undefined) {\n\t\t\ttry {\n\t\t\t\tconst config = await this.project.getSliceMachineConfig();\n\t\t\t\trepositoryName = config.repositoryName;\n\t\t\t\tstarter = config.starter;\n\t\t\t} catch {\n\t\t\t\t// noop, happens only when the user is not in a project\n\t\t\t}\n\t\t}\n\n\t\tlet environmentKind: Environment[\"kind\"] | \"_unknown\" | undefined =\n\t\t\tundefined;\n\t\tif (_includeEnvironmentKind) {\n\t\t\tif (this.project.checkSupportsEnvironments()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst activeEnvironmentResult =\n\t\t\t\t\t\tawait this.project.fetchActiveEnvironment();\n\n\t\t\t\t\tif (activeEnvironmentResult.type === \"ok\") {\n\t\t\t\t\t\tenvironmentKind = activeEnvironmentResult.activeEnvironment.kind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow activeEnvironmentResult.error;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tenvironmentKind = \"_unknown\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Assume only the production environment can be\n\t\t\t\t// used if the project's adapter does not\n\t\t\t\t// support environments.\n\t\t\t\tenvironmentKind = \"prod\";\n\t\t\t}\n\t\t}\n\n\t\tconst payload: {\n\t\t\tevent: HumanSegmentEventTypes;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\tproperties?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\tevent: HumanSegmentEventType[event],\n\t\t\tproperties: {\n\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\tenvironmentKind,\n\t\t\t\tstarter,\n\t\t\t\t...properties,\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().track(\n\t\t\t\tpayload as TrackParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`An error occurred during Segment tracking`,\n\t\t\t\t\t\t\tmaybeError,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t// TODO: Should `userID` and `intercomHash` be automatically populated\n\t// by the logged in user? We already have their info via\n\t// UserRepository.\n\tidentify(args: TelemetryManagerIdentifyArgs): Promise<void> {\n\t\tconst payload = {\n\t\t\tuserId: args.userID,\n\t\t\tanonymousId: this._anonymousID,\n\t\t\tintegrations: {\n\t\t\t\tIntercom: {\n\t\t\t\t\tuser_hash: args.intercomHash,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tthis._userID = args.userID;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().identify(payload, (maybeError?: unknown) => {\n\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\tconsole.warn(`An error occurred during Segment identify`, maybeError);\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync group(args: TelemetryManagerGroupArgs): Promise<void> {\n\t\tlet repositoryName;\n\n\t\ttry {\n\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t} catch (error) {\n\t\t\t// noop, happen only when the user is not in a project\n\t\t}\n\n\t\tconst payload: {\n\t\t\tgroupId?: string;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\ttraits?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\ttraits: args,\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.groupId = repositoryName;\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\tthis._segmentClient().group(\n\t\t\t\tpayload as GroupParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(`An error occurred during Segment group`, maybeError);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync checkIsTelemetryEnabled(): Promise<boolean> {\n\t\tlet root: string;\n\t\ttry {\n\t\t\troot = await this.project\n\t\t\t\t.getRoot()\n\t\t\t\t.catch(() => this.project.suggestRoot());\n\n\t\t\treturn readPrismicrc(root).telemetry !== false;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate initExperiment(): void {\n\t\ttry {\n\t\t\tthis._experiment = Experiment.initializeRemote(API_TOKENS.AmplitudeKey);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Error initializing experiment\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getExperimentVariant(variantKey: string): Promise<Variant | undefined> {\n\t\tif (this._experiment) {\n\t\t\ttry {\n\t\t\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\t\t\tconst variants = await this._experiment.fetchV2({\n\t\t\t\t\tuser_id: this._userID,\n\t\t\t\t\tuser_properties: {\n\t\t\t\t\t\tRepository: repositoryName,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst variantValue = variants[variantKey].value;\n\t\t\t\tif (variantValue) {\n\t\t\t\t\tawait this.track({\n\t\t\t\t\t\tevent: \"experiment:exposure\",\n\t\t\t\t\t\tflag_key: variantKey,\n\t\t\t\t\t\tvariant: variantValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn variants[variantKey];\n\t\t\t} catch (error) {\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(\"Error fetching experiment variant\", error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"],"names":["Experiment"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slicemachine/manager",
|
|
3
|
-
"version": "0.27.2
|
|
3
|
+
"version": "0.27.2",
|
|
4
4
|
"description": "Manage all aspects of a Slice Machine project.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@prismicio/mocks": "2.14.0",
|
|
72
72
|
"@prismicio/types-internal": "3.11.2",
|
|
73
73
|
"@segment/analytics-node": "^2.1.2",
|
|
74
|
-
"@slicemachine/plugin-kit": "0.4.94
|
|
74
|
+
"@slicemachine/plugin-kit": "0.4.94",
|
|
75
75
|
"cookie": "^1.0.1",
|
|
76
76
|
"cors": "^2.8.5",
|
|
77
77
|
"execa": "^7.1.1",
|
|
@@ -131,6 +131,5 @@
|
|
|
131
131
|
},
|
|
132
132
|
"publishConfig": {
|
|
133
133
|
"access": "public"
|
|
134
|
-
}
|
|
135
|
-
"stableVersion": "0.27.1"
|
|
134
|
+
}
|
|
136
135
|
}
|
|
@@ -102,12 +102,15 @@ export class TelemetryManager extends BaseManager {
|
|
|
102
102
|
async track(args: TelemetryManagerTrackArgs): Promise<void> {
|
|
103
103
|
const { event, repository, _includeEnvironmentKind, ...properties } = args;
|
|
104
104
|
let repositoryName = repository;
|
|
105
|
+
let starter: string | undefined;
|
|
105
106
|
|
|
106
107
|
if (repositoryName === undefined) {
|
|
107
108
|
try {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
const config = await this.project.getSliceMachineConfig();
|
|
110
|
+
repositoryName = config.repositoryName;
|
|
111
|
+
starter = config.starter;
|
|
112
|
+
} catch {
|
|
113
|
+
// noop, happens only when the user is not in a project
|
|
111
114
|
}
|
|
112
115
|
}
|
|
113
116
|
|
|
@@ -150,6 +153,7 @@ export class TelemetryManager extends BaseManager {
|
|
|
150
153
|
properties: {
|
|
151
154
|
nodeVersion: process.versions.node,
|
|
152
155
|
environmentKind,
|
|
156
|
+
starter,
|
|
153
157
|
...properties,
|
|
154
158
|
},
|
|
155
159
|
context: { ...this._context },
|
package/src/types.ts
CHANGED