mono/packages/osrl/plugins/js.js
2025-12-30 16:33:03 +01:00

210 lines
20 KiB
JavaScript

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.runJSExpression = exports.register = exports.runJSExpressionEx = exports.runJS = void 0;
const path = require("path");
const fs_1 = require("fs");
const exists_1 = require("@plastichub/fs/exists");
const write_1 = require("@plastichub/fs/write");
const primitives_1 = require("@plastichub/core/primitives");
const strings_1 = require("@plastichub/core/strings");
const parser_1 = require("../liquid/parser");
const eval_1 = require("../vm/eval");
const fs_2 = require("../lib/fs");
const crypto_1 = require("crypto");
const bootstrap_1 = require("../conf/bootstrap");
const StringUtils_1 = require("../lib/StringUtils");
const index_1 = require("../index");
const exceptionFormatter = require('exception-formatter');
var fm = require('front-matter');
const query_string_1 = require("query-string");
const toModule = (expr) => {
let _header = 'module.exports = function () {';
return `${_header}\n ${expr.trim()};\n}`;
};
const resolve = (filePath, hints, variables) => {
let resolved;
filePath = (0, strings_1.substitute)(filePath, variables);
hints.find((f) => {
let testPath = path.join(f, filePath);
if ((0, exists_1.sync)(testPath)) {
const stat = (0, fs_1.statSync)(testPath);
if (stat.isFile()) {
resolved = testPath;
}
}
});
return resolved;
};
const toScript = (path) => {
try {
const script = require(path);
if (script && script.default) {
return script.default;
}
if (script && typeof script === 'function') {
return script;
}
}
catch (e) {
index_1.logger.error(e);
}
};
const runJS = (path, options, engine, parsed) => {
let scope = Object.assign({}, engine.variables);
const script = resolve(path, options.profile.includes, engine.variables);
const pageVariables = (0, parser_1.toVariables)(parsed);
pageVariables.forEach((t) => scope[t.key] = t.value);
let ret;
if (script) {
const fn = toScript(script);
if (fn) {
ret = fn.apply(engine, [scope]);
}
else {
console.warn('invalid script ' + script);
}
}
return ret;
};
exports.runJS = runJS;
const createScope = (engine, parsed, ctx, options, templateFile = "") => {
let scope = Object.assign({}, engine.variables);
const pageVariables = (0, parser_1.toVariables)(parsed);
pageVariables.forEach((t) => scope[t.key] = t.value);
// mixin liquid variables
(ctx.scopes || []).forEach(_scope => {
scope = Object.assign(Object.assign({}, _scope), scope);
});
const ret = Object.assign(Object.assign(Object.assign({}, bootstrap_1.context), scope), { scope: scope, substitute: (string, variables = {}) => (0, strings_1.substitute)(string, Object.assign(Object.assign({}, scope), variables)), lookup: (fileName) => {
const hints = [
...options.profile.includes,
path.parse(templateFile).dir
];
return resolve(fileName, [...new Set(hints)], engine.variables);
}, engine: engine, forward_slash: fs_2.forward_slash, read: (file) => (0, fs_2.read)((0, strings_1.substitute)(file, scope)) || {}, write: (file, data) => (0, write_1.sync)((0, strings_1.substitute)(file, scope), data), readJSON: (file) => (0, fs_2.read)((0, strings_1.substitute)(file, scope), 'json') || {}, writeJSON: (file, data) => (0, write_1.sync)((0, strings_1.substitute)(file, scope), data), readFile: (file) => (0, fs_2.read)((0, strings_1.substitute)(file, scope)) || {}, store: engine.global, addGlobal: (what) => {
engine.global = Object.assign(Object.assign({}, engine.global), what);
}, register: (key, value) => {
ctx.bottom()[key] = value;
} });
ret.logger = index_1.logger;
return ret;
};
const loadPlugins = (engine, options) => {
let ret = {};
if (options.plugins) {
options.plugins.forEach((d) => {
const jsFiles = (0, fs_2.files)(d, '*.js');
jsFiles.map((f) => {
try {
const plugin = require(f);
ret = Object.assign(Object.assign({}, ret), plugin);
}
catch (e) {
index_1.logger.error(`Couldnt load plugin from ${f} : \n ${e.message}`, e);
}
});
});
}
return ret;
};
const runJSExpressionEx = (expr, options, engine, parsed = [], _ctx, args = {}, templateFile = "") => {
let expression = "" + expr;
let ret;
try {
let ctx = createScope(engine, parsed, _ctx, options, templateFile);
let _fm = { fm: {} };
if (fm.test(options.string)) {
_fm = {
fm: fm(options.string).attributes
};
}
engine['context'] = ctx;
let plugins = loadPlugins(engine, options);
let scopeArgs = Object.assign(Object.assign(Object.assign({}, engine['context']), plugins), _fm.fm);
for (let k in args) {
if ((0, primitives_1.isString)(args[k])) {
args[k] = (0, strings_1.substitute)(args[k], scopeArgs);
}
}
ret = (0, eval_1.evaluate)(toModule(expr), templateFile + '.js', Object.assign(Object.assign({}, scopeArgs), args), true)(args);
return ret;
}
catch (e) {
index_1.logger.error(`Error running expression ${expression} :: ${templateFile}.js @ ${options.source || options.string} : ${e.message}`);
return exceptionFormatter(e, {
format: 'html'
});
}
return ret;
};
exports.runJSExpressionEx = runJSExpressionEx;
const register = (engine) => {
engine.registerTag('js', {
parse: function (token, remainTokens) {
this.tokens = [];
const stream = this.liquid.parser.parseStream(remainTokens);
this['currentFile'] = token.file;
const argsStr = (0, StringUtils_1.replaceAll)(" ", "&", token.args || "");
this.args = (0, query_string_1.parse)(argsStr, { parseNumbers: true, parseBooleans: true }) || {};
stream
.on('token', (token) => {
if (token['name'] === 'endjs') {
stream.stop();
}
else {
this.tokens.push(token);
}
})
.on('end', () => {
throw new Error(`tag ${token.raw} not closed`);
});
stream.start();
},
render: function (ctx) {
return __awaiter(this, void 0, void 0, function* () {
const file = this['currentFile'];
const text = this.tokens.map((token) => token.getText()).join('').replace('<script>', '').replace('</script>', '');
const { liquid } = this;
const _hash = (0, crypto_1.createHash)('md5').update(text).digest('base64');
if (_hash in liquid.owner.expressionCache) {
// return liquid.owner.expressionCache[_hash];
}
const content = (0, exports.runJSExpressionEx)(text, liquid.owner.engine.options, liquid.owner, [], ctx, this.args, file);
liquid.owner.expressionCache[_hash] = content;
return content;
});
}
});
};
exports.register = register;
const runJSExpression = (expr, options, engine, parsed = []) => {
let expression = "" + expr;
expr = 'return ' + expr.trim();
let ret;
try {
try {
let ctx = createScope(engine, parsed, null, options, "");
ret = (0, eval_1.evaluate)(toModule(expr), 'js expression', ctx, true);
return ret();
}
catch (e) {
index_1.logger.error(`Error running expression ${expression} :: ${e.message}`);
return 'Invalid Expression: ' + `"${expression}"`;
}
}
catch (e) {
index_1.logger.error(`Error running expression ${expr}`, e);
}
return ret;
};
exports.runJSExpression = runJSExpression;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGx1Z2lucy9qcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFFQSw2QkFBNEI7QUFDNUIsMkJBQTZCO0FBQzdCLGtEQUFzRDtBQUN0RCxnREFBb0Q7QUFDcEQsNERBQXNEO0FBQ3RELHNEQUFxRDtBQUNyRCw2Q0FBOEM7QUFDOUMscUNBQXFDO0FBQ3JDLGtDQUFzRDtBQUN0RCxtQ0FBbUM7QUFDbkMsaURBQTJDO0FBQzNDLG9EQUErQztBQUMvQyxvQ0FBaUM7QUFFakMsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQTtBQUN6RCxJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7QUFDaEMsK0NBQW9DO0FBRXBDLE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUU7SUFDdEIsSUFBSSxPQUFPLEdBQUcsZ0NBQWdDLENBQUE7SUFDOUMsT0FBTyxHQUFHLE9BQU8sTUFBTSxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQztBQUM3QyxDQUFDLENBQUE7QUFDRCxNQUFNLE9BQU8sR0FBRyxDQUFDLFFBQWdCLEVBQUUsS0FBZSxFQUFFLFNBQWMsRUFBRSxFQUFFO0lBQ2xFLElBQUksUUFBUSxDQUFBO0lBQ1osUUFBUSxHQUFHLElBQUEsb0JBQVUsRUFBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUE7SUFDMUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ2IsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFDckMsSUFBSSxJQUFBLGFBQU0sRUFBQyxRQUFRLENBQUMsRUFBRTtZQUNsQixNQUFNLElBQUksR0FBRyxJQUFBLGFBQVEsRUFBQyxRQUFRLENBQUMsQ0FBQTtZQUMvQixJQUFJLElBQUksQ0FBQyxN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