UNPKG

eyeglass

Version:
220 lines 9.65 kB
"use strict"; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = __importStar(require("fs")); const fs_1 = require("fs"); const path = __importStar(require("path")); const glob_1 = __importDefault(require("glob")); const SassImplementation_1 = require("../util/SassImplementation"); const assertions_1 = require("../util/assertions"); const perf_1 = require("../util/perf"); function pathInSandboxDir(fsPath, sandboxDir) { if (path.relative(sandboxDir, fsPath).match(/^\.\./)) { return false; } else { return true; } } const fsFunctions = function (eyeglass, sass) { let sassUtils = require("node-sass-utils")(sass); function accessViolation(location) { return new sass.types.Error("Security violation: Cannot access " + location); } function inSandbox(fsPath) { let sandbox = eyeglass.options.eyeglass.fsSandbox; // if there are no sandbox restrictions, return true if (!sandbox) { return true; } else if (Array.isArray(sandbox)) { // iterate over them and return true if we find one that is valid return sandbox.some(function (sb) { if (pathInSandboxDir(fsPath, sb)) { return true; } else { return false; } }); } else { return assertions_1.unreachable(sandbox, "sandbox"); } } function globFiles(directory, globPattern, includeFiles, includeDirectories, done) { if (inSandbox(directory)) { let globOpts = { root: directory, cwd: directory, mark: true }; glob_1.default(globPattern, globOpts, function (error, files) { /* istanbul ignore if - we do not need to simulate a glob error here */ if (error) { done(new sass.types.Error(error.message)); return; } let filesToReturn = []; for (let i = 0; i < files.length; i++) { let endsWithSlash = /\/$/.test(files[i]); if (endsWithSlash && includeDirectories) { if (!inSandbox(path.join(directory, files[i]))) { done(accessViolation(files[i])); return; } filesToReturn[filesToReturn.length] = files[i].slice(-files[i].length, -1); } if (!endsWithSlash && includeFiles) { if (!inSandbox(path.join(directory, files[i]))) { done(accessViolation(files[i])); return; } filesToReturn[filesToReturn.length] = files[i]; } } done(sassUtils.castToSass(filesToReturn)); }); } else { done(accessViolation(directory)); } } return { "eyeglass-fs-absolute-path($fs-registered-pathnames, $path-id, $segments...)": function (fsRegisteredPathnames, fsPathId, fsSegments, done) { let pathId = sassUtils.castToJs(fsPathId); let segments = sassUtils.castToJs(fsSegments); let registeredPathnames = sassUtils.castToJs(fsRegisteredPathnames); let expandedPath = registeredPathnames.coerce.get(pathId); if (expandedPath) { segments.unshift(expandedPath); let resolved = path.resolve.apply(null, segments); done(new sass.types.String(resolved)); } else { done(new sass.types.Error(`No path is registered for ${pathId}`)); } }, "eyeglass-fs-join($segments...)": function (segments, done) { let jsSegments = sassUtils.castToJs(segments); let joined = path.join.apply(null, jsSegments); done(new sass.types.String(joined)); }, "eyeglass-fs-exists($absolute-path)": function (fsAbsolutePath, done) { if (!SassImplementation_1.isSassString(sass, fsAbsolutePath)) { return done(SassImplementation_1.typeError(sass, "string", fsAbsolutePath)); } let absolutePath = fsAbsolutePath.getValue(); if (inSandbox(absolutePath)) { if (fs_1.existsSync(absolutePath)) { done(sass.types.Boolean.TRUE); } else { done(sass.types.Boolean.FALSE); } } else { done(accessViolation(absolutePath)); } }, "eyeglass-fs-path-separator()": function (done) { done(new sass.types.String(path.sep)); }, "eyeglass-fs-list-files($directory, $glob: '*')": function ($directory, $globPattern, done) { if (!SassImplementation_1.isSassString(sass, $directory)) { return done(SassImplementation_1.typeError(sass, "string", $directory)); } if (!SassImplementation_1.isSassString(sass, $globPattern)) { return done(SassImplementation_1.typeError(sass, "string", $globPattern)); } globFiles($directory.getValue(), $globPattern.getValue(), true, false, done); }, "eyeglass-fs-list-directories($directory, $glob: '*')": function ($directory, $globPattern, done) { if (!SassImplementation_1.isSassString(sass, $directory)) { return done(SassImplementation_1.typeError(sass, "string", $directory)); } if (!SassImplementation_1.isSassString(sass, $globPattern)) { return done(SassImplementation_1.typeError(sass, "string", $globPattern)); } globFiles($directory.getValue(), $globPattern.getValue(), false, true, done); }, "eyeglass-fs-parse-filename($filename)": function ($filename, done) { if (!SassImplementation_1.isSassString(sass, $filename)) { return done(SassImplementation_1.typeError(sass, "string", $filename)); } let parsedFilename = path.parse($filename.getValue()); done(sassUtils.castToSass({ base: parsedFilename.base, dir: parsedFilename.dir, name: parsedFilename.name, ext: parsedFilename.ext, "is-absolute": path.isAbsolute($filename.getValue()) })); }, "eyeglass-fs-info($filename)": function ($filename, done) { if (!SassImplementation_1.isSassString(sass, $filename)) { return done(SassImplementation_1.typeError(sass, "string", $filename)); } let filename = $filename.getValue(); if (inSandbox(filename)) { fs.stat(filename, function (err, stats) { /* istanbul ignore if - we do not need to simulate an fs error here */ if (err) { done(new sass.types.Error(err.message)); } else { try { let realpath = perf_1.realpathSync(filename); done(sassUtils.castToSass({ "modification-time": stats.mtime.getTime(), "creation-time": stats.birthtime.getTime(), "is-file": stats.isFile(), "is-directory": stats.isDirectory(), "real-path": realpath, "size": stats.size, })); } catch (e) { /* istanbul ignore next - we do not need to simulate an fs error here */ done(new sass.types.Error(e.message)); } } }); } else { done(accessViolation(filename)); } }, "eyeglass-fs-read-file($filename)": function ($filename, done) { if (!SassImplementation_1.isSassString(sass, $filename)) { return done(SassImplementation_1.typeError(sass, "string", $filename)); } let filename = $filename.getValue(); if (inSandbox(filename)) { fs.readFile(filename, function (err, contents) { /* istanbul ignore if - we do not need to simulate an fs error here */ if (err) { done(new sass.types.Error(err.message)); } else { done(new sass.types.String(contents.toString())); } }); } else { done(accessViolation(filename)); } } }; }; exports.default = fsFunctions; //# sourceMappingURL=fs.js.map