easy-template-x-angular-expressions
Version:
Angular expressions support for easy-template-x
75 lines (62 loc) • 2.73 kB
text/typescript
import { ScopeData } from "easy-template-x";
import { ResolveError } from "./resolveError";
import { ResolverOptions } from "./resolverOptions";
import { isNumber, isObject } from "./utils";
import type { ScopeDataArgs, ScopeDataResolver, TemplateContent, TemplateData } from 'easy-template-x';
import expressions from "angular-expressions";
import getProp from "lodash.get";
const undefinedResolver: ScopeDataResolver = () => undefined;
export class AngularResolver {
private readonly options: ResolverOptions;
private readonly fallback: ScopeDataResolver;
constructor(options?: ResolverOptions) {
this.options = new ResolverOptions(options);
this.fallback = this.options.defaultFallback ? ScopeData.defaultResolver : undefinedResolver;
// Configure 'angular-expressions' filters.
for (const key of Object.keys(this.options.angularFilters || {})) {
expressions.filters[key] = this.options.angularFilters[key];
}
}
public resolve(args: ScopeDataArgs): TemplateContent | TemplateData[] {
// Fallback on empty paths.
if (!args.path.length) {
return this.fallback(args);
}
// Fallback on number paths (generated by the loop plugin).
const lastPart = args.path[args.path.length - 1];
if (isNumber(lastPart)) {
return this.fallback(args);
}
// Check required prefix.
let exp = (lastPart?.name || "").trim();
if (this.options.requiredPrefix && !exp.startsWith(this.options.requiredPrefix)) {
return this.fallback(args);
}
if (this.options.requiredPrefix) {
exp = exp.substr(this.options.requiredPrefix.length);
}
// Flatten the scope.
const finalScope = Object.assign({}, args.data);
let curScop: any = finalScope;
for (const part of args.path) {
const partIndexer = isNumber(part) ? part : part.name;
// Apply the path filter.
if (this.options.pathFilter && !this.options.pathFilter(partIndexer)) {
continue;
}
// If it's not an object don't go deeper.
curScop = getProp(curScop, partIndexer);
if (!isObject(curScop)) {
break;
}
Object.assign(finalScope, curScop);
}
// Resolve the expression.
exp = exp.replace(/(’|‘)/g, "'").replace(/(“|”)/g, '"');
try {
return expressions.compile(exp)(finalScope);
} catch (e) {
throw new ResolveError(exp, args.strPath, e);
}
}
}