es-dev-server
Version:
Development server for modern web apps
118 lines • 4.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPluginTransformMiddlware = exports.TransformSyntaxError = void 0;
const tslib_1 = require("tslib");
const fs_1 = tslib_1.__importDefault(require("fs"));
const util_1 = require("util");
const response_body_cache_1 = require("../response-body-cache");
const utils_1 = require("../utils/utils");
const strip_ansi_1 = tslib_1.__importDefault(require("strip-ansi"));
class TransformSyntaxError extends Error {
}
exports.TransformSyntaxError = TransformSyntaxError;
const stat = util_1.promisify(fs_1.default.stat);
/**
* Cache by user agent + file path, so that there can be unique transforms
* per browser.
*/
function createCacheKey(ctx) {
return `${ctx.get('user-agent')}${ctx.url}`;
}
async function getLastModified(path) {
try {
return (await stat(path)).mtimeMs;
}
catch (error) {
return -1;
}
}
/**
* Sets up a middleware which allows plugins to transform files before they are served to the browser.
*/
function createPluginTransformMiddlware(cfg) {
let cache;
let cacheKeysForFilePaths;
if (cfg.fileWatcher) {
({ cache, cacheKeysForFilePaths } = response_body_cache_1.createResponseBodyCache(cfg, cfg.fileWatcher));
}
const transformPlugins = cfg.plugins.filter(p => 'transform' in p);
if (transformPlugins.length === 0) {
// nothing to transform
return (ctx, next) => next();
}
return async function pluginTransformMiddleware(context, next) {
var _a, _b;
let cached = false;
let cacheKey = '';
let cachedBody;
if (cfg.fileWatcher && cache) {
const result = await response_body_cache_1.tryServeFromCache(cache, context);
({ cached, cacheKey, cachedBody } = result);
}
if (cached) {
context.body = cachedBody;
return undefined;
}
await next();
if (context.status < 200 || context.status >= 300) {
return undefined;
}
if (!utils_1.isUtf8(context)) {
return undefined;
}
// responses are streams initially, but to allow transforming we turn it
// into a string first
try {
context.body = await utils_1.getBodyAsString(context);
}
catch (error) {
if (error instanceof utils_1.RequestCancelledError) {
return undefined;
}
return undefined;
}
let transformCache = true;
for (const plugin of transformPlugins) {
try {
const response = await ((_a = plugin.transform) === null || _a === void 0 ? void 0 : _a.call(plugin, context));
if (response) {
transformCache = response.transformCache === false ? false : transformCache;
if (response.body != null) {
context.body = response.body;
}
if (response.headers) {
for (const [k, v] of Object.entries(response.headers)) {
context.response.set(k, v);
}
}
}
}
catch (error) {
if (error instanceof TransformSyntaxError) {
const errorMessage = error.message.replace(`${process.cwd()}/`, '');
context.status = 500;
console.error(`Syntax error: ${errorMessage}`);
if (cfg.logErrorsToBrowser) {
(_b = cfg.messageChannel) === null || _b === void 0 ? void 0 : _b.sendMessage({
name: 'error-message',
data: JSON.stringify(strip_ansi_1.default(errorMessage)),
});
}
return;
}
throw error;
}
}
if (cfg.fileWatcher && transformCache) {
response_body_cache_1.addToCache({
cache,
cacheKey,
cacheKeysForFilePaths,
context,
cfg,
});
}
};
}
exports.createPluginTransformMiddlware = createPluginTransformMiddlware;
//# sourceMappingURL=plugin-transform.js.map