Initial commit

This commit is contained in:
Spencer Pincott
2024-07-15 22:20:13 -04:00
commit 97737ca1ae
16618 changed files with 934131 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
"use strict";
const p = require('path');
const requireFromStringOfCode = require('require-from-string');
const objectToAST = require('./object-to-ast');
module.exports = {
getReplacement,
requireFromString
};
function requireFromString({
string: stringToPreval,
fileOpts: {
filename
},
args = []
}) {
let mod = requireFromStringOfCode(String(stringToPreval), filename);
mod = mod && mod.__esModule ? mod.default : mod;
if (typeof mod === 'function') {
mod = mod(...args);
} else if (args.length) {
throw new Error(`\`preval.require\`-ed module (${p.relative(process.cwd(), filename)}) cannot accept arguments because it does not export a function. You passed the arguments: ${args.join(', ')}`);
}
return mod;
}
function getReplacement({
string,
fileOpts,
args,
babel
}) {
const mod = requireFromString({
string,
fileOpts,
args,
babel
});
return objectToAST(mod, {
babel,
fileOptions: fileOpts
});
}

View File

@@ -0,0 +1,208 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
const p = require('path');
const fs = require('fs'); // const printAST = require('ast-pretty-print')
const {
getReplacement,
requireFromString
} = require('./helpers');
module.exports = prevalPlugin;
function prevalPlugin(babel) {
const {
types: t,
template,
transformFromAst
} = babel;
const assignmentBuilder = template('const NAME = VALUE');
return {
name: 'preval',
visitor: {
Program(path, {
file: {
opts: fileOpts
}
}) {
const firstNode = path.node.body[0] || {};
const comments = firstNode.leadingComments || [];
const isPreval = comments.some(isPrevalComment);
if (!isPreval) {
return;
}
comments.find(isPrevalComment).value = ' this file was prevaled';
const {
code: string
} = transformFromAst(path.node, null,
/* istanbul ignore next (babel 6 vs babel 7 check) */
/^6\./.test(babel.version) ? {} : {
babelrc: false,
configFile: false
});
const replacement = getReplacement({
string,
fileOpts,
babel
});
const moduleExports = (0, _extends2.default)({}, t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('module'), t.identifier('exports')), replacement)), {
leadingComments: comments
});
path.replaceWith(t.program([moduleExports]));
},
TaggedTemplateExpression(path, {
file: {
opts: fileOpts
}
}) {
const isPreval = path.node.tag.name === 'preval';
if (!isPreval) {
return;
}
const string = path.get('quasi').evaluate().value;
if (!string) {
throw new Error('Unable to determine the value of your preval string');
}
const replacement = getReplacement({
string,
fileOpts,
babel
});
path.replaceWith(replacement);
},
ImportDeclaration(path, {
file: {
opts: fileOpts
}
}) {
const isPreval = looksLike(path, {
node: {
source: {
leadingComments(comments) {
return comments && comments.some(isPrevalComment);
}
}
}
});
if (!isPreval) {
return;
}
const prevalComment = path.node.source.leadingComments.find(isPrevalComment).value.trim();
let argValues;
if (prevalComment !== 'preval') {
const arg = prevalComment.replace(/preval\((.*)\)/, '$1').trim();
const argValue = requireFromString({
string: `module.exports = ${arg}`,
fileOpts
});
argValues = [argValue];
}
const absolutePath = p.resolve(p.dirname(fileOpts.filename), path.node.source.value);
const code = fs.readFileSync(require.resolve(absolutePath));
const replacement = getReplacement({
string: code,
fileOpts,
args: argValues,
babel
});
path.replaceWith(assignmentBuilder({
NAME: t.identifier(path.node.specifiers[0].local.name),
VALUE: replacement
}));
},
CallExpression(path, {
file: {
opts: fileOpts
}
}) {
const isPreval = looksLike(path, {
node: {
callee: {
type: 'MemberExpression',
object: {
name: 'preval'
},
property: {
name: 'require'
}
}
}
});
if (!isPreval) {
return;
}
const [source, ...args] = path.get('arguments');
const argValues = args.map(a => {
const result = a.evaluate();
if (!result.confident) {
throw new Error('preval cannot determine the value of an argument in preval.require');
}
return result.value;
});
const absolutePath = p.resolve(p.dirname(fileOpts.filename), source.node.value);
const code = fs.readFileSync(require.resolve(absolutePath));
const replacement = getReplacement({
string: code,
fileOpts,
args: argValues,
babel
});
path.replaceWith(replacement);
}
}
};
}
function isPrevalComment(comment) {
const normalisedComment = comment.value.trim().split(' ')[0].trim();
return normalisedComment.startsWith('preval') || normalisedComment.startsWith('@preval');
}
function looksLike(a, b) {
return a && b && Object.keys(b).every(bKey => {
const bVal = b[bKey];
const aVal = a[bKey];
if (typeof bVal === 'function') {
return bVal(aVal);
}
return isPrimitive(bVal) ? bVal === aVal : looksLike(aVal, bVal);
});
}
function isPrimitive(val) {
// eslint-disable-next-line
return val == null || /^[sbn]/.test(typeof val);
}
/*
eslint
import/no-unassigned-import: off,
import/no-dynamic-require: off,
max-lines-per-function: off,
*/

