eyeglass
Version:
Sass modules for npm.
156 lines • 6.33 kB
JavaScript
"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 debug = __importStar(require("../util/debug"));
const URI_1 = require("../util/URI");
const lodash_merge_1 = __importDefault(require("lodash.merge"));
const typescriptUtils_1 = require("../util/typescriptUtils");
const heimdall = require("heimdalljs");
const TIME_IMPORTS = !!(process.env.EYEGLASS_PERF_DEBUGGING);
function hasContents(data) {
return typeof data === "object" && data !== null && typeof data.contents === "string";
}
function resolveLazyImport(data) {
let file = data.file;
let contents = typeof data.contents === "function" ? data.contents() : data.contents;
return { file, contents };
}
class ImportSchema {
constructor() {
this.uri = "";
}
}
class ImportUtilities {
constructor(eyeglass, sass, options, fallbackImporter, context) {
this.root = options.eyeglass.root;
this.eyeglass = eyeglass;
this.sass = sass;
this._isDartSass = /dart-sass/.test(sass.info);
this.fallbackImporter = fallbackImporter;
this.options = options;
this.context = lodash_merge_1.default(context, {
eyeglass: {
imported: {} // keep track of files already imported @see importOnce
}
});
}
static createImporter(name, importer) {
return function (uri, prev, doneImporting) {
let importTimer;
if (TIME_IMPORTS) {
importTimer = heimdall.start(`eyeglass:import:${name}`, ImportSchema);
importTimer.stats["uri"] = uri;
}
let done = (data) => {
if (importTimer) {
importTimer.stop();
}
doneImporting(data);
};
uri = URI_1.URI.web(uri);
prev = URI_1.URI.system(prev);
importer.call(this, uri, prev, done);
};
}
importOnce(data, done) {
if (this.options.eyeglass.enableImportOnce && this.context.eyeglass.imported[data.file]) {
// log that we've already imported this file
/* istanbul ignore next - don't test debug */
debug.importer("%s was already imported", data.file);
done(this._adaptResult({ contents: "", file: "already-imported:" + data.file }));
}
else {
this.context.eyeglass.imported[data.file] = true;
done(this._adaptResult(resolveLazyImport(data)));
}
}
_adaptResult(data) {
let result;
if (hasContents(data)) {
if (data.file) {
// Work around for dart-sass incompatibility: https://github.com/sass/dart-sass/issues/975
if (this._isDartSass && !fs.existsSync(data.file)) {
// If the file doesn't exist we can't supply the filename or else
// dart-sass will try to read the file causing an import error.
result = { contents: data.contents };
}
else {
// If this is dart-sass:
// If the file does exist we supply the filename.
// In the short term, this means that sass will read the file again.
// Once the bug is fixed the duplicate read won't happen anymore.
// In the interim, the duplicate read is required because otherwise
// dart-sass won't know the absolute path to the file (this causes
// downstream issues in asset imports.)
// If this isn't dart-sass:
// It's fine to pass the filename whether or not the file exists.
result = { contents: data.contents, file: data.file };
}
}
else {
// There's no file, so we don't set the key.
result = { contents: data.contents };
}
}
else {
// All other values are ok to pass through unaltered.
result = data;
}
return result;
}
fallback(uri, prev, done, noFallback) {
if (Array.isArray(this.fallbackImporter)) {
if (this.fallbackImporter.length > 0) {
this.fallbackNth(uri, prev, 0, done, noFallback);
}
else {
noFallback.call(this.context);
}
}
else if (typescriptUtils_1.isPresent(this.fallbackImporter)) {
this.fallbackImporter.call(this.context, uri, prev, (result) => {
if (result === this.sass.types.Null.NULL || !result) {
noFallback.call(this.context);
}
else {
done(this._adaptResult(result));
}
});
}
else {
noFallback.call(this.context);
}
}
fallbackNth(uri, prev, index, done, noFallback) {
if (!Array.isArray(this.fallbackImporter)) {
return done(new Error("[internal error] fallbackNth can only be called for a list of fallbacks."));
}
let fallbackImporter = this.fallbackImporter[index];
// TODO (test) - how do we get into this condition? needs a test case
if (!fallbackImporter) {
noFallback.call(this.context);
}
else {
fallbackImporter.call(this.context, uri, prev, (result) => {
if (result === this.sass.types.Null.NULL || !result) {
this.fallbackNth(uri, prev, index + 1, done, noFallback);
}
else {
done(this._adaptResult(result));
}
});
}
}
}
exports.default = ImportUtilities;
//# sourceMappingURL=ImportUtilities.js.map