@dereekb/nestjs 13.0.0 → 13.0.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.
@@ -12,32 +12,32 @@ import { VapiClient } from '@vapi-ai/server-sdk';
12
12
  * @returns
13
13
  */
14
14
  function vapiAiWebhookEvent(event) {
15
- return event;
15
+ return event;
16
16
  }
17
- const vapiaiEventHandlerFactory = handlerFactory(x => x.type, {
18
- defaultResult: {
19
- handled: true,
20
- response: undefined
21
- },
22
- negativeResult: {
23
- handled: true,
24
- response: undefined
25
- }
17
+ const vapiaiEventHandlerFactory = handlerFactory((x) => x.type, {
18
+ defaultResult: {
19
+ handled: true,
20
+ response: undefined
21
+ },
22
+ negativeResult: {
23
+ handled: true,
24
+ response: undefined
25
+ }
26
26
  });
27
27
  const vapiaiEventHandlerConfigurerFactory = handlerConfigurerFactory({
28
- configurerForAccessor: accessor => {
29
- // eslint-disable-next-line
30
- const fnWithKey = handlerMappedSetFunctionFactory(accessor, vapiAiWebhookEvent);
31
- const configurer = {
32
- ...accessor,
33
- handleAssistantRequest: fnWithKey('assistant-request'),
34
- handleStatusUpdate: fnWithKey('status-update'),
35
- handleFunctionCall: fnWithKey('function-call'),
36
- handleEndOfCallReport: fnWithKey('end-of-call-report'),
37
- handleHang: fnWithKey('hang')
38
- };
39
- return configurer;
40
- }
28
+ configurerForAccessor: (accessor) => {
29
+ // eslint-disable-next-line
30
+ const fnWithKey = handlerMappedSetFunctionFactory(accessor, vapiAiWebhookEvent);
31
+ const configurer = {
32
+ ...accessor,
33
+ handleAssistantRequest: fnWithKey('assistant-request'),
34
+ handleStatusUpdate: fnWithKey('status-update'),
35
+ handleFunctionCall: fnWithKey('function-call'),
36
+ handleEndOfCallReport: fnWithKey('end-of-call-report'),
37
+ handleHang: fnWithKey('hang')
38
+ };
39
+ return configurer;
40
+ }
41
41
  });
42
42
 
43
43
  /******************************************************************************
@@ -84,55 +84,42 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
84
84
  * @returns A function that verifies a VapiAi webhook event.
85
85
  */
86
86
  function vapiAiWebhookEventVerifier(config) {
87
- const {
88
- verificationType: inputVerificationType,
89
- secret: inputSecret,
90
- hmacSecret: inputHmacSecret,
91
- signaturePrefix: inputSignaturePrefix
92
- } = config;
93
- const verificationType = inputVerificationType ?? (inputHmacSecret != null ? 'hmac' : 'secret'); // default to secret always, never default to none
94
- const secretToken = (verificationType === 'hmac' ? inputHmacSecret ?? inputSecret : inputSecret) ?? '';
95
- const signaturePrefix = inputSignaturePrefix ?? '';
96
- function verifyNone(input) {
97
- return true;
98
- }
99
- function verifySecret(input) {
100
- const {
101
- request
102
- } = input;
103
- const headers = request.headers;
104
- const vapiSecret = headers['x-vapi-secret'];
105
- const valid = vapiSecret === secretToken;
106
- return valid;
107
- }
108
- function verifyHmac(input) {
109
- const {
110
- request,
111
- requestBodyString
112
- } = input;
113
- const headers = request.headers;
114
- const timestamp = headers['x-timestamp'];
115
- const vapiSignature = headers['x-signature'];
116
- const message = `${timestamp}.${requestBodyString}`;
117
- const hashForVerify = createHmac('sha256', secretToken).update(message).digest('hex');
118
- const signature = `${signaturePrefix}${hashForVerify}`;
119
- const valid = vapiSignature === signature;
120
- return valid;
121
- }
122
- const verify = verificationType === 'hmac' ? verifyHmac : verificationType === 'secret' ? verifySecret : verifyNone;
123
- return async (request, rawBody) => {
124
- const requestBodyString = String(request.body);
125
- const valid = verify({
126
- request,
127
- requestBodyString
128
- });
129
- const requestBody = JSON.parse(requestBodyString);
130
- const result = {
131
- valid,
132
- event: requestBody.message
87
+ const { verificationType: inputVerificationType, secret: inputSecret, hmacSecret: inputHmacSecret, signaturePrefix: inputSignaturePrefix } = config;
88
+ const verificationType = inputVerificationType ?? (inputHmacSecret != null ? 'hmac' : 'secret'); // default to secret always, never default to none
89
+ const secretToken = (verificationType === 'hmac' ? (inputHmacSecret ?? inputSecret) : inputSecret) ?? '';
90
+ const signaturePrefix = inputSignaturePrefix ?? '';
91
+ function verifyNone(input) {
92
+ return true;
93
+ }
94
+ function verifySecret(input) {
95
+ const { request } = input;
96
+ const headers = request.headers;
97
+ const vapiSecret = headers['x-vapi-secret'];
98
+ const valid = vapiSecret === secretToken;
99
+ return valid;
100
+ }
101
+ function verifyHmac(input) {
102
+ const { request, requestBodyString } = input;
103
+ const headers = request.headers;
104
+ const timestamp = headers['x-timestamp'];
105
+ const vapiSignature = headers['x-signature'];
106
+ const message = `${timestamp}.${requestBodyString}`;
107
+ const hashForVerify = createHmac('sha256', secretToken).update(message).digest('hex');
108
+ const signature = `${signaturePrefix}${hashForVerify}`;
109
+ const valid = vapiSignature === signature;
110
+ return valid;
111
+ }
112
+ const verify = verificationType === 'hmac' ? verifyHmac : verificationType === 'secret' ? verifySecret : verifyNone;
113
+ return async (request, rawBody) => {
114
+ const requestBodyString = String(request.body);
115
+ const valid = verify({ request, requestBodyString });
116
+ const requestBody = JSON.parse(requestBodyString);
117
+ const result = {
118
+ valid,
119
+ event: requestBody.message
120
+ };
121
+ return result;
133
122
  };
134
- return result;
135
- };
136
123
  }
137
124
 
138
125
  const VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_WEBHOOK_SECRET_TOKEN';
@@ -143,155 +130,181 @@ const VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR = 'VAPI_AI_WEBHOOK_SIGNATURE_PREF
143
130
  * Configuration for VapiAiService
144
131
  */
145
132
  class VapiAiWebhookServiceConfig {
146
- webhookConfig;
147
- static assertValidConfig(config) {
148
- if (!config.webhookConfig.secret && !config.webhookConfig.hmacSecret) {
149
- throw new Error('No Vapi.ai webhook secret token specified.');
133
+ webhookConfig;
134
+ static assertValidConfig(config) {
135
+ if (!config.webhookConfig.secret && !config.webhookConfig.hmacSecret) {
136
+ throw new Error('No Vapi.ai webhook secret token specified.');
137
+ }
150
138
  }
151
- }
152
139
  }
153
140
 
154
141
  /**
155
142
  * Service that makes system changes based on VapiAi webhook events.
156
143
  */
157
144
  let VapiAiWebhookService = class VapiAiWebhookService {
158
- logger = new Logger('VapiAiWebhookService');
159
- _verifier;
160
- handler = vapiaiEventHandlerFactory();
161
- configure = vapiaiEventHandlerConfigurerFactory(this.handler);
162
- constructor(vapiAiWebhookServiceConfig) {
163
- this._verifier = vapiAiWebhookEventVerifier(vapiAiWebhookServiceConfig.webhookConfig);
164
- }
165
- async updateForWebhook(req, rawBody) {
166
- const {
167
- valid,
168
- event
169
- } = await this._verifier(req, rawBody);
170
- let result = {
171
- handled: false
172
- };
173
- if (!valid) {
174
- this.logger.warn('Received invalid Vapi.ai event: ', event);
175
- } else {
176
- result = await this.updateForVapiAiEvent(event);
145
+ logger = new Logger('VapiAiWebhookService');
146
+ _verifier;
147
+ handler = vapiaiEventHandlerFactory();
148
+ configure = vapiaiEventHandlerConfigurerFactory(this.handler);
149
+ constructor(vapiAiWebhookServiceConfig) {
150
+ this._verifier = vapiAiWebhookEventVerifier(vapiAiWebhookServiceConfig.webhookConfig);
177
151
  }
178
- const response = {
179
- valid,
180
- event,
181
- ...result
182
- };
183
- return response;
184
- }
185
- async updateForVapiAiEvent(event) {
186
- const result = await this.handler(event);
187
- if (!result.handled) {
188
- this.logger.warn('Received unexpected/unhandled Vapi.ai event: ', event);
152
+ async updateForWebhook(req, rawBody) {
153
+ const { valid, event } = await this._verifier(req, rawBody);
154
+ let result = {
155
+ handled: false
156
+ };
157
+ if (!valid) {
158
+ this.logger.warn('Received invalid Vapi.ai event: ', event);
159
+ }
160
+ else {
161
+ result = await this.updateForVapiAiEvent(event);
162
+ }
163
+ const response = {
164
+ valid,
165
+ event,
166
+ ...result
167
+ };
168
+ return response;
169
+ }
170
+ async updateForVapiAiEvent(event) {
171
+ const result = await this.handler(event);
172
+ if (!result.handled) {
173
+ this.logger.warn('Received unexpected/unhandled Vapi.ai event: ', event);
174
+ }
175
+ return result;
189
176
  }
190
- return result;
191
- }
192
177
  };
193
- VapiAiWebhookService = __decorate([Injectable(), __param(0, Inject(VapiAiWebhookServiceConfig)), __metadata("design:paramtypes", [VapiAiWebhookServiceConfig])], VapiAiWebhookService);
178
+ VapiAiWebhookService = __decorate([
179
+ Injectable(),
180
+ __param(0, Inject(VapiAiWebhookServiceConfig)),
181
+ __metadata("design:paramtypes", [VapiAiWebhookServiceConfig])
182
+ ], VapiAiWebhookService);
194
183
 
195
184
  let VapiAiWebhookController = class VapiAiWebhookController {
196
- _vapiaiWebhookService;
197
- constructor(vapiaiWebhookService) {
198
- this._vapiaiWebhookService = vapiaiWebhookService;
199
- }
200
- async handleVapiAiWebhook(res, req, rawBody) {
201
- const {
202
- valid,
203
- response: responseData
204
- } = await this._vapiaiWebhookService.updateForWebhook(req, rawBody);
205
- const response = res.status(200); // always return a 200 status code
206
- if (valid && responseData) {
207
- response.json(responseData);
208
- } else {
209
- response.json({});
185
+ _vapiaiWebhookService;
186
+ constructor(vapiaiWebhookService) {
187
+ this._vapiaiWebhookService = vapiaiWebhookService;
188
+ }
189
+ async handleVapiAiWebhook(res, req, rawBody) {
190
+ const { valid, response: responseData } = await this._vapiaiWebhookService.updateForWebhook(req, rawBody);
191
+ const response = res.status(200); // always return a 200 status code
192
+ if (valid && responseData) {
193
+ response.json(responseData);
194
+ }
195
+ else {
196
+ response.json({});
197
+ }
210
198
  }
211
- }
212
199
  };
213
- __decorate([Post(), __param(0, Res()), __param(1, Req()), __param(2, RawBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, Object]), __metadata("design:returntype", Promise)], VapiAiWebhookController.prototype, "handleVapiAiWebhook", null);
214
- VapiAiWebhookController = __decorate([Controller('/webhook/vapiai'), __param(0, Inject(VapiAiWebhookService)), __metadata("design:paramtypes", [VapiAiWebhookService])], VapiAiWebhookController);
200
+ __decorate([
201
+ Post(),
202
+ __param(0, Res()),
203
+ __param(1, Req()),
204
+ __param(2, RawBody()),
205
+ __metadata("design:type", Function),
206
+ __metadata("design:paramtypes", [Object, Object, Object]),
207
+ __metadata("design:returntype", Promise)
208
+ ], VapiAiWebhookController.prototype, "handleVapiAiWebhook", null);
209
+ VapiAiWebhookController = __decorate([
210
+ Controller('/webhook/vapiai'),
211
+ __param(0, Inject(VapiAiWebhookService)),
212
+ __metadata("design:paramtypes", [VapiAiWebhookService])
213
+ ], VapiAiWebhookController);
215
214
 
216
215
  function vapiaiWebhookServiceConfigFactory(configService) {
217
- const config = {
218
- webhookConfig: {
219
- secret: configService.get(VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR),
220
- hmacSecret: configService.get(VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR),
221
- verificationType: configService.get(VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR),
222
- signaturePrefix: configService.get(VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR)
223
- }
224
- };
225
- VapiAiWebhookServiceConfig.assertValidConfig(config);
226
- return config;
216
+ const config = {
217
+ webhookConfig: {
218
+ secret: configService.get(VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR),
219
+ hmacSecret: configService.get(VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR),
220
+ verificationType: configService.get(VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR),
221
+ signaturePrefix: configService.get(VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR)
222
+ }
223
+ };
224
+ VapiAiWebhookServiceConfig.assertValidConfig(config);
225
+ return config;
227
226
  }
228
- let VapiAiWebhookModule = class VapiAiWebhookModule {};
229
- VapiAiWebhookModule = __decorate([Module({
230
- imports: [ConfigModule],
231
- controllers: [VapiAiWebhookController],
232
- providers: [{
233
- provide: VapiAiWebhookServiceConfig,
234
- inject: [ConfigService],
235
- useFactory: vapiaiWebhookServiceConfigFactory
236
- }, VapiAiWebhookService],
237
- exports: [VapiAiWebhookService]
238
- })], VapiAiWebhookModule);
227
+ let VapiAiWebhookModule = class VapiAiWebhookModule {
228
+ };
229
+ VapiAiWebhookModule = __decorate([
230
+ Module({
231
+ imports: [ConfigModule],
232
+ controllers: [VapiAiWebhookController],
233
+ providers: [
234
+ {
235
+ provide: VapiAiWebhookServiceConfig,
236
+ inject: [ConfigService],
237
+ useFactory: vapiaiWebhookServiceConfigFactory
238
+ },
239
+ VapiAiWebhookService
240
+ ],
241
+ exports: [VapiAiWebhookService]
242
+ })
243
+ ], VapiAiWebhookModule);
239
244
 
240
245
  const VAPI_AI_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_SECRET_TOKEN';
241
246
  /**
242
247
  * Configuration for VapiAiService
243
248
  */
244
249
  class VapiAiServiceConfig {
245
- vapiai;
246
- static assertValidConfig(config) {
247
- if (!config.vapiai.config.token) {
248
- throw new Error('No Vapi.ai secret/token specified.');
250
+ vapiai;
251
+ static assertValidConfig(config) {
252
+ if (!config.vapiai.config.token) {
253
+ throw new Error('No Vapi.ai secret/token specified.');
254
+ }
249
255
  }
250
- }
251
256
  }
252
257
 
253
258
  let VapiAiApi = class VapiAiApi {
254
- config;
255
- vapiClient;
256
- constructor(config) {
257
- this.config = config;
258
- this.vapiClient = new VapiClient(config.vapiai.config);
259
- }
260
- // MARK: Accessors
261
- /**
262
- * Gets a call by ID.
263
- *
264
- * @param callId
265
- * @returns
266
- */
267
- getCall(callId) {
268
- return this.vapiClient.calls.get({
269
- id: callId
270
- });
271
- }
259
+ config;
260
+ vapiClient;
261
+ constructor(config) {
262
+ this.config = config;
263
+ this.vapiClient = new VapiClient(config.vapiai.config);
264
+ }
265
+ // MARK: Accessors
266
+ /**
267
+ * Gets a call by ID.
268
+ *
269
+ * @param callId
270
+ * @returns
271
+ */
272
+ getCall(callId) {
273
+ return this.vapiClient.calls.get({ id: callId });
274
+ }
272
275
  };
273
- VapiAiApi = __decorate([Injectable(), __param(0, Inject(VapiAiServiceConfig)), __metadata("design:paramtypes", [VapiAiServiceConfig])], VapiAiApi);
276
+ VapiAiApi = __decorate([
277
+ Injectable(),
278
+ __param(0, Inject(VapiAiServiceConfig)),
279
+ __metadata("design:paramtypes", [VapiAiServiceConfig])
280
+ ], VapiAiApi);
274
281
 
275
282
  function vapiaiServiceConfigFactory(configService) {
276
- const config = {
277
- vapiai: {
278
- config: {
279
- token: configService.get(VAPI_AI_SECRET_TOKEN_ENV_VAR)
280
- }
281
- }
282
- };
283
- VapiAiServiceConfig.assertValidConfig(config);
284
- return config;
283
+ const config = {
284
+ vapiai: {
285
+ config: {
286
+ token: configService.get(VAPI_AI_SECRET_TOKEN_ENV_VAR)
287
+ }
288
+ }
289
+ };
290
+ VapiAiServiceConfig.assertValidConfig(config);
291
+ return config;
285
292
  }
286
- let VapiAiModule = class VapiAiModule {};
287
- VapiAiModule = __decorate([Module({
288
- imports: [ConfigModule],
289
- providers: [{
290
- provide: VapiAiServiceConfig,
291
- inject: [ConfigService],
292
- useFactory: vapiaiServiceConfigFactory
293
- }, VapiAiApi],
294
- exports: [VapiAiApi]
295
- })], VapiAiModule);
293
+ let VapiAiModule = class VapiAiModule {
294
+ };
295
+ VapiAiModule = __decorate([
296
+ Module({
297
+ imports: [ConfigModule],
298
+ providers: [
299
+ {
300
+ provide: VapiAiServiceConfig,
301
+ inject: [ConfigService],
302
+ useFactory: vapiaiServiceConfigFactory
303
+ },
304
+ VapiAiApi
305
+ ],
306
+ exports: [VapiAiApi]
307
+ })
308
+ ], VapiAiModule);
296
309
 
297
310
  export { VAPI_AI_SECRET_TOKEN_ENV_VAR, VapiAiApi, VapiAiModule, VapiAiServiceConfig, VapiAiWebhookController, VapiAiWebhookModule, VapiAiWebhookService, vapiAiWebhookEvent, vapiAiWebhookEventVerifier, vapiaiEventHandlerConfigurerFactory, vapiaiEventHandlerFactory, vapiaiServiceConfigFactory, vapiaiWebhookServiceConfigFactory };
@@ -1,28 +1,27 @@
1
1
  {
2
2
  "name": "@dereekb/nestjs/vapiai",
3
- "version": "13.0.0",
4
- "types": "./src/index.d.ts",
5
- "module": "./index.esm.js",
6
- "main": "./index.cjs.js",
3
+ "version": "13.0.2",
4
+ "peerDependencies": {
5
+ "@dereekb/date": "13.0.2",
6
+ "@dereekb/model": "13.0.2",
7
+ "@dereekb/nestjs": "13.0.2",
8
+ "@dereekb/rxjs": "13.0.2",
9
+ "@dereekb/util": "13.0.2",
10
+ "@nestjs/common": "^11.0.0",
11
+ "@nestjs/config": "^4.0.0",
12
+ "@vapi-ai/server-sdk": "^0.11.0",
13
+ "express": "^5.0.0"
14
+ },
7
15
  "exports": {
16
+ "./package.json": "./package.json",
8
17
  ".": {
9
- "types": "./src/index.d.ts",
10
- "node": {
11
- "require": "./index.cjs.js"
12
- },
13
- "browser": {
14
- "require": "./index.cjs.js",
15
- "import": "./index.esm.js"
16
- },
18
+ "module": "./index.esm.js",
19
+ "types": "./index.d.ts",
20
+ "import": "./index.cjs.mjs",
17
21
  "default": "./index.cjs.js"
18
22
  }
19
23
  },
20
- "peerDependencies": {
21
- "@dereekb/date": "13.0.0",
22
- "@dereekb/nestjs": "13.0.0",
23
- "@dereekb/model": "13.0.0",
24
- "@dereekb/rxjs": "13.0.0",
25
- "@dereekb/util": "13.0.0",
26
- "core-js": "^3.0.0"
27
- }
24
+ "module": "./index.esm.js",
25
+ "main": "./index.cjs.js",
26
+ "types": "./index.d.ts"
28
27
  }