Skip to content

Commit 3770301

Browse files
committed
Add test middleware handler
1 parent 235aeab commit 3770301

File tree

1 file changed

+109
-114
lines changed

1 file changed

+109
-114
lines changed

extension.js

Lines changed: 109 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ import cheerio from 'cheerio';
1212
* Validating the incoming host should help prevent abuse by restricting
1313
* the passed host header to the allowedHosts list.
1414
*/
15-
const allowedHosts = new Set([
16-
'83c5-2600-1700-f2e0-b0f-74f7-c2c1-a4ad-e69d.ngrok-free.app',
17-
]);
15+
const allowedHosts = new Set(['83c5-2600-1700-f2e0-b0f-74f7-c2c1-a4ad-e69d.ngrok-free.app']);
1816

1917
/**
2018
* @typedef {Object} ExtensionOptions - The configuration options for the extension.
@@ -31,14 +29,10 @@ const allowedHosts = new Set([
3129
* @param {string} expectedType The expected type (i.e. `'string'`, `'number'`, `'boolean'`, etc.).
3230
*/
3331
function assertType(name, option, expectedType) {
34-
if (option) {
35-
const found = typeof option;
36-
assert.strictEqual(
37-
found,
38-
expectedType,
39-
`${name} must be type ${expectedType}. Received: ${found}`
40-
);
41-
}
32+
if (option) {
33+
const found = typeof option;
34+
assert.strictEqual(found, expectedType, `${name} must be type ${expectedType}. Received: ${found}`);
35+
}
4236
}
4337

4438
/**
@@ -47,114 +41,115 @@ function assertType(name, option, expectedType) {
4741
* @returns {Required<ExtensionOptions>}
4842
*/
4943
function resolveConfig(options) {
50-
assertType('port', options.port, 'number');
51-
assertType('subPath', options.subPath, 'string');
52-
53-
// Remove leading and trailing slashes from subPath
54-
if (options.subPath?.[0] === '/') {
55-
options.subPath = options.subPath.slice(1);
56-
}
57-
if (options.subPath?.[options.subPath?.length - 1] === '/') {
58-
options.subPath = options.subPath.slice(0, -1);
59-
}
60-
61-
return {
62-
port: options.port ?? 3000,
63-
subPath: options.subPath ?? '',
64-
servers: options.servers,
65-
};
44+
assertType('port', options.port, 'number');
45+
assertType('subPath', options.subPath, 'string');
46+
47+
// Remove leading and trailing slashes from subPath
48+
if (options.subPath?.[0] === '/') {
49+
options.subPath = options.subPath.slice(1);
50+
}
51+
if (options.subPath?.[options.subPath?.length - 1] === '/') {
52+
options.subPath = options.subPath.slice(0, -1);
53+
}
54+
55+
return {
56+
port: options.port ?? 3000,
57+
subPath: options.subPath ?? '',
58+
servers: options.servers,
59+
};
6660
}
6761

