diff --git a/deno_dist/README.md b/deno_dist/README.md
index 647da37..7ee6e57 100644
--- a/deno_dist/README.md
+++ b/deno_dist/README.md
@@ -12,7 +12,7 @@
-[logo]: https://img.shields.io/badge/all_contributors-7-orange.svg 'Number of contributors on All-Contributors'
+[logo]: https://img.shields.io/badge/all_contributors-8-orange.svg 'Number of contributors on All-Contributors'
@@ -134,6 +134,45 @@ Simply put, Eta is super: super lightweight, super fast, super powerful, and sup
Additionally, Eta is a letter of the Greek alphabet (it stands for all sorts of cool things in various mathematical fields, including efficiency) and is three letters long (perfect for a file extension).
+## Integrations
+
+
+
+ ESLint
+
+
+ [eslint-plugin-eta](https://github.com/eta-dev/eslint-plugin-eta) was created to provide an ESLint processor so you can lint your Eta templates.
+
+
+
+
+
+ CLI
+
+
+ An official Eta CLI exists called [etajs-cli](https://github.com/eta-dev/etajs-cli).
+
+
+
+
+
+ Webpack
+
+
+ Currently there is no official Webpack integration but [@clshortfuse](https://github.com/clshortfuse) shared the loader he uses:
+ ```javascript
+ {
+ loader: 'html-loader',
+ options: {
+ preprocessor(content, loaderContext) {
+ return eta.render(content, {}, { filename: loaderContext.resourcePath });
+ },
+ },
+ }
+ ```
+
+
+
## 📜 Docs
We know nobody reads through the long and boring documentation in the ReadMe anyway, so head over to the documentation website:
@@ -216,6 +255,9 @@ Made with ❤ by [@nebrelbug](https://github.com/eta-dev) and all these wonderfu
shadowtime2000 💻 🤔 |
Hamza Hamidi 📖 |
+
+ Calum Knott 🤔 |
+
diff --git a/deno_dist/browser.ts b/deno_dist/browser.ts
index efb2e48..7df6463 100644
--- a/deno_dist/browser.ts
+++ b/deno_dist/browser.ts
@@ -1,11 +1,6 @@
-export { default as compileToString } from "./compile-string.ts";
-export { default as compile } from "./compile.ts";
-export { default as parse } from "./parse.ts";
-export { default as render } from "./render.ts";
-export { templates } from "./containers.ts";
-export {
- config,
- config as defaultConfig,
- configure,
- getConfig,
-} from "./config.ts";
+export { default as compileToString } from './compile-string.ts'
+export { default as compile } from './compile.ts'
+export { default as parse } from './parse.ts'
+export { default as render, renderAsync } from './render.ts'
+export { templates } from './containers.ts'
+export { config, config as defaultConfig, getConfig, configure } from './config.ts'
diff --git a/deno_dist/compile-string.ts b/deno_dist/compile-string.ts
index 797e5d9..b20bea5 100644
--- a/deno_dist/compile-string.ts
+++ b/deno_dist/compile-string.ts
@@ -1,9 +1,9 @@
-import Parse from "./parse.ts";
+import Parse from './parse.ts'
/* TYPES */
-import type { EtaConfig } from "./config.ts";
-import type { AstObject } from "./parse.ts";
+import type { EtaConfig } from './config.ts'
+import type { AstObject } from './parse.ts'
/* END TYPES */
@@ -18,40 +18,38 @@ import type { AstObject } from "./parse.ts";
* ```
*/
-export default function compileToString(
- str: string,
- config: EtaConfig,
-): string {
- var buffer: Array = Parse(str, config);
-
- var res = "var tR='',__l,__lP" +
- (config.include ? ",include=E.include.bind(E)" : "") +
- (config.includeFile ? ",includeFile=E.includeFile.bind(E)" : "") +
- "\nfunction layout(p,d){__l=p;__lP=d}\n" +
- (config.useWith ? "with(" + config.varName + "||{}){" : "") +
+export default function compileToString(str: string, config: EtaConfig): string {
+ var buffer: Array = Parse(str, config)
+
+ var res =
+ "var tR='',__l,__lP" +
+ (config.include ? ',include=E.include.bind(E)' : '') +
+ (config.includeFile ? ',includeFile=E.includeFile.bind(E)' : '') +
+ '\nfunction layout(p,d){__l=p;__lP=d}\n' +
+ (config.useWith ? 'with(' + config.varName + '||{}){' : '') +
compileScope(buffer, config) +
(config.includeFile
- ? "if(__l)tR=" +
- (config.async ? "await " : "") +
+ ? 'if(__l)tR=' +
+ (config.async ? 'await ' : '') +
`includeFile(__l,Object.assign(${config.varName},{body:tR},__lP))\n`
: config.include
- ? "if(__l)tR=" +
- (config.async ? "await " : "") +
+ ? 'if(__l)tR=' +
+ (config.async ? 'await ' : '') +
`include(__l,Object.assign(${config.varName},{body:tR},__lP))\n`
- : "") +
- "if(cb){cb(null,tR)} return tR" +
- (config.useWith ? "}" : "");
+ : '') +
+ 'if(cb){cb(null,tR)} return tR' +
+ (config.useWith ? '}' : '')
if (config.plugins) {
for (var i = 0; i < config.plugins.length; i++) {
- var plugin = config.plugins[i];
+ var plugin = config.plugins[i]
if (plugin.processFnString) {
- res = plugin.processFnString(res, config);
+ res = plugin.processFnString(res, config)
}
}
}
- return res;
+ return res
}
/**
@@ -68,47 +66,47 @@ export default function compileToString(
*/
function compileScope(buff: Array, config: EtaConfig) {
- var i = 0;
- var buffLength = buff.length;
- var returnStr = "";
+ var i = 0
+ var buffLength = buff.length
+ var returnStr = ''
for (i; i < buffLength; i++) {
- var currentBlock = buff[i];
- if (typeof currentBlock === "string") {
- var str = currentBlock;
+ var currentBlock = buff[i]
+ if (typeof currentBlock === 'string') {
+ var str = currentBlock
// we know string exists
- returnStr += "tR+='" + str + "'\n";
+ returnStr += "tR+='" + str + "'\n"
} else {
- var type = currentBlock.t; // ~, s, !, ?, r
- var content = currentBlock.val || "";
+ var type = currentBlock.t // ~, s, !, ?, r
+ var content = currentBlock.val || ''
- if (type === "r") {
+ if (type === 'r') {
// raw
if (config.filter) {
- content = "E.filter(" + content + ")";
+ content = 'E.filter(' + content + ')'
}
- returnStr += "tR+=" + content + "\n";
- } else if (type === "i") {
+ returnStr += 'tR+=' + content + '\n'
+ } else if (type === 'i') {
// interpolate
if (config.filter) {
- content = "E.filter(" + content + ")";
+ content = 'E.filter(' + content + ')'
}
if (config.autoEscape) {
- content = "E.e(" + content + ")";
+ content = 'E.e(' + content + ')'
}
- returnStr += "tR+=" + content + "\n";
+ returnStr += 'tR+=' + content + '\n'
// reference
- } else if (type === "e") {
+ } else if (type === 'e') {
// execute
- returnStr += content + "\n"; // you need a \n in case you have <% } %>
+ returnStr += content + '\n' // you need a \n in case you have <% } %>
}
}
}
- return returnStr;
+ return returnStr
}
diff --git a/deno_dist/compile.ts b/deno_dist/compile.ts
index 32d4170..39e078a 100644
--- a/deno_dist/compile.ts
+++ b/deno_dist/compile.ts
@@ -1,17 +1,13 @@
-import compileToString from "./compile-string.ts";
-import { getConfig } from "./config.ts";
-import EtaErr from "./err.ts";
+import compileToString from './compile-string.ts'
+import { getConfig } from './config.ts'
+import EtaErr from './err.ts'
/* TYPES */
-import type { EtaConfig, PartialConfig } from "./config.ts";
-import type { CallbackFn } from "./file-handlers.ts";
-import { getAsyncFunctionConstructor } from "./polyfills.ts";
-export type TemplateFunction = (
- data: object,
- config: EtaConfig,
- cb?: CallbackFn,
-) => string;
+import type { EtaConfig, PartialConfig } from './config.ts'
+import type { CallbackFn } from './file-handlers.ts'
+import { getAsyncFunctionConstructor } from './polyfills.ts'
+export type TemplateFunction = (data: object, config: EtaConfig, cb?: CallbackFn) => string
/* END TYPES */
@@ -31,41 +27,38 @@ export type TemplateFunction = (
* ```
*/
-export default function compile(
- str: string,
- config?: PartialConfig,
-): TemplateFunction {
- var options: EtaConfig = getConfig(config || {});
- var ctor; // constructor
+export default function compile(str: string, config?: PartialConfig): TemplateFunction {
+ var options: EtaConfig = getConfig(config || {})
+ var ctor // constructor
/* ASYNC HANDLING */
// The below code is modified from mde/ejs. All credit should go to them.
if (options.async) {
- ctor = getAsyncFunctionConstructor() as FunctionConstructor;
+ ctor = getAsyncFunctionConstructor() as FunctionConstructor
} else {
- ctor = Function;
+ ctor = Function
}
/* END ASYNC HANDLING */
try {
return new ctor(
options.varName,
- "E", // EtaConfig
- "cb", // optional callback
- compileToString(str, options),
- ) as TemplateFunction; // eslint-disable-line no-new-func
+ 'E', // EtaConfig
+ 'cb', // optional callback
+ compileToString(str, options)
+ ) as TemplateFunction // eslint-disable-line no-new-func
} catch (e) {
if (e instanceof SyntaxError) {
throw EtaErr(
- "Bad template syntax\n\n" +
+ 'Bad template syntax\n\n' +
e.message +
- "\n" +
- Array(e.message.length + 1).join("=") +
- "\n" +
+ '\n' +
+ Array(e.message.length + 1).join('=') +
+ '\n' +
compileToString(str, options) +
- "\n", // This will put an extra newline before the callstack for extra readability
- );
+ '\n' // This will put an extra newline before the callstack for extra readability
+ )
} else {
- throw e;
+ throw e
}
}
}
diff --git a/deno_dist/config.ts b/deno_dist/config.ts
index 21a8296..7945542 100644
--- a/deno_dist/config.ts
+++ b/deno_dist/config.ts
@@ -1,101 +1,95 @@
-import { templates } from "./containers.ts";
-import { copyProps, XMLEscape } from "./utils.ts";
-import EtaErr from "./err.ts";
+import { templates } from './containers.ts'
+import { copyProps, XMLEscape } from './utils.ts'
+import EtaErr from './err.ts'
/* TYPES */
-import type { TemplateFunction } from "./compile.ts";
-import type { Cacher } from "./storage.ts";
+import type { TemplateFunction } from './compile.ts'
+import type { Cacher } from './storage.ts'
-type trimConfig = "nl" | "slurp" | false;
+type trimConfig = 'nl' | 'slurp' | false
export interface EtaConfig {
/** Whether or not to automatically XML-escape interpolations. Default true */
- autoEscape: boolean;
+ autoEscape: boolean
/** Configure automatic whitespace trimming. Default `[false, 'nl']` */
- autoTrim: trimConfig | [trimConfig, trimConfig];
+ autoTrim: trimConfig | [trimConfig, trimConfig]
/** Compile to async function */
- async: boolean;
+ async: boolean
/** Whether or not to cache templates if `name` or `filename` is passed */
- cache: boolean;
+ cache: boolean
/** XML-escaping function */
- e: (str: string) => string;
+ e: (str: string) => string
/** Parsing options */
parse: {
/** Which prefix to use for evaluation. Default `""` */
- exec: string;
+ exec: string
/** Which prefix to use for interpolation. Default `"="` */
- interpolate: string;
+ interpolate: string
/** Which prefix to use for raw interpolation. Default `"~"` */
- raw: string;
- };
+ raw: string
+ }
/** Array of plugins */
- plugins: Array<
- {
- processFnString?: Function;
- processAST?: Function;
- processTemplate?: Function;
- }
- >;
+ plugins: Array<{ processFnString?: Function; processAST?: Function; processTemplate?: Function }>
/** Remove all safe-to-remove whitespace */
- rmWhitespace: boolean;
+ rmWhitespace: boolean
/** Delimiters: by default `['<%', '%>']` */
- tags: [string, string];
+ tags: [string, string]
/** Holds template cache */
- templates: Cacher;
+ templates: Cacher
/** Name of the data object. Default `it` */
- varName: string;
+ varName: string
/** Absolute path to template file */
- filename?: string;
+ filename?: string
/** Holds cache of resolved filepaths. Set to `false` to disable */
- filepathCache?: Record | false;
+ filepathCache?: Record | false
/** A filter function applied to every interpolation or raw interpolation */
- filter?: Function;
+ filter?: Function
/** Function to include templates by name */
- include?: Function;
+ include?: Function
/** Function to include templates by filepath */
- includeFile?: Function;
+ includeFile?: Function
/** Name of template */
- name?: string;
+ name?: string
/** Where should absolute paths begin? Default '/' */
- root?: string;
+ root?: string
/** Make data available on the global object instead of varName */
- useWith?: boolean;
+ useWith?: boolean
/** Whether or not to cache templates if `name` or `filename` is passed: duplicate of `cache` */
- "view cache"?: boolean;
+ 'view cache'?: boolean
/** Directory or directories that contain templates */
- views?: string | Array;
+ views?: string | Array
- [index: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
+ [index: string]: any // eslint-disable-line @typescript-eslint/no-explicit-any
}
export interface EtaConfigWithFilename extends EtaConfig {
- filename: string;
+ filename: string
}
-export type PartialConfig = Partial;
+export type PartialConfig = Partial
/* END TYPES */
@@ -105,38 +99,34 @@ export type PartialConfig = Partial;
* Called like `include(templateNameOrPath, data)`
*/
-function includeHelper(
- this: EtaConfig,
- templateNameOrPath: string,
- data: object,
-): string {
- var template = this.templates.get(templateNameOrPath);
+function includeHelper(this: EtaConfig, templateNameOrPath: string, data: object): string {
+ var template = this.templates.get(templateNameOrPath)
if (!template) {
- throw EtaErr('Could not fetch template "' + templateNameOrPath + '"');
+ throw EtaErr('Could not fetch template "' + templateNameOrPath + '"')
}
- return template(data, this);
+ return template(data, this)
}
/** Eta's base (global) configuration */
var config: EtaConfig = {
async: false,
autoEscape: true,
- autoTrim: [false, "nl"],
+ autoTrim: [false, 'nl'],
cache: false,
e: XMLEscape,
include: includeHelper,
parse: {
- exec: "",
- interpolate: "=",
- raw: "~",
+ exec: '',
+ interpolate: '=',
+ raw: '~'
},
plugins: [],
rmWhitespace: false,
- tags: ["<%", "%>"],
+ tags: ['<%', '%>'],
templates: templates,
useWith: false,
- varName: "it",
-};
+ varName: 'it'
+}
/**
* Takes one or two partial (not necessarily complete) configuration objects, merges them 1 layer deep into eta.config, and returns the result
@@ -154,24 +144,24 @@ var config: EtaConfig = {
function getConfig(override: PartialConfig, baseConfig?: EtaConfig): EtaConfig {
// TODO: run more tests on this
- var res: PartialConfig = {}; // Linked
- copyProps(res, config); // Creates deep clone of eta.config, 1 layer deep
+ var res: PartialConfig = {} // Linked
+ copyProps(res, config) // Creates deep clone of eta.config, 1 layer deep
if (baseConfig) {
- copyProps(res, baseConfig);
+ copyProps(res, baseConfig)
}
if (override) {
- copyProps(res, override);
+ copyProps(res, override)
}
- return res as EtaConfig;
+ return res as EtaConfig
}
/** Update Eta's base config */
function configure(options: PartialConfig): Partial {
- return copyProps(config, options);
+ return copyProps(config, options)
}
-export { config, configure, getConfig };
+export { config, getConfig, configure }
diff --git a/deno_dist/containers.ts b/deno_dist/containers.ts
index 004bcd2..71f27c5 100644
--- a/deno_dist/containers.ts
+++ b/deno_dist/containers.ts
@@ -1,8 +1,8 @@
-import { Cacher } from "./storage.ts";
+import { Cacher } from './storage.ts'
/* TYPES */
-import type { TemplateFunction } from "./compile.ts";
+import type { TemplateFunction } from './compile.ts'
/* END TYPES */
@@ -12,6 +12,6 @@ import type { TemplateFunction } from "./compile.ts";
* Stores partials and cached templates
*/
-var templates = new Cacher({});
+var templates = new Cacher({})
-export { templates };
+export { templates }
diff --git a/deno_dist/err.ts b/deno_dist/err.ts
index 377228e..6e5930b 100644
--- a/deno_dist/err.ts
+++ b/deno_dist/err.ts
@@ -1,9 +1,9 @@
function setPrototypeOf(obj: any, proto: any) {
// eslint-disable-line @typescript-eslint/no-explicit-any
if (Object.setPrototypeOf) {
- Object.setPrototypeOf(obj, proto);
+ Object.setPrototypeOf(obj, proto)
} else {
- obj.__proto__ = proto;
+ obj.__proto__ = proto
}
}
@@ -23,34 +23,35 @@ function setPrototypeOf(obj: any, proto: any) {
*/
export default function EtaErr(message: string): Error {
- var err = new Error(message);
- setPrototypeOf(err, EtaErr.prototype);
- return err;
+ var err = new Error(message)
+ setPrototypeOf(err, EtaErr.prototype)
+ return err
}
EtaErr.prototype = Object.create(Error.prototype, {
- name: { value: "Eta Error", enumerable: false },
-});
+ name: { value: 'Eta Error', enumerable: false }
+})
/**
* Throws an EtaErr with a nicely formatted error and message showing where in the template the error occurred.
*/
export function ParseErr(message: string, str: string, indx: number): void {
- var whitespace = str.slice(0, indx).split(/\n/);
+ var whitespace = str.slice(0, indx).split(/\n/)
- var lineNo = whitespace.length;
- var colNo = whitespace[lineNo - 1].length + 1;
- message += " at line " +
+ var lineNo = whitespace.length
+ var colNo = whitespace[lineNo - 1].length + 1
+ message +=
+ ' at line ' +
lineNo +
- " col " +
+ ' col ' +
colNo +
- ":\n\n" +
- " " +
+ ':\n\n' +
+ ' ' +
str.split(/\n/)[lineNo - 1] +
- "\n" +
- " " +
- Array(colNo).join(" ") +
- "^";
- throw EtaErr(message);
+ '\n' +
+ ' ' +
+ Array(colNo).join(' ') +
+ '^'
+ throw EtaErr(message)
}
diff --git a/deno_dist/file-handlers.ts b/deno_dist/file-handlers.ts
index e177365..8ce17e4 100644
--- a/deno_dist/file-handlers.ts
+++ b/deno_dist/file-handlers.ts
@@ -1,33 +1,29 @@
// express is set like: app.engine('html', require('eta').renderFile)
-import EtaErr from "./err.ts";
-import compile from "./compile.ts";
-import { getConfig } from "./config.ts";
-import { getPath, readFile } from "./file-utils.ts";
-import { copyProps } from "./utils.ts";
-import { promiseImpl } from "./polyfills.ts";
+import EtaErr from './err.ts'
+import compile from './compile.ts'
+import { getConfig } from './config.ts'
+import { getPath, readFile } from './file-utils.ts'
+import { copyProps } from './utils.ts'
+import { promiseImpl } from './polyfills.ts'
/* TYPES */
-import type {
- EtaConfig,
- EtaConfigWithFilename,
- PartialConfig,
-} from "./config.ts";
-import type { TemplateFunction } from "./compile.ts";
+import type { EtaConfig, PartialConfig, EtaConfigWithFilename } from './config.ts'
+import type { TemplateFunction } from './compile.ts'
-export type CallbackFn = (err: Error | null, str?: string) => void;
+export type CallbackFn = (err: Error | null, str?: string) => void
interface DataObj {
/** Express.js settings may be stored here */
settings?: {
- [key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
- };
- [key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
+ [key: string]: any // eslint-disable-line @typescript-eslint/no-explicit-any
+ }
+ [key: string]: any // eslint-disable-line @typescript-eslint/no-explicit-any
}
interface PartialConfigWithFilename extends Partial {
- filename: string;
+ filename: string
}
/* END TYPES */
@@ -43,21 +39,18 @@ interface PartialConfigWithFilename extends Partial {
export function loadFile(
filePath: string,
options: PartialConfigWithFilename,
- noCache?: boolean,
+ noCache?: boolean
): TemplateFunction {
- var config = getConfig(options);
- var template = readFile(filePath);
+ var config = getConfig(options)
+ var template = readFile(filePath)
try {
- var compiledTemplate = compile(template, config);
+ var compiledTemplate = compile(template, config)
if (!noCache) {
- config.templates.define(
- (config as EtaConfigWithFilename).filename,
- compiledTemplate,
- );
+ config.templates.define((config as EtaConfigWithFilename).filename, compiledTemplate)
}
- return compiledTemplate;
+ return compiledTemplate
} catch (e) {
- throw EtaErr("Loading file: " + filePath + " failed:\n\n" + e.message);
+ throw EtaErr('Loading file: ' + filePath + ' failed:\n\n' + e.message)
}
}
@@ -73,19 +66,19 @@ export function loadFile(
*/
function handleCache(options: EtaConfigWithFilename): TemplateFunction {
- var filename = options.filename;
+ var filename = options.filename
if (options.cache) {
- var func = options.templates.get(filename);
+ var func = options.templates.get(filename)
if (func) {
- return func;
+ return func
}
- return loadFile(filename, options);
+ return loadFile(filename, options)
}
// Caching is disabled, so pass noCache = true
- return loadFile(filename, options, true);
+ return loadFile(filename, options, true)
}
/**
@@ -98,38 +91,30 @@ function handleCache(options: EtaConfigWithFilename): TemplateFunction {
* @param cb callback
*/
-function tryHandleCache(
- data: object,
- options: EtaConfigWithFilename,
- cb: CallbackFn | undefined,
-) {
+function tryHandleCache(data: object, options: EtaConfigWithFilename, cb: CallbackFn | undefined) {
if (cb) {
try {
// Note: if there is an error while rendering the template,
// It will bubble up and be caught here
- var templateFn = handleCache(options);
- templateFn(data, options, cb);
+ var templateFn = handleCache(options)
+ templateFn(data, options, cb)
} catch (err) {
- return cb(err);
+ return cb(err)
}
} else {
// No callback, try returning a promise
- if (typeof promiseImpl === "function") {
- return new promiseImpl(
- function (resolve: Function, reject: Function) {
- try {
- var templateFn = handleCache(options);
- var result = templateFn(data, options);
- resolve(result);
- } catch (err) {
- reject(err);
- }
- },
- );
+ if (typeof promiseImpl === 'function') {
+ return new promiseImpl(function (resolve: Function, reject: Function) {
+ try {
+ var templateFn = handleCache(options)
+ var result = templateFn(data, options)
+ resolve(result)
+ } catch (err) {
+ reject(err)
+ }
+ })
} else {
- throw EtaErr(
- "Please provide a callback function, this env doesn't support Promises",
- );
+ throw EtaErr("Please provide a callback function, this env doesn't support Promises")
}
}
}
@@ -151,14 +136,11 @@ function tryHandleCache(
* @return [Eta template function, new config object]
*/
-function includeFile(
- path: string,
- options: EtaConfig,
-): [TemplateFunction, EtaConfig] {
+function includeFile(path: string, options: EtaConfig): [TemplateFunction, EtaConfig] {
// the below creates a new options object, using the parent filepath of the old options object and the path
- var newFileOptions = getConfig({ filename: getPath(path, options) }, options);
+ var newFileOptions = getConfig({ filename: getPath(path, options) }, options)
// TODO: make sure properties are currectly copied over
- return [handleCache(newFileOptions as EtaConfigWithFilename), newFileOptions];
+ return [handleCache(newFileOptions as EtaConfigWithFilename), newFileOptions]
}
/**
@@ -192,20 +174,16 @@ function renderFile(
filename: string,
data: DataObj,
config?: PartialConfig,
- cb?: CallbackFn,
-): Promise | void;
+ cb?: CallbackFn
+): Promise | void
-function renderFile(
- filename: string,
- data: DataObj,
- cb?: CallbackFn,
-): Promise | void;
+function renderFile(filename: string, data: DataObj, cb?: CallbackFn): Promise | void
function renderFile(
filename: string,
data: DataObj,
config?: PartialConfig,
- cb?: CallbackFn,
+ cb?: CallbackFn
): Promise | void {
/*
Here we have some function overloading.
@@ -215,54 +193,70 @@ function renderFile(
And we want to also make (filename, data, options, cb) available
*/
- var renderConfig: EtaConfigWithFilename;
- var callback: CallbackFn | undefined;
- data = data || {}; // If data is undefined, we don't want accessing data.settings to error
+ var renderConfig: EtaConfigWithFilename
+ var callback: CallbackFn | undefined
+ data = data || {} // If data is undefined, we don't want accessing data.settings to error
// First, assign our callback function to `callback`
// We can leave it undefined if neither parameter is a function;
// Callbacks are optional
- if (typeof cb === "function") {
+ if (typeof cb === 'function') {
// The 4th argument is the callback
- callback = cb;
- } else if (typeof config === "function") {
+ callback = cb
+ } else if (typeof config === 'function') {
// The 3rd arg is the callback
- callback = config;
+ callback = config
}
// If there is a config object passed in explicitly, use it
- if (typeof config === "object") {
- renderConfig = getConfig(
- (config as PartialConfig) || {},
- ) as EtaConfigWithFilename;
+ if (typeof config === 'object') {
+ renderConfig = getConfig((config as PartialConfig) || {}) as EtaConfigWithFilename
} else {
// Otherwise, get the config from the data object
// And then grab some config options from data.settings
// Which is where Express sometimes stores them
- renderConfig = getConfig(data as PartialConfig) as EtaConfigWithFilename;
+ renderConfig = getConfig(data as PartialConfig) as EtaConfigWithFilename
if (data.settings) {
// Pull a few things from known locations
if (data.settings.views) {
- renderConfig.views = data.settings.views;
+ renderConfig.views = data.settings.views
}
- if (data.settings["view cache"]) {
- renderConfig.cache = true;
+ if (data.settings['view cache']) {
+ renderConfig.cache = true
}
// Undocumented after Express 2, but still usable, esp. for
// items that are unsafe to be passed along with data, like `root`
- var viewOpts = data.settings["view options"];
+ var viewOpts = data.settings['view options']
if (viewOpts) {
- copyProps(renderConfig, viewOpts);
+ copyProps(renderConfig, viewOpts)
}
}
}
// Set the filename option on the template
// This will first try to resolve the file path (see getPath for details)
- renderConfig.filename = getPath(filename, renderConfig);
+ renderConfig.filename = getPath(filename, renderConfig)
- return tryHandleCache(data, renderConfig, callback);
+ return tryHandleCache(data, renderConfig, callback)
+}
+
+function renderFileAsync(
+ filename: string,
+ data: DataObj,
+ config?: PartialConfig,
+ cb?: CallbackFn
+): Promise | void
+
+function renderFileAsync(filename: string, data: DataObj, cb?: CallbackFn): Promise | void
+
+function renderFileAsync(
+ filename: string,
+ data: DataObj,
+ config?: PartialConfig,
+ cb?: CallbackFn
+): Promise | void {
+ return renderFile(filename, data, { ...config, async: true }, cb)
}
-export { includeFile, renderFile };
+export { includeFile, renderFile, renderFileAsync }
diff --git a/deno_dist/file-helpers.ts b/deno_dist/file-helpers.ts
index a009c40..551ded2 100644
--- a/deno_dist/file-helpers.ts
+++ b/deno_dist/file-helpers.ts
@@ -1,11 +1,11 @@
-import { includeFile } from "./file-handlers.ts";
+import { includeFile } from './file-handlers.ts'
/* TYPES */
-import type { EtaConfig } from "./config.ts";
+import type { EtaConfig } from './config.ts'
interface GenericData {
- [index: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
+ [index: string]: any // eslint-disable-line @typescript-eslint/no-explicit-any
}
/* END TYPES */
@@ -14,11 +14,7 @@ interface GenericData {
* Called with `includeFile(path, data)`
*/
-export function includeFileHelper(
- this: EtaConfig,
- path: string,
- data: GenericData,
-): string {
- var templateAndConfig = includeFile(path, this);
- return templateAndConfig[0](data, templateAndConfig[1]);
+export function includeFileHelper(this: EtaConfig, path: string, data: GenericData): string {
+ var templateAndConfig = includeFile(path, this)
+ return templateAndConfig[0](data, templateAndConfig[1])
}
diff --git a/deno_dist/file-methods.ts b/deno_dist/file-methods.ts
index b4c921f..f2cce45 100644
--- a/deno_dist/file-methods.ts
+++ b/deno_dist/file-methods.ts
@@ -1,4 +1,4 @@
-export * as fs from "https://deno.land/std@0.66.0/fs/mod.ts";
-export * as path from "https://deno.land/std@0.66.0/path/mod.ts";
+export * as fs from "https://deno.land/std@0.66.0/fs/mod.ts"
+export * as path from "https://deno.land/std@0.66.0/path/mod.ts"
-export var readFileSync = Deno.readTextFileSync;
+export var readFileSync = Deno.readTextFileSync
diff --git a/deno_dist/file-utils.ts b/deno_dist/file-utils.ts
index eca8080..0815db2 100644
--- a/deno_dist/file-utils.ts
+++ b/deno_dist/file-utils.ts
@@ -1,13 +1,13 @@
-import { fs, path, readFileSync } from "./file-methods.ts";
-var _BOM = /^\uFEFF/;
+import { fs, path, readFileSync } from './file-methods.ts'
+var _BOM = /^\uFEFF/
// express is set like: app.engine('html', require('eta').renderFile)
-import EtaErr from "./err.ts";
+import EtaErr from './err.ts'
/* TYPES */
-import type { EtaConfig } from "./config.ts";
+import type { EtaConfig } from './config.ts'
/* END TYPES */
@@ -23,20 +23,16 @@ import type { EtaConfig } from "./config.ts";
* @return absolute path to template
*/
-function getWholeFilePath(
- name: string,
- parentfile: string,
- isDirectory?: boolean,
-): string {
+function getWholeFilePath(name: string, parentfile: string, isDirectory?: boolean): string {
var includePath = path.resolve(
isDirectory ? parentfile : path.dirname(parentfile), // returns directory the parent file is in
- name, // file
- );
- var ext = path.extname(name);
+ name // file
+ )
+ var ext = path.extname(name)
if (!ext) {
- includePath += ".eta";
+ includePath += '.eta'
}
- return includePath;
+ return includePath
}
/**
@@ -58,9 +54,9 @@ function getWholeFilePath(
*/
function getPath(path: string, options: EtaConfig): string {
- var includePath: string | false = false;
- var views = options.views;
- var searchedPaths: Array = [];
+ var includePath: string | false = false
+ var views = options.views
+ var searchedPaths: Array = []
// If these four values are the same,
// getPath() will return the same result every time.
@@ -70,20 +66,18 @@ function getPath(path: string, options: EtaConfig): string {
filename: options.filename, // filename of the template which called includeFile()
path: path,
root: options.root,
- views: options.views,
- });
+ views: options.views
+ })
- if (
- options.cache && options.filepathCache && options.filepathCache[pathOptions]
- ) {
+ if (options.cache && options.filepathCache && options.filepathCache[pathOptions]) {
// Use the cached filepath
- return options.filepathCache[pathOptions];
+ return options.filepathCache[pathOptions]
}
/** Add a filepath to the list of paths we've checked for a template */
function addPathToSearched(pathSearched: string) {
if (!searchedPaths.includes(pathSearched)) {
- searchedPaths.push(pathSearched);
+ searchedPaths.push(pathSearched)
}
}
@@ -95,97 +89,87 @@ function getPath(path: string, options: EtaConfig): string {
* @param path the path to the template
*/
- function searchViews(
- views: Array | string | undefined,
- path: string,
- ): string | false {
- var filePath;
+ function searchViews(views: Array | string | undefined, path: string): string | false {
+ var filePath
// If views is an array, then loop through each directory
// And attempt to find the template
if (
Array.isArray(views) &&
views.some(function (v) {
- filePath = getWholeFilePath(path, v, true);
+ filePath = getWholeFilePath(path, v, true)
- addPathToSearched(filePath);
+ addPathToSearched(filePath)
- return fs.existsSync(filePath);
+ return fs.existsSync(filePath)
})
) {
// If the above returned true, we know that the filePath was just set to a path
// That exists (Array.some() returns as soon as it finds a valid element)
- return (filePath as unknown) as string;
- } else if (typeof views === "string") {
+ return (filePath as unknown) as string
+ } else if (typeof views === 'string') {
// Search for the file if views is a single directory
- filePath = getWholeFilePath(path, views, true);
+ filePath = getWholeFilePath(path, views, true)
- addPathToSearched(filePath);
+ addPathToSearched(filePath)
if (fs.existsSync(filePath)) {
- return filePath;
+ return filePath
}
}
// Unable to find a file
- return false;
+ return false
}
// Path starts with '/', 'C:\', etc.
- var match = /^[A-Za-z]+:\\|^\//.exec(path);
+ var match = /^[A-Za-z]+:\\|^\//.exec(path)
// Absolute path, like /partials/partial.eta
if (match && match.length) {
// We have to trim the beginning '/' off the path, or else
// path.resolve(dir, path) will always resolve to just path
- var formattedPath = path.replace(/^\/*/, "");
+ var formattedPath = path.replace(/^\/*/, '')
// First, try to resolve the path within options.views
- includePath = searchViews(views, formattedPath);
+ includePath = searchViews(views, formattedPath)
if (!includePath) {
// If that fails, searchViews will return false. Try to find the path
// inside options.root (by default '/', the base of the filesystem)
- var pathFromRoot = getWholeFilePath(
- formattedPath,
- options.root || "/",
- true,
- );
+ var pathFromRoot = getWholeFilePath(formattedPath, options.root || '/', true)
- addPathToSearched(pathFromRoot);
+ addPathToSearched(pathFromRoot)
- includePath = pathFromRoot;
+ includePath = pathFromRoot
}
} else {
// Relative paths
// Look relative to a passed filename first
if (options.filename) {
- var filePath = getWholeFilePath(path, options.filename);
+ var filePath = getWholeFilePath(path, options.filename)
- addPathToSearched(filePath);
+ addPathToSearched(filePath)
if (fs.existsSync(filePath)) {
- includePath = filePath;
+ includePath = filePath
}
}
// Then look for the template in options.views
if (!includePath) {
- includePath = searchViews(views, path);
+ includePath = searchViews(views, path)
}
if (!includePath) {
- throw EtaErr(
- 'Could not find the template "' + path + '". Paths tried: ' +
- searchedPaths,
- );
+ throw EtaErr('Could not find the template "' + path + '". Paths tried: ' + searchedPaths)
}
}
// If caching and filepathCache are enabled,
// cache the input & output of this function.
if (options.cache && options.filepathCache) {
- options.filepathCache[pathOptions] = includePath;
+ options.filepathCache[pathOptions] = includePath
}
- return includePath;
+ return includePath
}
/**
@@ -194,10 +178,10 @@ function getPath(path: string, options: EtaConfig): string {
function readFile(filePath: string): string {
try {
- return readFileSync(filePath).toString().replace(_BOM, ""); // TODO: is replacing BOM's necessary?
+ return readFileSync(filePath).toString().replace(_BOM, '') // TODO: is replacing BOM's necessary?
} catch {
- throw EtaErr("Failed to read template at '" + filePath + "'");
+ throw EtaErr("Failed to read template at '" + filePath + "'")
}
}
-export { getPath, readFile };
+export { getPath, readFile }
diff --git a/deno_dist/mod.ts b/deno_dist/mod.ts
index 4f41a05..0216471 100644
--- a/deno_dist/mod.ts
+++ b/deno_dist/mod.ts
@@ -1,26 +1,17 @@
/* Export file stuff */
-import { includeFileHelper } from "./file-helpers.ts";
-import { config } from "./config.ts";
+import { includeFileHelper } from './file-helpers.ts'
+import { config } from './config.ts'
-config.includeFile = includeFileHelper;
-config.filepathCache = {};
+config.includeFile = includeFileHelper
+config.filepathCache = {}
-export {
- loadFile,
- renderFile,
- renderFile as __express,
-} from "./file-handlers.ts";
+export { loadFile, renderFile, renderFileAsync, renderFile as __express } from './file-handlers.ts'
/* End file stuff */
-export { default as compileToString } from "./compile-string.ts";
-export { default as compile } from "./compile.ts";
-export { default as parse } from "./parse.ts";
-export { default as render } from "./render.ts";
-export { templates } from "./containers.ts";
-export {
- config,
- config as defaultConfig,
- configure,
- getConfig,
-} from "./config.ts";
+export { default as compileToString } from './compile-string.ts'
+export { default as compile } from './compile.ts'
+export { default as parse } from './parse.ts'
+export { default as render, renderAsync } from './render.ts'
+export { templates } from './containers.ts'
+export { config, config as defaultConfig, getConfig, configure } from './config.ts'
diff --git a/deno_dist/parse.ts b/deno_dist/parse.ts
index 19e69fc..82efeca 100644
--- a/deno_dist/parse.ts
+++ b/deno_dist/parse.ts
@@ -1,49 +1,45 @@
-import { ParseErr } from "./err.ts";
-import { trimWS } from "./utils.ts";
+import { ParseErr } from './err.ts'
+import { trimWS } from './utils.ts'
/* TYPES */
-import type { EtaConfig } from "./config.ts";
+import type { EtaConfig } from './config.ts'
-export type TagType = "r" | "e" | "i" | "";
+export type TagType = 'r' | 'e' | 'i' | ''
export interface TemplateObject {
- t: TagType;
- val: string;
+ t: TagType
+ val: string
}
-export type AstObject = string | TemplateObject;
+export type AstObject = string | TemplateObject
/* END TYPES */
-var templateLitReg =
- /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g;
+var templateLitReg = /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g
-var singleQuoteReg = /'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g;
+var singleQuoteReg = /'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g
-var doubleQuoteReg = /"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g;
+var doubleQuoteReg = /"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g
/** Escape special regular expression characters inside a string */
function escapeRegExp(string: string) {
// From MDN
- return string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
+ return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
}
-export default function parse(
- str: string,
- config: EtaConfig,
-): Array {
- var buffer: Array = [];
- var trimLeftOfNextStr: string | false = false;
- var lastIndex = 0;
- var parseOptions = config.parse;
+export default function parse(str: string, config: EtaConfig): Array {
+ var buffer: Array = []
+ var trimLeftOfNextStr: string | false = false
+ var lastIndex = 0
+ var parseOptions = config.parse
if (config.plugins) {
for (var i = 0; i < config.plugins.length; i++) {
- var plugin = config.plugins[i];
+ var plugin = config.plugins[i]
if (plugin.processTemplate) {
- str = plugin.processTemplate(str, config);
+ str = plugin.processTemplate(str, config)
}
}
}
@@ -55,13 +51,13 @@ export default function parse(
// work well with `\r` and empty lines don't work well with the `m` flag.
// Essentially, this replaces the whitespace at the beginning and end of
// each line and removes multiple newlines.
- str = str.replace(/[\r\n]+/g, "\n").replace(/^\s+|\s+$/gm, "");
+ str = str.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, '')
}
/* End rmWhitespace option */
- templateLitReg.lastIndex = 0;
- singleQuoteReg.lastIndex = 0;
- doubleQuoteReg.lastIndex = 0;
+ templateLitReg.lastIndex = 0
+ singleQuoteReg.lastIndex = 0
+ doubleQuoteReg.lastIndex = 0
function pushString(strng: string, shouldTrimRightOfString?: string | false) {
if (strng) {
@@ -71,137 +67,136 @@ export default function parse(
strng,
config,
trimLeftOfNextStr, // this will only be false on the first str, the next ones will be null or undefined
- shouldTrimRightOfString,
- );
+ shouldTrimRightOfString
+ )
if (strng) {
// replace \ with \\, ' with \'
// we're going to convert all CRLF to LF so it doesn't take more than one replace
- strng = strng.replace(/\\|'/g, "\\$&").replace(/\r\n|\n|\r/g, "\\n");
+ strng = strng.replace(/\\|'/g, '\\$&').replace(/\r\n|\n|\r/g, '\\n')
- buffer.push(strng);
+ buffer.push(strng)
}
}
}
- var prefixes = [parseOptions.exec, parseOptions.interpolate, parseOptions.raw]
- .reduce(function (
- accumulator,
- prefix,
- ) {
- if (accumulator && prefix) {
- return accumulator + "|" + escapeRegExp(prefix);
- } else if (prefix) {
- // accumulator is falsy
- return escapeRegExp(prefix);
- } else {
- // prefix and accumulator are both falsy
- return accumulator;
- }
- }, "");
+ var prefixes = [parseOptions.exec, parseOptions.interpolate, parseOptions.raw].reduce(function (
+ accumulator,
+ prefix
+ ) {
+ if (accumulator && prefix) {
+ return accumulator + '|' + escapeRegExp(prefix)
+ } else if (prefix) {
+ // accumulator is falsy
+ return escapeRegExp(prefix)
+ } else {
+ // prefix and accumulator are both falsy
+ return accumulator
+ }
+ },
+ '')
var parseOpenReg = new RegExp(
- "([^]*?)" + escapeRegExp(config.tags[0]) + "(-|_)?\\s*(" + prefixes +
- ")?\\s*",
- "g",
- );
+ '([^]*?)' + escapeRegExp(config.tags[0]) + '(-|_)?\\s*(' + prefixes + ')?\\s*',
+ 'g'
+ )
var parseCloseReg = new RegExp(
- "'|\"|`|\\/\\*|(\\s*(-|_)?" + escapeRegExp(config.tags[1]) + ")",
- "g",
- );
+ '\'|"|`|\\/\\*|(\\s*(-|_)?' + escapeRegExp(config.tags[1]) + ')',
+ 'g'
+ )
// TODO: benchmark having the \s* on either side vs using str.trim()
- var m;
+ var m
while ((m = parseOpenReg.exec(str))) {
- lastIndex = m[0].length + m.index;
+ lastIndex = m[0].length + m.index
- var precedingString = m[1];
- var wsLeft = m[2];
- var prefix = m[3] || ""; // by default either ~, =, or empty
+ var precedingString = m[1]
+ var wsLeft = m[2]
+ var prefix = m[3] || '' // by default either ~, =, or empty
- pushString(precedingString, wsLeft);
+ pushString(precedingString, wsLeft)
- parseCloseReg.lastIndex = lastIndex;
- var closeTag;
- var currentObj: AstObject | false = false;
+ parseCloseReg.lastIndex = lastIndex
+ var closeTag
+ var currentObj: AstObject | false = false
while ((closeTag = parseCloseReg.exec(str))) {
if (closeTag[1]) {
- var content = str.slice(lastIndex, closeTag.index);
+ var content = str.slice(lastIndex, closeTag.index)
- parseOpenReg.lastIndex = lastIndex = parseCloseReg.lastIndex;
+ parseOpenReg.lastIndex = lastIndex = parseCloseReg.lastIndex
- trimLeftOfNextStr = closeTag[2];
+ trimLeftOfNextStr = closeTag[2]
- var currentType: TagType = "";
+ var currentType: TagType = ''
if (prefix === parseOptions.exec) {
- currentType = "e";
+ currentType = 'e'
} else if (prefix === parseOptions.raw) {
- currentType = "r";
+ currentType = 'r'
} else if (prefix === parseOptions.interpolate) {
- currentType = "i";
+ currentType = 'i'
}
- currentObj = { t: currentType, val: content };
- break;
+ currentObj = { t: currentType, val: content }
+ break
} else {
- var char = closeTag[0];
- if (char === "/*") {
- var commentCloseInd = str.indexOf("*/", parseCloseReg.lastIndex);
+ var char = closeTag[0]
+ if (char === '/*') {
+ var commentCloseInd = str.indexOf('*/', parseCloseReg.lastIndex)
if (commentCloseInd === -1) {
- ParseErr("unclosed comment", str, closeTag.index);
+ ParseErr('unclosed comment', str, closeTag.index)
}
- parseCloseReg.lastIndex = commentCloseInd;
+ parseCloseReg.lastIndex = commentCloseInd
} else if (char === "'") {
- singleQuoteReg.lastIndex = closeTag.index;
+ singleQuoteReg.lastIndex = closeTag.index
- var singleQuoteMatch = singleQuoteReg.exec(str);
+ var singleQuoteMatch = singleQuoteReg.exec(str)
if (singleQuoteMatch) {
- parseCloseReg.lastIndex = singleQuoteReg.lastIndex;
+ parseCloseReg.lastIndex = singleQuoteReg.lastIndex
} else {
- ParseErr("unclosed string", str, closeTag.index);
+ ParseErr('unclosed string', str, closeTag.index)
}
} else if (char === '"') {
- doubleQuoteReg.lastIndex = closeTag.index;
- var doubleQuoteMatch = doubleQuoteReg.exec(str);
+ doubleQuoteReg.lastIndex = closeTag.index
+ var doubleQuoteMatch = doubleQuoteReg.exec(str)
if (doubleQuoteMatch) {
- parseCloseReg.lastIndex = doubleQuoteReg.lastIndex;
+ parseCloseReg.lastIndex = doubleQuoteReg.lastIndex
} else {
- ParseErr("unclosed string", str, closeTag.index);
+ ParseErr('unclosed string', str, closeTag.index)
}
- } else if (char === "`") {
- templateLitReg.lastIndex = closeTag.index;
- var templateLitMatch = templateLitReg.exec(str);
+ } else if (char === '`') {
+ templateLitReg.lastIndex = closeTag.index
+ var templateLitMatch = templateLitReg.exec(str)
if (templateLitMatch) {
- parseCloseReg.lastIndex = templateLitReg.lastIndex;
+ parseCloseReg.lastIndex = templateLitReg.lastIndex
} else {
- ParseErr("unclosed string", str, closeTag.index);
+ ParseErr('unclosed string', str, closeTag.index)
}
}
}
}
if (currentObj) {
- buffer.push(currentObj);
+ buffer.push(currentObj)
} else {
- ParseErr("unclosed tag", str, m.index + precedingString.length);
+ ParseErr('unclosed tag', str, m.index + precedingString.length)
}
}
- pushString(str.slice(lastIndex, str.length), false);
+ pushString(str.slice(lastIndex, str.length), false)
if (config.plugins) {
for (var i = 0; i < config.plugins.length; i++) {
- var plugin = config.plugins[i];
+ var plugin = config.plugins[i]
if (plugin.processAST) {
- buffer = plugin.processAST(buffer, config);
+ buffer = plugin.processAST(buffer, config)
}
}
}
- return buffer;
+ return buffer
}
diff --git a/deno_dist/polyfills.ts b/deno_dist/polyfills.ts
index b0b60a5..333fea8 100644
--- a/deno_dist/polyfills.ts
+++ b/deno_dist/polyfills.ts
@@ -1,13 +1,13 @@
-export var promiseImpl = Promise;
+export var promiseImpl = Promise
-export function getAsyncFunctionConstructor(): Function {
- return async function () {}.constructor;
+export function getAsyncFunctionConstructor (): Function {
+ return async function () {}.constructor
}
-export function trimLeft(str: string): string {
- return str.trimLeft();
+export function trimLeft (str: string): string {
+ return str.trimLeft()
}
-export function trimRight(str: string): string {
- return str.trimRight();
+export function trimRight (str: string): string {
+ return str.trimRight()
}
diff --git a/deno_dist/render.ts b/deno_dist/render.ts
index 1f08c0f..8f5bf86 100644
--- a/deno_dist/render.ts
+++ b/deno_dist/render.ts
@@ -1,39 +1,36 @@
-import compile from "./compile.ts";
-import { getConfig } from "./config.ts";
-import { promiseImpl } from "./polyfills.ts";
-import EtaErr from "./err.ts";
+import compile from './compile.ts'
+import { getConfig } from './config.ts'
+import { promiseImpl } from './polyfills.ts'
+import EtaErr from './err.ts'
/* TYPES */
-import type { EtaConfig, PartialConfig } from "./config.ts";
-import type { TemplateFunction } from "./compile.ts";
-import type { CallbackFn } from "./file-handlers.ts";
+import type { EtaConfig, PartialConfig } from './config.ts'
+import type { TemplateFunction } from './compile.ts'
+import type { CallbackFn } from './file-handlers.ts'
/* END TYPES */
-function handleCache(
- template: string | TemplateFunction,
- options: EtaConfig,
-): TemplateFunction {
- var templateFunc;
+function handleCache(template: string | TemplateFunction, options: EtaConfig): TemplateFunction {
+ var templateFunc
if (options.cache && options.name && options.templates.get(options.name)) {
- return options.templates.get(options.name);
+ return options.templates.get(options.name)
}
- if (typeof template === "function") {
- templateFunc = template;
+ if (typeof template === 'function') {
+ templateFunc = template
} else {
- templateFunc = compile(template, options);
+ templateFunc = compile(template, options)
}
// Note that we don't have to check if it already exists in the cache;
// it would have returned earlier if it had
if (options.cache && options.name) {
- options.templates.define(options.name, templateFunc);
+ options.templates.define(options.name, templateFunc)
}
- return templateFunc;
+ return templateFunc
}
/**
@@ -59,40 +56,43 @@ export default function render(
template: string | TemplateFunction,
data: object,
config?: PartialConfig,
- cb?: CallbackFn,
+ cb?: CallbackFn
): string | Promise | void {
- var options = getConfig(config || {});
+ var options = getConfig(config || {})
if (options.async) {
- var result;
+ var result
if (cb) {
// If user passes callback
try {
// Note: if there is an error while rendering the template,
// It will bubble up and be caught here
- var templateFn = handleCache(template, options);
- templateFn(data, options, cb);
+ var templateFn = handleCache(template, options)
+ templateFn(data, options, cb)
} catch (err) {
- return cb(err);
+ return cb(err)
}
} else {
// No callback, try returning a promise
- if (typeof promiseImpl === "function") {
+ if (typeof promiseImpl === 'function') {
return new promiseImpl(function (resolve: Function, reject: Function) {
try {
- result = handleCache(template, options)(data, options);
- resolve(result);
+ result = handleCache(template, options)(data, options)
+ resolve(result)
} catch (err) {
- reject(err);
+ reject(err)
}
- });
+ })
} else {
- throw EtaErr(
- "Please provide a callback function, this env doesn't support Promises",
- );
+ throw EtaErr("Please provide a callback function, this env doesn't support Promises")
}
}
} else {
- return handleCache(template, options)(data, options);
+ return handleCache(template, options)(data, options)
}
}
+
+export function renderAsync(template: string | TemplateFunction, data: object, config?: PartialConfig, cb?: CallbackFn): string | Promise | void {
+ // Using Object.assign to lower bundle size, using spread operator makes it larger
+ return render(template, data, Object.assign({}, config, { async: true }), cb)
+}
diff --git a/deno_dist/storage.ts b/deno_dist/storage.ts
index 118298a..6dc7e98 100644
--- a/deno_dist/storage.ts
+++ b/deno_dist/storage.ts
@@ -1,4 +1,4 @@
-import { copyProps } from "./utils.ts";
+import { copyProps } from './utils.ts'
/**
* Handles storage and accessing of values
@@ -9,23 +9,23 @@ import { copyProps } from "./utils.ts";
class Cacher {
constructor(private cache: Record) {}
define(key: string, val: T): void {
- this.cache[key] = val;
+ this.cache[key] = val
}
get(key: string): T {
// string | array.
// TODO: allow array of keys to look down
// TODO: create plugin to allow referencing helpers, filters with dot notation
- return this.cache[key];
+ return this.cache[key]
}
remove(key: string): void {
- delete this.cache[key];
+ delete this.cache[key]
}
reset(): void {
- this.cache = {};
+ this.cache = {}
}
load(cacheObj: Record): void {
- copyProps(this.cache, cacheObj);
+ copyProps(this.cache, cacheObj)
}
}
-export { Cacher };
+export { Cacher }
diff --git a/deno_dist/utils.ts b/deno_dist/utils.ts
index a773363..e598bdc 100644
--- a/deno_dist/utils.ts
+++ b/deno_dist/utils.ts
@@ -1,34 +1,34 @@
// TODO: allow '-' to trim up until newline. Use [^\S\n\r] instead of \s
// TODO: only include trimLeft polyfill if not in ES6
-import { trimLeft, trimRight } from "./polyfills.ts";
+import { trimLeft, trimRight } from './polyfills.ts'
/* TYPES */
-import type { EtaConfig } from "./config.ts";
+import type { EtaConfig } from './config.ts'
interface EscapeMap {
- "&": "&";
- "<": "<";
- ">": ">";
- '"': """;
- "'": "'";
- [index: string]: string;
+ '&': '&'
+ '<': '<'
+ '>': '>'
+ '"': '"'
+ "'": '''
+ [index: string]: string
}
/* END TYPES */
export function hasOwnProp(obj: object, prop: string): boolean {
- return Object.prototype.hasOwnProperty.call(obj, prop);
+ return Object.prototype.hasOwnProperty.call(obj, prop)
}
export function copyProps(toObj: T, fromObj: T): T {
for (var key in fromObj) {
if (hasOwnProp((fromObj as unknown) as object, key)) {
- toObj[key] = fromObj[key];
+ toObj[key] = fromObj[key]
}
}
- return toObj;
+ return toObj
}
/**
@@ -39,55 +39,55 @@ function trimWS(
str: string,
config: EtaConfig,
wsLeft: string | false,
- wsRight?: string | false,
+ wsRight?: string | false
): string {
- var leftTrim;
- var rightTrim;
+ var leftTrim
+ var rightTrim
if (Array.isArray(config.autoTrim)) {
// kinda confusing
// but _}} will trim the left side of the following string
- leftTrim = config.autoTrim[1];
- rightTrim = config.autoTrim[0];
+ leftTrim = config.autoTrim[1]
+ rightTrim = config.autoTrim[0]
} else {
- leftTrim = rightTrim = config.autoTrim;
+ leftTrim = rightTrim = config.autoTrim
}
if (wsLeft || wsLeft === false) {
- leftTrim = wsLeft;
+ leftTrim = wsLeft
}
if (wsRight || wsRight === false) {
- rightTrim = wsRight;
+ rightTrim = wsRight
}
if (!rightTrim && !leftTrim) {
- return str;
+ return str
}
- if (leftTrim === "slurp" && rightTrim === "slurp") {
- return str.trim();
+ if (leftTrim === 'slurp' && rightTrim === 'slurp') {
+ return str.trim()
}
- if (leftTrim === "_" || leftTrim === "slurp") {
+ if (leftTrim === '_' || leftTrim === 'slurp') {
// console.log('trimming left' + leftTrim)
// full slurp
- str = trimLeft(str);
- } else if (leftTrim === "-" || leftTrim === "nl") {
+ str = trimLeft(str)
+ } else if (leftTrim === '-' || leftTrim === 'nl') {
// nl trim
- str = str.replace(/^(?:\r\n|\n|\r)/, "");
+ str = str.replace(/^(?:\r\n|\n|\r)/, '')
}
- if (rightTrim === "_" || rightTrim === "slurp") {
+ if (rightTrim === '_' || rightTrim === 'slurp') {
// full slurp
- str = trimRight(str);
- } else if (rightTrim === "-" || rightTrim === "nl") {
+ str = trimRight(str)
+ } else if (rightTrim === '-' || rightTrim === 'nl') {
// nl trim
- str = str.replace(/(?:\r\n|\n|\r)$/, ""); // TODO: make sure this gets \r\n
+ str = str.replace(/(?:\r\n|\n|\r)$/, '') // TODO: make sure this gets \r\n
}
- return str;
+ return str
}
/**
@@ -95,15 +95,15 @@ function trimWS(
*/
var escMap: EscapeMap = {
- "&": "&",
- "<": "<",
- ">": ">",
- '"': """,
- "'": "'",
-};
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": '''
+}
function replaceChar(s: string): string {
- return escMap[s];
+ return escMap[s]
}
/**
@@ -116,12 +116,12 @@ function replaceChar(s: string): string {
function XMLEscape(str: any): string {
// eslint-disable-line @typescript-eslint/no-explicit-any
// To deal with XSS. Based on Escape implementations of Mustache.JS and Marko, then customized.
- var newStr = String(str);
+ var newStr = String(str)
if (/[&<>"']/.test(newStr)) {
- return newStr.replace(/[&<>"']/g, replaceChar);
+ return newStr.replace(/[&<>"']/g, replaceChar)
} else {
- return newStr;
+ return newStr
}
}
-export { trimWS, XMLEscape };
+export { trimWS, XMLEscape }