@dereekb/nestjs 13.0.0 → 13.0.1

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.
@@ -14,19 +14,19 @@ var apiClient = require('@typeform/api-client');
14
14
  * @returns
15
15
  */
16
16
  function typeFormWebhookEvent(event) {
17
- return event;
17
+ return event;
18
18
  }
19
- const typeformEventHandlerFactory = util.handlerFactory(x => x.event_type);
19
+ const typeformEventHandlerFactory = util.handlerFactory((x) => x.event_type);
20
20
  const typeformEventHandlerConfigurerFactory = util.handlerConfigurerFactory({
21
- configurerForAccessor: accessor => {
22
- // eslint-disable-next-line
23
- const fnWithKey = util.handlerMappedSetFunctionFactory(accessor, typeFormWebhookEvent);
24
- const configurer = {
25
- ...accessor,
26
- handleFormResponse: fnWithKey('form_response')
27
- };
28
- return configurer;
29
- }
21
+ configurerForAccessor: (accessor) => {
22
+ // eslint-disable-next-line
23
+ const fnWithKey = util.handlerMappedSetFunctionFactory(accessor, typeFormWebhookEvent);
24
+ const configurer = {
25
+ ...accessor,
26
+ handleFormResponse: fnWithKey('form_response')
27
+ };
28
+ return configurer;
29
+ }
30
30
  });
31
31
 
32
32
  const TYPEFORM_WEBHOOK_SECRET_TOKEN_ENV_VAR = 'TYPEFORM_WEBHOOK_SECRET_TOKEN';
@@ -34,12 +34,12 @@ const TYPEFORM_WEBHOOK_SECRET_TOKEN_ENV_VAR = 'TYPEFORM_WEBHOOK_SECRET_TOKEN';
34
34
  * Configuration for TypeformService
35
35
  */
