impulse-api 3.0.5 → 3.0.7

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/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "test": "nyc --reporter=lcov --reporter=text-summary mocha",
13
13
  "test-server": "node ./test/integration/test-server.js"
14
14
  },
15
- "version": "3.0.5",
15
+ "version": "3.0.7",
16
16
  "engines": {
17
17
  "node": ">=22"
18
18
  },
@@ -25,7 +25,6 @@
25
25
  "jsonwebtoken": "8.5.1",
26
26
  "lodash": "4.17.21",
27
27
  "morgan": "1.10.0",
28
- "multer": "1.4.5-lts.2",
29
28
  "path-to-regexp": "0.1.12"
30
29
  },
31
30
  "devDependencies": {
package/src/server.js CHANGED
@@ -1,6 +1,5 @@
1
1
  const fs = require('fs');
2
2
  const express = require('express');
3
- const multer = require('multer');
4
3
  const cors = require('cors');
5
4
  const morgan = require('morgan');
6
5
  const pathToRegexp = require('path-to-regexp');
@@ -277,6 +276,11 @@ class Server {
277
276
  }
278
277
  }
279
278
 
279
+ // Handle rawBody - append the raw Buffer if rawBody flag is set
280
+ if (route.rawBody === true) {
281
+ data.rawBody = req.body; // This will be a Buffer, not a parsed object
282
+ }
283
+
280
284
  if (route.headers) {
281
285
  try {
282
286
  data.headers = this.buildParameters(req.headers, route.headers);
@@ -475,9 +479,13 @@ class Server {
475
479
  method = route.method.toLowerCase();
476
480
  verb = (verbMap[method]) ? verbMap[method] : method;
477
481
 
478
- if (verb === 'post' || verb === 'patch' || verb === 'put') {
479
- this.http[verb](route.endpoint, multer().none(), this.preprocessor.bind(this, route));
482
+ // For routes that need raw body (e.g., webhooks), use express.raw() instead of JSON
483
+ if (route.rawBody === true) {
484
+ this.http[verb](route.endpoint, express.raw({ type: 'application/json' }), this.preprocessor.bind(this, route));
480
485
  } else {
486
+ // express-fileupload handles multipart/form-data (including files)
487
+ // express.json() handles JSON bodies
488
+ // multer().none() is not needed and conflicts with file uploads
481
489
  this.http[verb](route.endpoint, this.preprocessor.bind(this, route));
482
490
  }
483
491
 
@@ -253,12 +253,13 @@ exports.testRoute = {
253
253
  });
254
254
 
255
255
  it('should validate custom validator function type', () => {
256
+ const auth = new Auth('test-secret');
256
257
  assert.throws(() => {
257
- Auth.createCustomValidator('not-a-function');
258
+ auth.createCustomValidator('not-a-function');
258
259
  }, /Custom validator must be a function/);
259
260
 
260
261
  assert.doesNotThrow(() => {
261
- Auth.createCustomValidator(() => {});
262
+ auth.createCustomValidator(() => {});
262
263
  });
263
264
  });
264
265
  });
@@ -449,7 +449,7 @@ describe('server-test', () => {
449
449
  auth.createCustomValidator('not-a-function');
450
450
  assert.fail('Should have thrown an error');
451
451
  } catch (e) {
452
- assert.contains(e.message, 'must be a function');
452
+ assert.contains(e.message, 'Custom validator must be a function');
453
453
  }
454
454
  });
455
455
 
@@ -499,4 +499,207 @@ describe('server-test', () => {
499
499
  assert.strictEqual(server.auth, null);
500
500
  });
501
501
  });
