@skillswaveca/nova-shared-libraries 4.25.0 → 4.27.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.
@@ -3,7 +3,7 @@
3
3
  "name": "@skillswaveca/nova-drivers",
4
4
  "description": "Some helper drivers for AWS services",
5
5
  "repository": "https://github.com/SkillsWave/nova-shared-libraries",
6
- "version": "4.25.0",
6
+ "version": "4.27.0",
7
7
  "main": "index.js",
8
8
  "scripts": {
9
9
  "pre-release": "pnpm run create-index",
@@ -16,17 +16,20 @@
16
16
  "devDependencies": {
17
17
  "chai": "^5.1.0",
18
18
  "eslint": "^9.0.0",
19
- "mocha": "^10.4.0"
19
+ "mocha": "^10.4.0",
20
+ "sinon": "^21.0.0",
21
+ "sinon-chai": "^4.0.0"
20
22
  },
21
23
  "dependencies": {
22
- "simple-oauth2": "^5.0.0",
23
24
  "@aws-sdk/client-dynamodb": "^3.572.0",
24
25
  "@aws-sdk/client-secrets-manager": "^3.572.0",
25
26
  "@aws-sdk/client-sqs": "^3.572.0",
26
27
  "@aws-sdk/lib-dynamodb": "^3.572.0",
28
+ "@hubspot/api-client": "^13.0.0",
27
29
  "aws-xray-sdk-core": "^3.6.0",
28
30
  "lodash.chunk": "^4.2.0",
29
31
  "node-fetch": "^3.1.0",
30
- "pino": "^9.0.0"
32
+ "pino": "^9.0.0",
33
+ "simple-oauth2": "^5.0.0"
31
34
  }
32
35
  }
