first commit
This commit is contained in:
7
node_modules/eta/LICENSE
generated
vendored
Normal file
7
node_modules/eta/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright 2025 Ben Gubler <nebrelbug@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
174
node_modules/eta/README.md
generated
vendored
Normal file
174
node_modules/eta/README.md
generated
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
<p align="center">
|
||||
<img align="center" width="50%" src="https://github.com/bgub/eta/assets/25597854/041dbe34-883b-459b-8607-c787815c441a">
|
||||
</p>
|
||||
|
||||
<h1 align="center" style="text-align: center; width: fit-content; margin-left: auto; margin-right: auto;">eta (η)</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://eta.js.org">Documentation</a> -
|
||||
<a href="https://discord.gg/27gGncJYE2">Chat</a> -
|
||||
<a href="https://eta.js.org/playground">Playground</a>
|
||||
</p>
|
||||
|
||||
<span align="center">
|
||||
|
||||
[](https://www.npmjs.com/package/eta)
|
||||
[](https://github.com/bgub/eta/actions)
|
||||
[](https://codecov.io/github/bgub/eta)
|
||||
[](https://paypal.me/bengubler)
|
||||
|
||||
</span>
|
||||
|
||||
<span align="center">
|
||||
|
||||
**You're viewing the source for Eta v4 (ESM-only)**
|
||||
|
||||
</span>
|
||||
|
||||
## Summary
|
||||
|
||||
Eta is a lightweight and blazing fast embedded JS templating engine that works inside Node, Deno, and the browser. It's written in TypeScript and emphasizes great performance, configurability, and small bundle size.
|
||||
|
||||
### 🌟 Features
|
||||
|
||||
- 📦 0 dependencies
|
||||
- 💡 Only ~3.5 KB minzipped
|
||||
- ⚡️ Written in TypeScript
|
||||
- ✨ Deno support (+ Node and browser)
|
||||
- 🚀 Super Fast
|
||||
- 🔧 Configurable
|
||||
- Plugins, custom delimiters, caching
|
||||
- 🔨 Powerful
|
||||
- Precompilation, partials, async
|
||||
- **Layout support**!
|
||||
- 🔥 Reliable
|
||||
- Better quotes/comments support
|
||||
- _ex._ `<%= someval + "string %>" %>` compiles correctly, while it fails with doT or EJS
|
||||
- Great error reporting
|
||||
- ⚡️ Exports ES Modules
|
||||
- 📝 Easy template syntax
|
||||
|
||||
## Get Started
|
||||
|
||||
_For more thorough documentation, visit [https://eta.js.org](https://eta.js.org)_
|
||||
|
||||
Install Eta
|
||||
|
||||
```bash
|
||||
npm install eta
|
||||
```
|
||||
|
||||
In the root of your project, create `templates/simple.eta`
|
||||
|
||||
```eta
|
||||
Hi <%= it.name %>!
|
||||
```
|
||||
|
||||
Then, in your JS file:
|
||||
|
||||
```js
|
||||
import { Eta } from "eta";
|
||||
// or use https://jsr.io/@bgub/eta
|
||||
|
||||
const eta = new Eta({ views: path.join(__dirname, "templates") });
|
||||
|
||||
// Render a template
|
||||
|
||||
const res = eta.render("./simple", { name: "Ben" });
|
||||
console.log(res); // Hi Ben!
|
||||
```
|
||||
|
||||
## FAQs
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>Where did Eta's name come from?</b>
|
||||
</summary>
|
||||
|
||||
"Eta" means tiny in Esperanto. Plus, it can be used as an acronym for all sorts of cool phrases: "ECMAScript Template Awesomeness", "Embedded Templating Alternative", etc....
|
||||
|
||||
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).
|
||||
|
||||
</details>
|
||||
|
||||
<br />
|
||||
|
||||
## Integrations
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>Visual Studio Code</b>
|
||||
</summary>
|
||||
|
||||
[@shadowtime2000](https://github.com/shadowtime2000) created [eta-vscode](https://marketplace.visualstudio.com/items?itemName=shadowtime2000.eta-vscode).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>ESLint</b>
|
||||
</summary>
|
||||
|
||||
[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.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>Webpack</b>
|
||||
</summary>
|
||||
|
||||
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 });
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>Node-RED</b>
|
||||
</summary>
|
||||
|
||||
To operate with Eta templates in Node-RED: [@ralphwetzel/node-red-contrib-eta](https://flows.nodered.org/node/@ralphwetzel/node-red-contrib-eta)
|
||||
|
||||
<img width="150" alt="image" src="https://user-images.githubusercontent.com/16342003/160198427-2a69ff10-e8bf-4873-9d99-2929a584ccc8.png">
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>Koa</b>
|
||||
</summary>
|
||||
|
||||
To render Eta templates in [Koa](https://koajs.com) web framework: [@cedx/koa-eta](https://github.com/cedx/koa-eta/wiki)
|
||||
|
||||
</details>
|
||||
|
||||
<br />
|
||||
|
||||
## Projects using `eta`
|
||||
|
||||
- [Docusaurus v2](https://v2.docusaurus.io): open-source documentation framework that uses Eta to generate a SSR build
|
||||
- [swagger-typescript-api](https://github.com/acacode/swagger-typescript-api): Open source typescript api codegenerator from Swagger. Uses Eta as codegenerator by templates
|
||||
- [html-bundler-webpack-plugin](https://github.com/webdiscus/html-bundler-webpack-plugin): Webpack plugin make easily to bundle HTML pages from templates, source styles and scripts
|
||||
- [SmartDeno](https://github.com/guildenstern70/SmartDeno): SmartDeno is an easy to setup web template using Deno & Oak
|
||||
- [stc](https://github.com/long-woo/stc): OpenAPI (Swagger) and Apifox documentation converted to api. Use eta templates to generate code.
|
||||
- [Add yours!](https://github.com/bgub/eta/edit/master/README.md)
|
||||
|
||||
## Contributors
|
||||
|
||||
Made with ❤️ by [bgub](https://github.com/bgub) and [many wonderful contributors](https://github.com/bgub/eta/graphs/contributors). Contributions of any kind are welcome!
|
||||
|
||||
## Credits
|
||||
|
||||
- Async support, file handling, and error formatting were based on code from [EJS](https://github.com/mde/ejs), which is licensed under the Apache-2.0 license. Code was modified and refactored to some extent.
|
||||
- Syntax and some parts of compilahttps://jsr.io/@bgub/etation are heavily based off EJS, Nunjucks, and doT.
|
||||
163
node_modules/eta/dist/core.d.ts
generated
vendored
Normal file
163
node_modules/eta/dist/core.d.ts
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
//#region src/parse.d.ts
|
||||
type TagType = "r" | "e" | "i" | "";
|
||||
interface TemplateObject {
|
||||
t: TagType;
|
||||
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;
|
||||
/** 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;
|
||||
/** 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 all safe-to-remove whitespace */
|
||||
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;
|
||||
}
|
||||
/** Eta's base (global) configuration */
|
||||
//#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 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 };
|
||||
//# sourceMappingURL=core.d.ts.map
|
||||
40
node_modules/eta/dist/core.js
generated
vendored
Normal file
40
node_modules/eta/dist/core.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
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=`EtaNameResolution Error`}};function i(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 a(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=c?c+`:`+r+`
|
||||
`:`line `+r+`
|
||||
`,d=new n(u+l+`
|
||||
|
||||
`+e.message);throw d.name=e.name,d}const o=(async()=>{}).constructor;function s(e,n){let r=this.config,i=n?.async?o: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 c(e,t){let n=this.config,r=t?.async,i=this.compileBody,a=this.parse.call(this,e),o=`${n.functionHeader}
|
||||
let include = (template, data) => this.render(template, data, options);
|
||||
let includeAsync = (template, data) => this.renderAsync(template, data, options);
|
||||
|
||||
let __eta = {res: "", e: this.config.escapeFunction, f: this.config.filterFunction${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+`||{}){`:``}
|
||||
|
||||
${i.call(this,a)}
|
||||
if (__eta.layout) {
|
||||
__eta.res = ${r?`await includeAsync`:`include`} (__eta.layout, {...${n.varName}, body: __eta.res, ...__eta.layoutData});
|
||||
}
|
||||
${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 l(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+`
|
||||
`)}}return i}function u(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 d={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};function f(e){return d[e]}function p(e){let t=String(e);return/[&<>"']/.test(t)?t.replace(/[&<>"']/g,f):t}const m={autoEscape:!0,autoFilter:!1,autoTrim:[!1,`nl`],cache:!1,cacheFilepaths:!0,debug:!1,escapeFunction:p,filterFunction:e=>String(e),functionHeader:``,parse:{exec:``,interpolate:`=`,raw:`~`},plugins:[],rmWhitespace:!1,tags:[`<%`,`%>`],useWith:!1,varName:`it`,defaultExtension:`.eta`},h=/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g,g=/'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g,_=/"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g;function v(e){return e.replace(/[.*+\-?^${}()|[\]\\]/g,`\\$&`)}function y(e,t){return e.slice(0,t).split(`
|
||||
`).length}function b(e){let t=this.config,n=[],r=!1,a=0,o=t.parse;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,``)),h.lastIndex=0,g.lastIndex=0,_.lastIndex=0;function s(e,i){e&&(e=u(e,t,r,i),e&&(e=e.replace(/\\|'/g,`\\$&`).replace(/\r\n|\n|\r/g,`\\n`),n.push(e)))}let c=[o.exec,o.interpolate,o.raw].reduce((e,t)=>e&&t?e+`|`+v(t):t?v(t):e,``),l=RegExp(v(t.tags[0])+`(-|_)?\\s*(`+c+`)?\\s*`,`g`),d=RegExp(`'|"|\`|\\/\\*|(\\s*(-|_)?`+v(t.tags[1])+`)`,`g`),f;for(;f=l.exec(e);){let c=e.slice(a,f.index);a=f[0].length+f.index;let u=f[1],p=f[2]||``;s(c,u),d.lastIndex=a;let m,v=!1;for(;m=d.exec(e);)if(m[1]){let t=e.slice(a,m.index);l.lastIndex=a=d.lastIndex,r=m[2],v={t:p===o.exec?`e`:p===o.raw?`r`:p===o.interpolate?`i`:``,val:t};break}else{let t=m[0];if(t===`/*`){let t=e.indexOf(`*/`,d.lastIndex);t===-1&&i(`unclosed comment`,e,m.index),d.lastIndex=t}else t===`'`?(g.lastIndex=m.index,g.exec(e)?d.lastIndex=g.lastIndex:i(`unclosed string`,e,m.index)):t===`"`?(_.lastIndex=m.index,_.exec(e)?d.lastIndex=_.lastIndex:i(`unclosed string`,e,m.index)):t==="`"&&(h.lastIndex=m.index,h.exec(e)?d.lastIndex=h.lastIndex:i(`unclosed string`,e,m.index))}v?(t.debug&&(v.lineNo=y(e,f.index)),n.push(v)):i(`unclosed tag`,e,f.index)}if(s(e.slice(a,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 x(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 r(`Failed to get template '${e}'`)}}function S(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=x.call(this,e,i)):r=e,r.call(this,t,i)}function C(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=x.call(this,e,i)):r=e;let a=r.call(this,t,i);return Promise.resolve(a)}function w(e,t){let n=this.compile(e,{async:!1});return S.call(this,n,t)}function T(e,t){let n=this.compile(e,{async:!0});return C.call(this,n,t)}var E=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}}},D=class{constructor(e){e?this.config={...m,...e}:this.config={...m}}config;RuntimeErr=a;compile=s;compileToString=c;compileBody=l;parse=b;render=S;renderAsync=C;renderString=w;renderStringAsync=T;filepathCache={};templatesSync=new E({});templatesAsync=new E({});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)}}},O=class extends D{};export{O as Eta};
|
||||
//# sourceMappingURL=core.js.map
|
||||
1
node_modules/eta/dist/core.js.map
generated
vendored
Normal file
1
node_modules/eta/dist/core.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
190
node_modules/eta/dist/index.d.ts
generated
vendored
Normal file
190
node_modules/eta/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
//#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);
|
||||
}
|
||||
/**
|
||||
* Throws an EtaError with a nicely formatted error and message showing where in the template the error occurred.
|
||||
*/
|
||||
|
||||
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
|
||||
type TagType = "r" | "e" | "i" | "";
|
||||
interface TemplateObject {
|
||||
t: TagType;
|
||||
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;
|
||||
/** 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;
|
||||
/** 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 all safe-to-remove whitespace */
|
||||
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;
|
||||
}
|
||||
/** Eta's base (global) configuration */
|
||||
//#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 };
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
509
node_modules/eta/dist/index.js
generated
vendored
Normal file
509
node_modules/eta/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,509 @@
|
||||
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 header = filename ? filename + ":" + lineNo + "\n" : "line " + lineNo + "\n";
|
||||
const err = new EtaRuntimeError(header + context + "\n\n" + originalError.message);
|
||||
err.name = originalError.name;
|
||||
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 = (template, data) => this.render(template, data, options);
|
||||
let includeAsync = (template, data) => this.renderAsync(template, data, options);
|
||||
|
||||
let __eta = {res: "", e: this.config.escapeFunction, f: this.config.filterFunction${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 + "||{}){" : ""}
|
||||
|
||||
${compileBody$1.call(this, buffer)}
|
||||
if (__eta.layout) {
|
||||
__eta.res = ${isAsync ? "await includeAsync" : "include"} (__eta.layout, {...${config.varName}, body: __eta.res, ...__eta.layoutData});
|
||||
}
|
||||
${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";
|
||||
}
|
||||
}
|
||||
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 = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
"\"": """,
|
||||
"'": "'"
|
||||
};
|
||||
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,
|
||||
debug: false,
|
||||
escapeFunction: XMLEscape,
|
||||
filterFunction: (val) => String(val),
|
||||
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;
|
||||
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
|
||||
].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" : "",
|
||||
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 };
|
||||
}
|
||||
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.js.map
|
||||
1
node_modules/eta/dist/index.js.map
generated
vendored
Normal file
1
node_modules/eta/dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
67
node_modules/eta/package.json
generated
vendored
Normal file
67
node_modules/eta/package.json
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "eta",
|
||||
"version": "4.0.1",
|
||||
"description": "Lightweight, fast, and powerful embedded JS template engine",
|
||||
"keywords": [
|
||||
"handlebars",
|
||||
"ejs",
|
||||
"eta",
|
||||
"template engine",
|
||||
"embedded template engine",
|
||||
"layouts",
|
||||
"partials",
|
||||
"typescript types"
|
||||
],
|
||||
"homepage": "https://eta.js.org",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"types": "./index.d.ts"
|
||||
},
|
||||
"./core": {
|
||||
"import": "./dist/core.js",
|
||||
"types": "./dist/core.d.ts"
|
||||
}
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"browser": "./dist/core.js",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsdown",
|
||||
"dev": "tsdown --watch",
|
||||
"lint": "biome check --error-on-warnings",
|
||||
"format": "biome format --write",
|
||||
"test": "vitest run --coverage",
|
||||
"size": "size-limit"
|
||||
},
|
||||
"author": "Ben Gubler <nebrelbug@gmail.com>",
|
||||
"funding": "https://github.com/bgub/eta?sponsor=1",
|
||||
"repository": "github:bgub/eta",
|
||||
"bugs": {
|
||||
"url": "https://github.com/bgub/eta/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"size-limit": [
|
||||
{
|
||||
"path": "dist/core.js",
|
||||
"limit": "3.5 KB"
|
||||
}
|
||||
],
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.2.3",
|
||||
"@size-limit/preset-small-lib": "^8.2.4",
|
||||
"@types/node": "^22.18.1",
|
||||
"@vitest/coverage-istanbul": "3.2.4",
|
||||
"size-limit": "^8.2.4",
|
||||
"tsdown": "^0.15.0",
|
||||
"typescript": "^5.9.2",
|
||||
"vitest": "^3.2.4"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user