UNPKG

@stylable/core

Version:

CSS for Components

106 lines (92 loc) 2.97 kB
import { dirname } from 'path'; const deindent = require('deindent'); import { MinimalFS } from './cached-process-file'; export interface File { content: string; mtime?: Date; } export interface MinimalFSSetup { files: { [absolutePath: string]: File }; trimWS?: boolean; } export function createMinimalFS({ files, trimWS }: MinimalFSSetup) { const creationDate = new Date(); const filePaths = new Map<string, { content: string; mtime: Date }>( Object.entries(files).map(([filePath, { content, mtime = creationDate }]) => [ filePath, { content, mtime }, ]) ); const directoryPaths = new Set<string>(); for (const filePath of filePaths.keys()) { for (const directoryPath of getParentPaths(dirname(filePath))) { directoryPaths.add(directoryPath); } } const fs: MinimalFS = { readFileSync(path: string) { if (!files[path]) { throw new Error('Cannot find file: ' + path); } if (trimWS) { return deindent(files[path].content).trim(); } return files[path].content; }, statSync(path: string) { const isDirectory = directoryPaths.has(path); const fileEntry = filePaths.get(path); if (!fileEntry && !isDirectory) { throw new Error(`ENOENT: no such file or directory, stat ${path}`); } return { isDirectory() { return isDirectory; }, isFile() { return !!fileEntry; }, mtime: fileEntry ? fileEntry.mtime : new Date(), }; }, readlinkSync() { throw new Error(`not implemented`); }, }; const requireModule = function require(id: string): any { const _module = { id, exports: {}, }; try { if (!id.match(/\.js$/)) { id += '.js'; } // eslint-disable-next-line @typescript-eslint/no-implied-eval const fn = new Function('module', 'exports', 'require', files[id].content); fn(_module, _module.exports, requireModule); } catch (e) { throw new Error('Cannot require file: ' + id); } return _module.exports; }; function resolvePath(_ctx: string, path: string) { return path; } return { fs, requireModule, resolvePath, }; } function getParentPaths(initialDirectoryPath: string) { const parentPaths: string[] = []; let currentPath = initialDirectoryPath; let lastPath: string | undefined; while (currentPath !== lastPath) { parentPaths.push(currentPath); lastPath = currentPath; currentPath = dirname(currentPath); } return parentPaths; }