eyeglass
Version:
Sass modules for npm.
189 lines • 6.92 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;
};
Object.defineProperty(exports, "__esModule", { value: true });
const packageUtils = __importStar(require("../util/package"));
const merge = require("lodash.merge");
const includes = require("lodash.includes");
const path = __importStar(require("path"));
const typescriptUtils_1 = require("../util/typescriptUtils");
const perf_1 = require("../util/perf");
const semver_1 = require("semver");
const rInvalidName = /\.(?:sass|s?css)$/;
const EYEGLASS_KEYWORD = "eyeglass-module";
function isModuleReference(mod) {
return typeof mod === "object" && mod !== null && typeof mod.path === "string";
}
exports.isModuleReference = isModuleReference;
class EyeglassModule {
constructor(modArg, discoverModules, isRoot = false) {
// some defaults
let mod = merge({
eyeglass: {}
}, modArg);
// if we were given a path, resolve it to the package.json
if (isModuleReference(mod)) {
let pkg = packageUtils.getPackage(mod.path);
// if pkg.data is empty, this is an invalid path, so throw an error
if (!pkg.data) {
throw new Error("Could not find a valid package.json at " + mod.path);
}
let modulePath = perf_1.realpathSync(path.dirname(pkg.path));
mod = merge({
isEyeglassModule: EyeglassModule.isEyeglassModule(pkg.data),
inDevelopment: false,
isRoot
}, mod, {
path: modulePath,
name: getModuleName(pkg.data),
rawName: pkg.data.name,
version: pkg.data.version,
// only resolve dependencies if we were given a discoverModules function
dependencies: discoverModules && discoverModules({
dir: modulePath,
isRoot: isRoot
}) || mod.dependencies,
eyeglass: normalizeEyeglassOptions(pkg.data.eyeglass, modulePath)
});
if (mod.isEyeglassModule) {
let moduleMain = getModuleExports(pkg.data, modulePath);
let mainInfo = {
main: moduleMain && require(moduleMain) || null,
mainPath: moduleMain
};
merge(mod, mainInfo);
if (rInvalidName.test(mod.name)) {
throw new Error("An eyeglass module cannot contain an extension in it's name: " + mod.name);
}
}
}
// if a sassDir is specified in eyeglass options, it takes precedence
mod.sassDir = mod.eyeglass.sassDir || mod.sassDir;
// set the rawName if it's not already set
mod.rawName = mod.rawName || mod.name;
// these are handled by merge but are here to make the compiler happy
// TODO: Rewrite this to not use the intermediate object.
this.dependencies = mod.dependencies;
this.eyeglass = mod.eyeglass;
this.isEyeglassModule = mod.isEyeglassModule;
this.name = mod.name;
this.path = mod.path;
this.rawName = mod.rawName;
this.version = mod.version;
this.inDevelopment = mod.inDevelopment;
this.isRoot = mod.isRoot;
// merge the module properties into the instance
merge(this, mod);
if (this.version) {
this.semver = new semver_1.SemVer(this.version);
}
else {
this.semver = new semver_1.SemVer("0.0.0");
}
}
/**
* initializes the module with the given engines
*
* @param {Eyeglass} eyeglass - the eyeglass instance
* @param {Function} sass - the sass engine
*/
init(eyeglass, sass) {
merge(this, this.main && this.main(eyeglass, sass));
}
/**
* whether or not the given package is an eyeglass module
*
* @param {Object} pkg - the package.json
* @returns {Boolean} whether or not it is an eyeglass module
*/
static isEyeglassModule(pkg) {
return !!(typescriptUtils_1.isPresent(pkg) && includes(pkg.keywords, EYEGLASS_KEYWORD));
}
hasModulePath(path) {
if (this.path === path) {
return true;
}
let keys = this.dependencies ? Object.keys(this.dependencies) : [];
for (let depKey of keys) {
let dep = this.dependencies[depKey];
if (dep instanceof EyeglassModule && dep.hasModulePath(path)) {
return true;
}
}
return false;
}
}
exports.default = EyeglassModule;
/**
* given a package.json reference, gets the Eyeglass module name
*
* @param {Object} pkg - the package.json reference
* @returns {String} the name of the module
*/
function getModuleName(pkg) {
// check for `eyeglass.name` first, otherwise use `name`
return normalizeEyeglassOptions(pkg.eyeglass).name || pkg.name;
}
/**
* normalizes a given `eyeglass` reference from a package.json
*
* @param {Object} options - The eyeglass options from the package.json
* @param {String} pkgPath - The location of the package.json.
* @returns {Object} the normalized options
*/
function normalizeEyeglassOptions(options, pkgPath) {
let normalizedOpts;
if (typeof options === "object") {
normalizedOpts = options;
}
else if (typeof options === "string") {
// if it's a string, treat it as the export
normalizedOpts = {
exports: options
};
}
else {
normalizedOpts = {};
}
if (pkgPath && normalizedOpts.sassDir) {
normalizedOpts.sassDir = path.resolve(pkgPath, normalizedOpts.sassDir);
}
return normalizedOpts;
}
/**
* gets the export from a given `eyeglass` reference from a package.json
*
* @param {Object} options - the eyeglass options from the package.json
* @returns {Object} the normalized options
*/
function getExportsFileFromOptions(options) {
return normalizeEyeglassOptions(options).exports;
}
/**
* gets the export for a given package.json
*
* @param {Object} pkg - the package.json
* @param {String} modulePath - the path to the module
* @returns {String} the export file to use
*/
function getModuleExports(pkg, modulePath) {
let exportsFile = getExportsFileFromOptions(pkg.eyeglass);
if (exportsFile === false) {
return null;
}
else {
exportsFile = exportsFile || pkg.main;
}
if (exportsFile) {
return path.join(modulePath, exportsFile);
}
else {
return null;
}
}
//# sourceMappingURL=EyeglassModule.js.map