impulse-api 3.0.8 → 3.0.10
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 +4 -2
- package/src/server.js +39 -6
- package/test/integration/rawbody-integration-test.js +113 -0
- package/test/integration/rawresponse-integration-test.js +259 -0
- package/test/integration/routes/normal.js +24 -0
- package/test/integration/routes/raw-response.js +65 -0
- package/test/integration/routes/webhook.js +18 -0
- package/test/{api-test.js → unit/api-test.js} +1 -1
- package/test/{custom-jwt-validation.js → unit/custom-jwt-validation.js} +2 -2
- package/test/unit/server-test.js +938 -0
package/package.json
CHANGED
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
11
|
"lint": "eslint --ignore-path .gitignore .",
|
|
12
|
-
"test": "
|
|
12
|
+
"test": "npm run test:unit && npm run test:integration",
|
|
13
|
+
"test:unit": "nyc --reporter=lcov --reporter=text-summary mocha test/unit/**/*.js",
|
|
14
|
+
"test:integration": "nyc --reporter=lcov --reporter=text-summary mocha 'test/integration/**/*-test.js'",
|
|
13
15
|
"test-server": "node ./test/integration/test-server.js"
|
|
14
16
|
},
|
|
15
|
-
"version": "3.0.
|
|
17
|
+
"version": "3.0.10",
|
|
16
18
|
"engines": {
|
|
17
19
|
"node": ">=22"
|
|
18
20
|
},
|
package/src/server.js
CHANGED
|
@@ -92,9 +92,8 @@ class Server {
|
|
|
92
92
|
this.http.use(express.urlencoded({
|
|
93
93
|
extended: true,
|
|
94
94
|
}));
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}));
|
|
95
|
+
// Don't use global express.json() - apply it per-route to avoid conflicts with rawBody routes
|
|
96
|
+
// express.urlencoded() is safe to keep global as it only parses application/x-www-form-urlencoded
|
|
98
97
|
this.http.use(fileUpload({
|
|
99
98
|
preserveExtension: 10
|
|
100
99
|
}));
|
|
@@ -178,6 +177,40 @@ class Server {
|
|
|
178
177
|
};
|
|
179
178
|
|
|
180
179
|
function sendResponse(error, response) {
|
|
180
|
+
// Handle raw responses - send Buffer/string as-is without JSON serialization
|
|
181
|
+
// When rawResponse is true, only Buffer and string are sent raw via res.end().
|
|
182
|
+
// All other types fall through to default JSON serialization below.
|
|
183
|
+
if (route.rawResponse === true) {
|
|
184
|
+
if (response && !error) {
|
|
185
|
+
// Successful response - send raw if Buffer or string
|
|
186
|
+
if (Buffer.isBuffer(response) || typeof response === 'string') {
|
|
187
|
+
res.status(200).end(response);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Not raw-compatible, fall through to default JSON serialization
|
|
191
|
+
} else if (error && !response) {
|
|
192
|
+
// Error response - send raw if Buffer or string
|
|
193
|
+
if (Buffer.isBuffer(error) || typeof error === 'string') {
|
|
194
|
+
const statusCode = (typeof error === 'number' && !isNaN(error)) ? error : 400;
|
|
195
|
+
res.status(statusCode).end(error);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// Not raw-compatible, fall through to default JSON serialization
|
|
199
|
+
} else if (error && response) {
|
|
200
|
+
// Status code with response (redirects, etc.)
|
|
201
|
+
if ((error === 302 || error === 301 || error === 307 || error === 308) && response.Location) {
|
|
202
|
+
res.status(error).header('Location', response.Location).end();
|
|
203
|
+
return;
|
|
204
|
+
} else if (Buffer.isBuffer(response) || typeof response === 'string') {
|
|
205
|
+
res.status(error).end(response);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
// Not raw-compatible, fall through to default JSON serialization
|
|
209
|
+
}
|
|
210
|
+
// If rawResponse is true but response is not Buffer/string, fall through to default
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Default JSON serialization behavior
|
|
181
214
|
if (error instanceof Error) {
|
|
182
215
|
res.status(error.statusCode ? error.statusCode : 400).send(error);
|
|
183
216
|
} else if (error && !response) {
|
|
@@ -485,10 +518,10 @@ class Server {
|
|
|
485
518
|
if (route.rawBody === true) {
|
|
486
519
|
this.http[verb](route.endpoint, express.raw({ type: 'application/json' }), this.preprocessor.bind(this, route));
|
|
487
520
|
} else {
|
|
521
|
+
// Apply express.json() per-route for routes that need JSON parsing
|
|
488
522
|
// express-fileupload handles multipart/form-data (including files)
|
|
489
|
-
// express.
|
|
490
|
-
|
|
491
|
-
this.http[verb](route.endpoint, this.preprocessor.bind(this, route));
|
|
523
|
+
// express.urlencoded() is already global and only parses form-encoded data
|
|
524
|
+
this.http[verb](route.endpoint, express.json({ extended: true }), this.preprocessor.bind(this, route));
|
|
492
525
|
}
|
|
493
526
|
|
|
494
527
|
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const Server = require('../../src/server');
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
const http = require('http');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
describe('rawBody HTTP Integration', () => {
|
|
7
|
+
let testServer;
|
|
8
|
+
let testRouteDir;
|
|
9
|
+
let testPort = 9998;
|
|
10
|
+
|
|
11
|
+
before(async () => {
|
|
12
|
+
testRouteDir = path.join(__dirname, 'routes');
|
|
13
|
+
// Create and start test server once for all tests (use 'dev' env so server actually starts)
|
|
14
|
+
testServer = new Server({
|
|
15
|
+
name: 'test-server',
|
|
16
|
+
routeDir: testRouteDir,
|
|
17
|
+
port: testPort,
|
|
18
|
+
env: 'dev',
|
|
19
|
+
services: {}
|
|
20
|
+
});
|
|
21
|
+
await testServer.init();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
after(async () => {
|
|
25
|
+
// Clean up test server
|
|
26
|
+
if (testServer && testServer.http) {
|
|
27
|
+
await new Promise((resolve) => {
|
|
28
|
+
if (testServer.http.listening) {
|
|
29
|
+
testServer.http.close(() => resolve());
|
|
30
|
+
} else {
|
|
31
|
+
resolve();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should receive raw Buffer via HTTP request when rawBody is true', async () => {
|
|
38
|
+
|
|
39
|
+
// Make HTTP POST request
|
|
40
|
+
const testBody = JSON.stringify({ test: 'data', value: 123 });
|
|
41
|
+
const response = await new Promise((resolve, reject) => {
|
|
42
|
+
const options = {
|
|
43
|
+
hostname: 'localhost',
|
|
44
|
+
port: testPort,
|
|
45
|
+
path: '/webhook',
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: {
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
'Content-Length': Buffer.byteLength(testBody)
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const req = http.request(options, (res) => {
|
|
54
|
+
let data = '';
|
|
55
|
+
res.on('data', (chunk) => {
|
|
56
|
+
data += chunk;
|
|
57
|
+
});
|
|
58
|
+
res.on('end', () => {
|
|
59
|
+
resolve({ statusCode: res.statusCode, body: data });
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
req.on('error', reject);
|
|
64
|
+
req.write(testBody);
|
|
65
|
+
req.end();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
assert.strictEqual(response.statusCode, 200);
|
|
69
|
+
const responseBody = JSON.parse(response.body);
|
|
70
|
+
assert.strictEqual(responseBody.success, true);
|
|
71
|
+
assert.strictEqual(responseBody.isBuffer, true);
|
|
72
|
+
assert.strictEqual(responseBody.rawBodyString, testBody);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should receive parsed JSON via HTTP request when rawBody is false', async () => {
|
|
76
|
+
|
|
77
|
+
// Make HTTP POST request
|
|
78
|
+
const testBody = JSON.stringify({ test: 'data', value: 123 });
|
|
79
|
+
const response = await new Promise((resolve, reject) => {
|
|
80
|
+
const options = {
|
|
81
|
+
hostname: 'localhost',
|
|
82
|
+
port: testPort,
|
|
83
|
+
path: '/normal',
|
|
84
|
+
method: 'POST',
|
|
85
|
+
headers: {
|
|
86
|
+
'Content-Type': 'application/json',
|
|
87
|
+
'Content-Length': Buffer.byteLength(testBody)
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const req = http.request(options, (res) => {
|
|
92
|
+
let data = '';
|
|
93
|
+
res.on('data', (chunk) => {
|
|
94
|
+
data += chunk;
|
|
95
|
+
});
|
|
96
|
+
res.on('end', () => {
|
|
97
|
+
resolve({ statusCode: res.statusCode, body: data });
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
req.on('error', reject);
|
|
102
|
+
req.write(testBody);
|
|
103
|
+
req.end();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
assert.strictEqual(response.statusCode, 200);
|
|
107
|
+
const responseBody = JSON.parse(response.body);
|
|
108
|
+
assert.strictEqual(responseBody.success, true);
|
|
109
|
+
assert.strictEqual(responseBody.test, 'data');
|
|
110
|
+
assert.strictEqual(responseBody.value, 123);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
const Server = require('../../src/server');
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
const http = require('http');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
describe('rawResponse HTTP Integration', () => {
|
|
7
|
+
let testServer;
|
|
8
|
+
let testRouteDir;
|
|
9
|
+
let testPort = 9999;
|
|
10
|
+
|
|
11
|
+
before(async () => {
|
|
12
|
+
testRouteDir = path.join(__dirname, 'routes');
|
|
13
|
+
// Create and start test server once for all tests (use 'dev' env so server actually starts)
|
|
14
|
+
testServer = new Server({
|
|
15
|
+
name: 'test-server',
|
|
16
|
+
routeDir: testRouteDir,
|
|
17
|
+
port: testPort,
|
|
18
|
+
env: 'dev',
|
|
19
|
+
services: {}
|
|
20
|
+
});
|
|
21
|
+
await testServer.init();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
after(async () => {
|
|
25
|
+
// Clean up test server
|
|
26
|
+
if (testServer && testServer.http) {
|
|
27
|
+
await new Promise((resolve) => {
|
|
28
|
+
if (testServer.http.listening) {
|
|
29
|
+
testServer.http.close(() => resolve());
|
|
30
|
+
} else {
|
|
31
|
+
resolve();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should send raw Buffer response when rawResponse is true', async () => {
|
|
38
|
+
const response = await new Promise((resolve, reject) => {
|
|
39
|
+
const options = {
|
|
40
|
+
hostname: 'localhost',
|
|
41
|
+
port: testPort,
|
|
42
|
+
path: '/raw-response-buffer',
|
|
43
|
+
method: 'GET'
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const req = http.request(options, (res) => {
|
|
47
|
+
let data = Buffer.alloc(0);
|
|
48
|
+
res.on('data', (chunk) => {
|
|
49
|
+
data = Buffer.concat([data, chunk]);
|
|
50
|
+
});
|
|
51
|
+
res.on('end', () => {
|
|
52
|
+
resolve({
|
|
53
|
+
statusCode: res.statusCode,
|
|
54
|
+
body: data,
|
|
55
|
+
headers: res.headers
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
req.on('error', reject);
|
|
61
|
+
req.end();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
assert.strictEqual(response.statusCode, 200);
|
|
65
|
+
assert.strictEqual(Buffer.isBuffer(response.body), true);
|
|
66
|
+
assert.strictEqual(response.body.toString(), 'raw buffer response data');
|
|
67
|
+
// Should not have JSON content-type since it's raw
|
|
68
|
+
assert.strictEqual(response.headers['content-type'], undefined);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should send raw string response when rawResponse is true', async () => {
|
|
72
|
+
const response = await new Promise((resolve, reject) => {
|
|
73
|
+
const options = {
|
|
74
|
+
hostname: 'localhost',
|
|
75
|
+
port: testPort,
|
|
76
|
+
path: '/raw-response-string',
|
|
77
|
+
method: 'GET'
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const req = http.request(options, (res) => {
|
|
81
|
+
let data = '';
|
|
82
|
+
res.on('data', (chunk) => {
|
|
83
|
+
data += chunk;
|
|
84
|
+
});
|
|
85
|
+
res.on('end', () => {
|
|
86
|
+
resolve({
|
|
87
|
+
statusCode: res.statusCode,
|
|
88
|
+
body: data,
|
|
89
|
+
headers: res.headers
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
req.on('error', reject);
|
|
95
|
+
req.end();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
assert.strictEqual(response.statusCode, 200);
|
|
99
|
+
assert.strictEqual(typeof response.body, 'string');
|
|
100
|
+
assert.strictEqual(response.body, 'raw string response data');
|
|
101
|
+
// Should not have JSON content-type since it's raw
|
|
102
|
+
assert.strictEqual(response.headers['content-type'], undefined);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should send JSON serialized response when rawResponse is false', async () => {
|
|
106
|
+
const response = await new Promise((resolve, reject) => {
|
|
107
|
+
const options = {
|
|
108
|
+
hostname: 'localhost',
|
|
109
|
+
port: testPort,
|
|
110
|
+
path: '/json-response',
|
|
111
|
+
method: 'GET'
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const req = http.request(options, (res) => {
|
|
115
|
+
let data = '';
|
|
116
|
+
res.on('data', (chunk) => {
|
|
117
|
+
data += chunk;
|
|
118
|
+
});
|
|
119
|
+
res.on('end', () => {
|
|
120
|
+
resolve({
|
|
121
|
+
statusCode: res.statusCode,
|
|
122
|
+
body: data,
|
|
123
|
+
headers: res.headers
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
req.on('error', reject);
|
|
129
|
+
req.end();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
assert.strictEqual(response.statusCode, 200);
|
|
133
|
+
const responseBody = JSON.parse(response.body);
|
|
134
|
+
assert.strictEqual(responseBody.success, true);
|
|
135
|
+
assert.strictEqual(responseBody.message, 'This is a JSON response');
|
|
136
|
+
assert.deepStrictEqual(responseBody.data, { test: 'value' });
|
|
137
|
+
// Should have JSON content-type when serialized
|
|
138
|
+
assert.ok(response.headers['content-type'].includes('application/json'));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should send JSON serialized response when rawResponse is true but object is returned', async () => {
|
|
142
|
+
const response = await new Promise((resolve, reject) => {
|
|
143
|
+
const options = {
|
|
144
|
+
hostname: 'localhost',
|
|
145
|
+
port: testPort,
|
|
146
|
+
path: '/raw-response-object',
|
|
147
|
+
method: 'GET'
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const req = http.request(options, (res) => {
|
|
151
|
+
let data = '';
|
|
152
|
+
res.on('data', (chunk) => {
|
|
153
|
+
data += chunk;
|
|
154
|
+
});
|
|
155
|
+
res.on('end', () => {
|
|
156
|
+
resolve({
|
|
157
|
+
statusCode: res.statusCode,
|
|
158
|
+
body: data,
|
|
159
|
+
headers: res.headers
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
req.on('error', reject);
|
|
165
|
+
req.end();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
assert.strictEqual(response.statusCode, 200);
|
|
169
|
+
// Even with rawResponse: true, objects should fall through to JSON serialization
|
|
170
|
+
const responseBody = JSON.parse(response.body);
|
|
171
|
+
assert.strictEqual(responseBody.success, true);
|
|
172
|
+
assert.strictEqual(responseBody.message, 'This should be JSON serialized');
|
|
173
|
+
// Should have JSON content-type when serialized
|
|
174
|
+
assert.ok(response.headers['content-type'].includes('application/json'));
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should handle raw response with route parameters', async () => {
|
|
178
|
+
const testBody = JSON.stringify({ prefix: 'PREFIX' });
|
|
179
|
+
const response = await new Promise((resolve, reject) => {
|
|
180
|
+
const options = {
|
|
181
|
+
hostname: 'localhost',
|
|
182
|
+
port: testPort,
|
|
183
|
+
path: '/raw-response-params',
|
|
184
|
+
method: 'POST',
|
|
185
|
+
headers: {
|
|
186
|
+
'Content-Type': 'application/json',
|
|
187
|
+
'Content-Length': Buffer.byteLength(testBody)
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const req = http.request(options, (res) => {
|
|
192
|
+
let data = '';
|
|
193
|
+
res.on('data', (chunk) => {
|
|
194
|
+
data += chunk;
|
|
195
|
+
});
|
|
196
|
+
res.on('end', () => {
|
|
197
|
+
resolve({
|
|
198
|
+
statusCode: res.statusCode,
|
|
199
|
+
body: data,
|
|
200
|
+
headers: res.headers
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
req.on('error', reject);
|
|
206
|
+
req.write(testBody);
|
|
207
|
+
req.end();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
assert.strictEqual(response.statusCode, 200);
|
|
211
|
+
assert.strictEqual(typeof response.body, 'string');
|
|
212
|
+
assert.strictEqual(response.body, 'PREFIX: raw response with params');
|
|
213
|
+
// Should not have JSON content-type since it's raw
|
|
214
|
+
assert.strictEqual(response.headers['content-type'], undefined);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should handle both rawBody and rawResponse together', async () => {
|
|
218
|
+
const testBody = 'raw request body';
|
|
219
|
+
const response = await new Promise((resolve, reject) => {
|
|
220
|
+
const options = {
|
|
221
|
+
hostname: 'localhost',
|
|
222
|
+
port: testPort,
|
|
223
|
+
path: '/webhook',
|
|
224
|
+
method: 'POST',
|
|
225
|
+
headers: {
|
|
226
|
+
'Content-Type': 'application/json',
|
|
227
|
+
'Content-Length': Buffer.byteLength(testBody)
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const req = http.request(options, (res) => {
|
|
232
|
+
let data = '';
|
|
233
|
+
res.on('data', (chunk) => {
|
|
234
|
+
data += chunk;
|
|
235
|
+
});
|
|
236
|
+
res.on('end', () => {
|
|
237
|
+
resolve({
|
|
238
|
+
statusCode: res.statusCode,
|
|
239
|
+
body: data,
|
|
240
|
+
headers: res.headers
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
req.on('error', reject);
|
|
246
|
+
req.write(testBody);
|
|
247
|
+
req.end();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
assert.strictEqual(response.statusCode, 200);
|
|
251
|
+
// The webhook route returns JSON (doesn't have rawResponse), so verify JSON
|
|
252
|
+
const responseBody = JSON.parse(response.body);
|
|
253
|
+
assert.strictEqual(responseBody.success, true);
|
|
254
|
+
assert.strictEqual(responseBody.isBuffer, true);
|
|
255
|
+
// Original functionality: rawBody works for requests
|
|
256
|
+
assert.strictEqual(responseBody.rawBodyString, testBody);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
exports.normal = {
|
|
2
|
+
name: 'normal',
|
|
3
|
+
method: 'post',
|
|
4
|
+
endpoint: '/normal',
|
|
5
|
+
inputs: {
|
|
6
|
+
test: {
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
value: {
|
|
10
|
+
required: true
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
run: (services, inputs, next) => {
|
|
14
|
+
if (inputs.rawBody !== undefined) {
|
|
15
|
+
return next(500, { error: 'rawBody should not be set' });
|
|
16
|
+
}
|
|
17
|
+
next(200, {
|
|
18
|
+
success: true,
|
|
19
|
+
test: inputs.test,
|
|
20
|
+
value: inputs.value
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
exports.rawResponseBuffer = {
|
|
2
|
+
name: 'rawResponseBuffer',
|
|
3
|
+
method: 'get',
|
|
4
|
+
endpoint: '/raw-response-buffer',
|
|
5
|
+
rawResponse: true,
|
|
6
|
+
run: (services, inputs, next) => {
|
|
7
|
+
const buffer = Buffer.from('raw buffer response data');
|
|
8
|
+
next(null, buffer);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
exports.rawResponseString = {
|
|
13
|
+
name: 'rawResponseString',
|
|
14
|
+
method: 'get',
|
|
15
|
+
endpoint: '/raw-response-string',
|
|
16
|
+
rawResponse: true,
|
|
17
|
+
run: (services, inputs, next) => {
|
|
18
|
+
next(null, 'raw string response data');
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
exports.rawResponseWithParams = {
|
|
23
|
+
name: 'rawResponseWithParams',
|
|
24
|
+
method: 'post',
|
|
25
|
+
endpoint: '/raw-response-params',
|
|
26
|
+
rawResponse: true,
|
|
27
|
+
inputs: {
|
|
28
|
+
prefix: {
|
|
29
|
+
required: true
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
run: (services, inputs, next) => {
|
|
33
|
+
const response = `${inputs.prefix}: raw response with params`;
|
|
34
|
+
next(null, response);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
exports.jsonResponse = {
|
|
39
|
+
name: 'jsonResponse',
|
|
40
|
+
method: 'get',
|
|
41
|
+
endpoint: '/json-response',
|
|
42
|
+
rawResponse: false,
|
|
43
|
+
run: (services, inputs, next) => {
|
|
44
|
+
next(null, {
|
|
45
|
+
success: true,
|
|
46
|
+
message: 'This is a JSON response',
|
|
47
|
+
data: { test: 'value' }
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
exports.rawResponseObject = {
|
|
53
|
+
name: 'rawResponseObject',
|
|
54
|
+
method: 'get',
|
|
55
|
+
endpoint: '/raw-response-object',
|
|
56
|
+
rawResponse: true,
|
|
57
|
+
run: (services, inputs, next) => {
|
|
58
|
+
// Even with rawResponse: true, objects should fall through to JSON serialization
|
|
59
|
+
next(null, {
|
|
60
|
+
success: true,
|
|
61
|
+
message: 'This should be JSON serialized'
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
exports.webhook = {
|
|
2
|
+
name: 'webhook',
|
|
3
|
+
method: 'post',
|
|
4
|
+
endpoint: '/webhook',
|
|
5
|
+
rawBody: true,
|
|
6
|
+
run: (services, inputs, next) => {
|
|
7
|
+
if (!Buffer.isBuffer(inputs.rawBody)) {
|
|
8
|
+
return next(500, { error: 'rawBody is not a Buffer' });
|
|
9
|
+
}
|
|
10
|
+
next(200, {
|
|
11
|
+
success: true,
|
|
12
|
+
isBuffer: Buffer.isBuffer(inputs.rawBody),
|
|
13
|
+
rawBodyLength: inputs.rawBody.length,
|
|
14
|
+
rawBodyString: inputs.rawBody.toString()
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|