Add minimal add-in playgrounds and orchestrator
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
const https = require('https');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const PORT = process.env.PORT || 3001;
|
||||
const DIST_DIR = path.join(__dirname, 'dist');
|
||||
|
||||
const certDir = process.env.DEV_CERT_DIR || path.join(process.env.USERPROFILE || '~', '.office-addin-dev-certs');
|
||||
const certPath = path.join(certDir, 'localhost.crt');
|
||||
const keyPath = path.join(certDir, 'localhost.key');
|
||||
|
||||
function getContentType(filePath) {
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
switch (ext) {
|
||||
case '.html': return 'text/html; charset=utf-8';
|
||||
case '.js': return 'application/javascript; charset=utf-8';
|
||||
case '.css': return 'text/css; charset=utf-8';
|
||||
case '.png': return 'image/png';
|
||||
case '.jpg': case '.jpeg': return 'image/jpeg';
|
||||
case '.gif': return 'image/gif';
|
||||
case '.svg': return 'image/svg+xml';
|
||||
case '.json': return 'application/json';
|
||||
case '.ico': return 'image/x-icon';
|
||||
default: return 'application/octet-stream';
|
||||
}
|
||||
}
|
||||
|
||||
let options;
|
||||
try {
|
||||
options = {
|
||||
cert: fs.readFileSync(certPath),
|
||||
key: fs.readFileSync(keyPath),
|
||||
};
|
||||
} catch (err) {
|
||||
console.error('Failed to read dev cert/key. Check DEV_CERT_DIR or ~/.office-addin-dev-certs:', err.message);
|
||||
process.exitCode = 1;
|
||||
}
|
||||
|
||||
const server = https.createServer(options, (req, res) => {
|
||||
// Normalize URL and prevent directory traversal
|
||||
const safeUrl = decodeURIComponent(req.url.split('?')[0] || '/');
|
||||
let filePath = path.join(DIST_DIR, safeUrl.replace(/^\//, ''));
|
||||
|
||||
// If request is for directory or root, fallback to index.html
|
||||
if (safeUrl === '/' || safeUrl.endsWith('/')) {
|
||||
filePath = path.join(DIST_DIR, 'taskpane.html');
|
||||
}
|
||||
|
||||
// If file doesn't exist, attempt to serve the file within dist, else 404
|
||||
fs.stat(filePath, (err, stats) => {
|
||||
if (err || !stats.isFile()) {
|
||||
res.writeHead(404, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*' });
|
||||
res.end('Not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const contentType = getContentType(filePath);
|
||||
res.writeHead(200, { 'Content-Type': contentType, 'Access-Control-Allow-Origin': '*' });
|
||||
const stream = fs.createReadStream(filePath);
|
||||
stream.pipe(res);
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(PORT, '127.0.0.1', () => {
|
||||
console.log(`HTTPS static server running at https://localhost:${PORT}/ serving ${DIST_DIR}`);
|
||||
});
|
||||
|
||||
server.on('error', (err) => {
|
||||
console.error('Server error:', err.message || err);
|
||||
});
|
||||
Reference in New Issue
Block a user