eyeglass
Version:
Sass modules for npm.
220 lines • 9.65 kB
JavaScript
;
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