502
+
503
+ describe('rawBody functionality', () => {
504
+ it('should set rawBody as Buffer when route.rawBody is true', async () => {
505
+ const Api = new Server({
506
+ name: 'test-Server',
507
+ routeDir: './test-routes',
508
+ port: 4000,
509
+ env: 'test',
510
+ services: {}
511
+ });
512
+
513
+ const testBody = Buffer.from(JSON.stringify({ test: 'data' }));
514
+ const req = {
515
+ body: testBody,
516
+ query: {},
517
+ params: {},
518
+ files: {},
519
+ headers: {},
520
+ get: (header) => {
521
+ if (header === 'origin') return 'http://localhost:4000';
522
+ if (header === 'host') return 'localhost:4000';
523
+ return null;
524
+ }
525
+ };
526
+ const res = {
527
+ status: (code) => {
528
+ res.statusCode = code;
529
+ return res;
530
+ },
531
+ send: (data) => {
532
+ res.sentData = data;
533
+ }
534
+ };
535
+
536
+ const route = {
537
+ name: 'test-raw-body',
538
+ method: 'post',
539
+ endpoint: '/test',
540
+ rawBody: true,
541
+ run: (services, inputs, next) => {
542
+ assert.strictEqual(Buffer.isBuffer(inputs.rawBody), true);
543
+ assert.deepStrictEqual(inputs.rawBody, testBody);
544
+ next(200, { success: true });
545
+ }
546
+ };
547
+
548
+ await Api.preprocessor(route, req, res);
549
+ assert.strictEqual(res.statusCode, 200);
550
+ });
551
+
552
+ it('should not set rawBody when route.rawBody is false', async () => {
553
+ const Api = new Server({
554
+ name: 'test-Server',
555
+ routeDir: './test-routes',
556
+ port: 4000,
557
+ env: 'test',
558
+ services: {}
559
+ });
560
+
561
+ const testBody = { test: 'data' };
562
+ const req = {
563
+ body: testBody,
564
+ query: {},
565
+ params: {},
566
+ files: {},
567
+ headers: {},
568
+ get: (header) => {
569
+ if (header === 'origin') return 'http://localhost:4000';
570
+ if (header === 'host') return 'localhost:4000';
571
+ return null;
572
+ }
573
+ };
574
+ const res = {
575
+ status: (code) => {
576
+ res.statusCode = code;
577
+ return res;
578
+ },
579
+ send: (data) => {
580
+ res.sentData = data;
581
+ }
582
+ };
583
+
584
+ const route = {
585
+ name: 'test-no-raw-body',
586
+ method: 'post',
587
+ endpoint: '/test',
588
+ rawBody: false,
589
+ run: (services, inputs, next) => {
590
+ assert.strictEqual(inputs.rawBody, undefined);
591
+ next(200, { success: true });
592
+ }
593
+ };
594
+
595
+ await Api.preprocessor(route, req, res);
596
+ assert.strictEqual(res.statusCode, 200);
597
+ });
598
+
599
+ it('should process inputs alongside rawBody when both are present', async () => {
600
+ const Api = new Server({
601
+ name: 'test-Server',
602
+ routeDir: './test-routes',
603
+ port: 4000,
604
+ env: 'test',
605
+ services: {}
606
+ });
607
+
608
+ const testBody = Buffer.from(JSON.stringify({ test: 'data' }));
609
+ const req = {
610
+ body: testBody,
611
+ query: { param1: 'value1' },
612
+ params: { id: '123' },
613
+ files: {},
614
+ headers: {},
615
+ get: (header) => {
616
+ if (header === 'origin') return 'http://localhost:4000';
617
+ if (header === 'host') return 'localhost:4000';
618
+ return null;
619
+ }
620
+ };
621
+ const res = {
622
+ status: (code) => {
623
+ res.statusCode = code;
624
+ return res;
625
+ },
626
+ send: (data) => {
627
+ res.sentData = data;
628
+ }
629
+ };
630
+
631
+ const route = {
632
+ name: 'test-raw-body-with-inputs',
633
+ method: 'post',
634
+ endpoint: '/test/:id',
635
+ rawBody: true,
636
+ inputs: {
637
+ param1: {
638
+ required: true
639
+ },
640
+ id: {
641
+ required: true
642
+ }
643
+ },
644
+ run: (services, inputs, next) => {
645
+ assert.strictEqual(Buffer.isBuffer(inputs.rawBody), true);
646
+ assert.deepStrictEqual(inputs.rawBody, testBody);
647
+ assert.strictEqual(inputs.param1, 'value1');
648
+ assert.strictEqual(inputs.id, '123');
649
+ next(200, { success: true });
650
+ }
651
+ };
652
+
653
+ await Api.preprocessor(route, req, res);
654
+ assert.strictEqual(res.statusCode, 200);
655
+ });
656
+
657
+ it('should handle rawBody without inputs', async () => {
658
+ const Api = new Server({
659
+ name: 'test-Server',
660
+ routeDir: './test-routes',
661
+ port: 4000,
662
+ env: 'test',
663
+ services: {}
664
+ });
665
+
666
+ const testBody = Buffer.from('raw string data');
667
+ const req = {
668
+ body: testBody,
669
+ query: {},
670
+ params: {},
671
+ files: {},
672
+ headers: {},
673
+ get: (header) => {
674
+ if (header === 'origin') return 'http://localhost:4000';
675
+ if (header === 'host') return 'localhost:4000';
676
+ return null;
677
+ }
678
+ };
679
+ const res = {
680
+ status: (code) => {
681
+ res.statusCode = code;
682
+ return res;
683
+ },
684
+ send: (data) => {
685
+ res.sentData = data;
686
+ }
687
+ };
688
+
689
+ const route = {
690
+ name: 'test-raw-body-only',
691
+ method: 'post',
692
+ endpoint: '/test',
693
+ rawBody: true,
694
+ run: (services, inputs, next) => {
695
+ assert.strictEqual(Buffer.isBuffer(inputs.rawBody), true);
696
+ assert.deepStrictEqual(inputs.rawBody, testBody);
697
+ next(200, { success: true });
698
+ }
699
+ };
700
+
701
+ await Api.preprocessor(route, req, res);
702
+ assert.strictEqual(res.statusCode, 200);
703
+ });
704
+ });
502
705
  });