View File

@@ -0,0 +1,87 @@
"use strict";
// const printAST = require('ast-pretty-print')
const {
createMacro
} = require('babel-plugin-macros');
const {
getReplacement
} = require('./helpers');
module.exports = createMacro(prevalMacros);
function prevalMacros({
references,
state,
babel
}) {
references.default.forEach(referencePath => {
if (referencePath.parentPath.type === 'TaggedTemplateExpression') {
asTag(referencePath.parentPath.get('quasi'), state, babel);
} else if (referencePath.parentPath.type === 'CallExpression') {
asFunction(referencePath.parentPath.get('arguments'), state, babel);
} else if (referencePath.parentPath.type === 'JSXOpeningElement') {
asJSX({
attributes: referencePath.parentPath.get('attributes'),
children: referencePath.parentPath.parentPath.get('children')
}, state, babel);
} else if (!(referencePath.parentPath.type === 'JSXClosingElement')) {
throw new Error(`babel-plugin-preval/macro can only be used as tagged template expression, function call or JSX element. You tried ${referencePath.parentPath.type}.`);
}
});
}
function asTag(quasiPath, {
file: {
opts: fileOpts
}
}, babel) {
const string = quasiPath.parentPath.get('quasi').evaluate().value;
quasiPath.parentPath.replaceWith(getReplacement({
string,
fileOpts,
babel
}));
}
function asFunction(argumentsPaths, {
file: {
opts: fileOpts
}
}, babel) {
const string = argumentsPaths[0].evaluate().value;
argumentsPaths[0].parentPath.replaceWith(getReplacement({
string,
fileOpts,
babel
}));
} // eslint-disable-next-line no-unused-vars
function asJSX({
attributes,
children
}, {
file: {
opts: fileOpts
}
}, babel) {
// It's a shame you cannot use evaluate() with JSX
const string = children[0].node.value;
children[0].replaceWith(getReplacement({
string,
fileOpts,
babel
}));
const {
parentPath: {
node: {
openingElement,
closingElement
}
}
} = children[0];
openingElement.name.name = 'div';
closingElement.name.name = 'div';
}

View File

@@ -0,0 +1,39 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
module.exports = objectToAST;
function objectToAST(object, {
babel,
fileOptions
}) {
const stringified = stringify(object);
const variableDeclarationNode = babel.template(`var x = ${stringified}`, (0, _extends2.default)({
preserveComments: true,
placeholderPattern: false
}, fileOptions.parserOpts, {
sourceType: 'module'
}))();
return variableDeclarationNode.declarations[0].init;
}
function stringify(object) {
let str = JSON.stringify(object, function (key, value) {
if (typeof value === 'function') {
return `__FUNCTION_START__${value.toString()}__FUNCTION_END__`;
}
return value;
});
if (str === undefined) {
str = 'undefined';
}
return str.replace(/"__FUNCTION_START__(.*?)__FUNCTION_END__"/g, function (match, p1) {
return p1.replace(/\\"/g, '"').replace(/\\n/g, '\n');
});
}