edgerender-yatl
Version:
Yet Another Template Language
102 lines • 4.05 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.evaluate_as_loop = exports.evaluate_as_bool = exports.evaluate_as_str = exports.evaluate_string = exports.evaluate_clause = exports.build_clause = void 0;
const utils_1 = require("../utils");
const tokenize_1 = __importDefault(require("./tokenize"));
const build_1 = __importDefault(require("./build"));
const evaluate_1 = __importDefault(require("./evaluate"));
function build_clause(expression) {
const tokens = tokenize_1.default(expression);
return build_1.default(tokens);
}
exports.build_clause = build_clause;
async function evaluate_clause(clause, context, functions) {
const e = new evaluate_1.default(context, functions);
return await e.evaluate(clause);
}
exports.evaluate_clause = evaluate_clause;
async function evaluate_string(expression, context, functions) {
const clause = build_clause(expression);
return await evaluate_clause(clause, context, functions);
}
exports.evaluate_string = evaluate_string;
async function evaluate_as_str(clause, context, functions) {
const v = await evaluate_clause(clause, context, functions);
if (typeof v == 'string') {
return v;
}
else if (typeof v == 'number') {
return v.toString();
}
else if (v == null) {
return '';
}
else {
throw TypeError(`Only strings and numbers can be rendered in templates, not ${typeof v}`);
}
}
exports.evaluate_as_str = evaluate_as_str;
async function evaluate_as_bool(clause, context, functions) {
const v = await evaluate_clause(clause, context, functions);
const t = utils_1.smart_typeof(v);
if (t == utils_1.SmartType.Array) {
return v.length > 0;
}
else if (t == utils_1.SmartType.Object) {
return Object.keys(v).length > 0;
}
else {
return Boolean(v);
}
}
exports.evaluate_as_bool = evaluate_as_bool;
function map_items(item, names) {
switch (utils_1.smart_typeof(item)) {
case utils_1.SmartType.Array:
if (item.length != names.length) {
throw new Error(`Loop variable names ${JSON.stringify(names)} cannot be mapped to ${JSON.stringify(item)}`);
}
return Object.fromEntries(names.map((name, i) => [name, item[i]]));
case utils_1.SmartType.Object:
if (Object.keys(item).length != names.length) {
throw new Error(`Loop variable names ${JSON.stringify(names)} cannot be mapped to ${JSON.stringify(item)}`);
}
return Object.fromEntries(names.map(name => [name, item[name]]));
default:
throw new Error(`Loop variable names ${JSON.stringify(names)} cannot be mapped to ${JSON.stringify(item)}`);
}
}
async function evaluate_as_loop(clause, names, context, functions) {
const v = await evaluate_clause(clause, context, functions);
const t = utils_1.smart_typeof(v);
if (t == utils_1.SmartType.Array) {
const arr = v;
if (names.length == 1) {
const name = names[0];
return arr.map(item => ({ [name]: item }));
}
else {
return arr.map(item => map_items(item, names));
}
}
else if (t == utils_1.SmartType.Object) {
const obj = v;
const [key_name, value_name] = names;
switch (names.length) {
case 1:
return Object.values(obj).map(item => ({ [key_name]: item }));
case 2:
return Object.entries(obj).map(([key, value]) => ({ [key_name]: key, [value_name]: value }));
default:
throw new Error(`objects can only be mapped to one or two names, not ${names.length} names`);
}
}
else {
throw new Error(`${t}s can't be used in for loop expressions`);
}
}
exports.evaluate_as_loop = evaluate_as_loop;
//# sourceMappingURL=index.js.map