| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.watchFileIfOutOfRoot = exports.lookupFile = exports.readBody = exports.cachedRead = void 0;
- const path_1 = __importDefault(require("path"));
- const fs_extra_1 = __importDefault(require("fs-extra"));
- const lru_cache_1 = __importDefault(require("lru-cache"));
- const stream_1 = require("stream");
- const serverPluginServeStatic_1 = require("../server/serverPluginServeStatic");
- const mime_types_1 = __importDefault(require("mime-types"));
- const getETag = require('etag');
- const fsReadCache = new lru_cache_1.default({
- max: 10000
- });
- /**
- * Read a file with in-memory cache.
- * Also sets appropriate headers and body on the Koa context.
- * This is exposed on middleware context as `ctx.read` with the `ctx` already
- * bound, so it can be used as `ctx.read(file)`.
- */
- async function cachedRead(ctx, file) {
- const lastModified = fs_extra_1.default.statSync(file).mtimeMs;
- const cached = fsReadCache.get(file);
- if (ctx) {
- ctx.set('Cache-Control', 'no-cache');
- ctx.type = mime_types_1.default.lookup(path_1.default.extname(file)) || 'application/octet-stream';
- }
- if (cached && cached.lastModified === lastModified) {
- if (ctx) {
- // a private marker in case the user ticks "disable cache" during dev
- ctx.__notModified = true;
- ctx.etag = cached.etag;
- ctx.lastModified = new Date(cached.lastModified);
- if (ctx.get('If-None-Match') === ctx.etag && serverPluginServeStatic_1.seenUrls.has(ctx.url)) {
- ctx.status = 304;
- }
- serverPluginServeStatic_1.seenUrls.add(ctx.url);
- ctx.body = cached.content;
- }
- return cached.content;
- }
- // #395 some file is an binary file, eg. font
- let content = await fs_extra_1.default.readFile(file);
- // Populate the "sourcesContent" array and resolve relative paths in the
- // "sources" array, so the debugger can trace back to the original source.
- if (file.endsWith('.map')) {
- const map = JSON.parse(content.toString('utf8'));
- if (!map.sourcesContent || !map.sources.every(path_1.default.isAbsolute)) {
- const sourcesContent = map.sourcesContent || [];
- map.sources = await Promise.all(map.sources.map(async (source, i) => {
- const originalPath = path_1.default.resolve(path_1.default.dirname(file), source);
- if (!sourcesContent[i]) {
- const originalCode = await cachedRead(null, originalPath);
- sourcesContent[i] = originalCode.toString('utf8');
- }
- return originalPath;
- }));
- map.sourcesContent = sourcesContent;
- content = Buffer.from(JSON.stringify(map));
- }
- }
- const etag = getETag(content);
- fsReadCache.set(file, {
- content,
- etag,
- lastModified
- });
- if (ctx) {
- ctx.etag = etag;
- ctx.lastModified = new Date(lastModified);
- ctx.body = content;
- ctx.status = 200;
- // watch the file if it's out of root.
- const { root, watcher } = ctx;
- watchFileIfOutOfRoot(watcher, root, file);
- }
- return content;
- }
- exports.cachedRead = cachedRead;
- /**
- * Read already set body on a Koa context and normalize it into a string.
- * Useful in post-processing middlewares.
- */
- async function readBody(stream) {
- if (stream instanceof stream_1.Readable) {
- return new Promise((resolve, reject) => {
- let res = '';
- stream
- .on('data', (chunk) => (res += chunk))
- .on('error', reject)
- .on('end', () => {
- resolve(res);
- });
- });
- }
- else {
- return !stream || typeof stream === 'string' ? stream : stream.toString();
- }
- }
- exports.readBody = readBody;
- function lookupFile(dir, formats, pathOnly = false) {
- for (const format of formats) {
- const fullPath = path_1.default.join(dir, format);
- if (fs_extra_1.default.existsSync(fullPath) && fs_extra_1.default.statSync(fullPath).isFile()) {
- return pathOnly ? fullPath : fs_extra_1.default.readFileSync(fullPath, 'utf-8');
- }
- }
- const parentDir = path_1.default.dirname(dir);
- if (parentDir !== dir) {
- return lookupFile(parentDir, formats, pathOnly);
- }
- }
- exports.lookupFile = lookupFile;
- /**
- * Files under root are watched by default, but with user aliases we can still
- * serve files out of root. Add such files to the watcher (if not node_modules)
- */
- function watchFileIfOutOfRoot(watcher, root, file) {
- if (!file.startsWith(root) && !/node_modules/.test(file)) {
- watcher.add(file);
- }
- }
- exports.watchFileIfOutOfRoot = watchFileIfOutOfRoot;
- //# sourceMappingURL=fsUtils.js.map
|