mirror of
https://github.com/obra/superpowers.git
synced 2026-06-11 21:29:07 +08:00
fix(brainstorm-server): ignore macOS resource-fork dotfiles
On macOS (and ExFAT/SMB volumes) the OS writes ._<name>.html sidecar files holding binary resource-fork metadata. These end with .html, so they passed the content filter and could be picked as the newest screen — serving binary garbage to the browser instead of the mockup — or fetched via /files/. Skip dotfiles (leading '.') at all four sites that list or serve content: getNewestScreen, the /files/ endpoint, the known-files seed, and the fs.watch handler. Tests cover serving (/ and /files/) and the watch path (a ._ file must not trigger a reload). Refs #950
This commit is contained in:
@@ -124,7 +124,7 @@ function wrapInFrame(content) {
|
||||
|
||||
function getNewestScreen() {
|
||||
const files = fs.readdirSync(CONTENT_DIR)
|
||||
.filter(f => f.endsWith('.html'))
|
||||
.filter(f => !f.startsWith('.') && f.endsWith('.html'))
|
||||
.map(f => {
|
||||
const fp = path.join(CONTENT_DIR, f);
|
||||
return { path: fp, mtime: fs.statSync(fp).mtime.getTime() };
|
||||
@@ -152,9 +152,9 @@ function handleRequest(req, res) {
|
||||
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
||||
res.end(html);
|
||||
} else if (req.method === 'GET' && req.url.startsWith('/files/')) {
|
||||
const fileName = req.url.slice(7);
|
||||
const filePath = path.join(CONTENT_DIR, path.basename(fileName));
|
||||
if (!fs.existsSync(filePath)) {
|
||||
const fileName = path.basename(req.url.slice(7));
|
||||
const filePath = path.join(CONTENT_DIR, fileName);
|
||||
if (fileName.startsWith('.') || !fs.existsSync(filePath)) {
|
||||
res.writeHead(404);
|
||||
res.end('Not found');
|
||||
return;
|
||||
@@ -276,14 +276,14 @@ function startServer() {
|
||||
// macOS fs.watch reports 'rename' for both new files and overwrites,
|
||||
// so we can't rely on eventType alone.
|
||||
const knownFiles = new Set(
|
||||
fs.readdirSync(CONTENT_DIR).filter(f => f.endsWith('.html'))
|
||||
fs.readdirSync(CONTENT_DIR).filter(f => !f.startsWith('.') && f.endsWith('.html'))
|
||||
);
|
||||
|
||||
const server = http.createServer(handleRequest);
|
||||
server.on('upgrade', handleUpgrade);
|
||||
|
||||
const watcher = fs.watch(CONTENT_DIR, (eventType, filename) => {
|
||||
if (!filename || !filename.endsWith('.html')) return;
|
||||
if (!filename || filename.startsWith('.') || !filename.endsWith('.html')) return;
|
||||
|
||||
if (debounceTimers.has(filename)) clearTimeout(debounceTimers.get(filename));
|
||||
debounceTimers.set(filename, setTimeout(() => {
|
||||
|
||||
Reference in New Issue
Block a user