impulse-api 3.0.6 → 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 +1 -1
- package/src/server.js +14 -4
- package/test/custom-jwt-validation.js +3 -2
- package/test/server-test.js +204 -1
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -276,6 +276,11 @@ class Server {
|
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
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
|
+
|
|
279
284
|
if (route.headers) {
|
|
280
285
|
try {
|
|
281
286
|
data.headers = this.buildParameters(req.headers, route.headers);
|
|
@@ -474,10 +479,15 @@ class Server {
|
|
|
474
479
|
method = route.method.toLowerCase();
|
|
475
480
|
verb = (verbMap[method]) ? verbMap[method] : method;
|
|
476
481
|
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
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));
|
|
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
|
|
489
|
+
this.http[verb](route.endpoint, this.preprocessor.bind(this, route));
|
|
490
|
+
}
|
|
481
491
|
|
|
482
492
|
});
|
|
483
493
|
});
|
|
@@ -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
|
-
|
|
258
|
+
auth.createCustomValidator('not-a-function');
|
|
258
259
|
}, /Custom validator must be a function/);
|
|
259
260
|
|
|
260
261
|
assert.doesNotThrow(() => {
|
|
261
|
-
|
|
262
|
+
auth.createCustomValidator(() => {});
|
|
262
263
|
});
|
|
263
264
|
});
|
|
264
265
|
});
|
package/test/server-test.js
CHANGED
|
@@ -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
|
});
|