Phase 1 PWA: prayer times, qibla, quran, hijri, tasbih, 99 names

This commit is contained in:
Hermes Bot
2026-08-06 11:55:47 +08:00
parent 4def05d0ef
commit 0d37e7ec1e
10869 changed files with 959465 additions and 18 deletions
+180
View File
@@ -0,0 +1,180 @@
//#region src/parse.d.ts
interface TemplateObject {
t: string;
val: string;
lineNo?: number;
}
type AstObject = string | TemplateObject;
declare function parse(this: Eta$1, str: string): Array<AstObject>;
//#endregion
//#region src/config.d.ts
type trimConfig = "nl" | "slurp" | false;
interface Options {
/** Compile to async function */
async?: boolean;
/** Absolute path to template file */
filepath?: string;
}
interface EtaConfig {
/** Whether or not to automatically XML-escape interpolations. Default true */
autoEscape: boolean;
/** Apply a filter function defined on the class to every interpolation or raw interpolation */
autoFilter: boolean;
/** Configure automatic whitespace trimming. Default `[false, 'nl']` */
autoTrim: trimConfig | [trimConfig, trimConfig];
/** Whether or not to cache templates if `name` or `filename` is passed */
cache: boolean;
/** Holds cache of resolved filepaths. Set to `false` to disable. */
cacheFilepaths: boolean;
/** Object specifying custom tags. Keys are tag prefixes, values are functions which take tag content and return a string. */
customTags: Record<string, (content: string, data: unknown) => string>;
/** Whether to pretty-format error messages (introduces runtime penalties) */
debug: boolean;
/** Function to XML-sanitize interpolations */
escapeFunction: (str: unknown) => string;
/** Function applied to all interpolations when autoFilter is true */
filterFunction: (val: unknown) => string;
/** Name of the function that can be used in template code to output text to the result (like EJS's `outputFunctionName`). */
outputFunctionName: string;
/** Raw JS code inserted in the template function. Useful for declaring global variables for user templates */
functionHeader: string;
/** Parsing options */
parse: {
/** Which prefix to use for evaluation. Default `""`, does not support `"-"` or `"_"` */
exec: string;
/** Which prefix to use for interpolation. Default `"="`, does not support `"-"` or `"_"` */
interpolate: string;
/** Which prefix to use for raw interpolation. Default `"~"`, does not support `"-"` or `"_"` */
raw: string;
};
/** Array of plugins */
plugins: Array<{
processFnString?: (fnString: string, env?: EtaConfig) => string;
processAST?: (ast: AstObject[], env?: EtaConfig) => AstObject[];
processTemplate?: (fnString: string, env?: EtaConfig) => string;
}>;
/** Remove empty lines and whitespace between lines */
rmWhitespace: boolean;
/** Delimiters: by default `['<%', '%>']` */
tags: [string, string];
/** Make data available on the global object instead of varName */
useWith: boolean;
/** Name of the data object. Default `it` */
varName: string;
/** Directory that contains templates */
views?: string;
/** Control template file extension defaults. Default `.eta` */
defaultExtension?: string;
}
//#endregion
//#region src/compile.d.ts
type TemplateFunction = (this: Eta$1, data?: object, options?: Partial<Options>) => string;
/**
* Takes a template string and returns a template function that can be called with (data, config)
*
* @param str - The template string
* @param config - A custom configuration object (optional)
*/
declare function compile(this: Eta$1, str: string, options?: Partial<Options>): TemplateFunction;
//#endregion
//#region src/compile-string.d.ts
/**
* Compiles a template string to a function string. Most often users just use `compile()`, which calls `compileToString` and creates a new function using the result
*/
declare function compileToString(this: Eta$1, str: string, options?: Partial<Options>): string;
/**
* Loops through the AST generated by `parse` and transform each item into JS calls
*
* **Example**
*
* ```js
* let templateAST = ['Hi ', { val: 'it.name', t: 'i' }]
* compileBody.call(Eta, templateAST)
* // => "__eta.res+='Hi '\n__eta.res+=__eta.e(it.name)\n"
* ```
*/
declare function compileBody(this: Eta$1, buff: Array<AstObject>): string;
//#endregion
//#region src/err.d.ts
declare class EtaError extends Error {
constructor(message: string);
}
declare class EtaParseError extends EtaError {
constructor(message: string);
}
declare class EtaRuntimeError extends EtaError {
constructor(message: string);
}
declare class EtaFileResolutionError extends EtaError {
constructor(message: string);
}
declare class EtaNameResolutionError extends EtaError {
constructor(message: string);
}
declare function RuntimeErr(originalError: Error, str: string, lineNo: number, path: string): never;
//#endregion
//#region src/render.d.ts
declare function render<T extends object>(this: Eta$1, template: string | TemplateFunction,
// template name or template function
data: T, meta?: {
filepath: string;
}): string;
declare function renderAsync<T extends object>(this: Eta$1, template: string | TemplateFunction,
// template name or template function
data: T, meta?: {
filepath: string;
}): Promise<string>;
declare function renderString<T extends object>(this: Eta$1, template: string, data: T): string;
declare function renderStringAsync<T extends object>(this: Eta$1, template: string, data: T): Promise<string>;
//#endregion
//#region src/storage.d.ts
/**
* Handles storage and accessing of values
*
* In this case, we use it to store compiled template functions
* Indexed by their `name` or `filename`
*/
declare class Cacher<T> {
private cache;
constructor(cache: Record<string, T>);
define(key: string, val: T): void;
get(key: string): T;
remove(key: string): void;
reset(): void;
load(cacheObj: Record<string, T>): void;
}
//#endregion
//#region src/internal.d.ts
declare class Eta$1 {
constructor(customConfig?: Partial<EtaConfig>);
config: EtaConfig;
RuntimeErr: typeof RuntimeErr;
compile: typeof compile;
compileToString: typeof compileToString;
compileBody: typeof compileBody;
parse: typeof parse;
render: typeof render;
renderAsync: typeof renderAsync;
renderString: typeof renderString;
renderStringAsync: typeof renderStringAsync;
filepathCache: Record<string, string>;
templatesSync: Cacher<TemplateFunction>;
templatesAsync: Cacher<TemplateFunction>;
resolvePath: null | ((this: Eta$1, template: string, options?: Partial<Options>) => string);
readFile: null | ((this: Eta$1, path: string) => string);
configure(customConfig: Partial<EtaConfig>): void;
withConfig(customConfig: Partial<EtaConfig>): this & {
config: EtaConfig;
};
loadTemplate(name: string, template: string | TemplateFunction,
// template string or template function
options?: {
async: boolean;
}): void;
}
//#endregion
//#region src/core.d.ts
declare class Eta extends Eta$1 {}
//#endregion
export { Eta, type EtaConfig, EtaError, EtaFileResolutionError, EtaNameResolutionError, EtaParseError, EtaRuntimeError, type Options, type TemplateFunction };
//# sourceMappingURL=core.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"core.d.ts","names":[],"sources":["../src/parse.ts","../src/config.ts","../src/compile.ts","../src/compile-string.ts","../src/err.ts","../src/render.ts","../src/storage.ts","../src/internal.ts","../src/core.ts"],"sourcesContent":[],"mappings":"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"}
+46
View File
@@ -0,0 +1,46 @@
var e=class extends Error{constructor(e){super(e),this.name=`Eta Error`}},t=class extends e{constructor(e){super(e),this.name=`EtaParser Error`}},n=class extends e{constructor(e){super(e),this.name=`EtaRuntime Error`}},r=class extends e{constructor(e){super(e),this.name=`EtaFileResolution Error`}},i=class extends e{constructor(e){super(e),this.name=`EtaNameResolution Error`}};function a(e,n,r){let i=n.slice(0,r).split(/\n/),a=i.length,o=i[a-1].length+1;throw e+=` at line `+a+` col `+o+`:
`+n.split(/\n/)[a-1]+`
`+Array(o).join(` `)+`^`,new t(e)}function o(e,t,r,i){let a=t.split(`
`),o=Math.max(r-3,0),s=Math.min(a.length,r+3),c=i,l=a.slice(o,s).map((e,t)=>{let n=t+o+1;return(n===r?` >> `:` `)+n+`| `+e}).join(`
`),u=new n((c?c+`:`+r+`
`:`line `+r+`
`)+l+`
`+e.message);throw u.name=e.name,u.cause=e,u}const s=(async()=>{}).constructor;function c(e,n){let r=this.config,i=n?.async?s:Function;try{return new i(r.varName,`options`,this.compileToString.call(this,e,n))}catch(r){throw r instanceof SyntaxError?new t(`Bad template syntax
`+r.message+`
`+Array(r.message.length+1).join(`=`)+`
`+this.compileToString.call(this,e,n)+`
`):r}}function l(e,t){let n=this.config,r=t?.async,i=this.compileBody,a=this.parse.call(this,e),o=`${n.functionHeader}
let include = (__eta_t, __eta_d) => this.render(__eta_t, {...${n.varName}, ...(__eta_d ?? {})}, options);
let includeAsync = (__eta_t, __eta_d) => this.renderAsync(__eta_t, {...${n.varName}, ...(__eta_d ?? {})}, options);
let __eta = {res: "", e: this.config.escapeFunction, f: this.config.filterFunction, blocks: {}${n.debug?`, line: 1, templateStr: "`+e.replace(/\\|"/g,`\\$&`).replace(/\r\n|\n|\r/g,`\\n`)+`"`:``}};
function layout(path, data) {
__eta.layout = path;
__eta.layoutData = data;
}${n.debug?`try {`:``}${n.useWith?`with(`+n.varName+`||{}){`:``}
function ${n.outputFunctionName}(s){__eta.res+=s;}
function capture(fn){const s=__eta.res;__eta.res='';try{fn();return __eta.res}finally{__eta.res=s;}}
async function captureAsync(fn){const s=__eta.res;__eta.res='';try{await fn();return __eta.res}finally{__eta.res=s;}}
function block(name,fn){if(__eta.layout){if(fn){__eta.blocks[name]=capture(fn);}return '';}const b=${n.varName}.__blocks||{};if(name in b){return b[name];}return fn?capture(fn):'';}
async function blockAsync(name,fn){if(__eta.layout){if(fn){__eta.blocks[name]=await captureAsync(fn);}return '';}const b=${n.varName}.__blocks||{};if(name in b){return b[name];}return fn?await captureAsync(fn):'';}
${i.call(this,a)}
if (__eta.layout) {
__eta.res = ${r?`await includeAsync`:`include`} (__eta.layout, {...${n.varName}, body: __eta.res, ...__eta.layoutData, __blocks: __eta.blocks});
}
${n.useWith?`}`:``}${n.debug?`} catch (e) { this.RuntimeErr(e, __eta.templateStr, __eta.line, options.filepath) }`:``}
return __eta.res;
`;if(n.plugins)for(let e=0;e<n.plugins.length;e++){let t=n.plugins[e];t.processFnString&&(o=t.processFnString(o,n))}return o}function u(e){let t=this.config,n=0,r=e.length,i=``;for(;n<r;n++){let r=e[n];if(typeof r==`string`)i+=`__eta.res+='`+r+`';
`;else{let e=r.t,n=r.val||``;t.debug&&(i+=`__eta.line=`+r.lineNo+`
`),e===`r`?(t.autoFilter&&(n=`__eta.f(`+n+`)`),i+=`__eta.res+=`+n+`;
`):e===`i`?(t.autoFilter&&(n=`__eta.f(`+n+`)`),t.autoEscape&&(n=`__eta.e(`+n+`)`),i+=`__eta.res+=`+n+`;
`):e===`e`?i+=n+`
`:Object.hasOwn(t.customTags,e)&&(i+=`__eta.res+=this.config.customTags[${JSON.stringify(e)}](${JSON.stringify(n)},${t.varName});\n`)}}return i}function d(e,t,n,r){let i,a;return Array.isArray(t.autoTrim)?(i=t.autoTrim[1],a=t.autoTrim[0]):i=a=t.autoTrim,(n||n===!1)&&(i=n),(r||r===!1)&&(a=r),!a&&!i?e:i===`slurp`&&a===`slurp`?e.trim():(i===`_`||i===`slurp`?e=e.trimStart():(i===`-`||i===`nl`)&&(e=e.replace(/^(?:\r\n|\n|\r)/,``)),a===`_`||a===`slurp`?e=e.trimEnd():(a===`-`||a===`nl`)&&(e=e.replace(/(?:\r\n|\n|\r)$/,``)),e)}const f={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`};function p(e){return f[e]}function m(e){let t=String(e);return/[&<>"']/.test(t)?t.replace(/[&<>"']/g,p):t}const h={autoEscape:!0,autoFilter:!1,autoTrim:[!1,`nl`],cache:!1,cacheFilepaths:!0,customTags:{},debug:!1,escapeFunction:m,filterFunction:e=>String(e),outputFunctionName:`output`,functionHeader:``,parse:{exec:``,interpolate:`=`,raw:`~`},plugins:[],rmWhitespace:!1,tags:[`<%`,`%>`],useWith:!1,varName:`it`,defaultExtension:`.eta`},g=/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g,_=/'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g,v=/"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g;function y(e){return e.replace(/[.*+\-?^${}()|[\]\\]/g,`\\$&`)}function b(e,t){return e.slice(0,t).split(`
`).length}function x(e){let t=this.config,n=[],r=!1,i=0,o=t.parse,s=Object.keys(t.customTags);if(t.plugins)for(let n=0;n<t.plugins.length;n++){let r=t.plugins[n];r.processTemplate&&(e=r.processTemplate(e,t))}t.rmWhitespace&&(e=e.replace(/[\r\n]+/g,`
`).replace(/^\s+|\s+$/gm,``)),g.lastIndex=0,_.lastIndex=0,v.lastIndex=0;function c(e,i){e&&(e=d(e,t,r,i),e&&(e=e.replace(/\\|'/g,`\\$&`).replace(/\r\n|\n|\r/g,`\\n`),n.push(e)))}let l=[o.exec,o.interpolate,o.raw,...s].reduce((e,t)=>e&&t?e+`|`+y(t):t?y(t):e,``),u=RegExp(y(t.tags[0])+`(-|_)?\\s*(`+l+`)?\\s*`,`g`),f=RegExp(`'|"|\`|\\/\\*|(\\s*(-|_)?`+y(t.tags[1])+`)`,`g`),p;for(;p=u.exec(e);){let l=e.slice(i,p.index);i=p[0].length+p.index;let d=p[1],m=p[2]||``;c(l,d),f.lastIndex=i;let h,y=!1;for(;h=f.exec(e);)if(h[1]){let t=e.slice(i,h.index);u.lastIndex=i=f.lastIndex,r=h[2],y={t:m===o.exec?`e`:m===o.raw?`r`:m===o.interpolate?`i`:s.includes(m)?m:``,val:t};break}else{let t=h[0];if(t===`/*`){let t=e.indexOf(`*/`,f.lastIndex);t===-1&&a(`unclosed comment`,e,h.index),f.lastIndex=t}else t===`'`?(_.lastIndex=h.index,_.exec(e)?f.lastIndex=_.lastIndex:a(`unclosed string`,e,h.index)):t===`"`?(v.lastIndex=h.index,v.exec(e)?f.lastIndex=v.lastIndex:a(`unclosed string`,e,h.index)):t==="`"&&(g.lastIndex=h.index,g.exec(e)?f.lastIndex=g.lastIndex:a(`unclosed string`,e,h.index))}y?(t.debug&&(y.lineNo=b(e,p.index)),n.push(y)):a(`unclosed tag`,e,p.index)}if(c(e.slice(i,e.length),!1),t.plugins)for(let e=0;e<t.plugins.length;e++){let r=t.plugins[e];r.processAST&&(n=r.processAST(n,t))}return n}function S(e,t){let n=t?.async?this.templatesAsync:this.templatesSync;if(this.resolvePath&&this.readFile&&!e.startsWith(`@`)){let e=t.filepath,r=n.get(e);if(this.config.cache&&r)return r;{let r=this.readFile(e),i=this.compile(r,t);return this.config.cache&&n.define(e,i),i}}else{let t=n.get(e);if(t)return t;throw new i(`Failed to get template '${e}'`)}}function C(e,t,n){let r,i={...n,async:!1};return typeof e==`string`?(this.resolvePath&&this.readFile&&!e.startsWith(`@`)&&(i.filepath=this.resolvePath(e,i)),r=S.call(this,e,i)):r=e,r.call(this,t,i)}function w(e,t,n){let r,i={...n,async:!0};typeof e==`string`?(this.resolvePath&&this.readFile&&!e.startsWith(`@`)&&(i.filepath=this.resolvePath(e,i)),r=S.call(this,e,i)):r=e;let a=r.call(this,t,i);return Promise.resolve(a)}function T(e,t){let n=this.compile(e,{async:!1});return C.call(this,n,t)}function E(e,t){let n=this.compile(e,{async:!0});return w.call(this,n,t)}var D=class{constructor(e){this.cache=e}define(e,t){this.cache[e]=t}get(e){return this.cache[e]}remove(e){delete this.cache[e]}reset(){this.cache={}}load(e){this.cache={...this.cache,...e}}},O=class{constructor(t){t?this.config={...h,...t}:this.config={...h};let n=[this.config.parse.exec,this.config.parse.interpolate,this.config.parse.raw,`-`,`_`];for(let t of Object.keys(this.config.customTags))if(n.includes(t))throw new e(`Custom tag prefix "${t}" conflicts with a built-in prefix`)}config;RuntimeErr=o;compile=c;compileToString=l;compileBody=u;parse=x;render=C;renderAsync=w;renderString=T;renderStringAsync=E;filepathCache={};templatesSync=new D({});templatesAsync=new D({});resolvePath=null;readFile=null;configure(e){this.config={...this.config,...e}}withConfig(e){return{...this,config:{...this.config,...e}}}loadTemplate(e,t,n){if(typeof t==`string`)(n?.async?this.templatesAsync:this.templatesSync).define(e,this.compile(t,n));else{let r=this.templatesSync;(t.constructor.name===`AsyncFunction`||n?.async)&&(r=this.templatesAsync),r.define(e,t)}}},k=class extends O{};export{k as Eta,e as EtaError,r as EtaFileResolutionError,i as EtaNameResolutionError,t as EtaParseError,n as EtaRuntimeError};
//# sourceMappingURL=core.js.map
+1
View File
File diff suppressed because one or more lines are too long
+558
View File
@@ -0,0 +1,558 @@
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
let node_fs = require("node:fs");
node_fs = __toESM(node_fs);
let node_path = require("node:path");
node_path = __toESM(node_path);
//#region src/err.ts
var EtaError = class extends Error {
constructor(message) {
super(message);
this.name = "Eta Error";
}
};
var EtaParseError = class extends EtaError {
constructor(message) {
super(message);
this.name = "EtaParser Error";
}
};
var EtaRuntimeError = class extends EtaError {
constructor(message) {
super(message);
this.name = "EtaRuntime Error";
}
};
var EtaFileResolutionError = class extends EtaError {
constructor(message) {
super(message);
this.name = "EtaFileResolution Error";
}
};
var EtaNameResolutionError = class extends EtaError {
constructor(message) {
super(message);
this.name = "EtaNameResolution Error";
}
};
/**
* Throws an EtaError with a nicely formatted error and message showing where in the template the error occurred.
*/
function ParseErr(message, str, indx) {
const whitespace = str.slice(0, indx).split(/\n/);
const lineNo = whitespace.length;
const colNo = whitespace[lineNo - 1].length + 1;
message += " at line " + lineNo + " col " + colNo + ":\n\n " + str.split(/\n/)[lineNo - 1] + "\n " + Array(colNo).join(" ") + "^";
throw new EtaParseError(message);
}
function RuntimeErr(originalError, str, lineNo, path) {
const lines = str.split("\n");
const start = Math.max(lineNo - 3, 0);
const end = Math.min(lines.length, lineNo + 3);
const filename = path;
const context = lines.slice(start, end).map((line, i) => {
const curr = i + start + 1;
return (curr === lineNo ? " >> " : " ") + curr + "| " + line;
}).join("\n");
const err = new EtaRuntimeError((filename ? filename + ":" + lineNo + "\n" : "line " + lineNo + "\n") + context + "\n\n" + originalError.message);
err.name = originalError.name;
err.cause = originalError;
throw err;
}
//#endregion
//#region src/file-handling.ts
function readFile(path) {
let res = "";
try {
res = node_fs.readFileSync(path, "utf8");
} catch (err) {
if (err?.code === "ENOENT") throw new EtaFileResolutionError(`Could not find template: ${path}`);
else throw err;
}
return res;
}
function resolvePath(templatePath, options) {
let resolvedFilePath = "";
const views = this.config.views;
if (!views) throw new EtaFileResolutionError("Views directory is not defined");
const baseFilePath = options?.filepath;
const defaultExtension = this.config.defaultExtension === void 0 ? ".eta" : this.config.defaultExtension;
const cacheIndex = JSON.stringify({
filename: baseFilePath,
path: templatePath,
views: this.config.views
});
templatePath += node_path.extname(templatePath) ? "" : defaultExtension;
if (baseFilePath) {
if (this.config.cacheFilepaths && this.filepathCache[cacheIndex]) return this.filepathCache[cacheIndex];
if (absolutePathRegExp.exec(templatePath)?.length) {
const formattedPath = templatePath.replace(/^\/*|^\\*/, "");
resolvedFilePath = node_path.join(views, formattedPath);
} else resolvedFilePath = node_path.join(node_path.dirname(baseFilePath), templatePath);
} else resolvedFilePath = node_path.join(views, templatePath);
if (dirIsChild(views, resolvedFilePath)) {
if (baseFilePath && this.config.cacheFilepaths) this.filepathCache[cacheIndex] = resolvedFilePath;
return resolvedFilePath;
} else throw new EtaFileResolutionError(`Template '${templatePath}' is not in the views directory`);
}
function dirIsChild(parent, dir) {
const relative = node_path.relative(parent, dir);
return relative && !relative.startsWith("..") && !node_path.isAbsolute(relative);
}
const absolutePathRegExp = /^\\|^\//;
//#endregion
//#region src/compile.ts
/* istanbul ignore next */
const AsyncFunction = (async () => {}).constructor;
/**
* Takes a template string and returns a template function that can be called with (data, config)
*
* @param str - The template string
* @param config - A custom configuration object (optional)
*/
function compile(str, options) {
const config = this.config;
const ctor = options?.async ? AsyncFunction : Function;
try {
return new ctor(config.varName, "options", this.compileToString.call(this, str, options));
} catch (e) {
if (e instanceof SyntaxError) throw new EtaParseError("Bad template syntax\n\n" + e.message + "\n" + Array(e.message.length + 1).join("=") + "\n" + this.compileToString.call(this, str, options) + "\n");
else throw e;
}
}
//#endregion
//#region src/compile-string.ts
/**
* Compiles a template string to a function string. Most often users just use `compile()`, which calls `compileToString` and creates a new function using the result
*/
function compileToString(str, options) {
const config = this.config;
const isAsync = options?.async;
const compileBody$1 = this.compileBody;
const buffer = this.parse.call(this, str);
let res = `${config.functionHeader}
let include = (__eta_t, __eta_d) => this.render(__eta_t, {...${config.varName}, ...(__eta_d ?? {})}, options);
let includeAsync = (__eta_t, __eta_d) => this.renderAsync(__eta_t, {...${config.varName}, ...(__eta_d ?? {})}, options);
let __eta = {res: "", e: this.config.escapeFunction, f: this.config.filterFunction, blocks: {}${config.debug ? ", line: 1, templateStr: \"" + str.replace(/\\|"/g, "\\$&").replace(/\r\n|\n|\r/g, "\\n") + "\"" : ""}};
function layout(path, data) {
__eta.layout = path;
__eta.layoutData = data;
}${config.debug ? "try {" : ""}${config.useWith ? "with(" + config.varName + "||{}){" : ""}
function ${config.outputFunctionName}(s){__eta.res+=s;}
function capture(fn){const s=__eta.res;__eta.res='';try{fn();return __eta.res}finally{__eta.res=s;}}
async function captureAsync(fn){const s=__eta.res;__eta.res='';try{await fn();return __eta.res}finally{__eta.res=s;}}
function block(name,fn){if(__eta.layout){if(fn){__eta.blocks[name]=capture(fn);}return '';}const b=${config.varName}.__blocks||{};if(name in b){return b[name];}return fn?capture(fn):'';}
async function blockAsync(name,fn){if(__eta.layout){if(fn){__eta.blocks[name]=await captureAsync(fn);}return '';}const b=${config.varName}.__blocks||{};if(name in b){return b[name];}return fn?await captureAsync(fn):'';}
${compileBody$1.call(this, buffer)}
if (__eta.layout) {
__eta.res = ${isAsync ? "await includeAsync" : "include"} (__eta.layout, {...${config.varName}, body: __eta.res, ...__eta.layoutData, __blocks: __eta.blocks});
}
${config.useWith ? "}" : ""}${config.debug ? "} catch (e) { this.RuntimeErr(e, __eta.templateStr, __eta.line, options.filepath) }" : ""}
return __eta.res;
`;
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
const plugin = config.plugins[i];
if (plugin.processFnString) res = plugin.processFnString(res, config);
}
return res;
}
/**
* Loops through the AST generated by `parse` and transform each item into JS calls
*
* **Example**
*
* ```js
* let templateAST = ['Hi ', { val: 'it.name', t: 'i' }]
* compileBody.call(Eta, templateAST)
* // => "__eta.res+='Hi '\n__eta.res+=__eta.e(it.name)\n"
* ```
*/
function compileBody(buff) {
const config = this.config;
let i = 0;
const buffLength = buff.length;
let returnStr = "";
for (; i < buffLength; i++) {
const currentBlock = buff[i];
if (typeof currentBlock === "string") returnStr += "__eta.res+='" + currentBlock + "';\n";
else {
const type = currentBlock.t;
let content = currentBlock.val || "";
if (config.debug) returnStr += "__eta.line=" + currentBlock.lineNo + "\n";
if (type === "r") {
if (config.autoFilter) content = "__eta.f(" + content + ")";
returnStr += "__eta.res+=" + content + ";\n";
} else if (type === "i") {
if (config.autoFilter) content = "__eta.f(" + content + ")";
if (config.autoEscape) content = "__eta.e(" + content + ")";
returnStr += "__eta.res+=" + content + ";\n";
} else if (type === "e") returnStr += content + "\n";
else if (Object.hasOwn(config.customTags, type)) returnStr += `__eta.res+=this.config.customTags[${JSON.stringify(type)}](${JSON.stringify(content)},${config.varName});\n`;
}
}
return returnStr;
}
//#endregion
//#region src/utils.ts
/**
* Takes a string within a template and trims it, based on the preceding tag's whitespace control and `config.autoTrim`
*/
function trimWS(str, config, wsLeft, wsRight) {
let leftTrim;
let rightTrim;
if (Array.isArray(config.autoTrim)) {
leftTrim = config.autoTrim[1];
rightTrim = config.autoTrim[0];
} else leftTrim = rightTrim = config.autoTrim;
if (wsLeft || wsLeft === false) leftTrim = wsLeft;
if (wsRight || wsRight === false) rightTrim = wsRight;
if (!rightTrim && !leftTrim) return str;
if (leftTrim === "slurp" && rightTrim === "slurp") return str.trim();
if (leftTrim === "_" || leftTrim === "slurp") str = str.trimStart();
else if (leftTrim === "-" || leftTrim === "nl") str = str.replace(/^(?:\r\n|\n|\r)/, "");
if (rightTrim === "_" || rightTrim === "slurp") str = str.trimEnd();
else if (rightTrim === "-" || rightTrim === "nl") str = str.replace(/(?:\r\n|\n|\r)$/, "");
return str;
}
/**
* A map of special HTML characters to their XML-escaped equivalents
*/
const escMap = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
"\"": "&quot;",
"'": "&#39;"
};
function replaceChar(s) {
return escMap[s];
}
/**
* XML-escapes an input value after converting it to a string
*
* @param str - Input value (usually a string)
* @returns XML-escaped string
*/
function XMLEscape(str) {
const newStr = String(str);
if (/[&<>"']/.test(newStr)) return newStr.replace(/[&<>"']/g, replaceChar);
else return newStr;
}
//#endregion
//#region src/config.ts
/** Eta's base (global) configuration */
const defaultConfig = {
autoEscape: true,
autoFilter: false,
autoTrim: [false, "nl"],
cache: false,
cacheFilepaths: true,
customTags: {},
debug: false,
escapeFunction: XMLEscape,
filterFunction: (val) => String(val),
outputFunctionName: "output",
functionHeader: "",
parse: {
exec: "",
interpolate: "=",
raw: "~"
},
plugins: [],
rmWhitespace: false,
tags: ["<%", "%>"],
useWith: false,
varName: "it",
defaultExtension: ".eta"
};
//#endregion
//#region src/parse.ts
const templateLitReg = /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g;
const singleQuoteReg = /'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g;
const doubleQuoteReg = /"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g;
/** Escape special regular expression characters inside a string */
function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&");
}
function getLineNo(str, index) {
return str.slice(0, index).split("\n").length;
}
function parse(str) {
const config = this.config;
let buffer = [];
let trimLeftOfNextStr = false;
let lastIndex = 0;
const parseOptions = config.parse;
const customTagPrefixes = Object.keys(config.customTags);
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
const plugin = config.plugins[i];
if (plugin.processTemplate) str = plugin.processTemplate(str, config);
}
if (config.rmWhitespace) str = str.replace(/[\r\n]+/g, "\n").replace(/^\s+|\s+$/gm, "");
templateLitReg.lastIndex = 0;
singleQuoteReg.lastIndex = 0;
doubleQuoteReg.lastIndex = 0;
function pushString(strng, shouldTrimRightOfString) {
if (strng) {
strng = trimWS(strng, config, trimLeftOfNextStr, shouldTrimRightOfString);
if (strng) {
strng = strng.replace(/\\|'/g, "\\$&").replace(/\r\n|\n|\r/g, "\\n");
buffer.push(strng);
}
}
}
const prefixes = [
parseOptions.exec,
parseOptions.interpolate,
parseOptions.raw,
...customTagPrefixes
].reduce((accumulator, prefix) => {
if (accumulator && prefix) return accumulator + "|" + escapeRegExp(prefix);
else if (prefix) return escapeRegExp(prefix);
else return accumulator;
}, "");
const parseOpenReg = new RegExp(escapeRegExp(config.tags[0]) + "(-|_)?\\s*(" + prefixes + ")?\\s*", "g");
const parseCloseReg = new RegExp("'|\"|`|\\/\\*|(\\s*(-|_)?" + escapeRegExp(config.tags[1]) + ")", "g");
let m;
while (m = parseOpenReg.exec(str)) {
const precedingString = str.slice(lastIndex, m.index);
lastIndex = m[0].length + m.index;
const wsLeft = m[1];
const prefix = m[2] || "";
pushString(precedingString, wsLeft);
parseCloseReg.lastIndex = lastIndex;
let closeTag;
let currentObj = false;
while (closeTag = parseCloseReg.exec(str)) if (closeTag[1]) {
const content = str.slice(lastIndex, closeTag.index);
parseOpenReg.lastIndex = lastIndex = parseCloseReg.lastIndex;
trimLeftOfNextStr = closeTag[2];
currentObj = {
t: prefix === parseOptions.exec ? "e" : prefix === parseOptions.raw ? "r" : prefix === parseOptions.interpolate ? "i" : customTagPrefixes.includes(prefix) ? prefix : "",
val: content
};
break;
} else {
const char = closeTag[0];
if (char === "/*") {
const commentCloseInd = str.indexOf("*/", parseCloseReg.lastIndex);
if (commentCloseInd === -1) ParseErr("unclosed comment", str, closeTag.index);
parseCloseReg.lastIndex = commentCloseInd;
} else if (char === "'") {
singleQuoteReg.lastIndex = closeTag.index;
if (singleQuoteReg.exec(str)) parseCloseReg.lastIndex = singleQuoteReg.lastIndex;
else ParseErr("unclosed string", str, closeTag.index);
} else if (char === "\"") {
doubleQuoteReg.lastIndex = closeTag.index;
if (doubleQuoteReg.exec(str)) parseCloseReg.lastIndex = doubleQuoteReg.lastIndex;
else ParseErr("unclosed string", str, closeTag.index);
} else if (char === "`") {
templateLitReg.lastIndex = closeTag.index;
if (templateLitReg.exec(str)) parseCloseReg.lastIndex = templateLitReg.lastIndex;
else ParseErr("unclosed string", str, closeTag.index);
}
}
if (currentObj) {
if (config.debug) currentObj.lineNo = getLineNo(str, m.index);
buffer.push(currentObj);
} else ParseErr("unclosed tag", str, m.index);
}
pushString(str.slice(lastIndex, str.length), false);
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
const plugin = config.plugins[i];
if (plugin.processAST) buffer = plugin.processAST(buffer, config);
}
return buffer;
}
//#endregion
//#region src/render.ts
function handleCache(template, options) {
const templateStore = options?.async ? this.templatesAsync : this.templatesSync;
if (this.resolvePath && this.readFile && !template.startsWith("@")) {
const templatePath = options.filepath;
const cachedTemplate = templateStore.get(templatePath);
if (this.config.cache && cachedTemplate) return cachedTemplate;
else {
const templateString = this.readFile(templatePath);
const templateFn = this.compile(templateString, options);
if (this.config.cache) templateStore.define(templatePath, templateFn);
return templateFn;
}
} else {
const cachedTemplate = templateStore.get(template);
if (cachedTemplate) return cachedTemplate;
else throw new EtaNameResolutionError(`Failed to get template '${template}'`);
}
}
function render(template, data, meta) {
let templateFn;
const options = {
...meta,
async: false
};
if (typeof template === "string") {
if (this.resolvePath && this.readFile && !template.startsWith("@")) options.filepath = this.resolvePath(template, options);
templateFn = handleCache.call(this, template, options);
} else templateFn = template;
return templateFn.call(this, data, options);
}
function renderAsync(template, data, meta) {
let templateFn;
const options = {
...meta,
async: true
};
if (typeof template === "string") {
if (this.resolvePath && this.readFile && !template.startsWith("@")) options.filepath = this.resolvePath(template, options);
templateFn = handleCache.call(this, template, options);
} else templateFn = template;
const res = templateFn.call(this, data, options);
return Promise.resolve(res);
}
function renderString(template, data) {
const templateFn = this.compile(template, { async: false });
return render.call(this, templateFn, data);
}
function renderStringAsync(template, data) {
const templateFn = this.compile(template, { async: true });
return renderAsync.call(this, templateFn, data);
}
//#endregion
//#region src/storage.ts
/**
* Handles storage and accessing of values
*
* In this case, we use it to store compiled template functions
* Indexed by their `name` or `filename`
*/
var Cacher = class {
constructor(cache) {
this.cache = cache;
}
define(key, val) {
this.cache[key] = val;
}
get(key) {
return this.cache[key];
}
remove(key) {
delete this.cache[key];
}
reset() {
this.cache = {};
}
load(cacheObj) {
this.cache = {
...this.cache,
...cacheObj
};
}
};
//#endregion
//#region src/internal.ts
var Eta$1 = class {
constructor(customConfig) {
if (customConfig) this.config = {
...defaultConfig,
...customConfig
};
else this.config = { ...defaultConfig };
const reserved = [
this.config.parse.exec,
this.config.parse.interpolate,
this.config.parse.raw,
"-",
"_"
];
for (const prefix of Object.keys(this.config.customTags)) if (reserved.includes(prefix)) throw new EtaError(`Custom tag prefix "${prefix}" conflicts with a built-in prefix`);
}
config;
RuntimeErr = RuntimeErr;
compile = compile;
compileToString = compileToString;
compileBody = compileBody;
parse = parse;
render = render;
renderAsync = renderAsync;
renderString = renderString;
renderStringAsync = renderStringAsync;
filepathCache = {};
templatesSync = new Cacher({});
templatesAsync = new Cacher({});
resolvePath = null;
readFile = null;
configure(customConfig) {
this.config = {
...this.config,
...customConfig
};
}
withConfig(customConfig) {
return {
...this,
config: {
...this.config,
...customConfig
}
};
}
loadTemplate(name, template, options) {
if (typeof template === "string") (options?.async ? this.templatesAsync : this.templatesSync).define(name, this.compile(template, options));
else {
let templates = this.templatesSync;
if (template.constructor.name === "AsyncFunction" || options?.async) templates = this.templatesAsync;
templates.define(name, template);
}
}
};
//#endregion
//#region src/index.ts
var Eta = class extends Eta$1 {
readFile = readFile;
resolvePath = resolvePath;
};
//#endregion
exports.Eta = Eta;
exports.EtaError = EtaError;
exports.EtaFileResolutionError = EtaFileResolutionError;
exports.EtaNameResolutionError = EtaNameResolutionError;
exports.EtaParseError = EtaParseError;
exports.EtaRuntimeError = EtaRuntimeError;
//# sourceMappingURL=index.cjs.map
+1
View File
File diff suppressed because one or more lines are too long
+188
View File
@@ -0,0 +1,188 @@
//#region src/compile.d.ts
type TemplateFunction = (this: Eta$1, data?: object, options?: Partial<Options>) => string;
/**
* Takes a template string and returns a template function that can be called with (data, config)
*
* @param str - The template string
* @param config - A custom configuration object (optional)
*/
declare function compile(this: Eta$1, str: string, options?: Partial<Options>): TemplateFunction;
//#endregion
//#region src/compile-string.d.ts
/**
* Compiles a template string to a function string. Most often users just use `compile()`, which calls `compileToString` and creates a new function using the result
*/
declare function compileToString(this: Eta$1, str: string, options?: Partial<Options>): string;
/**
* Loops through the AST generated by `parse` and transform each item into JS calls
*
* **Example**
*
* ```js
* let templateAST = ['Hi ', { val: 'it.name', t: 'i' }]
* compileBody.call(Eta, templateAST)
* // => "__eta.res+='Hi '\n__eta.res+=__eta.e(it.name)\n"
* ```
*/
declare function compileBody(this: Eta$1, buff: Array<AstObject>): string;
//#endregion
//#region src/err.d.ts
declare class EtaError extends Error {
constructor(message: string);
}
declare class EtaParseError extends EtaError {
constructor(message: string);
}
declare class EtaRuntimeError extends EtaError {
constructor(message: string);
}
declare class EtaFileResolutionError extends EtaError {
constructor(message: string);
}
declare class EtaNameResolutionError extends EtaError {
constructor(message: string);
}
declare function RuntimeErr(originalError: Error, str: string, lineNo: number, path: string): never;
//#endregion
//#region src/render.d.ts
declare function render<T extends object>(this: Eta$1, template: string | TemplateFunction,
// template name or template function
data: T, meta?: {
filepath: string;
}): string;
declare function renderAsync<T extends object>(this: Eta$1, template: string | TemplateFunction,
// template name or template function
data: T, meta?: {
filepath: string;
}): Promise<string>;
declare function renderString<T extends object>(this: Eta$1, template: string, data: T): string;
declare function renderStringAsync<T extends object>(this: Eta$1, template: string, data: T): Promise<string>;
//#endregion
//#region src/storage.d.ts
/**
* Handles storage and accessing of values
*
* In this case, we use it to store compiled template functions
* Indexed by their `name` or `filename`
*/
declare class Cacher<T> {
private cache;
constructor(cache: Record<string, T>);
define(key: string, val: T): void;
get(key: string): T;
remove(key: string): void;
reset(): void;
load(cacheObj: Record<string, T>): void;
}
//#endregion
//#region src/internal.d.ts
declare class Eta$1 {
constructor(customConfig?: Partial<EtaConfig>);
config: EtaConfig;
RuntimeErr: typeof RuntimeErr;
compile: typeof compile;
compileToString: typeof compileToString;
compileBody: typeof compileBody;
parse: typeof parse;
render: typeof render;
renderAsync: typeof renderAsync;
renderString: typeof renderString;
renderStringAsync: typeof renderStringAsync;
filepathCache: Record<string, string>;
templatesSync: Cacher<TemplateFunction>;
templatesAsync: Cacher<TemplateFunction>;
resolvePath: null | ((this: Eta$1, template: string, options?: Partial<Options>) => string);
readFile: null | ((this: Eta$1, path: string) => string);
configure(customConfig: Partial<EtaConfig>): void;
withConfig(customConfig: Partial<EtaConfig>): this & {
config: EtaConfig;
};
loadTemplate(name: string, template: string | TemplateFunction,
// template string or template function
options?: {
async: boolean;
}): void;
}
//#endregion
//#region src/parse.d.ts
interface TemplateObject {
t: string;
val: string;
lineNo?: number;
}
type AstObject = string | TemplateObject;
declare function parse(this: Eta$1, str: string): Array<AstObject>;
//#endregion
//#region src/config.d.ts
type trimConfig = "nl" | "slurp" | false;
interface Options {
/** Compile to async function */
async?: boolean;
/** Absolute path to template file */
filepath?: string;
}
interface EtaConfig {
/** Whether or not to automatically XML-escape interpolations. Default true */
autoEscape: boolean;
/** Apply a filter function defined on the class to every interpolation or raw interpolation */
autoFilter: boolean;
/** Configure automatic whitespace trimming. Default `[false, 'nl']` */
autoTrim: trimConfig | [trimConfig, trimConfig];
/** Whether or not to cache templates if `name` or `filename` is passed */
cache: boolean;
/** Holds cache of resolved filepaths. Set to `false` to disable. */
cacheFilepaths: boolean;
/** Object specifying custom tags. Keys are tag prefixes, values are functions which take tag content and return a string. */
customTags: Record<string, (content: string, data: unknown) => string>;
/** Whether to pretty-format error messages (introduces runtime penalties) */
debug: boolean;
/** Function to XML-sanitize interpolations */
escapeFunction: (str: unknown) => string;
/** Function applied to all interpolations when autoFilter is true */
filterFunction: (val: unknown) => string;
/** Name of the function that can be used in template code to output text to the result (like EJS's `outputFunctionName`). */
outputFunctionName: string;
/** Raw JS code inserted in the template function. Useful for declaring global variables for user templates */
functionHeader: string;
/** Parsing options */
parse: {
/** Which prefix to use for evaluation. Default `""`, does not support `"-"` or `"_"` */
exec: string;
/** Which prefix to use for interpolation. Default `"="`, does not support `"-"` or `"_"` */
interpolate: string;
/** Which prefix to use for raw interpolation. Default `"~"`, does not support `"-"` or `"_"` */
raw: string;
};
/** Array of plugins */
plugins: Array<{
processFnString?: (fnString: string, env?: EtaConfig) => string;
processAST?: (ast: AstObject[], env?: EtaConfig) => AstObject[];
processTemplate?: (fnString: string, env?: EtaConfig) => string;
}>;
/** Remove empty lines and whitespace between lines */
rmWhitespace: boolean;
/** Delimiters: by default `['<%', '%>']` */
tags: [string, string];
/** Make data available on the global object instead of varName */
useWith: boolean;
/** Name of the data object. Default `it` */
varName: string;
/** Directory that contains templates */
views?: string;
/** Control template file extension defaults. Default `.eta` */
defaultExtension?: string;
}
//#endregion
//#region src/file-handling.d.ts
declare function readFile(this: Eta$1, path: string): string;
declare function resolvePath(this: Eta$1, templatePath: string, options?: Partial<Options>): string;
//#endregion
//#region src/index.d.ts
declare class Eta extends Eta$1 {
readFile: typeof readFile;
resolvePath: typeof resolvePath;
}
//#endregion
export { Eta, type EtaConfig, EtaError, EtaFileResolutionError, EtaNameResolutionError, EtaParseError, EtaRuntimeError, type Options, type TemplateFunction };
//# sourceMappingURL=index.d.cts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/compile.ts","../src/compile-string.ts","../src/err.ts","../src/render.ts","../src/storage.ts","../src/internal.ts","../src/parse.ts","../src/config.ts","../src/file-handling.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
+188
View File
@@ -0,0 +1,188 @@
//#region src/compile.d.ts
type TemplateFunction = (this: Eta$1, data?: object, options?: Partial<Options>) => string;
/**
* Takes a template string and returns a template function that can be called with (data, config)
*
* @param str - The template string
* @param config - A custom configuration object (optional)
*/
declare function compile(this: Eta$1, str: string, options?: Partial<Options>): TemplateFunction;
//#endregion
//#region src/compile-string.d.ts
/**
* Compiles a template string to a function string. Most often users just use `compile()`, which calls `compileToString` and creates a new function using the result
*/
declare function compileToString(this: Eta$1, str: string, options?: Partial<Options>): string;
/**
* Loops through the AST generated by `parse` and transform each item into JS calls
*
* **Example**
*
* ```js
* let templateAST = ['Hi ', { val: 'it.name', t: 'i' }]
* compileBody.call(Eta, templateAST)
* // => "__eta.res+='Hi '\n__eta.res+=__eta.e(it.name)\n"
* ```
*/
declare function compileBody(this: Eta$1, buff: Array<AstObject>): string;
//#endregion
//#region src/err.d.ts
declare class EtaError extends Error {
constructor(message: string);
}
declare class EtaParseError extends EtaError {
constructor(message: string);
}
declare class EtaRuntimeError extends EtaError {
constructor(message: string);
}
declare class EtaFileResolutionError extends EtaError {
constructor(message: string);
}
declare class EtaNameResolutionError extends EtaError {
constructor(message: string);
}
declare function RuntimeErr(originalError: Error, str: string, lineNo: number, path: string): never;
//#endregion
//#region src/render.d.ts
declare function render<T extends object>(this: Eta$1, template: string | TemplateFunction,
// template name or template function
data: T, meta?: {
filepath: string;
}): string;
declare function renderAsync<T extends object>(this: Eta$1, template: string | TemplateFunction,
// template name or template function
data: T, meta?: {
filepath: string;
}): Promise<string>;
declare function renderString<T extends object>(this: Eta$1, template: string, data: T): string;
declare function renderStringAsync<T extends object>(this: Eta$1, template: string, data: T): Promise<string>;
//#endregion
//#region src/storage.d.ts
/**
* Handles storage and accessing of values
*
* In this case, we use it to store compiled template functions
* Indexed by their `name` or `filename`
*/
declare class Cacher<T> {
private cache;
constructor(cache: Record<string, T>);
define(key: string, val: T): void;
get(key: string): T;
remove(key: string): void;
reset(): void;
load(cacheObj: Record<string, T>): void;
}
//#endregion
//#region src/internal.d.ts
declare class Eta$1 {
constructor(customConfig?: Partial<EtaConfig>);
config: EtaConfig;
RuntimeErr: typeof RuntimeErr;
compile: typeof compile;
compileToString: typeof compileToString;
compileBody: typeof compileBody;
parse: typeof parse;
render: typeof render;
renderAsync: typeof renderAsync;
renderString: typeof renderString;
renderStringAsync: typeof renderStringAsync;
filepathCache: Record<string, string>;
templatesSync: Cacher<TemplateFunction>;
templatesAsync: Cacher<TemplateFunction>;
resolvePath: null | ((this: Eta$1, template: string, options?: Partial<Options>) => string);
readFile: null | ((this: Eta$1, path: string) => string);
configure(customConfig: Partial<EtaConfig>): void;
withConfig(customConfig: Partial<EtaConfig>): this & {
config: EtaConfig;
};
loadTemplate(name: string, template: string | TemplateFunction,
// template string or template function
options?: {
async: boolean;
}): void;
}
//#endregion
//#region src/parse.d.ts
interface TemplateObject {
t: string;
val: string;
lineNo?: number;
}
type AstObject = string | TemplateObject;
declare function parse(this: Eta$1, str: string): Array<AstObject>;
//#endregion
//#region src/config.d.ts
type trimConfig = "nl" | "slurp" | false;
interface Options {
/** Compile to async function */
async?: boolean;
/** Absolute path to template file */
filepath?: string;
}
interface EtaConfig {
/** Whether or not to automatically XML-escape interpolations. Default true */
autoEscape: boolean;
/** Apply a filter function defined on the class to every interpolation or raw interpolation */
autoFilter: boolean;
/** Configure automatic whitespace trimming. Default `[false, 'nl']` */
autoTrim: trimConfig | [trimConfig, trimConfig];
/** Whether or not to cache templates if `name` or `filename` is passed */
cache: boolean;
/** Holds cache of resolved filepaths. Set to `false` to disable. */
cacheFilepaths: boolean;
/** Object specifying custom tags. Keys are tag prefixes, values are functions which take tag content and return a string. */
customTags: Record<string, (content: string, data: unknown) => string>;
/** Whether to pretty-format error messages (introduces runtime penalties) */
debug: boolean;
/** Function to XML-sanitize interpolations */
escapeFunction: (str: unknown) => string;
/** Function applied to all interpolations when autoFilter is true */
filterFunction: (val: unknown) => string;
/** Name of the function that can be used in template code to output text to the result (like EJS's `outputFunctionName`). */
outputFunctionName: string;
/** Raw JS code inserted in the template function. Useful for declaring global variables for user templates */
functionHeader: string;
/** Parsing options */
parse: {
/** Which prefix to use for evaluation. Default `""`, does not support `"-"` or `"_"` */
exec: string;
/** Which prefix to use for interpolation. Default `"="`, does not support `"-"` or `"_"` */
interpolate: string;
/** Which prefix to use for raw interpolation. Default `"~"`, does not support `"-"` or `"_"` */
raw: string;
};
/** Array of plugins */
plugins: Array<{
processFnString?: (fnString: string, env?: EtaConfig) => string;
processAST?: (ast: AstObject[], env?: EtaConfig) => AstObject[];
processTemplate?: (fnString: string, env?: EtaConfig) => string;
}>;
/** Remove empty lines and whitespace between lines */
rmWhitespace: boolean;
/** Delimiters: by default `['<%', '%>']` */
tags: [string, string];
/** Make data available on the global object instead of varName */
useWith: boolean;
/** Name of the data object. Default `it` */
varName: string;
/** Directory that contains templates */
views?: string;
/** Control template file extension defaults. Default `.eta` */
defaultExtension?: string;
}
//#endregion
//#region src/file-handling.d.ts
declare function readFile(this: Eta$1, path: string): string;
declare function resolvePath(this: Eta$1, templatePath: string, options?: Partial<Options>): string;
//#endregion
//#region src/index.d.ts
declare class Eta extends Eta$1 {
readFile: typeof readFile;
resolvePath: typeof resolvePath;
}
//#endregion
export { Eta, type EtaConfig, EtaError, EtaFileResolutionError, EtaNameResolutionError, EtaParseError, EtaRuntimeError, type Options, type TemplateFunction };
//# sourceMappingURL=index.d.mts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/compile.ts","../src/compile-string.ts","../src/err.ts","../src/render.ts","../src/storage.ts","../src/internal.ts","../src/parse.ts","../src/config.ts","../src/file-handling.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
+528
View File
@@ -0,0 +1,528 @@
import * as fs from "node:fs";
import * as path from "node:path";
//#region src/err.ts
var EtaError = class extends Error {
constructor(message) {
super(message);
this.name = "Eta Error";
}
};
var EtaParseError = class extends EtaError {
constructor(message) {
super(message);
this.name = "EtaParser Error";
}
};
var EtaRuntimeError = class extends EtaError {
constructor(message) {
super(message);
this.name = "EtaRuntime Error";
}
};
var EtaFileResolutionError = class extends EtaError {
constructor(message) {
super(message);
this.name = "EtaFileResolution Error";
}
};
var EtaNameResolutionError = class extends EtaError {
constructor(message) {
super(message);
this.name = "EtaNameResolution Error";
}
};
/**
* Throws an EtaError with a nicely formatted error and message showing where in the template the error occurred.
*/
function ParseErr(message, str, indx) {
const whitespace = str.slice(0, indx).split(/\n/);
const lineNo = whitespace.length;
const colNo = whitespace[lineNo - 1].length + 1;
message += " at line " + lineNo + " col " + colNo + ":\n\n " + str.split(/\n/)[lineNo - 1] + "\n " + Array(colNo).join(" ") + "^";
throw new EtaParseError(message);
}
function RuntimeErr(originalError, str, lineNo, path$1) {
const lines = str.split("\n");
const start = Math.max(lineNo - 3, 0);
const end = Math.min(lines.length, lineNo + 3);
const filename = path$1;
const context = lines.slice(start, end).map((line, i) => {
const curr = i + start + 1;
return (curr === lineNo ? " >> " : " ") + curr + "| " + line;
}).join("\n");
const err = new EtaRuntimeError((filename ? filename + ":" + lineNo + "\n" : "line " + lineNo + "\n") + context + "\n\n" + originalError.message);
err.name = originalError.name;
err.cause = originalError;
throw err;
}
//#endregion
//#region src/file-handling.ts
function readFile(path$1) {
let res = "";
try {
res = fs.readFileSync(path$1, "utf8");
} catch (err) {
if (err?.code === "ENOENT") throw new EtaFileResolutionError(`Could not find template: ${path$1}`);
else throw err;
}
return res;
}
function resolvePath(templatePath, options) {
let resolvedFilePath = "";
const views = this.config.views;
if (!views) throw new EtaFileResolutionError("Views directory is not defined");
const baseFilePath = options?.filepath;
const defaultExtension = this.config.defaultExtension === void 0 ? ".eta" : this.config.defaultExtension;
const cacheIndex = JSON.stringify({
filename: baseFilePath,
path: templatePath,
views: this.config.views
});
templatePath += path.extname(templatePath) ? "" : defaultExtension;
if (baseFilePath) {
if (this.config.cacheFilepaths && this.filepathCache[cacheIndex]) return this.filepathCache[cacheIndex];
if (absolutePathRegExp.exec(templatePath)?.length) {
const formattedPath = templatePath.replace(/^\/*|^\\*/, "");
resolvedFilePath = path.join(views, formattedPath);
} else resolvedFilePath = path.join(path.dirname(baseFilePath), templatePath);
} else resolvedFilePath = path.join(views, templatePath);
if (dirIsChild(views, resolvedFilePath)) {
if (baseFilePath && this.config.cacheFilepaths) this.filepathCache[cacheIndex] = resolvedFilePath;
return resolvedFilePath;
} else throw new EtaFileResolutionError(`Template '${templatePath}' is not in the views directory`);
}
function dirIsChild(parent, dir) {
const relative = path.relative(parent, dir);
return relative && !relative.startsWith("..") && !path.isAbsolute(relative);
}
const absolutePathRegExp = /^\\|^\//;
//#endregion
//#region src/compile.ts
/* istanbul ignore next */
const AsyncFunction = (async () => {}).constructor;
/**
* Takes a template string and returns a template function that can be called with (data, config)
*
* @param str - The template string
* @param config - A custom configuration object (optional)
*/
function compile(str, options) {
const config = this.config;
const ctor = options?.async ? AsyncFunction : Function;
try {
return new ctor(config.varName, "options", this.compileToString.call(this, str, options));
} catch (e) {
if (e instanceof SyntaxError) throw new EtaParseError("Bad template syntax\n\n" + e.message + "\n" + Array(e.message.length + 1).join("=") + "\n" + this.compileToString.call(this, str, options) + "\n");
else throw e;
}
}
//#endregion
//#region src/compile-string.ts
/**
* Compiles a template string to a function string. Most often users just use `compile()`, which calls `compileToString` and creates a new function using the result
*/
function compileToString(str, options) {
const config = this.config;
const isAsync = options?.async;
const compileBody$1 = this.compileBody;
const buffer = this.parse.call(this, str);
let res = `${config.functionHeader}
let include = (__eta_t, __eta_d) => this.render(__eta_t, {...${config.varName}, ...(__eta_d ?? {})}, options);
let includeAsync = (__eta_t, __eta_d) => this.renderAsync(__eta_t, {...${config.varName}, ...(__eta_d ?? {})}, options);
let __eta = {res: "", e: this.config.escapeFunction, f: this.config.filterFunction, blocks: {}${config.debug ? ", line: 1, templateStr: \"" + str.replace(/\\|"/g, "\\$&").replace(/\r\n|\n|\r/g, "\\n") + "\"" : ""}};
function layout(path, data) {
__eta.layout = path;
__eta.layoutData = data;
}${config.debug ? "try {" : ""}${config.useWith ? "with(" + config.varName + "||{}){" : ""}
function ${config.outputFunctionName}(s){__eta.res+=s;}
function capture(fn){const s=__eta.res;__eta.res='';try{fn();return __eta.res}finally{__eta.res=s;}}
async function captureAsync(fn){const s=__eta.res;__eta.res='';try{await fn();return __eta.res}finally{__eta.res=s;}}
function block(name,fn){if(__eta.layout){if(fn){__eta.blocks[name]=capture(fn);}return '';}const b=${config.varName}.__blocks||{};if(name in b){return b[name];}return fn?capture(fn):'';}
async function blockAsync(name,fn){if(__eta.layout){if(fn){__eta.blocks[name]=await captureAsync(fn);}return '';}const b=${config.varName}.__blocks||{};if(name in b){return b[name];}return fn?await captureAsync(fn):'';}
${compileBody$1.call(this, buffer)}
if (__eta.layout) {
__eta.res = ${isAsync ? "await includeAsync" : "include"} (__eta.layout, {...${config.varName}, body: __eta.res, ...__eta.layoutData, __blocks: __eta.blocks});
}
${config.useWith ? "}" : ""}${config.debug ? "} catch (e) { this.RuntimeErr(e, __eta.templateStr, __eta.line, options.filepath) }" : ""}
return __eta.res;
`;
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
const plugin = config.plugins[i];
if (plugin.processFnString) res = plugin.processFnString(res, config);
}
return res;
}
/**
* Loops through the AST generated by `parse` and transform each item into JS calls
*
* **Example**
*
* ```js
* let templateAST = ['Hi ', { val: 'it.name', t: 'i' }]
* compileBody.call(Eta, templateAST)
* // => "__eta.res+='Hi '\n__eta.res+=__eta.e(it.name)\n"
* ```
*/
function compileBody(buff) {
const config = this.config;
let i = 0;
const buffLength = buff.length;
let returnStr = "";
for (; i < buffLength; i++) {
const currentBlock = buff[i];
if (typeof currentBlock === "string") returnStr += "__eta.res+='" + currentBlock + "';\n";
else {
const type = currentBlock.t;
let content = currentBlock.val || "";
if (config.debug) returnStr += "__eta.line=" + currentBlock.lineNo + "\n";
if (type === "r") {
if (config.autoFilter) content = "__eta.f(" + content + ")";
returnStr += "__eta.res+=" + content + ";\n";
} else if (type === "i") {
if (config.autoFilter) content = "__eta.f(" + content + ")";
if (config.autoEscape) content = "__eta.e(" + content + ")";
returnStr += "__eta.res+=" + content + ";\n";
} else if (type === "e") returnStr += content + "\n";
else if (Object.hasOwn(config.customTags, type)) returnStr += `__eta.res+=this.config.customTags[${JSON.stringify(type)}](${JSON.stringify(content)},${config.varName});\n`;
}
}
return returnStr;
}
//#endregion
//#region src/utils.ts
/**
* Takes a string within a template and trims it, based on the preceding tag's whitespace control and `config.autoTrim`
*/
function trimWS(str, config, wsLeft, wsRight) {
let leftTrim;
let rightTrim;
if (Array.isArray(config.autoTrim)) {
leftTrim = config.autoTrim[1];
rightTrim = config.autoTrim[0];
} else leftTrim = rightTrim = config.autoTrim;
if (wsLeft || wsLeft === false) leftTrim = wsLeft;
if (wsRight || wsRight === false) rightTrim = wsRight;
if (!rightTrim && !leftTrim) return str;
if (leftTrim === "slurp" && rightTrim === "slurp") return str.trim();
if (leftTrim === "_" || leftTrim === "slurp") str = str.trimStart();
else if (leftTrim === "-" || leftTrim === "nl") str = str.replace(/^(?:\r\n|\n|\r)/, "");
if (rightTrim === "_" || rightTrim === "slurp") str = str.trimEnd();
else if (rightTrim === "-" || rightTrim === "nl") str = str.replace(/(?:\r\n|\n|\r)$/, "");
return str;
}
/**
* A map of special HTML characters to their XML-escaped equivalents
*/
const escMap = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
"\"": "&quot;",
"'": "&#39;"
};
function replaceChar(s) {
return escMap[s];
}
/**
* XML-escapes an input value after converting it to a string
*
* @param str - Input value (usually a string)
* @returns XML-escaped string
*/
function XMLEscape(str) {
const newStr = String(str);
if (/[&<>"']/.test(newStr)) return newStr.replace(/[&<>"']/g, replaceChar);
else return newStr;
}
//#endregion
//#region src/config.ts
/** Eta's base (global) configuration */
const defaultConfig = {
autoEscape: true,
autoFilter: false,
autoTrim: [false, "nl"],
cache: false,
cacheFilepaths: true,
customTags: {},
debug: false,
escapeFunction: XMLEscape,
filterFunction: (val) => String(val),
outputFunctionName: "output",
functionHeader: "",
parse: {
exec: "",
interpolate: "=",
raw: "~"
},
plugins: [],
rmWhitespace: false,
tags: ["<%", "%>"],
useWith: false,
varName: "it",
defaultExtension: ".eta"
};
//#endregion
//#region src/parse.ts
const templateLitReg = /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g;
const singleQuoteReg = /'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g;
const doubleQuoteReg = /"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g;
/** Escape special regular expression characters inside a string */
function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&");
}
function getLineNo(str, index) {
return str.slice(0, index).split("\n").length;
}
function parse(str) {
const config = this.config;
let buffer = [];
let trimLeftOfNextStr = false;
let lastIndex = 0;
const parseOptions = config.parse;
const customTagPrefixes = Object.keys(config.customTags);
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
const plugin = config.plugins[i];
if (plugin.processTemplate) str = plugin.processTemplate(str, config);
}
if (config.rmWhitespace) str = str.replace(/[\r\n]+/g, "\n").replace(/^\s+|\s+$/gm, "");
templateLitReg.lastIndex = 0;
singleQuoteReg.lastIndex = 0;
doubleQuoteReg.lastIndex = 0;
function pushString(strng, shouldTrimRightOfString) {
if (strng) {
strng = trimWS(strng, config, trimLeftOfNextStr, shouldTrimRightOfString);
if (strng) {
strng = strng.replace(/\\|'/g, "\\$&").replace(/\r\n|\n|\r/g, "\\n");
buffer.push(strng);
}
}
}
const prefixes = [
parseOptions.exec,
parseOptions.interpolate,
parseOptions.raw,
...customTagPrefixes
].reduce((accumulator, prefix) => {
if (accumulator && prefix) return accumulator + "|" + escapeRegExp(prefix);
else if (prefix) return escapeRegExp(prefix);
else return accumulator;
}, "");
const parseOpenReg = new RegExp(escapeRegExp(config.tags[0]) + "(-|_)?\\s*(" + prefixes + ")?\\s*", "g");
const parseCloseReg = new RegExp("'|\"|`|\\/\\*|(\\s*(-|_)?" + escapeRegExp(config.tags[1]) + ")", "g");
let m;
while (m = parseOpenReg.exec(str)) {
const precedingString = str.slice(lastIndex, m.index);
lastIndex = m[0].length + m.index;
const wsLeft = m[1];
const prefix = m[2] || "";
pushString(precedingString, wsLeft);
parseCloseReg.lastIndex = lastIndex;
let closeTag;
let currentObj = false;
while (closeTag = parseCloseReg.exec(str)) if (closeTag[1]) {
const content = str.slice(lastIndex, closeTag.index);
parseOpenReg.lastIndex = lastIndex = parseCloseReg.lastIndex;
trimLeftOfNextStr = closeTag[2];
currentObj = {
t: prefix === parseOptions.exec ? "e" : prefix === parseOptions.raw ? "r" : prefix === parseOptions.interpolate ? "i" : customTagPrefixes.includes(prefix) ? prefix : "",
val: content
};
break;
} else {
const char = closeTag[0];
if (char === "/*") {
const commentCloseInd = str.indexOf("*/", parseCloseReg.lastIndex);
if (commentCloseInd === -1) ParseErr("unclosed comment", str, closeTag.index);
parseCloseReg.lastIndex = commentCloseInd;
} else if (char === "'") {
singleQuoteReg.lastIndex = closeTag.index;
if (singleQuoteReg.exec(str)) parseCloseReg.lastIndex = singleQuoteReg.lastIndex;
else ParseErr("unclosed string", str, closeTag.index);
} else if (char === "\"") {
doubleQuoteReg.lastIndex = closeTag.index;
if (doubleQuoteReg.exec(str)) parseCloseReg.lastIndex = doubleQuoteReg.lastIndex;
else ParseErr("unclosed string", str, closeTag.index);
} else if (char === "`") {
templateLitReg.lastIndex = closeTag.index;
if (templateLitReg.exec(str)) parseCloseReg.lastIndex = templateLitReg.lastIndex;
else ParseErr("unclosed string", str, closeTag.index);
}
}
if (currentObj) {
if (config.debug) currentObj.lineNo = getLineNo(str, m.index);
buffer.push(currentObj);
} else ParseErr("unclosed tag", str, m.index);
}
pushString(str.slice(lastIndex, str.length), false);
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
const plugin = config.plugins[i];
if (plugin.processAST) buffer = plugin.processAST(buffer, config);
}
return buffer;
}
//#endregion
//#region src/render.ts
function handleCache(template, options) {
const templateStore = options?.async ? this.templatesAsync : this.templatesSync;
if (this.resolvePath && this.readFile && !template.startsWith("@")) {
const templatePath = options.filepath;
const cachedTemplate = templateStore.get(templatePath);
if (this.config.cache && cachedTemplate) return cachedTemplate;
else {
const templateString = this.readFile(templatePath);
const templateFn = this.compile(templateString, options);
if (this.config.cache) templateStore.define(templatePath, templateFn);
return templateFn;
}
} else {
const cachedTemplate = templateStore.get(template);
if (cachedTemplate) return cachedTemplate;
else throw new EtaNameResolutionError(`Failed to get template '${template}'`);
}
}
function render(template, data, meta) {
let templateFn;
const options = {
...meta,
async: false
};
if (typeof template === "string") {
if (this.resolvePath && this.readFile && !template.startsWith("@")) options.filepath = this.resolvePath(template, options);
templateFn = handleCache.call(this, template, options);
} else templateFn = template;
return templateFn.call(this, data, options);
}
function renderAsync(template, data, meta) {
let templateFn;
const options = {
...meta,
async: true
};
if (typeof template === "string") {
if (this.resolvePath && this.readFile && !template.startsWith("@")) options.filepath = this.resolvePath(template, options);
templateFn = handleCache.call(this, template, options);
} else templateFn = template;
const res = templateFn.call(this, data, options);
return Promise.resolve(res);
}
function renderString(template, data) {
const templateFn = this.compile(template, { async: false });
return render.call(this, templateFn, data);
}
function renderStringAsync(template, data) {
const templateFn = this.compile(template, { async: true });
return renderAsync.call(this, templateFn, data);
}
//#endregion
//#region src/storage.ts
/**
* Handles storage and accessing of values
*
* In this case, we use it to store compiled template functions
* Indexed by their `name` or `filename`
*/
var Cacher = class {
constructor(cache) {
this.cache = cache;
}
define(key, val) {
this.cache[key] = val;
}
get(key) {
return this.cache[key];
}
remove(key) {
delete this.cache[key];
}
reset() {
this.cache = {};
}
load(cacheObj) {
this.cache = {
...this.cache,
...cacheObj
};
}
};
//#endregion
//#region src/internal.ts
var Eta$1 = class {
constructor(customConfig) {
if (customConfig) this.config = {
...defaultConfig,
...customConfig
};
else this.config = { ...defaultConfig };
const reserved = [
this.config.parse.exec,
this.config.parse.interpolate,
this.config.parse.raw,
"-",
"_"
];
for (const prefix of Object.keys(this.config.customTags)) if (reserved.includes(prefix)) throw new EtaError(`Custom tag prefix "${prefix}" conflicts with a built-in prefix`);
}
config;
RuntimeErr = RuntimeErr;
compile = compile;
compileToString = compileToString;
compileBody = compileBody;
parse = parse;
render = render;
renderAsync = renderAsync;
renderString = renderString;
renderStringAsync = renderStringAsync;
filepathCache = {};
templatesSync = new Cacher({});
templatesAsync = new Cacher({});
resolvePath = null;
readFile = null;
configure(customConfig) {
this.config = {
...this.config,
...customConfig
};
}
withConfig(customConfig) {
return {
...this,
config: {
...this.config,
...customConfig
}
};
}
loadTemplate(name, template, options) {
if (typeof template === "string") (options?.async ? this.templatesAsync : this.templatesSync).define(name, this.compile(template, options));
else {
let templates = this.templatesSync;
if (template.constructor.name === "AsyncFunction" || options?.async) templates = this.templatesAsync;
templates.define(name, template);
}
}
};
//#endregion
//#region src/index.ts
var Eta = class extends Eta$1 {
readFile = readFile;
resolvePath = resolvePath;
};
//#endregion
export { Eta, EtaError, EtaFileResolutionError, EtaNameResolutionError, EtaParseError, EtaRuntimeError };
//# sourceMappingURL=index.mjs.map
+1
View File
File diff suppressed because one or more lines are too long