@@ -113,8 +113,8 @@ export class HubSpotDriver extends NovaDriver {
113
113
 
114
114
  /**
115
115
  * Updates a HubSpot deal with the given properties.
116
- * @param {string} dealId
117
- * @param {object} properties
116
+ * @param {string} dealId
117
+ * @param {object} properties
118
118
  * @returns The updated deal object.
119
119
  */
120
120
  async updateDeal(dealId, properties) {
@@ -123,7 +123,7 @@ export class HubSpotDriver extends NovaDriver {
123
123
 
124
124
  /**
125
125
  * Looks up a HubSpot contact ID for a given user. May return multiple IDs.
126
- * @param {Object} user
126
+ * @param {Object} user
127
127
  * @returns {Promise<string[]|null>} An array of HubSpot contact IDs or null if no contact is found.
128
128
  */
129
129
  async lookupUserContactId(user) {
@@ -152,7 +152,7 @@ export class HubSpotDriver extends NovaDriver {
152
152
 
153
153
  /**
154
154
  * Creates or updates a HubSpot contact. If the provided user has a `hubSpotContactId`, it will update the existing contact; otherwise, it will create a new one.
155
- * @param {object} user
155
+ * @param {object} user
156
156
  * @returns {object} The created/updated HubSpot user.
157
157
  */
158
158
  async upsertUser(user) {
@@ -169,7 +169,7 @@ export class HubSpotDriver extends NovaDriver {
169
169
 
170
170
  /**
171
171
  * Deletes a HubSpot user.
172
- * @param {object} user
172
+ * @param {object} user
173
173
  * @returns {Promise<void>}
174
174
  */
175
175
  async deleteUser(user) {
@@ -184,7 +184,7 @@ export class HubSpotDriver extends NovaDriver {
184
184
  /**
185
185
  * Sends a custom event to HubSpot using the event definitions.
186
186
  * This method validates the event data against the predefined schema before sending.
187
- *
187
+ *
188
188
  * @param {string} eventName - The name of the event to send
189
189
  * @param {object} eventData - The event data to send
190
190
  * @returns {Promise<object>} The response from HubSpot API
@@ -192,6 +192,7 @@ export class HubSpotDriver extends NovaDriver {
192
192
  */
193
193
  async sendEvent(eventName, eventData) {
194
194
  try {
195
+ log.error({ eventName, eventData }, 'Sending event to HubSpot');
195
196
  // Validate the event exists and get its definition
196
197
  const eventDefinition = getEventDefinition(eventName);
197
198
  if (!eventDefinition) {
@@ -204,7 +205,7 @@ export class HubSpotDriver extends NovaDriver {
204
205
  const eventMetadata = await getEventMetadata(eventName, validatedData);
205
206
 
206
207
  const response = await this._callHubSpot('events.send.basicApi.send', {
207
- eventName: `pe${this.accountId}_${eventName}`,
208
+ eventName: `pe${this.accountId}_${eventDefinition.name}`,
208
209
  properties: validatedData,
209
210
  occurredAt: new Date(),
210
211
  ...eventMetadata,
@@ -213,14 +214,14 @@ export class HubSpotDriver extends NovaDriver {
213
214
  log.debug({ eventName, response }, 'Event sent to HubSpot successfully');
214
215
  return response;
215
216
  } catch (error) {
216
- log.error({
217
- eventName,
218
- eventData,
217
+ log.error({
218
+ eventName,
219
+ eventData,
219
220
  error: error.message,
220
- stack: error.stack
221
+ stack: error.stack
221
222
  }, 'Unexpected error while sending event');
222
-
223
+
223
224
  throw error;
224
225
  }
225
226
  }
226
- }
227
+ }
@@ -3,7 +3,7 @@
3
3
  "name": "@skillswaveca/nova-middleware",
4
4
  "description": "A collection of middleware used by nova projects",
5
5
  "repository": "https://github.com/SkillsWave/nova-shared-libraries",
6
- "version": "4.25.0",
6
+ "version": "4.27.0",
7
7
  "main": "index.js",
8
8
  "scripts": {
9
9
  "pre-release": "pnpm run create-index",
@@ -3,7 +3,7 @@
3
3
  "name": "@skillswaveca/nova-model",
4
4
  "description": "Nova model stuff",
5
5
  "repository": "https://github.com/SkillsWave/nova-shared-libraries",
6
- "version": "4.25.0",
6
+ "version": "4.27.0",
7
7
  "main": "index.js",
8
8
  "scripts": {
9
9
  "pre-release": "pnpm run create-index",
@@ -3,7 +3,7 @@
3
3
  "name": "@skillswaveca/nova-router",
4
4
  "description": "An extended Koa router that enables better validation",
5
5
  "repository": "https://github.com/SkillsWave/nova-shared-libraries",
6
- "version": "4.25.0",
6
+ "version": "4.27.0",
7
7
  "main": "index.js",
8
8
  "scripts": {
9
9
  "pre-release": "pnpm run create-index",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@skillswaveca/nova-utils",
3
- "version": "4.24.0",
3
+ "version": "4.25.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@skillswaveca/nova-utils",
9
- "version": "4.24.0",
9
+ "version": "4.25.0",
10
10
  "license": "UNLICENSED",
11
11
  "dependencies": {
12
12
  "yup": "^1.4.0"
@@ -3,7 +3,7 @@
3
3
  "name": "@skillswaveca/nova-utils",
4
4
  "description": "A collection of random utils used in nova repos",
5
5
  "repository": "https://github.com/SkillsWave/nova-shared-libraries",
6
- "version": "4.25.0",
6
+ "version": "4.27.0",
7
7
  "main": "index.js",
8
8
  "scripts": {
9
9
  "pre-release": "pnpm run create-index",
@@ -11,10 +11,37 @@ import * as yup from 'yup';
11
11
  * - validator: Yup validation schema for the event data
12
12
  */
13
13
 
14
- const testEventDefinition = {
15
- name: 'hubspot_test_event',
16
- description: 'Test event for HubSpot integration',
14
+ const TENANT_PROPERTIES = {
15
+ tenant_id: {
16
+ type: 'string',
17
+ required: true,
18
+ description: 'The ID of the tenant',
19
+ },
20
+ tenant_name: {
21
+ type: 'string',
22
+ required: true,
23
+ description: 'The name of the tenant',
24
+ },
25
+ };
26
+
27
+ const TENANT_PROPERTIES_VALIDATOR = {
28
+ tenant_id: yup.string().required('Tenant ID is required'),
29
+ tenant_name: yup.string().required('Tenant name is required'),
30
+ };
31
+
32
+ const TENANT_METADATA_PROPERTIES = data => {
33
+ return {
34
+ tenant_id: data.tenant_id,
35
+ tenant_name: data.tenant_name,
36
+ };
37
+ };
38
+
39
+ const clientOnboardingCompletedEventDefinition = {
40
+ key: 'clientOnboardingCompleted',
41
+ name: 'client_onboarding_completed',
42
+ description: 'Client has finished PLG onboarding and pressed "create workspace."',
17
43
  properties: {
44
+ ...TENANT_PROPERTIES,
18
45
  email: {
19
46
  type: 'string',
20
47
  required: true,
@@ -22,10 +49,108 @@ const testEventDefinition = {
22
49
  },
23
50
  },
24
51
  validator: yup.object({
52
+ ...TENANT_PROPERTIES_VALIDATOR,
25
53
  email: yup.string().email('Must be a valid email').required('Email is required'),
26
54
  }),
27
55
  getMetadata: eventData => {
28
56
  return {
57
+ ...TENANT_METADATA_PROPERTIES(eventData),
58
+ email: eventData.email,
59
+ };
60
+ },
61
+ };
62
+
63
+ const usersInvitedEventDefinition = {
64
+ key: 'usersInvited',
65
+ name: 'users_invited',
66
+ description: 'PLG Admin has invited one or more users to their workspace.',
67
+ properties: {
68
+ ...TENANT_PROPERTIES,
69
+ email: {
70
+ type: 'string',
71
+ required: true,
72
+ description: 'Email address of the user',
73
+ },
74
+ },
75
+ validator: yup.object({
76
+ ...TENANT_PROPERTIES_VALIDATOR,
77
+ email: yup.string().email('Must be a valid email').required('Email is required'),
78
+ }),
79
+ getMetadata: eventData => {
80
+ return {
81
+ ...TENANT_METADATA_PROPERTIES(eventData),
82
+ email: eventData.email,
83
+ };
84
+ },
85
+ };
86
+
87
+ const creditCardEventDefinition = {
88
+ key: 'creditCardAdded',
89
+ name: 'credit_card_added',
90
+ description: 'PLG Admin added a credit card in Stripe.',
91
+ properties: {
92
+ ...TENANT_PROPERTIES,
93
+ email: {
94
+ type: 'string',
95
+ required: true,
96
+ description: 'Email address of the user',
97
+ },
98
+ },
99
+ validator: yup.object({
100
+ ...TENANT_PROPERTIES_VALIDATOR,
101
+ email: yup.string().email('Must be a valid email').required('Email is required'),
102
+ }),
103
+ getMetadata: eventData => {
104
+ return {
105
+ ...TENANT_METADATA_PROPERTIES(eventData),
106
+ email: eventData.email,
107
+ };
108
+ },
109
+ };
110
+
111
+ const firstRequestSubmittedEventDefinition = {
112
+ key: 'firstRequestSubmitted',
113
+ name: 'first_request_submitted',
114
+ description: 'A user in the PLG workspace has submitted the first request.',
115
+ properties: {
116
+ ...TENANT_PROPERTIES,
117
+ email: {
118
+ type: 'string',
119
+ required: true,
120
+ description: 'Email address of the user',
121
+ },
122
+ },
123
+ validator: yup.object({
124
+ ...TENANT_PROPERTIES_VALIDATOR,
125
+ email: yup.string().email('Must be a valid email').required('Email is required'),
126
+ }),
127
+ getMetadata: eventData => {
128
+ return {
129
+ ...TENANT_METADATA_PROPERTIES(eventData),
130
+ email: eventData.email,
131
+ };
132
+ },
133
+ };
134
+
135
+ const transactionsThresholdMetEventDefinition = {
136
+ key: 'transactionsThresholdMet',
137
+ name: 'transactions_threshold_met',
138
+ description: 'The PLG tenant has completed a specified number of transactions.',
139
+ properties: {
140
+ ...TENANT_PROPERTIES,
141
+ email: {
142
+ type: 'string',
143
+ required: true,
144
+ description: 'Email address of the user',
145
+ },
146
+ },
147
+ validator: yup.object({
148
+ ...TENANT_PROPERTIES_VALIDATOR,
149
+ email: yup.string().email('Must be a valid email').required('Email is required'),
150
+ }),
151
+ getMetadata: eventData => {
152
+ return {
153
+ ...TENANT_METADATA_PROPERTIES(eventData),
29
154
  email: eventData.email,
30
155
  };
31
156
  },
@@ -36,9 +161,12 @@ const testEventDefinition = {
36
161
  * Key: event name, Value: event definition object
37
162
  */
38
163
  export const eventDefinitions = {
39
- [testEventDefinition.name]: testEventDefinition,
164
+ [clientOnboardingCompletedEventDefinition.key]: clientOnboardingCompletedEventDefinition,
165
+ [usersInvitedEventDefinition.key]: usersInvitedEventDefinition,
166
+ [creditCardEventDefinition.key]: creditCardEventDefinition,
167
+ [firstRequestSubmittedEventDefinition.key]: firstRequestSubmittedEventDefinition,
168
+ [transactionsThresholdMetEventDefinition.key]: transactionsThresholdMetEventDefinition,
40
169
  };
41
-
42
170
  /**
43
171
  * Get event definition by name
44
172
  * @param {string} eventName - The name of the event
@@ -84,7 +212,7 @@ export const validateEvent = async(eventName, eventData) => {
84
212
  * @returns {boolean} True if the event exists, false otherwise
85
213
  */
86
214
  export const isValidEventName = eventName => {
87
- return eventDefinitions.hasOwnProperty(eventName);
215
+ return Object.hasOwn(eventDefinitions, eventName);
88
216
  };
89
217
 
90
218
  /**