json-q
Version:
Retrieves values from JSON objects (and JavaScript objects) by css-selector-like query (includes attribute filters and array flattening).
170 lines (140 loc) • 4.02 kB
JavaScript
var path = require('path');
var relative = require('require-relative');
var serialize = require('./lib/serialize');
var getFlattenedPlugins = require('./lib/flatten');
var normalizePreset = require('./lib/normalize-preset');
// strip a nested module path + filename down to just the innermost module's (file)name
function getModuleName(path) {
return path.replace(/(?:..[\\/])*(?:(?:.+[\\/])?node_modules[\\/]|[\\/]|\.\.[\\/])((@[^\\/]+[\\/])?[^\\/]+)([\\/].*)?$/g, '$1');
}
function setHiddenProp(obj, prop, value) {
if (Object.defineProperty) {
Object.defineProperty(obj, prop, {
enumerable: false,
writable: true,
value: value
});
}
else {
obj[prop] = value;
}
}
function extend(base, props) {
for (var i in props) if (props.hasOwnProperty(i)) {
base[i] = props[i];
}
return base;
}
function requireBabelPlugin(name, relativeTo) {
if (!name.match(/^babel-plugin-/)) {
name = 'babel-plugin-' + name;
}
var relativeName;
if (relativeTo) {
try {
relativeName = relative.resolve(name, relativeTo);
} catch (err) {}
}
if (!relativeName) {
try {
relativeName = require.resolve(name);
} catch(err) {}
}
name = relativeName || name;
return { mod:require(name), name:name };
}
module.exports = function(presetInput, modifications) {
var options = {};
if (Array.isArray(presetInput)) {
options = presetInput[1];
presetInput = presetInput[0];
}
modifications = modifications || {};
var preset;
if (typeof presetInput==='string') {
if (!presetInput.match(/(^babel-preset-|[\\/])/)) {
try {
preset = relative.resolve('babel-preset-'+presetInput, __dirname);
} catch(err) {
console.log(err);
}
}
if (!preset) {
preset = require.resolve(presetInput);
}
}
preset = path.resolve(preset);
var presetModule = normalizePreset(require(preset), null, options);
var orig = presetModule['modify-babel-preset'];
if (orig) {
console.log('Found nested modify-babel-preset configuration, flattening.');
return modify(orig.preset, extend(extend({}, orig.modifications), modifications));
}
var cwd = path.dirname(preset) || process.cwd();
// console.log('cwd: ', cwd);
var serialized = serialize(preset, {
options: options,
cwd: cwd
});
var alias = serialized.alias;
var plugins = getFlattenedPlugins(serialized);
function isSameName(a, b) {
if (typeof a!=='string' || typeof b!=='string') return false;
return a.replace(/^babel-plugin-/i, '').toLowerCase() === b.replace(/^babel-plugin-/i, '').toLowerCase();
}
function indexOf(plugins, key) {
for (var i=plugins.length; i--; ) {
var mod = Array.isArray(plugins[i]) ? plugins[i][0] : plugins[i];
var name = typeof mod==='string' && getModuleName(mod) || mod._original_name;
name = alias[name] || name;
if (isSameName(name, key)) {
return i;
}
}
return -1;
}
Object.keys(modifications).forEach(function(key) {
if (key==='nameDrops' || key==='string') return;
var value = modifications[key],
index = indexOf(plugins, key);
if (value===false) {
if (index!==-1) {
plugins.splice(index, 1);
}
else if (process.env.NODE_ENV==='development') {
console.warn(key+' not found', __dirname);
}
}
else {
var imported = requireBabelPlugin(key, cwd),
p = imported.mod;
setHiddenProp(p, '_original_name', imported.name);
if (value!==true) {
p = [p].concat(value);
}
if (index<0) {
plugins.push(p);
}
else {
plugins[index] = p;
}
}
});
if (modifications.string!==true) {
plugins = plugins.map(function(plugin) {
var mod = Array.isArray(plugin) ? plugin[0] : plugin;
if (typeof mod==='string') {
var p = path.resolve(cwd, mod);
mod = require(p);
setHiddenProp(mod, '_original_name', p);
}
return Array.isArray(plugin) ? [mod].concat(plugin.slice(1)) : mod;
});
}
var out = { plugins:plugins };
setHiddenProp(out, 'modify-babel-preset', {
preset: path.dirname(path.resolve(preset)),
modifications: modifications
});
return out;
};