astro/src/dev.ts
2021-04-01 10:25:28 -06:00

77 lines
2.2 KiB
TypeScript

import type { AstroConfig } from './@types/astro';
import type { LogOptions } from './logger.js';
import { logger as snowpackLogger } from 'snowpack';
import http from 'http';
import { relative as pathRelative } from 'path';
import { defaultLogDestination, error, parseError } from './logger.js';
import { createRuntime } from './runtime.js';
const hostname = '127.0.0.1';
const port = 3000;
// Disable snowpack from writing to stdout/err.
snowpackLogger.level = 'silent';
const logging: LogOptions = {
level: 'debug',
dest: defaultLogDestination,
};
/** The primary dev action */
export default async function dev(astroConfig: AstroConfig) {
const { projectRoot } = astroConfig;
const runtime = await createRuntime(astroConfig, { mode: 'development', logging });
const server = http.createServer(async (req, res) => {
const result = await runtime.load(req.url);
switch (result.statusCode) {
case 200: {
if (result.contentType) {
res.setHeader('Content-Type', result.contentType);
}
res.write(result.contents);
res.end();
break;
}
case 404: {
const fullurl = new URL(req.url || '/', 'https://example.org/');
const reqPath = decodeURI(fullurl.pathname);
error(logging, 'static', 'Not found', reqPath);
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end('Not Found');
break;
}
case 500: {
switch (result.type) {
case 'parse-error': {
const err = result.error;
err.filename = pathRelative(projectRoot.pathname, err.filename);
parseError(logging, err);
break;
}
default: {
error(logging, 'executing astro', result.error);
break;
}
}
res.statusCode = 500;
res.end(formatErrorForBrowser(result.error));
break;
}
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
}
/** Format error message */
function formatErrorForBrowser(err: Error) {
// TODO make this pretty.
return err.toString();
}