6862
/**
6963
* Start the Express.js server and configure it to integrate with `options.servers.http`.
7064
* @param {ExtensionOptions} options
7165
*/
7266
export function start(options = {}) {
73-
const config = resolveConfig(options);
74-
75-
return {
76-
async handleDirectory(_, componentPath) {
77-
console.log(`Setting up Express.js app in ${componentPath}`);
78-
79-
if (
80-
!fs.existsSync(componentPath) ||
81-
!fs.statSync(componentPath).isDirectory()
82-
) {
83-
throw new Error(`Invalid component path: ${componentPath}`);
84-
}
85-
86-
const app = express();
87-
88-
// Middleware to validate host
89-
app.use((req, res, next) => {
90-
const host = req.headers['x-forwarded-host'] || req.hostname;
91-
if (!allowedHosts.has(host)) {
92-
console.error(`Rejected request from unauthorized host: ${host}`);
93-
return res.status(403).send('Forbidden');
94-
}
95-
next();
96-
});
97-
98-
// Middleware for proxying and DOM manipulation
99-
app.use(
100-
proxy('https://example.com', {
101-
proxyReqPathResolver: (req) => req.url,
102-
userResDecorator: async (proxyRes, proxyResData, req, res) => {
103-
const contentType = proxyRes.headers['content-type'] || '';
104-
if (contentType.includes('text/html')) {
105-
const $ = cheerio.load(proxyResData.toString('utf-8'));
106-
// Example DOM manipulation
107-
$('title').text('Modified Title');
108-
return $.html();
109-
}
110-
return proxyResData;
111-
},
112-
})
113-
);
114-
115-
// Middleware for static files
116-
const staticPath = path.join(componentPath, 'public');
117-
if (fs.existsSync(staticPath)) {
118-
app.use(express.static(staticPath));
119-
console.log(`Serving static files from: ${staticPath}`);
120-
}
121-
122-
// Middleware for subPath handling
123-
// app.use((req, res, next) => {
124-
// if (config.subPath && !req.url.startsWith(`/${config.subPath}/`)) {
125-
// return next(); // Not a matching path; skip handling
126-
// }
127-
128-
// // Rewrite the URL to remove the subPath prefix
129-
// req.url = config.subPath
130-
// ? req.url.replace(new RegExp(`^/${config.subPath}/`), '/')
131-
// : req.url;
132-
133-
// next();
134-
// });
135-
136-
// Hook into `options.servers.http`
137-
config.servers.http(async (request, nextHandler) => {
138-
const { _nodeRequest: req, _nodeResponse: res } = request;
139-
140-
app.handle(req, res, (err) => {
141-
if (err) {
142-
console.error(`Error handling request: ${err.message}`);
143-
res.statusCode = 500;
144-
res.end('Internal Server Error');
145-
} else {
146-
nextHandler(request);
147-
}
148-
});
149-
});
150-
151-
// Start the Express server
152-
const port = config.port;
153-
app.listen(port, () => {
154-
console.log(`Express.js server is running on port ${port}`);
155-
});
156-
157-
return true;
158-
},
159-
};
67+
const config = resolveConfig(options);
68+
69+
return {
70+
async handleDirectory(_, componentPath) {
71+
console.log(`Setting up Express.js app in ${componentPath}`);
72+
73+
if (!fs.existsSync(componentPath) || !fs.statSync(componentPath).isDirectory()) {
74+
throw new Error(`Invalid component path: ${componentPath}`);
75+
}
76+
77+
const app = express();
78+
79+
app.use((req, res, next) => {
80+
return res.status(200).send(`Hello World from ${req.url}`);
81+
});
82+
83+
// // Middleware to validate host
84+
// app.use((req, res, next) => {
85+
// const host = req.headers['x-forwarded-host'] || req.hostname;
86+
// if (!allowedHosts.has(host)) {
87+
// console.error(`Rejected request from unauthorized host: ${host}`);
88+
// return res.status(403).send('Forbidden');
89+
// }
90+
// next();
91+
// });
92+
93+
// // Middleware for proxying and DOM manipulation
94+
// app.use(
95+
// proxy('https://example.com', {
96+
// proxyReqPathResolver: (req) => req.url,
97+
// userResDecorator: async (proxyRes, proxyResData, req, res) => {
98+
// const contentType = proxyRes.headers['content-type'] || '';
99+
// if (contentType.includes('text/html')) {
100+
// const $ = cheerio.load(proxyResData.toString('utf-8'));
101+
// // Example DOM manipulation
102+
// $('title').text('Modified Title');
103+
// return $.html();
104+
// }
105+
// return proxyResData;
106+
// },
107+
// })
108+
// );
109+
110+
// Middleware for static files
111+
const staticPath = path.join(componentPath, 'public');
112+
if (fs.existsSync(staticPath)) {
113+
app.use(express.static(staticPath));
114+
console.log(`Serving static files from: ${staticPath}`);
115+
}
116+
117+
// Middleware for subPath handling
118+
// app.use((req, res, next) => {
119+
// if (config.subPath && !req.url.startsWith(`/${config.subPath}/`)) {
120+
// return next(); // Not a matching path; skip handling
121+
// }
122+
123+
// // Rewrite the URL to remove the subPath prefix
124+
// req.url = config.subPath
125+
// ? req.url.replace(new RegExp(`^/${config.subPath}/`), '/')
126+
// : req.url;
127+
128+
// next();
129+
// });
130+
131+
// Hook into `options.servers.http`
132+
config.servers.http(async (request, nextHandler) => {
133+
const { _nodeRequest: req, _nodeResponse: res } = request;
134+
135+
app.handle(req, res, (err) => {
136+
if (err) {
137+
console.error(`Error handling request: ${err.message}`);
138+
res.statusCode = 500;
139+
res.end('Internal Server Error');
140+
} else {
141+
nextHandler(request);
142+
}
143+
});
144+
});
145+
146+
// Start the Express server
147+
const port = config.port;
148+
app.listen(port, () => {
149+
console.log(`Express.js server is running on port ${port}`);
150+
});
151+
152+
return true;
153+
},
154+
};
160155
}

0 commit comments

Comments
 (0)