@knime/hub-features 1.27.0 → 1.28.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @knime/hub-features
2
2
 
3
+ ## 1.28.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2908385: - split returned events based on event source (editor/cloudhome)
8
+ - add secret created event (cloudhome)
9
+ - introduce page property to interaction property (only for cloudhome events)
10
+
11
+ ### Patch Changes
12
+
13
+ - a2f988b: add cloudhome events for creating and sharing deployments
14
+
3
15
  ## 1.27.0
4
16
 
5
17
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knime/hub-features",
3
- "version": "1.27.0",
3
+ "version": "1.28.0",
4
4
  "description": "Vue components & composables for shared hub features",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,8 +39,8 @@
39
39
  "lodash-es": "4.18.1",
40
40
  "ofetch": "^1.4.1",
41
41
  "typescript": "^5.9.3",
42
- "@knime/components": "1.46.6",
43
42
  "@knime/styles": "1.15.1",
43
+ "@knime/components": "1.46.6",
44
44
  "@knime/utils": "1.11.0"
45
45
  },
46
46
  "peerDependencies": {
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import * as functions from "./schema/event-functions";
2
+ import * as cloudHomeFunctions from "./schema/cloudhome-event-functions";
3
+ import * as editorFunctions from "./schema/editor-event-functions";
3
4
  import type {
4
5
  AnalyticsEvent,
5
6
  AnalyticsEventSender,
@@ -22,26 +23,51 @@ type UnwrapFunction<T> = T extends (ctx: DefaultContext) => infer R
22
23
  : never
23
24
  : never;
24
25
 
25
- type FunctionMap = typeof functions;
26
- type Names = keyof FunctionMap;
27
- type BuilderFunctions = {
28
- [K in Names]: UnwrapFunction<(typeof functions)[K]>;
26
+ type EditorFunctionMap = typeof editorFunctions;
27
+ type CloudHomeFunctionMap = typeof cloudHomeFunctions;
28
+
29
+ type EditorBuilderFunctions = {
30
+ [K in keyof EditorFunctionMap]: UnwrapFunction<EditorFunctionMap[K]>;
31
+ };
32
+ type CloudHomeBuilderFunctions = {
33
+ [K in keyof CloudHomeFunctionMap]: UnwrapFunction<CloudHomeFunctionMap[K]>;
29
34
  };
30
35
 
31
- type SenderFunctions = {
32
- [K in Names]: (...args: Parameters<BuilderFunctions[K]>) => void;
36
+ type EditorSenderFunctions = {
37
+ [K in keyof EditorBuilderFunctions]: (
38
+ ...args: Parameters<EditorBuilderFunctions[K]>
39
+ ) => void;
40
+ };
41
+ type CloudHomeSenderFunctions = {
42
+ [K in keyof CloudHomeBuilderFunctions]: (
43
+ ...args: Parameters<CloudHomeBuilderFunctions[K]>
44
+ ) => void;
33
45
  };
34
46
 
47
+ type BuilderFunctions<T extends DefaultContext> =
48
+ T["eventSource"] extends "editor"
49
+ ? EditorBuilderFunctions
50
+ : CloudHomeBuilderFunctions;
51
+
52
+ type SenderFunctions<T extends DefaultContext> =
53
+ T["eventSource"] extends "editor"
54
+ ? EditorSenderFunctions
55
+ : CloudHomeSenderFunctions;
56
+
35
57
  /**
36
58
  * This function creates an event builder, which lets you construct correct and strongly-typed
37
59
  * event payloads according to the current schema used by this package
38
60
  * @param context
39
61
  * @returns
40
62
  */
41
- function eventBuilder<T extends DefaultContext>(context: T) {
63
+ function eventBuilder<T extends DefaultContext>(
64
+ context: T,
65
+ ): BuilderFunctions<T> {
42
66
  const unwrapped = Object.fromEntries(
43
- Object.entries(functions).map(([name, fn]) => [name, fn(context)]),
44
- ) as BuilderFunctions;
67
+ Object.entries(
68
+ context.eventSource === "editor" ? editorFunctions : cloudHomeFunctions,
69
+ ).map(([name, fn]) => [name, fn(context)]),
70
+ ) as BuilderFunctions<T>;
45
71
 
46
72
  return { ...unwrapped };
47
73
  }
@@ -67,12 +93,12 @@ export const analyticsEvents = Object.freeze({
67
93
 
68
94
  type AnyFn = (...args: any[]) => any;
69
95
 
70
- const wrapper: SenderFunctions = {} as SenderFunctions;
96
+ const wrapper = {} as SenderFunctions<T>;
71
97
 
72
98
  // keep all the same functions of the builder but wrap around them for extra behavior
73
99
  Object.keys(builder).forEach((fnName) => {
74
- const key = fnName as keyof SenderFunctions;
75
- wrapper[key] = (...args: any[]) => {
100
+ const key = fnName as keyof SenderFunctions<T>;
101
+ (wrapper as any)[key] = (...args: any[]) => {
76
102
  // TS issue:
77
103
  // ```A spread argument must either have a tuple type or be passed to a rest parameter.```
78
104
  // This happens because when calling the methods generically, TS tries to join all function signatures
@@ -0,0 +1,247 @@
1
+
2
+ /* eslint-disable camelcase */
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ // AUTO-GENERATED FILE. DO NOT EDIT.
5
+ import type { AnalyticsEvent, DefaultContext, EventFunctionArgs, GeneratedStaticFields, SchemaStaticFields } from "../types";
6
+ import { toSnakeCaseDeep } from "../utils/toSnakeCaseDeep";
7
+
8
+ /**
9
+ * Fired when the user clicks Run from the deployments page
10
+ */
11
+ export const adHocExecutionStartedDeploymentsPage = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
12
+ const staticData = {
13
+ ...toSnakeCaseDeep(ctx),
14
+ unique_event_id: crypto.randomUUID(),
15
+ timestamp: new Date().toISOString(),
16
+ event_name: "adhoc_execution_started",
17
+ event_source: "cloudhome",
18
+ event_display_name: "Ad Hoc Execution Started",
19
+ interaction: {
20
+ location: "main_area",
21
+ page: "deployments",
22
+ trigger: "user",
23
+ type: "click",
24
+ },
25
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
26
+
27
+ const event = { id: staticData.event_name, data: { ...staticData } };
28
+
29
+ return event;
30
+ };
31
+
32
+ /**
33
+ * Fired when the user clicks Run in the ad hoc execution panel
34
+ */
35
+ export const adHocExecutionStartedExecutionPanel = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
36
+ const staticData = {
37
+ ...toSnakeCaseDeep(ctx),
38
+ unique_event_id: crypto.randomUUID(),
39
+ timestamp: new Date().toISOString(),
40
+ event_name: "adhoc_execution_started",
41
+ event_source: "cloudhome",
42
+ event_display_name: "Ad Hoc Execution Started",
43
+ interaction: {
44
+ location: "contextual_side_panel",
45
+ page: "workflow_details",
46
+ trigger: "user",
47
+ type: "click",
48
+ },
49
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
50
+
51
+ const event = { id: staticData.event_name, data: { ...staticData } };
52
+
53
+ return event;
54
+ };
55
+
56
+ /**
57
+ * Fired when the user clicks Run from the workflow page
58
+ */
59
+ export const adHocExecutionStartedWorkflowPage = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
60
+ const staticData = {
61
+ ...toSnakeCaseDeep(ctx),
62
+ unique_event_id: crypto.randomUUID(),
63
+ timestamp: new Date().toISOString(),
64
+ event_name: "adhoc_execution_started",
65
+ event_source: "cloudhome",
66
+ event_display_name: "Ad Hoc Execution Started",
67
+ interaction: {
68
+ location: "main_area",
69
+ page: "workflow_details",
70
+ trigger: "user",
71
+ type: "click",
72
+ },
73
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
74
+
75
+ const event = { id: staticData.event_name, data: { ...staticData } };
76
+
77
+ return event;
78
+ };
79
+
80
+ /**
81
+ * Fired when the user creates a new secret by clicking Create in the side panel on the team secrets page
82
+ */
83
+ export const secretCreatedTeamSecrets = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
84
+ const staticData = {
85
+ ...toSnakeCaseDeep(ctx),
86
+ unique_event_id: crypto.randomUUID(),
87
+ timestamp: new Date().toISOString(),
88
+ event_name: "secret_created",
89
+ event_source: "cloudhome",
90
+ event_display_name: "Secret Created",
91
+ interaction: {
92
+ location: "contextual_side_panel",
93
+ page: "secrets",
94
+ trigger: "user",
95
+ type: "click",
96
+ },
97
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
98
+
99
+ const event = { id: staticData.event_name, data: { ...staticData } };
100
+
101
+ return event;
102
+ };
103
+
104
+ /**
105
+ * Fired when the user creates a new secret by clicking Create in the side panel on the personal secrets page
106
+ */
107
+ export const secretCreatedMySecrets = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
108
+ const staticData = {
109
+ ...toSnakeCaseDeep(ctx),
110
+ unique_event_id: crypto.randomUUID(),
111
+ timestamp: new Date().toISOString(),
112
+ event_name: "secret_created",
113
+ event_source: "cloudhome",
114
+ event_display_name: "Secret Created",
115
+ interaction: {
116
+ location: "contextual_side_panel",
117
+ page: "my_secrets",
118
+ trigger: "user",
119
+ type: "click",
120
+ },
121
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
122
+
123
+ const event = { id: staticData.event_name, data: { ...staticData } };
124
+
125
+ return event;
126
+ };
127
+
128
+ /**
129
+ * Fired when the user clicks the Create button in the deployment creation side panel
130
+ */
131
+ export const deploymentCreated = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentCreated">): AnalyticsEvent => {
132
+ const staticData = {
133
+ ...toSnakeCaseDeep(ctx),
134
+ unique_event_id: crypto.randomUUID(),
135
+ timestamp: new Date().toISOString(),
136
+ event_name: "deployment_created",
137
+ event_source: "cloudhome",
138
+ event_display_name: "Deployment Created",
139
+ interaction: {
140
+ location: "contextual_side_panel",
141
+ page: "deployments",
142
+ trigger: "user",
143
+ type: "click",
144
+ },
145
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
146
+
147
+ const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
148
+
149
+ return event;
150
+ };
151
+
152
+ /**
153
+ * Fired when the user shares a deployment via the access management side panel on the deployments page
154
+ */
155
+ export const deploymentSharedDeploymentsAccessPanel = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentSharedDeploymentsAccessPanel">): AnalyticsEvent => {
156
+ const staticData = {
157
+ ...toSnakeCaseDeep(ctx),
158
+ unique_event_id: crypto.randomUUID(),
159
+ timestamp: new Date().toISOString(),
160
+ event_name: "deployment_shared",
161
+ event_source: "cloudhome",
162
+ event_display_name: "Deployment Shared",
163
+ interaction: {
164
+ location: "contextual_side_panel",
165
+ page: "deployments",
166
+ trigger: "user",
167
+ type: "click",
168
+ },
169
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
170
+
171
+ const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
172
+
173
+ return event;
174
+ };
175
+
176
+ /**
177
+ * Fired when the user shares a deployment via the sharing popup on the deployments page
178
+ */
179
+ export const deploymentSharedDeploymentsSharingPopup = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentSharedDeploymentsSharingPopup">): AnalyticsEvent => {
180
+ const staticData = {
181
+ ...toSnakeCaseDeep(ctx),
182
+ unique_event_id: crypto.randomUUID(),
183
+ timestamp: new Date().toISOString(),
184
+ event_name: "deployment_shared",
185
+ event_source: "cloudhome",
186
+ event_display_name: "Deployment Shared",
187
+ interaction: {
188
+ location: "module",
189
+ page: "deployments",
190
+ trigger: "user",
191
+ type: "click",
192
+ },
193
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
194
+
195
+ const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
196
+
197
+ return event;
198
+ };
199
+
200
+ /**
201
+ * Fired when the user shares a deployment via the access management side panel on the workflow page
202
+ */
203
+ export const deploymentSharedWorkflowAccessPanel = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentSharedWorkflowAccessPanel">): AnalyticsEvent => {
204
+ const staticData = {
205
+ ...toSnakeCaseDeep(ctx),
206
+ unique_event_id: crypto.randomUUID(),
207
+ timestamp: new Date().toISOString(),
208
+ event_name: "deployment_shared",
209
+ event_source: "cloudhome",
210
+ event_display_name: "Deployment Shared",
211
+ interaction: {
212
+ location: "contextual_side_panel",
213
+ page: "workflow_details",
214
+ trigger: "user",
215
+ type: "click",
216
+ },
217
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
218
+
219
+ const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
220
+
221
+ return event;
222
+ };
223
+
224
+ /**
225
+ * Fired when the user shares a deployment via the sharing popup on the workflow page
226
+ */
227
+ export const deploymentSharedWorkflowSharingPopup = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentSharedWorkflowSharingPopup">): AnalyticsEvent => {
228
+ const staticData = {
229
+ ...toSnakeCaseDeep(ctx),
230
+ unique_event_id: crypto.randomUUID(),
231
+ timestamp: new Date().toISOString(),
232
+ event_name: "deployment_shared",
233
+ event_source: "cloudhome",
234
+ event_display_name: "Deployment Shared",
235
+ interaction: {
236
+ location: "module",
237
+ page: "workflow_details",
238
+ trigger: "user",
239
+ type: "click",
240
+ },
241
+ } satisfies SchemaStaticFields & GeneratedStaticFields;
242
+
243
+ const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
244
+
245
+ return event;
246
+ };
247
+
@@ -4,7 +4,11 @@ import { fileURLToPath } from "node:url";
4
4
 
5
5
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
6
  const schemaPath = path.join(__dirname, "schema.json");
7
- const outputPath = path.join(__dirname, "event-functions.ts");
7
+ const editorOutputPath = path.join(__dirname, "editor-event-functions.ts");
8
+ const cloudHomeOutputPath = path.join(
9
+ __dirname,
10
+ "cloudhome-event-functions.ts",
11
+ );
8
12
 
9
13
  const schema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
10
14
  const events = schema.properties.events.properties;
@@ -25,7 +29,8 @@ const HEADER_LINES = [
25
29
  `import type { ${Object.values(TYPE_HELPERS).join(", ")} } from "../types";`,
26
30
  'import { toSnakeCaseDeep } from "../utils/toSnakeCaseDeep";',
27
31
  ];
28
- const result = [];
32
+ const editorResult = [];
33
+ const cloudHomeResult = [];
29
34
 
30
35
  /**
31
36
  * Generic event definition, read from the schema.json.
@@ -137,11 +142,17 @@ for (const [fnName, eventDef] of Object.entries(events)) {
137
142
  fn = `${jsdoc}\n${fn}`;
138
143
  }
139
144
 
140
- result.push(fn);
145
+ if (eventDef.properties.event_source.const === "editor") {
146
+ editorResult.push(fn);
147
+ } else if (eventDef.properties.event_source.const === "cloudhome") {
148
+ cloudHomeResult.push(fn);
149
+ }
141
150
  }
142
151
 
143
- const fileContent = `${HEADER_LINES.join("\n")}\n\n${result.join("")}`;
152
+ const editorFileContent = `${HEADER_LINES.join("\n")}\n\n${editorResult.join("")}`;
153
+ const cloudHomeFileContent = `${HEADER_LINES.join("\n")}\n\n${cloudHomeResult.join("")}`;
144
154
 
145
- fs.writeFileSync(outputPath, fileContent, "utf8");
155
+ fs.writeFileSync(editorOutputPath, editorFileContent, "utf8");
156
+ fs.writeFileSync(cloudHomeOutputPath, cloudHomeFileContent, "utf8");
146
157
  // eslint-disable-next-line no-console
147
158
  console.log("Generated static data based on the Events JSON Schema.");
@@ -422,6 +422,42 @@ export interface AnalyticsEventSchema {
422
422
  };
423
423
  payload: EmptyPayload;
424
424
  };
425
+ adHocExecutionStartedDeploymentsPage: {
426
+ event_name: "adhoc_execution_started";
427
+ event_source: "cloudhome";
428
+ event_display_name: "Ad Hoc Execution Started";
429
+ interaction: {
430
+ location: "main_area";
431
+ page: "deployments";
432
+ trigger: InteractionTrigger & "user";
433
+ type: InteractionType & "click";
434
+ };
435
+ payload: EmptyPayload;
436
+ };
437
+ adHocExecutionStartedExecutionPanel: {
438
+ event_name: "adhoc_execution_started";
439
+ event_source: "cloudhome";
440
+ event_display_name: "Ad Hoc Execution Started";
441
+ interaction: {
442
+ location: "contextual_side_panel";
443
+ page: "workflow_details";
444
+ trigger: InteractionTrigger & "user";
445
+ type: InteractionType & "click";
446
+ };
447
+ payload: EmptyPayload;
448
+ };
449
+ adHocExecutionStartedWorkflowPage: {
450
+ event_name: "adhoc_execution_started";
451
+ event_source: "cloudhome";
452
+ event_display_name: "Ad Hoc Execution Started";
453
+ interaction: {
454
+ location: "main_area";
455
+ page: "workflow_details";
456
+ trigger: InteractionTrigger & "user";
457
+ type: InteractionType & "click";
458
+ };
459
+ payload: EmptyPayload;
460
+ };
425
461
  actionRedoneToolbar: {
426
462
  event_name: "action_redone";
427
463
  event_source: "editor";
@@ -455,6 +491,30 @@ export interface AnalyticsEventSchema {
455
491
  };
456
492
  payload: EmptyPayload;
457
493
  };
494
+ secretCreatedTeamSecrets: {
495
+ event_name: "secret_created";
496
+ event_source: "cloudhome";
497
+ event_display_name: "Secret Created";
498
+ interaction: {
499
+ location: "contextual_side_panel";
500
+ page: "secrets";
501
+ trigger: InteractionTrigger & "user";
502
+ type: InteractionType & "click";
503
+ };
504
+ payload: EmptyPayload;
505
+ };
506
+ secretCreatedMySecrets: {
507
+ event_name: "secret_created";
508
+ event_source: "cloudhome";
509
+ event_display_name: "Secret Created";
510
+ interaction: {
511
+ location: "contextual_side_panel";
512
+ page: "my_secrets";
513
+ trigger: InteractionTrigger & "user";
514
+ type: InteractionType & "click";
515
+ };
516
+ payload: EmptyPayload;
517
+ };
458
518
  sessionEnded: {
459
519
  event_name: "session_ended";
460
520
  event_source: "editor";
@@ -612,6 +672,66 @@ export interface AnalyticsEventSchema {
612
672
  };
613
673
  payload: ContainerNodeTypePayload;
614
674
  };
675
+ deploymentCreated: {
676
+ event_name: "deployment_created";
677
+ event_source: "cloudhome";
678
+ event_display_name: "Deployment Created";
679
+ interaction: {
680
+ location: "contextual_side_panel";
681
+ page: "deployments";
682
+ trigger: InteractionTrigger & "user";
683
+ type: InteractionType & "click";
684
+ };
685
+ payload: DeploymentCreatedPayload;
686
+ };
687
+ deploymentSharedDeploymentsAccessPanel: {
688
+ event_name: "deployment_shared";
689
+ event_source: "cloudhome";
690
+ event_display_name: "Deployment Shared";
691
+ interaction: {
692
+ location: "contextual_side_panel";
693
+ page: "deployments";
694
+ trigger: InteractionTrigger & "user";
695
+ type: InteractionType & "click";
696
+ };
697
+ payload: DeploymentSharedPayload;
698
+ };
699
+ deploymentSharedDeploymentsSharingPopup: {
700
+ event_name: "deployment_shared";
701
+ event_source: "cloudhome";
702
+ event_display_name: "Deployment Shared";
703
+ interaction: {
704
+ location: "module";
705
+ page: "deployments";
706
+ trigger: InteractionTrigger & "user";
707
+ type: InteractionType & "click";
708
+ };
709
+ payload: DeploymentSharedPayload;
710
+ };
711
+ deploymentSharedWorkflowAccessPanel: {
712
+ event_name: "deployment_shared";
713
+ event_source: "cloudhome";
714
+ event_display_name: "Deployment Shared";
715
+ interaction: {
716
+ location: "contextual_side_panel";
717
+ page: "workflow_details";
718
+ trigger: InteractionTrigger & "user";
719
+ type: InteractionType & "click";
720
+ };
721
+ payload: DeploymentSharedPayload;
722
+ };
723
+ deploymentSharedWorkflowSharingPopup: {
724
+ event_name: "deployment_shared";
725
+ event_source: "cloudhome";
726
+ event_display_name: "Deployment Shared";
727
+ interaction: {
728
+ location: "module";
729
+ page: "workflow_details";
730
+ trigger: InteractionTrigger & "user";
731
+ type: InteractionType & "click";
732
+ };
733
+ payload: DeploymentSharedPayload;
734
+ };
615
735
  nodeCreatedCanvasDragDropFile: {
616
736
  event_name: "node_created";
617
737
  event_source: "editor";
@@ -687,7 +807,6 @@ export interface SearchPayload {
687
807
  }
688
808
  export interface SessionEndedPayload {
689
809
  type: "timedout" | "user_closed";
690
- [k: string]: unknown;
691
810
  }
692
811
  export interface ContainerNodeCreatedPayload {
693
812
  nodeType: "component" | "metanode";
@@ -706,3 +825,10 @@ export interface ConfigurationCompletedPayload {
706
825
  export interface ContainerNodeTypePayload {
707
826
  nodeType: "component" | "metanode";
708
827
  }
828
+ export interface DeploymentCreatedPayload {
829
+ deploymentType: "dataApp" | "schedule" | "service";
830
+ }
831
+ export interface DeploymentSharedPayload {
832
+ deploymentType: "dataApp" | "service";
833
+ sharingMethod: "invite" | "copy_link";
834
+ }