36
36
  class TypeformWebhookServiceConfig {
37
- typeformWebhook;
38
- static assertValidConfig(config) {
39
- if (!config.typeformWebhook.secretToken) {
40
- throw new Error('No Typeform webhook secret specified.');
37
+ typeformWebhook;
38
+ static assertValidConfig(config) {
39
+ if (!config.typeformWebhook.secretToken) {
40
+ throw new Error('No Typeform webhook secret specified.');
41
+ }
41
42
  }
42
- }
43
43
  }
44
44
 
45
45
  /******************************************************************************
@@ -86,230 +86,237 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
86
86
  * @returns A function that verifies a Typeform webhook event.
87
87
  */
88
88
  function typeFormWebhookEventVerifier(config) {
89
- const {
90
- secret
91
- } = config;
92
- return async (request, rawBody) => {
93
- const requestBodyString = String(request.body);
94
- const headers = request.headers;
95
- const vapiSignature = headers['typeform-signature'];
96
- const hashForVerify = crypto.createHmac('sha256', secret).update(requestBodyString).digest('base64');
97
- const signature = `sha256=${hashForVerify}`;
98
- const valid = vapiSignature === signature;
99
- const event = JSON.parse(requestBodyString);
100
- const result = {
101
- valid,
102
- event
89
+ const { secret } = config;
90
+ return async (request, rawBody) => {
91
+ const requestBodyString = String(request.body);
92
+ const headers = request.headers;
93
+ const vapiSignature = headers['typeform-signature'];
94
+ const hashForVerify = crypto.createHmac('sha256', secret).update(requestBodyString).digest('base64');
95
+ const signature = `sha256=${hashForVerify}`;
96
+ const valid = vapiSignature === signature;
97
+ const event = JSON.parse(requestBodyString);
98
+ const result = {
99
+ valid,
100
+ event
101
+ };
102
+ return result;
103
103
  };
104
- return result;
105
- };
106
104
  }
107
105
 
108
106
  /**
109
107
  * Service that makes system changes based on Typeform webhook events.
110
108
  */
111
109
  exports.TypeformWebhookService = class TypeformWebhookService {
112
- logger = new common.Logger('TypeformWebhookService');
113
- _verifier;
114
- handler = typeformEventHandlerFactory();
115
- configure = typeformEventHandlerConfigurerFactory(this.handler);
116
- constructor(typeFormWebhookServiceConfig) {
117
- const {
118
- secretToken: webhookSecret
119
- } = typeFormWebhookServiceConfig.typeformWebhook;
120
- this._verifier = typeFormWebhookEventVerifier({
121
- secret: webhookSecret
122
- });
123
- }
124
- async updateForWebhook(req, rawBody) {
125
- const result = await this._verifier(req, rawBody);
126
- if (!result.valid) {
127
- this.logger.warn('Received invalid Typeform event.', req);
128
- } else {
129
- await this.updateForTypeformEvent(result.event);
110
+ logger = new common.Logger('TypeformWebhookService');
111
+ _verifier;
112
+ handler = typeformEventHandlerFactory();
113
+ configure = typeformEventHandlerConfigurerFactory(this.handler);
114
+ constructor(typeFormWebhookServiceConfig) {
115
+ const { secretToken: webhookSecret } = typeFormWebhookServiceConfig.typeformWebhook;
116
+ this._verifier = typeFormWebhookEventVerifier({
117
+ secret: webhookSecret
118
+ });
119
+ }
120
+ async updateForWebhook(req, rawBody) {
121
+ const result = await this._verifier(req, rawBody);
122
+ if (!result.valid) {
123
+ this.logger.warn('Received invalid Typeform event.', req);
124
+ }
125
+ else {
126
+ await this.updateForTypeformEvent(result.event);
127
+ }
130
128
  }
131
- }
132
- async updateForTypeformEvent(event) {
133
- const result = await this.handler(event);
134
- if (!result) {
135
- this.logger.warn('Received unexpected/unhandled Typeform event.', event);
129
+ async updateForTypeformEvent(event) {
130
+ const result = await this.handler(event);
131
+ if (!result) {
132
+ this.logger.warn('Received unexpected/unhandled Typeform event.', event);
133
+ }
136
134
  }
137
- }
138
135
  };
139
- exports.TypeformWebhookService = __decorate([common.Injectable(), __param(0, common.Inject(TypeformWebhookServiceConfig)), __metadata("design:paramtypes", [TypeformWebhookServiceConfig])], exports.TypeformWebhookService);
136
+ exports.TypeformWebhookService = __decorate([
137
+ common.Injectable(),
138
+ __param(0, common.Inject(TypeformWebhookServiceConfig)),
139
+ __metadata("design:paramtypes", [TypeformWebhookServiceConfig])
140
+ ], exports.TypeformWebhookService);
140
141
 
141
142
  exports.TypeformWebhookController = class TypeformWebhookController {
142
- _typeformWebhookService;
143
- constructor(typeformWebhookService) {
144
- this._typeformWebhookService = typeformWebhookService;
145
- }
146
- async handleTypeformWebhook(req, rawBody) {
147
- await this._typeformWebhookService.updateForWebhook(req, rawBody);
148
- }
143
+ _typeformWebhookService;
144
+ constructor(typeformWebhookService) {
145
+ this._typeformWebhookService = typeformWebhookService;
146
+ }
147
+ async handleTypeformWebhook(req, rawBody) {
148
+ await this._typeformWebhookService.updateForWebhook(req, rawBody);
149
+ }
149
150
  };
150
- __decorate([common.Post(), __param(0, common.Req()), __param(1, nestjs.RawBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise)], exports.TypeformWebhookController.prototype, "handleTypeformWebhook", null);
151
- exports.TypeformWebhookController = __decorate([common.Controller('/webhook/typeform'), __param(0, common.Inject(exports.TypeformWebhookService)), __metadata("design:paramtypes", [exports.TypeformWebhookService])], exports.TypeformWebhookController);
151
+ __decorate([
152
+ common.Post(),
153
+ __param(0, common.Req()),
154
+ __param(1, nestjs.RawBody()),
155
+ __metadata("design:type", Function),
156
+ __metadata("design:paramtypes", [Object, Object]),
157
+ __metadata("design:returntype", Promise)
158
+ ], exports.TypeformWebhookController.prototype, "handleTypeformWebhook", null);
159
+ exports.TypeformWebhookController = __decorate([
160
+ common.Controller('/webhook/typeform'),
161
+ __param(0, common.Inject(exports.TypeformWebhookService)),
162
+ __metadata("design:paramtypes", [exports.TypeformWebhookService])
163
+ ], exports.TypeformWebhookController);
152
164
 
153
165
  function typeFormWebhookServiceConfigFactory(configService) {
154
- const config = {
155
- typeformWebhook: {
156
- secretToken: configService.get(TYPEFORM_WEBHOOK_SECRET_TOKEN_ENV_VAR)
157
- }
158
- };
159
- TypeformWebhookServiceConfig.assertValidConfig(config);
160
- return config;
166
+ const config = {
167
+ typeformWebhook: {
168
+ secretToken: configService.get(TYPEFORM_WEBHOOK_SECRET_TOKEN_ENV_VAR)
169
+ }
170
+ };
171
+ TypeformWebhookServiceConfig.assertValidConfig(config);
172
+ return config;
161
173
  }
162
- exports.TypeformWebhookModule = class TypeformWebhookModule {};
163
- exports.TypeformWebhookModule = __decorate([common.Module({
164
- imports: [config.ConfigModule],
165
- controllers: [exports.TypeformWebhookController],
166
- providers: [{
167
- provide: TypeformWebhookServiceConfig,
168
- inject: [config.ConfigService],
169
- useFactory: typeFormWebhookServiceConfigFactory
170
- }, exports.TypeformWebhookService],
171
- exports: [exports.TypeformWebhookService]
172
- })], exports.TypeformWebhookModule);
174
+ exports.TypeformWebhookModule = class TypeformWebhookModule {
175
+ };
176
+ exports.TypeformWebhookModule = __decorate([
177
+ common.Module({
178
+ imports: [config.ConfigModule],
179
+ controllers: [exports.TypeformWebhookController],
180
+ providers: [
181
+ {
182
+ provide: TypeformWebhookServiceConfig,
183
+ inject: [config.ConfigService],
184
+ useFactory: typeFormWebhookServiceConfigFactory
185
+ },
186
+ exports.TypeformWebhookService
187
+ ],
188
+ exports: [exports.TypeformWebhookService]
189
+ })
190
+ ], exports.TypeformWebhookModule);
173
191
 
174
192
  function findTypeformTemplateRefsInString(input) {
175
- /**
176
- * Used to search the input string to find field refs like the following:
177
- *
178
- * {{field:8f7adc1e-c3b8-44bd-b00c-1b6c8de65797}}
179
- * {{field:01H7G3DCZ1FZV4KYZGM755MXZZ}}
180
- */
181
- const regex = /\{\{\s*(field)\s*:\s*([A-Za-z0-9-]+)\s*\}\}/g;
182
- const matches = input.matchAll(regex);
183
- const result = [];
184
- for (const regexMatch of matches) {
185
- const match = regexMatch[0]; // {{field:8f7adc1e-c3b8-44bd-b00c-1b6c8de65797}}
186
- const type = regexMatch[1]; // field
187
- const ref = regexMatch[2]; // 8f7adc1e-c3b8-44bd-b00c-1b6c8de65797
188
- result.push({
189
- type,
190
- match,
191
- ref
192
- });
193
- }
194
- return result;
193
+ /**
194
+ * Used to search the input string to find field refs like the following:
195
+ *
196
+ * {{field:8f7adc1e-c3b8-44bd-b00c-1b6c8de65797}}
197
+ * {{field:01H7G3DCZ1FZV4KYZGM755MXZZ}}
198
+ */
199
+ const regex = /\{\{\s*(field)\s*:\s*([A-Za-z0-9-]+)\s*\}\}/g;
200
+ const matches = input.matchAll(regex);
201
+ const result = [];
202
+ for (const regexMatch of matches) {
203
+ const match = regexMatch[0]; // {{field:8f7adc1e-c3b8-44bd-b00c-1b6c8de65797}}
204
+ const type = regexMatch[1]; // field
205
+ const ref = regexMatch[2]; // 8f7adc1e-c3b8-44bd-b00c-1b6c8de65797
206
+ result.push({
207
+ type,
208
+ match,
209
+ ref
210
+ });
211
+ }
212
+ return result;
195
213
  }
196
214
 
197
215
  /**
198
216
  * Creates an ExpandedTypeformWebhookFormResponse from a TypeformWebhookFormResponse.
199
217
  */
200
218
  function expandTypeformWebhookFormResponse(formResponse) {
201
- const {
202
- answers,
203
- definition
204
- } = formResponse;
205
- const {
206
- fields = []
207
- } = definition;
208
- const questionFieldMap = new Map(util.filterMaybeArrayValues(fields.map(x => x.id ? [x.id, x] : null)));
209
- const answerValuePairs = answers.map(answer => makeTypeformFormResponseAnswerValuePair(answer));
210
- const answerValueFieldRefMap = new Map(util.filterMaybeArrayValues(answerValuePairs.map(x => x.answer.field.ref ? [x.answer.field.ref, x] : null)));
211
- function expandQuestionTitle(title) {
212
- let result = title;
213
- let hadReferenceInTitle = false;
214
- if (result) {
215
- const refsInTitle = findTypeformTemplateRefsInString(result);
216
- if (refsInTitle.length > 0) {
217
- hadReferenceInTitle = true;
218
- refsInTitle.forEach(refInTitle => {
219
- const {
220
- match,
221
- ref
222
- } = refInTitle;
223
- const fullMatch = match;
224
- const answer = answerValueFieldRefMap.get(ref);
225
- const answerValue = answer?.valueString;
226
- const replacedTitle = result.replaceAll(fullMatch, answerValue || '');
227
- result = replacedTitle;
228
- });
229
- }
219
+ const { answers, definition } = formResponse;
220
+ const { fields = [] } = definition;
221
+ const questionFieldMap = new Map(util.filterMaybeArrayValues(fields.map((x) => (x.id ? [x.id, x] : null))));
222
+ const answerValuePairs = answers.map((answer) => makeTypeformFormResponseAnswerValuePair(answer));
223
+ const answerValueFieldRefMap = new Map(util.filterMaybeArrayValues(answerValuePairs.map((x) => (x.answer.field.ref ? [x.answer.field.ref, x] : null))));
224
+ function expandQuestionTitle(title) {
225
+ let result = title;
226
+ let hadReferenceInTitle = false;
227
+ if (result) {
228
+ const refsInTitle = findTypeformTemplateRefsInString(result);
229
+ if (refsInTitle.length > 0) {
230
+ hadReferenceInTitle = true;
231
+ refsInTitle.forEach((refInTitle) => {
232
+ const { match, ref } = refInTitle;
233
+ const fullMatch = match;
234
+ const answer = answerValueFieldRefMap.get(ref);
235
+ const answerValue = answer?.valueString;
236
+ const replacedTitle = result.replaceAll(fullMatch, answerValue || '');
237
+ result = replacedTitle;
238
+ });
239
+ }
240
+ }
241
+ return {
242
+ questionTitle: result,
243
+ hadReferenceInTitle
244
+ };
230
245
  }
246
+ const pairs = answerValuePairs.map((answerValue) => {
247
+ const definitionField = questionFieldMap.get(answerValue.answer.field.id);
248
+ const { questionTitle, hadReferenceInTitle } = expandQuestionTitle(definitionField?.title);
249
+ const result = {
250
+ ...answerValue,
251
+ definitionField,
252
+ questionTitle,
253
+ hadReferenceInTitle
254
+ };
255
+ return result;
256
+ });
231
257
  return {
232
- questionTitle: result,
233
- hadReferenceInTitle
234
- };
235
- }
236
- const pairs = answerValuePairs.map(answerValue => {
237
- const definitionField = questionFieldMap.get(answerValue.answer.field.id);
238
- const {
239
- questionTitle,
240
- hadReferenceInTitle
241
- } = expandQuestionTitle(definitionField?.title);
242
- const result = {
243
- ...answerValue,
244
- definitionField,
245
- questionTitle,
246
- hadReferenceInTitle
258
+ formResponse,
259
+ pairs
247
260
  };
248
- return result;
249
- });
250
- return {
251
- formResponse,
252
- pairs
253
- };
254
261
  }
255
262
  /**
256
263
  * Creates a TypeformFormQuestionAnswerPair from a TypeformFormResponseAnswer.
257
264
  */
258
265
  function makeTypeformFormResponseAnswerValuePair(answer) {
259
- let value;
260
- let valueString;
261
- switch (answer.type) {
262
- case 'number':
263
- value = answer.number;
264
- valueString = answer.number.toString();
265
- break;
266
- case 'boolean':
267
- value = answer.boolean;
268
- valueString = answer.boolean.toString();
269
- break;
270
- case 'email':
271
- value = answer.email;
272
- valueString = answer.email;
273
- break;
274
- case 'phone_number':
275
- value = answer.phone_number;
276
- valueString = answer.phone_number;
277
- break;
278
- case 'date':
279
- value = answer.date;
280
- valueString = answer.date;
281
- break;
282
- case 'payment':
283
- value = answer.payment;
284
- valueString = answer.payment.amount.toString();
285
- break;
286
- case 'text':
287
- value = answer.text;
288
- valueString = answer.text;
289
- break;
290
- case 'choices':
291
- value = answer.choices;
292
- valueString = answer.choices.other || util.joinStringsWithCommas(answer.choices.labels);
293
- break;
294
- case 'choice':
295
- value = answer.choice;
296
- valueString = answer.choice.other || answer.choice.label || '';
297
- break;
298
- case 'url':
299
- value = answer.url;
300
- valueString = answer.url;
301
- break;
302
- case 'file_url':
303
- value = answer.file_url;
304
- valueString = answer.file_url;
305
- break;
306
- }
307
- const result = {
308
- answer,
309
- value,
310
- valueString
311
- };
312
- return result;
266
+ let value;
267
+ let valueString;
268
+ switch (answer.type) {
269
+ case 'number':
270
+ value = answer.number;
271
+ valueString = answer.number.toString();
272
+ break;
273
+ case 'boolean':
274
+ value = answer.boolean;
275
+ valueString = answer.boolean.toString();
276
+ break;
277
+ case 'email':
278
+ value = answer.email;
279
+ valueString = answer.email;
280
+ break;
281
+ case 'phone_number':
282
+ value = answer.phone_number;
283
+ valueString = answer.phone_number;
284
+ break;
285
+ case 'date':
286
+ value = answer.date;
287
+ valueString = answer.date;
288
+ break;
289
+ case 'payment':
290
+ value = answer.payment;
291
+ valueString = answer.payment.amount.toString();
292
+ break;
293
+ case 'text':
294
+ value = answer.text;
295
+ valueString = answer.text;
296
+ break;
297
+ case 'choices':
298
+ value = answer.choices;
299
+ valueString = answer.choices.other || util.joinStringsWithCommas(answer.choices.labels);
300
+ break;
301
+ case 'choice':
302
+ value = answer.choice;
303
+ valueString = answer.choice.other || answer.choice.label || '';
304
+ break;
305
+ case 'url':
306
+ value = answer.url;
307
+ valueString = answer.url;
308
+ break;
309
+ case 'file_url':
310
+ value = answer.file_url;
311
+ valueString = answer.file_url;
312
+ break;
313
+ }
314
+ const result = {
315
+ answer,
316
+ value,
317
+ valueString
318
+ };
319
+ return result;
313
320
  }
314
321
 
315
322
  /**
@@ -321,46 +328,56 @@ const TYPEFORM_BASE_URL_ENV_VAR = 'TYPEFORM_BASE_URL';
321
328
  * Configuration for TypeformService
322
329
  */
323
330
  class TypeformServiceConfig {
324
- typeform;
325
- static assertValidConfig(config) {
326
- if (!config.typeform.config.token) {
327
- throw new Error('No Typeform token specified.');
331
+ typeform;
332
+ static assertValidConfig(config) {
333
+ if (!config.typeform.config.token) {
334
+ throw new Error('No Typeform token specified.');
335
+ }
328
336
  }
329
- }
330
337
  }
331
338
 
332
339
  exports.TypeformApi = class TypeformApi {
333
- config;
334
- client;
335
- constructor(config) {
336
- this.config = config;
337
- this.client = apiClient.createClient(config.typeform.config);
338
- }
340
+ config;
341
+ client;
342
+ constructor(config) {
343
+ this.config = config;
344
+ this.client = apiClient.createClient(config.typeform.config);
345
+ }
339
346
  };
340
- exports.TypeformApi = __decorate([common.Injectable(), __param(0, common.Inject(TypeformServiceConfig)), __metadata("design:paramtypes", [TypeformServiceConfig])], exports.TypeformApi);
347
+ exports.TypeformApi = __decorate([
348
+ common.Injectable(),
349
+ __param(0, common.Inject(TypeformServiceConfig)),
350
+ __metadata("design:paramtypes", [TypeformServiceConfig])
351
+ ], exports.TypeformApi);
341
352
 
342
353
  function typeFormServiceConfigFactory(configService) {
343
- const config = {
344
- typeform: {
345
- config: {
346
- token: configService.get(TYPEFORM_SECRET_TOKEN_ENV_VAR),
347
- baseURL: configService.get(TYPEFORM_BASE_URL_ENV_VAR) ?? undefined
348
- }
349
- }
350
- };
351
- TypeformServiceConfig.assertValidConfig(config);
352
- return config;
354
+ const config = {
355
+ typeform: {
356
+ config: {
357
+ token: configService.get(TYPEFORM_SECRET_TOKEN_ENV_VAR),
358
+ baseURL: configService.get(TYPEFORM_BASE_URL_ENV_VAR) ?? undefined
359
+ }
360
+ }
361
+ };
362
+ TypeformServiceConfig.assertValidConfig(config);
363
+ return config;
353
364
  }
354
- exports.TypeformModule = class TypeformModule {};
355
- exports.TypeformModule = __decorate([common.Module({
356
- imports: [config.ConfigModule],
357
- providers: [{
358
- provide: TypeformServiceConfig,
359
- inject: [config.ConfigService],
360
- useFactory: typeFormServiceConfigFactory
361
- }, exports.TypeformApi],
362
- exports: [exports.TypeformApi]
363
- })], exports.TypeformModule);
365
+ exports.TypeformModule = class TypeformModule {
366
+ };
367
+ exports.TypeformModule = __decorate([
368
+ common.Module({
369
+ imports: [config.ConfigModule],
370
+ providers: [
371
+ {
372
+ provide: TypeformServiceConfig,
373
+ inject: [config.ConfigService],
374
+ useFactory: typeFormServiceConfigFactory
375
+ },
376
+ exports.TypeformApi
377
+ ],
378
+ exports: [exports.TypeformApi]
379
+ })
380
+ ], exports.TypeformModule);
364
381
 
365
382
  exports.TYPEFORM_BASE_URL_ENV_VAR = TYPEFORM_BASE_URL_ENV_VAR;
366
383
  exports.TYPEFORM_SECRET_TOKEN_ENV_VAR = TYPEFORM_SECRET_TOKEN_ENV_VAR;
@@ -0,0 +1,2 @@
1
+ export * from './index.cjs.js';
2
+ export { _default as default } from './index.cjs.default.js';