Migrate to oxlint and oxfmt v2 (#2130)

* Migrate to oxlint and oxfmt
* Address review comments
This commit is contained in:
Igor Savin
2026-03-10 18:27:44 +02:00
committed by GitHub
parent 169ef75066
commit 2f68d9425b
49 changed files with 3189 additions and 3564 deletions
-23
View File
@@ -1,23 +0,0 @@
.rvmrc
.DS_Store
/tmp/
*.sublime-project
*.sublime-workspace
npm-debug.log
.idea
yarn-error.log
node_modules
/handlebars-release.tgz
.nyc_output
# Generated files
/coverage/
/dist/
/tests/integration/*/dist/
# Third-party or files that must remain unchanged
/spec/expected/
/spec/vendor
# JS-Snippets
src/*.js
-64
View File
@@ -1,64 +0,0 @@
module.exports = {
extends: ['eslint:recommended', 'plugin:compat/recommended', 'prettier'],
globals: {
self: false,
},
env: {
node: true,
es2020: true,
},
parserOptions: {
sourceType: 'module',
},
rules: {
'no-console': 'warn',
// temporarily disabled until the violating places are fixed.
'no-func-assign': 'off',
'no-sparse-arrays': 'off',
// Best Practices //
//----------------//
'default-case': 'warn',
'guard-for-in': 'warn',
'no-alert': 'error',
'no-caller': 'error',
'no-div-regex': 'warn',
'no-eval': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'error',
'no-floating-decimal': 'error',
'no-implied-eval': 'error',
'no-iterator': 'error',
'no-labels': 'error',
'no-lone-blocks': 'error',
'no-loop-func': 'error',
'no-multi-str': 'warn',
'no-global-assign': 'error',
'no-new': 'error',
'no-new-func': 'error',
'no-new-wrappers': 'error',
'no-octal-escape': 'error',
'no-process-env': 'error',
'no-proto': 'error',
'no-return-assign': 'error',
'no-script-url': 'error',
'no-self-compare': 'error',
'no-sequences': 'error',
'no-throw-literal': 'error',
'no-unused-expressions': 'error',
'no-warning-comments': 'warn',
'no-with': 'error',
radix: 'error',
// Variables //
//-----------//
'no-label-var': 'error',
'no-undef-init': 'error',
'no-use-before-define': ['error', 'nofunc'],
// ECMAScript 6 //
//--------------//
'no-var': 'error',
},
};
+2
View File
@@ -2,3 +2,5 @@
3d228334530860a6e3f99dc10777c84bf22292c1 3d228334530860a6e3f99dc10777c84bf22292c1
# Format markdown files with Prettier # Format markdown files with Prettier
dfe2eaaf20f0b679d94e5a799757c4394d80f1cc dfe2eaaf20f0b679d94e5a799757c4394d80f1cc
# migrate to oxlint and oxfmt
0c1d00282ca619c3416ad819bdf53c0852b32415
+1 -1
View File
@@ -1,7 +1,7 @@
version: 2 version: 2
updates: updates:
- package-ecosystem: npm - package-ecosystem: npm
directory: "/" directory: '/'
open-pull-requests-limit: 0 open-pull-requests-limit: 0
schedule: schedule:
interval: weekly interval: weekly
+1 -1
View File
@@ -33,6 +33,6 @@ jobs:
git config --global user.name "handlebars-lang" git config --global user.name "handlebars-lang"
npm run publish:aws npm run publish:aws
env: env:
S3_BUCKET_NAME: "builds.handlebarsjs.com" S3_BUCKET_NAME: 'builds.handlebarsjs.com'
S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
+28
View File
@@ -0,0 +1,28 @@
{
"$schema": "https://raw.githubusercontent.com/nicolo-ribaudo/oxfmt-config-schema/refs/heads/main/schema.json",
"singleQuote": true,
"tabWidth": 2,
"semi": true,
"trailingComma": "es5",
"printWidth": 80,
"ignorePatterns": [
".rvmrc",
".DS_Store",
"/tmp/",
"*.sublime-project",
"*.sublime-workspace",
"npm-debug.log",
"sauce_connect.log*",
".idea",
"yarn-error.log",
"/coverage/",
".nyc_output/",
"/dist/",
"/tests/integration/*/dist/",
"/spec/expected/",
"/spec/mustache",
"/spec/vendor",
"*.handlebars",
"*.hbs"
]
}
+151
View File
@@ -0,0 +1,151 @@
{
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
"plugins": ["eslint", "typescript", "unicorn", "oxc", "node", "vitest"],
"categories": {
"correctness": "error"
},
"rules": {
"no-console": "warn",
"no-func-assign": "off",
"no-sparse-arrays": "off",
"default-case": "warn",
"guard-for-in": "warn",
"no-alert": "error",
"no-caller": "error",
"no-div-regex": "warn",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-implied-eval": "error",
"no-iterator": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-loop-func": "error",
"no-multi-str": "warn",
"no-global-assign": "error",
"no-new": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-proto": "error",
"no-return-assign": "error",
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-throw-literal": "error",
"no-unused-expressions": "error",
"no-warning-comments": "warn",
"no-with": "error",
"radix": "error",
"no-label-var": "error",
"no-use-before-define": ["error", { "functions": false }],
"no-var": "error",
"node/no-process-env": "error"
},
"ignorePatterns": [
"tmp/",
"dist/",
"coverage/",
".nyc_output/",
"handlebars-release.tgz",
"tests/integration/*/dist/",
"spec/expected/",
"spec/mustache",
"spec/vendor",
"node_modules",
"types/"
],
"overrides": [
{
"files": ["lib/**/*.js"],
"env": {
"node": false,
"browser": true
}
},
{
"files": ["spec/**/*.js"],
"globals": {
"CompilerContext": "readonly",
"Handlebars": "writable",
"handlebarsEnv": "readonly",
"expectTemplate": "readonly",
"suite": "readonly",
"test": "readonly",
"testBoth": "readonly",
"raises": "readonly",
"deepEqual": "readonly",
"start": "readonly",
"stop": "readonly",
"ok": "readonly",
"vi": "readonly",
"strictEqual": "readonly",
"define": "readonly",
"expect": "readonly",
"beforeEach": "readonly",
"afterEach": "readonly",
"describe": "readonly",
"it": "readonly"
},
"rules": {
"no-var": "off",
"dot-notation": "off",
"vitest/no-conditional-tests": "off"
}
},
{
"files": ["tasks/**/*.js"],
"rules": {
"node/no-process-env": "off",
"prefer-const": "warn",
"dot-notation": "error"
}
},
{
"files": ["tasks/tests/**/*.js"],
"globals": {
"describe": "readonly",
"it": "readonly",
"expect": "readonly",
"beforeEach": "readonly",
"afterEach": "readonly",
"vi": "readonly"
}
},
{
"files": ["tests/bench/**/*.js"],
"rules": {
"no-console": "off",
"no-var": "off"
}
},
{
"files": ["tests/integration/multi-nodejs-test/**/*.js"],
"rules": {
"no-console": "off",
"no-var": "off"
}
},
{
"files": ["tests/browser/**/*.js"],
"env": {
"browser": true
}
},
{
"files": [
"tests/integration/webpack-babel-test/src/**/*.js",
"tests/integration/webpack-test/src/**/*.js"
],
"env": {
"browser": true
},
"rules": {
"no-var": "off"
}
}
]
}
-21
View File
@@ -1,21 +0,0 @@
.rvmrc
.DS_Store
/tmp/
*.sublime-project
*.sublime-workspace
npm-debug.log
sauce_connect.log*
.idea
yarn-error.log
node_modules
/handlebars-release.tgz
.nyc_output
# Generated files
/coverage/
/dist/
/tests/integration/*/dist/
# Third-party or files that must remain unchanged
/spec/expected/
/spec/vendor
+57 -63
View File
@@ -5,8 +5,7 @@
[![Bundle size](https://badgen.net/bundlephobia/minzip/handlebars?label=minified%20%2B%20gzipped)](https://bundlephobia.com/package/handlebars) [![Bundle size](https://badgen.net/bundlephobia/minzip/handlebars?label=minified%20%2B%20gzipped)](https://bundlephobia.com/package/handlebars)
[![Install size](https://packagephobia.com/badge?p=handlebars)](https://packagephobia.com/result?p=handlebars) [![Install size](https://packagephobia.com/badge?p=handlebars)](https://packagephobia.com/result?p=handlebars)
Handlebars.js # Handlebars.js
=============
Handlebars provides the power necessary to let you build **semantic templates** effectively with no frustration. Handlebars provides the power necessary to let you build **semantic templates** effectively with no frustration.
Handlebars is largely compatible with Mustache templates. In most cases it is possible to swap out Mustache with Handlebars and continue using your current templates. Handlebars is largely compatible with Mustache templates. In most cases it is possible to swap out Mustache with Handlebars and continue using your current templates.
@@ -14,13 +13,12 @@ Handlebars is largely compatible with Mustache templates. In most cases it is po
Checkout the official Handlebars docs site at Checkout the official Handlebars docs site at
[handlebarsjs.com](https://handlebarsjs.com) and try our [live demo](https://handlebarsjs.com/playground.html). [handlebarsjs.com](https://handlebarsjs.com) and try our [live demo](https://handlebarsjs.com/playground.html).
Installing ## Installing
----------
See our [installation documentation](https://handlebarsjs.com/guide/installation/). See our [installation documentation](https://handlebarsjs.com/guide/installation/).
Usage ## Usage
-----
In general, the syntax of Handlebars.js templates is a superset In general, the syntax of Handlebars.js templates is a superset
of Mustache templates. For basic syntax, check out the [Mustache of Mustache templates. For basic syntax, check out the [Mustache
manpage](https://mustache.github.io/mustache.5.html). manpage](https://mustache.github.io/mustache.5.html).
@@ -30,13 +28,20 @@ the template into a function. The generated function takes a context
argument, which will be used to render the template. argument, which will be used to render the template.
```js ```js
var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " + var source =
"{{kids.length}} kids:</p>" + '<p>Hello, my name is {{name}}. I am from {{hometown}}. I have ' +
"<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>"; '{{kids.length}} kids:</p>' +
'<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>';
var template = Handlebars.compile(source); var template = Handlebars.compile(source);
var data = { "name": "Alan", "hometown": "Somewhere, TX", var data = {
"kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]}; name: 'Alan',
hometown: 'Somewhere, TX',
kids: [
{ name: 'Jimmy', age: '12' },
{ name: 'Sally', age: '4' },
],
};
var result = template(data); var result = template(data);
// Would render: // Would render:
@@ -49,13 +54,12 @@ var result = template(data);
Full documentation and more examples are at [handlebarsjs.com](https://handlebarsjs.com/). Full documentation and more examples are at [handlebarsjs.com](https://handlebarsjs.com/).
Precompiling Templates ## Precompiling Templates
----------------------
Handlebars allows templates to be precompiled and included as javascript code rather than the handlebars template allowing for faster startup time. Full details are located [here](https://handlebarsjs.com/guide/installation/precompilation.html). Handlebars allows templates to be precompiled and included as javascript code rather than the handlebars template allowing for faster startup time. Full details are located [here](https://handlebarsjs.com/guide/installation/precompilation.html).
Differences Between Handlebars.js and Mustache ## Differences Between Handlebars.js and Mustache
----------------------------------------------
Handlebars.js adds a couple of additional features to make writing Handlebars.js adds a couple of additional features to make writing
templates easier and also changes a tiny detail of how partials work. templates easier and also changes a tiny detail of how partials work.
@@ -70,14 +74,13 @@ Block expressions have the same syntax as mustache sections but should not be co
### Compatibility ### Compatibility
There are a few Mustache behaviors that Handlebars does not implement. There are a few Mustache behaviors that Handlebars does not implement.
- Handlebars deviates from Mustache slightly in that it does not perform recursive lookup by default. The compile time `compat` flag must be set to enable this functionality. Users should note that there is a performance cost for enabling this flag. The exact cost varies by template, but it's recommended that performance sensitive operations should avoid this mode and instead opt for explicit path references. - Handlebars deviates from Mustache slightly in that it does not perform recursive lookup by default. The compile time `compat` flag must be set to enable this functionality. Users should note that there is a performance cost for enabling this flag. The exact cost varies by template, but it's recommended that performance sensitive operations should avoid this mode and instead opt for explicit path references.
- The optional Mustache-style lambdas are not supported. Instead Handlebars provides its own lambda resolution that follows the behaviors of helpers. - The optional Mustache-style lambdas are not supported. Instead Handlebars provides its own lambda resolution that follows the behaviors of helpers.
- Handlebars does not allow space between the opening `{{` and a command character such as `#`, `/` or `>`. The command character must immediately follow the braces, so for example `{{> partial }}` is allowed but `{{ > partial }}` is not. - Handlebars does not allow space between the opening `{{` and a command character such as `#`, `/` or `>`. The command character must immediately follow the braces, so for example `{{> partial }}` is allowed but `{{ > partial }}` is not.
- Alternative delimiters are not supported. - Alternative delimiters are not supported.
## Supported Environments
Supported Environments
----------------------
Handlebars has been designed to work in any ECMAScript 2020 environment. This includes Handlebars has been designed to work in any ECMAScript 2020 environment. This includes
@@ -89,9 +92,7 @@ Handlebars has been designed to work in any ECMAScript 2020 environment. This in
If you need to support older environments, use Handlebars version 4. If you need to support older environments, use Handlebars version 4.
## Performance
Performance
-----------
In a rough performance test, precompiled Handlebars.js templates (in In a rough performance test, precompiled Handlebars.js templates (in
the original version of Handlebars.js) rendered in about half the the original version of Handlebars.js) rendered in about half the
@@ -103,9 +104,7 @@ does have some big performance advantages. Justin Marney, a.k.a.
rewritten Handlebars (current version) is faster than the old version, rewritten Handlebars (current version) is faster than the old version,
with many performance tests being 5 to 7 times faster than the Mustache equivalent. with many performance tests being 5 to 7 times faster than the Mustache equivalent.
## Upgrading
Upgrading
---------
See [release-notes.md](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md) for upgrade notes. See [release-notes.md](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md) for upgrade notes.
@@ -114,54 +113,49 @@ If you are using Handlebars in production, please regularly look for issues labe
If this label is applied to an issue, it means that the requested change is probably not a breaking change, If this label is applied to an issue, it means that the requested change is probably not a breaking change,
but since Handlebars is widely in use by a lot of people, there's always a chance that it breaks somebody's build. but since Handlebars is widely in use by a lot of people, there's always a chance that it breaks somebody's build.
## Known Issues
Known Issues
------------
See [FAQ.md](https://github.com/handlebars-lang/handlebars.js/blob/master/FAQ.md) for known issues and common pitfalls. See [FAQ.md](https://github.com/handlebars-lang/handlebars.js/blob/master/FAQ.md) for known issues and common pitfalls.
## Handlebars in the Wild
Handlebars in the Wild - [apiDoc](https://github.com/apidoc/apidoc) apiDoc uses handlebars as parsing engine for api documentation view generation.
---------------------- - [Assemble](https://assemble.io), by [@jonschlinkert](https://github.com/jonschlinkert) and [@doowb](https://github.com/doowb), is a static site generator that uses Handlebars.js as its template engine.
- [CoSchedule](https://coschedule.com) An editorial calendar for WordPress that uses Handlebars.js.
- [Ember.js](https://www.emberjs.com) makes Handlebars.js the primary way to structure your views, also with automatic data binding support.
- [express-handlebars](https://github.com/express-handlebars/express-handlebars) A Handlebars view engine for Express which doesn't suck.
- [express-hbs](https://github.com/TryGhost/express-hbs) Express Handlebars template engine with inheritance, partials, i18n and async helpers.
- [Ghost](https://ghost.org/) Just a blogging platform.
- [handlebars-action](https://github.com/marketplace/actions/handlebars-action) A GitHub action to transform files in your repository with Handlebars templating.
- [handlebars_assets](https://github.com/leshill/handlebars_assets) A Rails Asset Pipeline gem from Les Hill (@leshill).
- [handlebars-helpers](https://github.com/assemble/handlebars-helpers) is an extensive library with 100+ handlebars helpers.
- [handlebars-layouts](https://github.com/shannonmoeller/handlebars-layouts) is a set of helpers which implement extensible and embeddable layout blocks as seen in other popular templating languages.
- [handlebars-loader](https://github.com/pcardune/handlebars-loader) A handlebars template loader for webpack.
- [handlebars-wax](https://github.com/shannonmoeller/handlebars-wax) The missing Handlebars API. Effortless registration of data, partials, helpers, and decorators using file-system globs, modules, and plain-old JavaScript objects.
- [hbs](https://github.com/pillarjs/hbs) An Express.js view engine adapter for Handlebars.js, from Don Park.
- [html-bundler-webpack-plugin](https://github.com/webdiscus/html-bundler-webpack-plugin) The webpack plugin to compile templates, [supports Handlebars](https://github.com/webdiscus/html-bundler-webpack-plugin#using-template-handlebars).
- [incremental-bars](https://github.com/atomictag/incremental-bars) adds support for [incremental-dom](https://github.com/google/incremental-dom) as template target to Handlebars.
- [jQuery plugin](https://71104.github.io/jquery-handlebars/) allows you to use Handlebars.js with [jQuery](http://jquery.com/).
- [just-handlebars-helpers](https://github.com/leapfrogtechnology/just-handlebars-helpers) A fully tested lightweight package with common Handlebars helpers.
- [koa-hbs](https://github.com/jwilm/koa-hbs) [koa](https://github.com/koajs/koa) generator based renderer for Handlebars.js.
- [Marionette.Handlebars](https://github.com/hashchange/marionette.handlebars) adds support for Handlebars and Mustache templates to Marionette.
- [openVALIDATION](https://github.com/openvalidation/openvalidation) a natural language compiler for validation rules. Generates program code in Java, JavaScript, C#, Python and Rust with handlebars.
- [Plop](https://plopjs.com/) is a micro-generator framework that makes it easy to create files with a level of uniformity.
- [promised-handlebars](https://github.com/nknapp/promised-handlebars) is a wrapper for Handlebars that allows helpers to return Promises.
- [sammy.js](https://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey, supports Handlebars.js as one of its template plugins.
- [Swag](https://github.com/elving/swag) by [@elving](https://github.com/elving) is a growing collection of helpers for handlebars.js. Give your handlebars.js templates some swag son!
- [SproutCore](https://www.sproutcore.com) uses Handlebars.js as its main templating engine, extending it with automatic data binding support.
- [vite-plugin-handlebars](https://github.com/alexlafroscia/vite-plugin-handlebars) A package for Vite 2. Allows for running your HTML files through the Handlebars compiler.
- [YUI](https://yuilibrary.com/yui/docs/handlebars/) implements a port of handlebars.
* [apiDoc](https://github.com/apidoc/apidoc) apiDoc uses handlebars as parsing engine for api documentation view generation. ## External Resources
* [Assemble](https://assemble.io), by [@jonschlinkert](https://github.com/jonschlinkert) and [@doowb](https://github.com/doowb), is a static site generator that uses Handlebars.js as its template engine.
* [CoSchedule](https://coschedule.com) An editorial calendar for WordPress that uses Handlebars.js.
* [Ember.js](https://www.emberjs.com) makes Handlebars.js the primary way to structure your views, also with automatic data binding support.
* [express-handlebars](https://github.com/express-handlebars/express-handlebars) A Handlebars view engine for Express which doesn't suck.
* [express-hbs](https://github.com/TryGhost/express-hbs) Express Handlebars template engine with inheritance, partials, i18n and async helpers.
* [Ghost](https://ghost.org/) Just a blogging platform.
* [handlebars-action](https://github.com/marketplace/actions/handlebars-action) A GitHub action to transform files in your repository with Handlebars templating.
* [handlebars_assets](https://github.com/leshill/handlebars_assets) A Rails Asset Pipeline gem from Les Hill (@leshill).
* [handlebars-helpers](https://github.com/assemble/handlebars-helpers) is an extensive library with 100+ handlebars helpers.
* [handlebars-layouts](https://github.com/shannonmoeller/handlebars-layouts) is a set of helpers which implement extensible and embeddable layout blocks as seen in other popular templating languages.
* [handlebars-loader](https://github.com/pcardune/handlebars-loader) A handlebars template loader for webpack.
* [handlebars-wax](https://github.com/shannonmoeller/handlebars-wax) The missing Handlebars API. Effortless registration of data, partials, helpers, and decorators using file-system globs, modules, and plain-old JavaScript objects.
* [hbs](https://github.com/pillarjs/hbs) An Express.js view engine adapter for Handlebars.js, from Don Park.
* [html-bundler-webpack-plugin](https://github.com/webdiscus/html-bundler-webpack-plugin) The webpack plugin to compile templates, [supports Handlebars](https://github.com/webdiscus/html-bundler-webpack-plugin#using-template-handlebars).
* [incremental-bars](https://github.com/atomictag/incremental-bars) adds support for [incremental-dom](https://github.com/google/incremental-dom) as template target to Handlebars.
* [jQuery plugin](https://71104.github.io/jquery-handlebars/) allows you to use Handlebars.js with [jQuery](http://jquery.com/).
* [just-handlebars-helpers](https://github.com/leapfrogtechnology/just-handlebars-helpers) A fully tested lightweight package with common Handlebars helpers.
* [koa-hbs](https://github.com/jwilm/koa-hbs) [koa](https://github.com/koajs/koa) generator based renderer for Handlebars.js.
* [Marionette.Handlebars](https://github.com/hashchange/marionette.handlebars) adds support for Handlebars and Mustache templates to Marionette.
* [openVALIDATION](https://github.com/openvalidation/openvalidation) a natural language compiler for validation rules. Generates program code in Java, JavaScript, C#, Python and Rust with handlebars.
* [Plop](https://plopjs.com/) is a micro-generator framework that makes it easy to create files with a level of uniformity.
* [promised-handlebars](https://github.com/nknapp/promised-handlebars) is a wrapper for Handlebars that allows helpers to return Promises.
* [sammy.js](https://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey, supports Handlebars.js as one of its template plugins.
* [Swag](https://github.com/elving/swag) by [@elving](https://github.com/elving) is a growing collection of helpers for handlebars.js. Give your handlebars.js templates some swag son!
* [SproutCore](https://www.sproutcore.com) uses Handlebars.js as its main templating engine, extending it with automatic data binding support.
* [vite-plugin-handlebars](https://github.com/alexlafroscia/vite-plugin-handlebars) A package for Vite 2. Allows for running your HTML files through the Handlebars compiler.
* [YUI](https://yuilibrary.com/yui/docs/handlebars/) implements a port of handlebars.
External Resources - [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070)
------------------
* [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070)
Have a project using Handlebars? Send us a [pull request][pull-request]! Have a project using Handlebars? Send us a [pull request][pull-request]!
License ## License
-------
Handlebars.js is released under the MIT license. Handlebars.js is released under the MIT license.
[pull-request]: https://github.com/handlebars-lang/handlebars.js/pull/new/master [pull-request]: https://github.com/handlebars-lang/handlebars.js/pull/new/master
-2
View File
@@ -297,7 +297,6 @@ The `Handlebars.JavaScriptCompiler` object has a number of methods that may be c
- `nameLookup(parent, name, type)` - `nameLookup(parent, name, type)`
Used to generate the code to resolve a given path component. Used to generate the code to resolve a given path component.
- `parent` is the existing code in the path resolution - `parent` is the existing code in the path resolution
- `name` is the current path component - `name` is the current path component
- `type` is the type of name being evaluated. May be one of `context`, `data`, `helper`, `decorator`, or `partial`. - `type` is the type of name being evaluated. May be one of `context`, `data`, `helper`, `decorator`, or `partial`.
@@ -312,7 +311,6 @@ The `Handlebars.JavaScriptCompiler` object has a number of methods that may be c
- `appendToBuffer(source, location, explicit)` - `appendToBuffer(source, location, explicit)`
Allows for code buffer emitting code. Defaults behavior is string concatenation. Allows for code buffer emitting code. Defaults behavior is string concatenation.
- `source` is the source code whose result is to be appending - `source` is the source code whose result is to be appending
- `location` is the location of the source in the source map. - `location` is the location of the source in the source map.
- `explicit` is a flag signaling that the emit operation must occur, vs. the lazy evaled options otherwise. - `explicit` is a flag signaling that the emit operation must occur, vs. the lazy evaled options otherwise.
+17
View File
@@ -0,0 +1,17 @@
import compat from 'eslint-plugin-compat';
export default [
{
// Ignore everything except lib/
ignores: ['**', '!lib/**'],
},
{
// Only check browser API compat in the runtime library code.
// All other linting is handled by oxlint.
...compat.configs['flat/recommended'],
files: ['lib/**/*.js'],
linterOptions: {
reportUnusedDisableDirectives: 'off',
},
},
];
-7
View File
@@ -1,7 +0,0 @@
/* eslint-env node */
module.exports = {
env: {
// Handlebars should run natively in the browser
node: false,
},
};
+2 -1
View File
@@ -8,9 +8,10 @@ try {
if (typeof define !== 'function' || !define.amd) { if (typeof define !== 'function' || !define.amd) {
// We don't support this in AMD environments. For these environments, we assume that // We don't support this in AMD environments. For these environments, we assume that
// they are running on the browser and thus have no need for the source-map library. // they are running on the browser and thus have no need for the source-map library.
let SourceMap = require('source-map'); // eslint-disable-line no-undef let SourceMap = require('source-map');
SourceNode = SourceMap.SourceNode; SourceNode = SourceMap.SourceNode;
} }
// oxlint-disable-next-line no-unused-vars -- Babel 5 requires named catch param
} catch (err) { } catch (err) {
/* NOP */ /* NOP */
} }
+1 -3
View File
@@ -1,5 +1,3 @@
/* eslint-disable new-cap */
import { Exception } from '@handlebars/parser'; import { Exception } from '@handlebars/parser';
import { isArray, indexOf, extend } from '../utils'; import { isArray, indexOf, extend } from '../utils';
import AST from './ast'; import AST from './ast';
@@ -74,7 +72,7 @@ Compiler.prototype = {
}, },
compileProgram: function (program) { compileProgram: function (program) {
let childCompiler = new this.compiler(), // eslint-disable-line new-cap let childCompiler = new this.compiler(),
result = childCompiler.compile(program, this.options), result = childCompiler.compile(program, this.options),
guid = this.guid++; guid = this.guid++;
@@ -158,7 +158,7 @@ JavaScriptCompiler.prototype = {
}; };
if (this.decorators) { if (this.decorators) {
ret.main_d = this.decorators; // eslint-disable-line camelcase ret.main_d = this.decorators;
ret.useDecorators = true; ret.useDecorators = true;
} }
@@ -828,7 +828,7 @@ JavaScriptCompiler.prototype = {
for (let i = 0, l = children.length; i < l; i++) { for (let i = 0, l = children.length; i < l; i++) {
child = children[i]; child = children[i];
compiler = new this.compiler(); // eslint-disable-line new-cap compiler = new this.compiler();
let existing = this.matchExistingProgram(child); let existing = this.matchExistingProgram(child);
-1
View File
@@ -1,6 +1,5 @@
// USAGE: // USAGE:
// var handlebars = require('handlebars'); // var handlebars = require('handlebars');
/* eslint-env node */
/* eslint-disable no-var */ /* eslint-disable no-var */
// var local = handlebars.create(); // var local = handlebars.create();
-1
View File
@@ -1,4 +1,3 @@
/* eslint-env node */
/* eslint-disable no-console */ /* eslint-disable no-console */
import Async from 'neo-async'; import Async from 'neo-async';
import fs from 'fs'; import fs from 'fs';
+2530 -2954
View File
File diff suppressed because it is too large Load Diff
+69 -70
View File
@@ -2,21 +2,54 @@
"name": "handlebars", "name": "handlebars",
"version": "5.0.0-alpha.1", "version": "5.0.0-alpha.1",
"description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration", "description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration",
"homepage": "https://handlebarsjs.com/",
"keywords": [ "keywords": [
"handlebars", "handlebars",
"html",
"mustache", "mustache",
"template", "template"
"html"
], ],
"homepage": "https://handlebarsjs.com/",
"license": "MIT",
"author": "Yehuda Katz",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/handlebars-lang/handlebars.js.git" "url": "https://github.com/handlebars-lang/handlebars.js.git"
}, },
"author": "Yehuda Katz", "bin": {
"license": "MIT", "handlebars": "bin/handlebars.js"
"engines": { },
"node": ">=20" "files": [
"bin",
"dist/*.js",
"dist/cjs/**/*.js",
"lib",
"release-notes.md",
"runtime.js",
"types/*.d.ts",
"runtime.d.ts"
],
"main": "lib/index.js",
"browser": "./dist/cjs/handlebars.js",
"types": "types/index.d.ts",
"scripts": {
"build": "grunt build",
"release": "grunt release",
"publish:aws": "grunt && npm run test:tasks && grunt publish-to-aws",
"format": "oxfmt --write . && oxlint --fix .",
"lint": "npm run lint:oxlint && npm run lint:format && npm run lint:types && npm run lint:compat",
"lint:oxlint": "oxlint --max-warnings 0 .",
"lint:format": "oxfmt --check .",
"lint:types": "tsc --noEmit --project types",
"lint:compat": "eslint",
"test": "grunt build && vitest run --project node --project tasks --coverage",
"test:browser": "vitest run --project browser",
"test:unit": "vitest run --project node",
"test:tasks": "vitest run --project tasks",
"test:browser-smoke": "playwright test --config tests/browser/playwright.config.js",
"test:integration": "grunt integration-tests",
"test:serve": "grunt connect:server:keepalive",
"--- combined tasks ---": "",
"check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:test"
}, },
"dependencies": { "dependencies": {
"@handlebars/parser": "^2.1.0", "@handlebars/parser": "^2.1.0",
@@ -24,9 +57,6 @@
"source-map": "^0.6.1", "source-map": "^0.6.1",
"yargs": "^16.2.0" "yargs": "^16.2.0"
}, },
"peerDependencies": {
"uglify-js": "^3.1.4"
},
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.58.2", "@playwright/test": "^1.58.2",
"@vitest/browser": "^4.0.18", "@vitest/browser": "^4.0.18",
@@ -38,9 +68,8 @@
"benchmark": "~1.0", "benchmark": "~1.0",
"concurrently": "^5.0.0", "concurrently": "^5.0.0",
"dustjs-linkedin": "^2.0.2", "dustjs-linkedin": "^2.0.2",
"eslint": "^8.25.0", "eslint": "^10.0.3",
"eslint-config-prettier": "^8.9.0", "eslint-plugin-compat": "^7.0.1",
"eslint-plugin-compat": "4.0",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"grunt": "^1.0.4", "grunt": "^1.0.4",
"grunt-babel": "^5.0.0", "grunt-babel": "^5.0.0",
@@ -55,10 +84,11 @@
"grunt-shell": "^4.0.0", "grunt-shell": "^4.0.0",
"grunt-webpack": "^1.0.8", "grunt-webpack": "^1.0.8",
"husky": "^3.1.0", "husky": "^3.1.0",
"lint-staged": "^9.5.0", "lint-staged": "^16.3.2",
"mock-stdin": "^0.3.0", "mock-stdin": "^0.3.0",
"mustache": "^2.1.3", "mustache": "^2.1.3",
"prettier": "^3.0.0", "oxfmt": "^0.36.0",
"oxlint": "^1.51.0",
"semver": "^5.0.1", "semver": "^5.0.1",
"typescript": "^3.4.3", "typescript": "^3.4.3",
"uglify-js": "^3.1.4", "uglify-js": "^3.1.4",
@@ -67,30 +97,31 @@
"webpack": "^1.12.6", "webpack": "^1.12.6",
"webpack-dev-server": "^1.12.1" "webpack-dev-server": "^1.12.1"
}, },
"main": "lib/index.js", "peerDependencies": {
"types": "types/index.d.ts", "uglify-js": "^3.1.4"
"browser": "./dist/cjs/handlebars.js",
"bin": {
"handlebars": "bin/handlebars.js"
}, },
"scripts": { "husky": {
"build": "grunt build", "hooks": {
"release": "grunt release", "pre-commit": "lint-staged"
"publish:aws": "grunt && npm run test:tasks && grunt publish-to-aws", }
"format": "prettier --write '**/*.{js,css,json,md}' && eslint --fix .", },
"lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:types", "lint-staged": {
"lint:eslint": "eslint --max-warnings 0 .", "*.{js,css,json,md}": [
"lint:prettier": "prettier --check '**/*.js'", "oxfmt --write"
"lint:types": "tsc --noEmit --project types", ],
"test": "grunt build && vitest run --project node --project tasks --coverage", "*.js": [
"test:browser": "vitest run --project browser", "oxlint --fix"
"test:unit": "vitest run --project node", ]
"test:tasks": "vitest run --project tasks", },
"test:browser-smoke": "playwright test --config tests/browser/playwright.config.js", "browserslist": [
"test:integration": "grunt integration-tests", "last 2 versions",
"test:serve": "grunt connect:server:keepalive", "Firefox ESR",
"--- combined tasks ---": "", "not dead",
"check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:test" "not IE 11",
"maintained node versions"
],
"engines": {
"node": ">=20"
}, },
"jspm": { "jspm": {
"main": "handlebars", "main": "handlebars",
@@ -100,37 +131,5 @@
"buildConfig": { "buildConfig": {
"minify": true "minify": true
} }
},
"files": [
"bin",
"dist/*.js",
"dist/cjs/**/*.js",
"lib",
"release-notes.md",
"runtime.js",
"types/*.d.ts",
"runtime.d.ts"
],
"browserslist": [
"last 2 versions",
"Firefox ESR",
"not dead",
"not IE 11",
"maintained node versions"
],
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,css,json,md}": [
"prettier --write",
"git add"
],
"*.js": [
"eslint --fix",
"git add"
]
} }
} }
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
tabWidth: 2,
semi: true,
singleQuote: true,
trailingComma: 'es5',
};
-1
View File
@@ -356,7 +356,6 @@ Breaking changes:
Compatibility notes: Compatibility notes:
- Compiler revision increased - 06b7224 - Compiler revision increased - 06b7224
- This means that template compiled with versions prior to 4.3.0 will not work with runtimes >= 4.3.0 - This means that template compiled with versions prior to 4.3.0 will not work with runtimes >= 4.3.0
The increase was done because the "helperMissing" and "blockHelperMissing" are now moved from the helpers The increase was done because the "helperMissing" and "blockHelperMissing" are now moved from the helpers
to the internal "container.hooks" object, so old templates will not be able to call them anymore. We suggest to the internal "container.hooks" object, so old templates will not be able to call them anymore. We suggest
+2 -4
View File
@@ -1,5 +1,3 @@
import Handlebars = require('handlebars') import Handlebars = require('handlebars');
declare module "handlebars/runtime" { declare module 'handlebars/runtime' {}
}
-31
View File
@@ -1,31 +0,0 @@
module.exports = {
globals: {
CompilerContext: true,
Handlebars: true,
handlebarsEnv: true,
expectTemplate: true,
suite: true,
test: true,
testBoth: true,
raises: true,
deepEqual: true,
start: true,
stop: true,
ok: true,
vi: true,
strictEqual: true,
define: true,
expect: true,
beforeEach: true,
afterEach: true,
describe: true,
it: true,
},
rules: {
// Disabling for tests, for now.
'no-path-concat': 'off',
'no-var': 'off',
'dot-notation': 'off',
},
};
-2
View File
@@ -115,7 +115,6 @@ describe('ast', function () {
expect(node.loc.end.column).toBe(lastColumn); expect(node.loc.end.column).toBe(lastColumn);
} }
/* eslint-disable no-multi-spaces */
ast = Handlebars.parse( ast = Handlebars.parse(
'line 1 {{line1Token}}\n' + // 1 'line 1 {{line1Token}}\n' + // 1
' line 2 {{line2token}}\n' + // 2 ' line 2 {{line2token}}\n' + // 2
@@ -129,7 +128,6 @@ describe('ast', function () {
'{{else}}\n' + // 10 '{{else}}\n' + // 10
'{{/open}}' '{{/open}}'
); // 11 ); // 11
/* eslint-enable no-multi-spaces */
body = ast.body; body = ast.body;
it('gets ContentNode line numbers', function () { it('gets ContentNode line numbers', function () {
+16 -6
View File
@@ -2,8 +2,8 @@
<html> <html>
<head> <head>
<title>Handlebars UMD Smoke Test</title> <title>Handlebars UMD Smoke Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head> </head>
<body> <body>
<h1>Handlebars UMD Smoke Test</h1> <h1>Handlebars UMD Smoke Test</h1>
@@ -26,9 +26,18 @@
try { try {
assert(typeof Handlebars !== 'undefined', 'Handlebars is defined'); assert(typeof Handlebars !== 'undefined', 'Handlebars is defined');
assert(typeof Handlebars.compile === 'function', 'Handlebars.compile exists'); assert(
assert(typeof Handlebars.template === 'function', 'Handlebars.template exists'); typeof Handlebars.compile === 'function',
assert(typeof Handlebars.VERSION === 'string', 'Handlebars.VERSION exists'); 'Handlebars.compile exists'
);
assert(
typeof Handlebars.template === 'function',
'Handlebars.template exists'
);
assert(
typeof Handlebars.VERSION === 'string',
'Handlebars.VERSION exists'
);
var template = Handlebars.compile('Hello {{name}}!'); var template = Handlebars.compile('Hello {{name}}!');
var output = template({ name: 'World' }); var output = template({ name: 'World' });
@@ -38,7 +47,8 @@
results.textContent += 'ERROR: ' + e.message + '\n'; results.textContent += 'ERROR: ' + e.message + '\n';
} }
results.textContent += '\n' + tests + ' tests, ' + failures + ' failures\n'; results.textContent +=
'\n' + tests + ' tests, ' + failures + ' failures\n';
window.mochaResults = { passes: tests - failures, failures: failures }; window.mochaResults = { passes: tests - failures, failures: failures };
</script> </script>
</body> </body>
-2
View File
@@ -19,11 +19,9 @@ describe('javascript-compiler api', function () {
) { ) {
return parent + '.bar_' + name; return parent + '.bar_' + name;
}; };
/* eslint-disable camelcase */
expectTemplate('{{foo}}') expectTemplate('{{foo}}')
.withInput({ bar_foo: 'food' }) .withInput({ bar_foo: 'food' })
.toCompileTo('food'); .toCompileTo('food');
/* eslint-enable camelcase */
}); });
// Tests nameLookup dot vs. bracket behavior. Bracket is required in certain cases // Tests nameLookup dot vs. bracket behavior. Bracket is required in certain cases
+1 -2
View File
@@ -165,8 +165,7 @@ describe('partials', function () {
it('registering undefined partial throws an exception', function () { it('registering undefined partial throws an exception', function () {
expect(function () { expect(function () {
var undef; handlebarsEnv.registerPartial('undefined_test', undefined);
handlebarsEnv.registerPartial('undefined_test', undef);
}).toThrow( }).toThrow(
'Attempting to register a partial called "undefined_test" as undefined' 'Attempting to register a partial called "undefined_test" as undefined'
); );
-1
View File
@@ -274,7 +274,6 @@ describe('precompiler', function () {
describe('#loadTemplates', function () { describe('#loadTemplates', function () {
function loadTemplatesAsync(inputOpts) { function loadTemplatesAsync(inputOpts) {
// eslint-disable-next-line compat/compat
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
Precompiler.loadTemplates(inputOpts, function (err, opts) { Precompiler.loadTemplates(inputOpts, function (err, opts) {
if (err) { if (err) {
+1 -1
View File
@@ -3,7 +3,7 @@ try {
var SourceMap = require('source-map'), var SourceMap = require('source-map'),
SourceMapConsumer = SourceMap.SourceMapConsumer; SourceMapConsumer = SourceMap.SourceMapConsumer;
} }
} catch (err) { } catch {
/* NOP for in browser */ /* NOP for in browser */
} }
+19 -9
View File
@@ -2,8 +2,8 @@
<html> <html>
<head> <head>
<title>Handlebars Runtime UMD Smoke Test</title> <title>Handlebars Runtime UMD Smoke Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head> </head>
<body> <body>
<h1>Handlebars Runtime UMD Smoke Test</h1> <h1>Handlebars Runtime UMD Smoke Test</h1>
@@ -26,21 +26,31 @@
requirejs.config({ requirejs.config({
paths: { paths: {
'handlebars.runtime': '/dist/handlebars.runtime' 'handlebars.runtime': '/dist/handlebars.runtime',
} },
}); });
require(['handlebars.runtime'], function(Handlebars) { require(['handlebars.runtime'], function (Handlebars) {
try { try {
assert(typeof Handlebars !== 'undefined', 'Handlebars runtime loaded via RequireJS'); assert(
assert(typeof Handlebars.template === 'function', 'Handlebars.template exists'); typeof Handlebars !== 'undefined',
assert(typeof Handlebars.VERSION === 'string', 'Handlebars.VERSION exists'); 'Handlebars runtime loaded via RequireJS'
);
assert(
typeof Handlebars.template === 'function',
'Handlebars.template exists'
);
assert(
typeof Handlebars.VERSION === 'string',
'Handlebars.VERSION exists'
);
} catch (e) { } catch (e) {
failures++; failures++;
results.textContent += 'ERROR: ' + e.message + '\n'; results.textContent += 'ERROR: ' + e.message + '\n';
} }
results.textContent += '\n' + tests + ' tests, ' + failures + ' failures\n'; results.textContent +=
'\n' + tests + ' tests, ' + failures + ' failures\n';
window.mochaResults = { passes: tests - failures, failures: failures }; window.mochaResults = { passes: tests - failures, failures: failures };
}); });
</script> </script>
+23 -10
View File
@@ -2,8 +2,8 @@
<html> <html>
<head> <head>
<title>Handlebars UMD Module Smoke Test</title> <title>Handlebars UMD Module Smoke Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head> </head>
<body> <body>
<h1>Handlebars UMD Module Smoke Test</h1> <h1>Handlebars UMD Module Smoke Test</h1>
@@ -26,16 +26,28 @@
requirejs.config({ requirejs.config({
paths: { paths: {
handlebars: '/dist/handlebars' handlebars: '/dist/handlebars',
} },
}); });
require(['handlebars'], function(Handlebars) { require(['handlebars'], function (Handlebars) {
try { try {
assert(typeof Handlebars !== 'undefined', 'Handlebars loaded via RequireJS'); assert(
assert(typeof Handlebars.compile === 'function', 'Handlebars.compile exists'); typeof Handlebars !== 'undefined',
assert(typeof Handlebars.template === 'function', 'Handlebars.template exists'); 'Handlebars loaded via RequireJS'
assert(typeof Handlebars.VERSION === 'string', 'Handlebars.VERSION exists'); );
assert(
typeof Handlebars.compile === 'function',
'Handlebars.compile exists'
);
assert(
typeof Handlebars.template === 'function',
'Handlebars.template exists'
);
assert(
typeof Handlebars.VERSION === 'string',
'Handlebars.VERSION exists'
);
var template = Handlebars.compile('Hello {{name}}!'); var template = Handlebars.compile('Hello {{name}}!');
var output = template({ name: 'UMD' }); var output = template({ name: 'UMD' });
@@ -45,7 +57,8 @@
results.textContent += 'ERROR: ' + e.message + '\n'; results.textContent += 'ERROR: ' + e.message + '\n';
} }
results.textContent += '\n' + tests + ' tests, ' + failures + ' failures\n'; results.textContent +=
'\n' + tests + ' tests, ' + failures + ' failures\n';
window.mochaResults = { passes: tests - failures, failures: failures }; window.mochaResults = { passes: tests - failures, failures: failures };
}); });
</script> </script>
-8
View File
@@ -1,8 +0,0 @@
module.exports = {
rules: {
'no-process-env': 'off',
'prefer-const': 'warn',
'compat/compat': 'off',
'dot-notation': ['error', { allowKeywords: true }],
},
};
+1 -1
View File
@@ -9,7 +9,7 @@ module.exports = function (grunt) {
const events = {}; const events = {};
const promises = Object.keys(metrics).map(async (name) => { const promises = Object.keys(metrics).map(async (name) => {
if (/^_/.test(name)) { if (name.startsWith('_')) {
return; return;
} }
if (onlyExecuteName != null && name !== onlyExecuteName) { if (onlyExecuteName != null && name !== onlyExecuteName) {
-10
View File
@@ -1,10 +0,0 @@
module.exports = {
globals: {
describe: true,
it: true,
expect: true,
beforeEach: true,
afterEach: true,
vi: true,
},
};
+1 -1
View File
@@ -52,7 +52,7 @@ async function getTagName() {
} }
const tags = trimmedStdout.split(/\n|\r\n/); const tags = trimmedStdout.split(/\n|\r\n/);
const versionTags = tags.filter((tag) => /^v/.test(tag)); const versionTags = tags.filter((tag) => tag.startsWith('v'));
if (versionTags[0] != null) { if (versionTags[0] != null) {
return versionTags[0]; return versionTags[0];
} }
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
rules: {
'no-console': 'off',
'no-var': 'off',
},
};
+2 -2
View File
@@ -6,13 +6,13 @@ var _ = require('underscore'),
try { try {
dust = require('dustjs-linkedin'); dust = require('dustjs-linkedin');
} catch (err) { } catch {
/* NOP */ /* NOP */
} }
try { try {
Mustache = require('mustache'); Mustache = require('mustache');
} catch (err) { } catch {
/* NOP */ /* NOP */
} }
+2 -2
View File
@@ -165,7 +165,7 @@ BenchWarmer.prototype = {
horSize = horSize + 'WINNER(S)'.length; horSize = horSize + 'WINNER(S)'.length;
} }
console.log('\n' + new Array(horSize + 1).join('-')); console.log('\n' + '-'.repeat(horSize));
}, },
startLine: function (name) { startLine: function (name) {
@@ -214,7 +214,7 @@ BenchWarmer.prototype = {
writeValue: function (out) { writeValue: function (out) {
var padding = this.benchSize - out.length + 1; var padding = this.benchSize - out.length + 1;
out = out + new Array(padding).join(' '); out = out + ' '.repeat(Math.max(0, padding - 1));
console.log(out); console.log(out);
}, },
}; };
-5
View File
@@ -1,5 +0,0 @@
module.exports = {
parserOptions: {
ecmaVersion: 2018,
},
};
@@ -1,6 +0,0 @@
module.exports = {
rules: {
'no-console': 'off',
'no-var': 'off',
},
};
@@ -1,16 +1,16 @@
{ {
"name": "multi-nodejs-test", "name": "multi-nodejs-test",
"version": "1.0.0", "version": "1.0.0",
"private": true,
"description": "Simple integration test with all relevant NodeJS-versions.", "description": "Simple integration test with all relevant NodeJS-versions.",
"keywords": [], "keywords": [],
"author": "Nils Knappmeier",
"private": true,
"license": "MIT", "license": "MIT",
"dependencies": { "author": "Nils Knappmeier",
"handlebars": "file:../../.."
},
"scripts": { "scripts": {
"test": "node run-handlebars.js", "test": "node run-handlebars.js",
"test-precompile": "handlebars precompile-test-template.txt.hbs" "test-precompile": "handlebars precompile-test-template.txt.hbs"
},
"dependencies": {
"handlebars": "file:../../.."
} }
} }
+2 -2
View File
@@ -1,11 +1,11 @@
{ {
"name": "rollup-test", "name": "rollup-test",
"description": "Various tests with Handlebars and rollup",
"version": "1.0.0", "version": "1.0.0",
"private": true,
"description": "Various tests with Handlebars and rollup",
"scripts": { "scripts": {
"build": "rollup --config rollup.config.js" "build": "rollup --config rollup.config.js"
}, },
"private": true,
"devDependencies": { "devDependencies": {
"@rollup/plugin-node-resolve": "^13.1.1", "@rollup/plugin-node-resolve": "^13.1.1",
"handlebars": "file:../../..", "handlebars": "file:../../..",
@@ -1,11 +1,7 @@
{ {
"plugins": [ "plugins": [
"@roundingwellos/babel-plugin-handlebars-inline-precompile" "@roundingwellos/babel-plugin-handlebars-inline-precompile"
// "istanbul" // "istanbul"
], ],
"presets": [ "presets": [["@babel/preset-env"]]
[
"@babel/preset-env"
]
]
} }
@@ -1,8 +1,8 @@
{ {
"name": "webpack-babel-test", "name": "webpack-babel-test",
"description": "",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"description": "",
"scripts": { "scripts": {
"build": "webpack --config webpack.config.js" "build": "webpack --config webpack.config.js"
}, },
@@ -1,12 +0,0 @@
/* eslint-env node */
module.exports = {
root: true,
extends: ['eslint:recommended', 'prettier'],
env: {
browser: true,
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 6,
},
};
+1 -1
View File
@@ -1,8 +1,8 @@
{ {
"name": "webpack-test", "name": "webpack-test",
"description": "Various tests with Handlebars and multiple webpack versions",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"description": "Various tests with Handlebars and multiple webpack versions",
"scripts": { "scripts": {
"build": "webpack --config webpack.config.js" "build": "webpack --config webpack.config.js"
}, },
@@ -1,12 +0,0 @@
module.exports = {
root: true,
extends: ['eslint:recommended', 'prettier'],
env: {
node: true,
browser: true,
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 6,
},
};
+127 -109
View File
@@ -14,46 +14,54 @@
*/ */
// TypeScript Version: 2.3 // TypeScript Version: 2.3
import { import {
parse, parse,
parseWithoutProcessing, parseWithoutProcessing,
ParseOptions, ParseOptions,
AST AST,
} from '@handlebars/parser'; } from '@handlebars/parser';
declare namespace Handlebars { declare namespace Handlebars {
export interface TemplateDelegate<T = any> { export interface TemplateDelegate<T = any> {
(context: T, options?: RuntimeOptions): string; (context: T, options?: RuntimeOptions): string;
} }
export type Template<T = any> = TemplateDelegate<T>|string; export type Template<T = any> = TemplateDelegate<T> | string;
export interface RuntimeOptions { export interface RuntimeOptions {
partial?: boolean; partial?: boolean;
depths?: any[]; depths?: any[];
helpers?: { [name: string]: Function }; helpers?: { [name: string]: Function };
partials?: { [name: string]: Template }; partials?: { [name: string]: Template };
decorators?: { [name: string]: Function }; decorators?: { [name: string]: Function };
data?: any; data?: any;
blockParams?: any[]; blockParams?: any[];
allowCallsToHelperMissing?: boolean; allowCallsToHelperMissing?: boolean;
allowedProtoProperties?: { [name: string]: boolean }; allowedProtoProperties?: { [name: string]: boolean };
allowedProtoMethods?: { [name: string]: boolean }; allowedProtoMethods?: { [name: string]: boolean };
allowProtoPropertiesByDefault?: boolean; allowProtoPropertiesByDefault?: boolean;
allowProtoMethodsByDefault?: boolean; allowProtoMethodsByDefault?: boolean;
} }
export interface HelperOptions { export interface HelperOptions {
fn: TemplateDelegate; fn: TemplateDelegate;
inverse: TemplateDelegate; inverse: TemplateDelegate;
hash: Record<string, any>; hash: Record<string, any>;
data?: any; data?: any;
} }
export interface HelperDelegate { export interface HelperDelegate {
(context?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, options?: HelperOptions): any; (
context?: any,
arg1?: any,
arg2?: any,
arg3?: any,
arg4?: any,
arg5?: any,
options?: HelperOptions
): any;
} }
export interface HelperDeclareSpec { export interface HelperDeclareSpec {
[key: string]: HelperDelegate; [key: string]: HelperDelegate;
} }
export { parse, parseWithoutProcessing, ParseOptions }; export { parse, parseWithoutProcessing, ParseOptions };
@@ -75,9 +83,17 @@ declare namespace Handlebars {
export function blockParams(obj: any[], ids: any[]): any[]; export function blockParams(obj: any[], ids: any[]): any[];
export function log(level: number, obj: any): void; export function log(level: number, obj: any): void;
export function compile<T = any>(input: any, options?: CompileOptions): HandlebarsTemplateDelegate<T>; export function compile<T = any>(
export function precompile(input: any, options?: PrecompileOptions): TemplateSpecification; input: any,
export function template<T = any>(precompilation: TemplateSpecification): HandlebarsTemplateDelegate<T>; options?: CompileOptions
): HandlebarsTemplateDelegate<T>;
export function precompile(
input: any,
options?: PrecompileOptions
): TemplateSpecification;
export function template<T = any>(
precompilation: TemplateSpecification
): HandlebarsTemplateDelegate<T>;
export function create(): typeof Handlebars; export function create(): typeof Handlebars;
@@ -95,87 +111,86 @@ declare namespace Handlebars {
export function noConflict(): typeof Handlebars; export function noConflict(): typeof Handlebars;
export class Exception { export class Exception {
constructor(message: string, node?: hbs.AST.Node); constructor(message: string, node?: hbs.AST.Node);
description: string; description: string;
fileName: string; fileName: string;
lineNumber?: any; lineNumber?: any;
endLineNumber?: any; endLineNumber?: any;
message: string; message: string;
name: string; name: string;
number: number; number: number;
stack?: string; stack?: string;
column?: any; column?: any;
endColumn?: any; endColumn?: any;
} }
export class SafeString { export class SafeString {
constructor(str: string); constructor(str: string);
toString(): string; toString(): string;
toHTML(): string; toHTML(): string;
} }
export namespace Utils { export namespace Utils {
export function escapeExpression(str: string): string; export function escapeExpression(str: string): string;
export function createFrame(object: any): any; export function createFrame(object: any): any;
export function blockParams(obj: any[], ids: any[]): any[]; export function blockParams(obj: any[], ids: any[]): any[];
export function isEmpty(obj: any) : boolean; export function isEmpty(obj: any): boolean;
export function extend(obj: any, ...source: any[]): any; export function extend(obj: any, ...source: any[]): any;
export function toString(obj: any): string; export function toString(obj: any): string;
export function isArray(obj: any): boolean; export function isArray(obj: any): boolean;
export function isFunction(obj: any): boolean; export function isFunction(obj: any): boolean;
export function isMap(obj: any): boolean; export function isMap(obj: any): boolean;
export function isSet(obj: any): boolean; export function isSet(obj: any): boolean;
} }
export namespace AST { export namespace AST {
export const helpers: hbs.AST.helpers; export const helpers: hbs.AST.helpers;
} }
export interface ICompiler { export interface ICompiler {
accept(node: hbs.AST.Node): void; accept(node: hbs.AST.Node): void;
Program(program: hbs.AST.Program): void; Program(program: hbs.AST.Program): void;
BlockStatement(block: hbs.AST.BlockStatement): void; BlockStatement(block: hbs.AST.BlockStatement): void;
PartialStatement(partial: hbs.AST.PartialStatement): void; PartialStatement(partial: hbs.AST.PartialStatement): void;
PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void;
DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void;
Decorator(decorator: hbs.AST.Decorator): void; Decorator(decorator: hbs.AST.Decorator): void;
MustacheStatement(mustache: hbs.AST.MustacheStatement): void; MustacheStatement(mustache: hbs.AST.MustacheStatement): void;
ContentStatement(content: hbs.AST.ContentStatement): void; ContentStatement(content: hbs.AST.ContentStatement): void;
CommentStatement(comment?: hbs.AST.CommentStatement): void; CommentStatement(comment?: hbs.AST.CommentStatement): void;
SubExpression(sexpr: hbs.AST.SubExpression): void; SubExpression(sexpr: hbs.AST.SubExpression): void;
PathExpression(path: hbs.AST.PathExpression): void; PathExpression(path: hbs.AST.PathExpression): void;
StringLiteral(str: hbs.AST.StringLiteral): void; StringLiteral(str: hbs.AST.StringLiteral): void;
NumberLiteral(num: hbs.AST.NumberLiteral): void; NumberLiteral(num: hbs.AST.NumberLiteral): void;
BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; BooleanLiteral(bool: hbs.AST.BooleanLiteral): void;
UndefinedLiteral(): void; UndefinedLiteral(): void;
NullLiteral(): void; NullLiteral(): void;
Hash(hash: hbs.AST.Hash): void; Hash(hash: hbs.AST.Hash): void;
} }
export class Visitor implements ICompiler { export class Visitor implements ICompiler {
accept(node: hbs.AST.Node): void; accept(node: hbs.AST.Node): void;
acceptKey(node: hbs.AST.Node, name: string): void; acceptKey(node: hbs.AST.Node, name: string): void;
acceptArray(arr: hbs.AST.Expression[]): void; acceptArray(arr: hbs.AST.Expression[]): void;
Program(program: hbs.AST.Program): void; Program(program: hbs.AST.Program): void;
BlockStatement(block: hbs.AST.BlockStatement): void; BlockStatement(block: hbs.AST.BlockStatement): void;
PartialStatement(partial: hbs.AST.PartialStatement): void; PartialStatement(partial: hbs.AST.PartialStatement): void;
PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void;
DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void;
Decorator(decorator: hbs.AST.Decorator): void; Decorator(decorator: hbs.AST.Decorator): void;
MustacheStatement(mustache: hbs.AST.MustacheStatement): void; MustacheStatement(mustache: hbs.AST.MustacheStatement): void;
ContentStatement(content: hbs.AST.ContentStatement): void; ContentStatement(content: hbs.AST.ContentStatement): void;
CommentStatement(comment?: hbs.AST.CommentStatement): void; CommentStatement(comment?: hbs.AST.CommentStatement): void;
SubExpression(sexpr: hbs.AST.SubExpression): void; SubExpression(sexpr: hbs.AST.SubExpression): void;
PathExpression(path: hbs.AST.PathExpression): void; PathExpression(path: hbs.AST.PathExpression): void;
StringLiteral(str: hbs.AST.StringLiteral): void; StringLiteral(str: hbs.AST.StringLiteral): void;
NumberLiteral(num: hbs.AST.NumberLiteral): void; NumberLiteral(num: hbs.AST.NumberLiteral): void;
BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; BooleanLiteral(bool: hbs.AST.BooleanLiteral): void;
UndefinedLiteral(): void; UndefinedLiteral(): void;
NullLiteral(): void; NullLiteral(): void;
Hash(hash: hbs.AST.Hash): void; Hash(hash: hbs.AST.Hash): void;
} }
export interface ResolvePartialOptions { export interface ResolvePartialOptions {
name: string; name: string;
helpers?: { [name: string]: Function }; helpers?: { [name: string]: Function };
@@ -188,27 +203,30 @@ declare namespace Handlebars {
/** /**
* @deprecated * @deprecated
*/ */
export function resolvePartial<T = any>(partial: HandlebarsTemplateDelegate<T> | undefined, context: any, options: ResolvePartialOptions): HandlebarsTemplateDelegate<T>; export function resolvePartial<T = any>(
partial: HandlebarsTemplateDelegate<T> | undefined,
context: any,
options: ResolvePartialOptions
): HandlebarsTemplateDelegate<T>;
} }
} }
/** /**
* Implement this interface on your MVW/MVVM/MVC views such as Backbone.View * Implement this interface on your MVW/MVVM/MVC views such as Backbone.View
**/ **/
export interface HandlebarsTemplatable { export interface HandlebarsTemplatable {
template: HandlebarsTemplateDelegate; template: HandlebarsTemplateDelegate;
} }
// NOTE: for backward compatibility of this typing // NOTE: for backward compatibility of this typing
export type HandlebarsTemplateDelegate<T = any> = Handlebars.TemplateDelegate<T>; export type HandlebarsTemplateDelegate<T = any> =
Handlebars.TemplateDelegate<T>;
export interface HandlebarsTemplates { export interface HandlebarsTemplates {
[index: string]: HandlebarsTemplateDelegate; [index: string]: HandlebarsTemplateDelegate;
} }
export interface TemplateSpecification { export interface TemplateSpecification {}
}
// for backward compatibility of this typing // for backward compatibility of this typing
export type RuntimeOptions = Handlebars.RuntimeOptions; export type RuntimeOptions = Handlebars.RuntimeOptions;
@@ -231,14 +249,14 @@ export type KnownHelpers = {
}; };
export type BuiltinHelperName = export type BuiltinHelperName =
"helperMissing"| | 'helperMissing'
"blockHelperMissing"| | 'blockHelperMissing'
"each"| | 'each'
"if"| | 'if'
"unless"| | 'unless'
"with"| | 'with'
"log"| | 'log'
"lookup"; | 'lookup';
export type CustomHelperName = string; export type CustomHelperName = string;
@@ -253,7 +271,7 @@ export namespace hbs {
export type Utils = typeof Handlebars.Utils; export type Utils = typeof Handlebars.Utils;
export { AST } export { AST };
} }
export interface Logger { export interface Logger {
@@ -268,9 +286,9 @@ export interface Logger {
log(level: number, obj: string): void; log(level: number, obj: string): void;
} }
export type CompilerInfo = [number/* revision */, string /* versions */]; export type CompilerInfo = [number /* revision */, string /* versions */];
declare module "handlebars/runtime" { declare module 'handlebars/runtime' {
export = Handlebars; export = Handlebars;
} }
+120 -84
View File
@@ -10,184 +10,213 @@ import { HandlebarsTemplateDelegate, hbs } from 'handlebars';
const context = { const context = {
author: { firstName: 'Alan', lastName: 'Johnson' }, author: { firstName: 'Alan', lastName: 'Johnson' },
body: 'I Love Handlebars', body: 'I Love Handlebars',
comments: [{ comments: [
author: { firstName: 'Yehuda', lastName: 'Katz' }, {
body: 'Me too!' author: { firstName: 'Yehuda', lastName: 'Katz' },
}] body: 'Me too!',
},
],
}; };
Handlebars.registerHelper('fullName', (person: typeof context.author) => { Handlebars.registerHelper('fullName', (person: typeof context.author) => {
return person.firstName + ' ' + person.lastName; return person.firstName + ' ' + person.lastName;
}); });
Handlebars.registerHelper('agree_button', function(this: any) { Handlebars.registerHelper('agree_button', function (this: any) {
return new Handlebars.SafeString( return new Handlebars.SafeString(
'<button>I agree. I ' + this.emotion + ' ' + this.name + '</button>' '<button>I agree. I ' + this.emotion + ' ' + this.name + '</button>'
); );
}); });
const source1 = '<p>Hello, my name is {{name}}. I am from {{hometown}}. I have ' + const source1 =
'{{kids.length}} kids:</p>' + '<p>Hello, my name is {{name}}. I am from {{hometown}}. I have ' +
'<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>'; '{{kids.length}} kids:</p>' +
'<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>';
const template1 = Handlebars.compile(source1); const template1 = Handlebars.compile(source1);
template1({ name: "Alan", hometown: "Somewhere, TX", kids: [{name: "Jimmy", age: 12}, {name: "Sally", age: 4}]}); template1({
name: 'Alan',
hometown: 'Somewhere, TX',
kids: [
{ name: 'Jimmy', age: 12 },
{ name: 'Sally', age: 4 },
],
});
Handlebars.registerHelper('link_to', (context: typeof post) => { Handlebars.registerHelper('link_to', (context: typeof post) => {
return '<a href="' + context.url + '">' + context.body + '</a>'; return '<a href="' + context.url + '">' + context.body + '</a>';
}); });
const post = { url: "/hello-world", body: "Hello World!" }; const post = { url: '/hello-world', body: 'Hello World!' };
const context2 = { posts: [post] }; const context2 = { posts: [post] };
const source2 = '<ul>{{#posts}}<li>{{{link_to this}}}</li>{{/posts}}</ul>'; const source2 = '<ul>{{#posts}}<li>{{{link_to this}}}</li>{{/posts}}</ul>';
const template2: HandlebarsTemplateDelegate<{ posts: { url: string, body: string }[] }> = Handlebars.compile(source2); const template2: HandlebarsTemplateDelegate<{
posts: { url: string; body: string }[];
}> = Handlebars.compile(source2);
template2(context2); template2(context2);
Handlebars.registerHelper('link_to', (title: string, context: typeof post) => { Handlebars.registerHelper('link_to', (title: string, context: typeof post) => {
return '<a href="/posts' + context.url + '">' + title + '!</a>'; return '<a href="/posts' + context.url + '">' + title + '!</a>';
}); });
const context3 = { posts: [{url: '/hello-world', body: 'Hello World!'}] }; const context3 = { posts: [{ url: '/hello-world', body: 'Hello World!' }] };
const source3 = '<ul>{{#posts}}<li>{{{link_to "Post" this}}}</li>{{/posts}}</ul>'; const source3 =
'<ul>{{#posts}}<li>{{{link_to "Post" this}}}</li>{{/posts}}</ul>';
const template3 = Handlebars.compile<typeof context3>(source3); const template3 = Handlebars.compile<typeof context3>(source3);
template3(context3); template3(context3);
const source4 = '<ul>{{#people}}<li>{{#link}}{{name}}{{/link}}</li>{{/people}}</ul>'; const source4 =
Handlebars.registerHelper('link', function(this: any, context: any) { '<ul>{{#people}}<li>{{#link}}{{name}}{{/link}}</li>{{/people}}</ul>';
Handlebars.registerHelper('link', function (this: any, context: any) {
return '<a href="/people/' + this.id + '">' + context.fn(this) + '</a>'; return '<a href="/people/' + this.id + '">' + context.fn(this) + '</a>';
}); });
const template4 = Handlebars.compile<{ people: { name: string, id: number }[] }>(source4); const template4 = Handlebars.compile<{
const data2 = { 'people': [ people: { name: string; id: number }[];
{ 'name': 'Alan', 'id': 1 }, }>(source4);
{ 'name': 'Yehuda', 'id': 2 } const data2 = {
]}; people: [
{ name: 'Alan', id: 1 },
{ name: 'Yehuda', id: 2 },
],
};
template4(data2); template4(data2);
const source5 = '<ul>{{#people}}<li>{{> link}}</li>{{/people}}</ul>'; const source5 = '<ul>{{#people}}<li>{{> link}}</li>{{/people}}</ul>';
Handlebars.registerPartial('link', '<a href="/people/{{id}}">{{name}}</a>'); Handlebars.registerPartial('link', '<a href="/people/{{id}}">{{name}}</a>');
const template5 = Handlebars.compile(source5); const template5 = Handlebars.compile(source5);
const data3 = { 'people': [ const data3 = {
{ 'name': 'Alan', 'id': 1 }, people: [
{ 'name': 'Yehuda', 'id': 2 } { name: 'Alan', id: 1 },
]}; { name: 'Yehuda', id: 2 },
],
};
template5(data3); template5(data3);
const source6 = '{{#list nav}}<a href="{{url}}">{{title}}</a>{{/list}}'; const source6 = '{{#list nav}}<a href="{{url}}">{{title}}</a>{{/list}}';
const template6 = Handlebars.compile(source6); const template6 = Handlebars.compile(source6);
Handlebars.registerHelper('list', (context, options: Handlebars.HelperOptions) => { Handlebars.registerHelper(
let ret = "<ul>"; 'list',
for(let i=0, j=context.length; i<j; i++) { (context, options: Handlebars.HelperOptions) => {
ret = ret + "<li>" + options.fn(context[i]) + "</li>"; let ret = '<ul>';
for (let i = 0, j = context.length; i < j; i++) {
ret = ret + '<li>' + options.fn(context[i]) + '</li>';
}
return ret + '</ul>';
} }
return ret + "</ul>"; );
}); template6([{ url: '', title: '' }]);
template6([{url:"", title:""}]);
const escapedExpression = Handlebars.Utils.escapeExpression(
const escapedExpression = Handlebars.Utils.escapeExpression('<script>alert(\'xss\');</script>'); "<script>alert('xss');</script>"
);
Handlebars.helpers !== undefined; Handlebars.helpers !== undefined;
const parsedTmpl = Handlebars.parse('<p>Hello, my name is {{name}}.</p>', { const parsedTmpl = Handlebars.parse('<p>Hello, my name is {{name}}.</p>', {
srcName: "/foo/bar/baz.hbs", srcName: '/foo/bar/baz.hbs',
ignoreStandalone: true ignoreStandalone: true,
}); });
const parsedTmplWithoutOptions = Handlebars.parse('<p>Hello, my name is {{name}}.</p>'); const parsedTmplWithoutOptions = Handlebars.parse(
'<p>Hello, my name is {{name}}.</p>'
);
// Custom partial resolution. // Custom partial resolution.
const originalResolvePartial = Handlebars.VM.resolvePartial; const originalResolvePartial = Handlebars.VM.resolvePartial;
Handlebars.VM.resolvePartial = <T>(partial: HandlebarsTemplateDelegate<T> | undefined, context: any, options: Handlebars.ResolvePartialOptions): HandlebarsTemplateDelegate<T> => { Handlebars.VM.resolvePartial = <T>(
const name = options.name.replace(/my/,'your'); partial: HandlebarsTemplateDelegate<T> | undefined,
context: any,
options: Handlebars.ResolvePartialOptions
): HandlebarsTemplateDelegate<T> => {
const name = options.name.replace(/my/, 'your');
// transform name. // transform name.
options.name = name; options.name = name;
return originalResolvePartial(partial, context, options); return originalResolvePartial(partial, context, options);
}; };
// #1544, allow custom helpers in knownHelpers // #1544, allow custom helpers in knownHelpers
Handlebars.compile('test', { Handlebars.compile('test', {
knownHelpers: { knownHelpers: {
each: true, each: true,
customHelper: true customHelper: true,
} },
}); });
Handlebars.compile('test')({},{allowCallsToHelperMissing: true}); Handlebars.compile('test')({}, { allowCallsToHelperMissing: true });
Handlebars.compile('test')({},{}); Handlebars.compile('test')({}, {});
const allthings = {} as
| hbs.AST.MustacheStatement
| hbs.AST.BlockStatement
| hbs.AST.PartialStatement
| hbs.AST.PartialBlockStatement
| hbs.AST.ContentStatement
| hbs.AST.CommentStatement
| hbs.AST.SubExpression
| hbs.AST.PathExpression
| hbs.AST.StringLiteral
| hbs.AST.BooleanLiteral
| hbs.AST.NumberLiteral
| hbs.AST.UndefinedLiteral
| hbs.AST.NullLiteral
| hbs.AST.Hash
| hbs.AST.HashPair;
const allthings = {} as hbs.AST.MustacheStatement | switch (allthings.type) {
hbs.AST.BlockStatement | case 'MustacheStatement':
hbs.AST.PartialStatement |
hbs.AST.PartialBlockStatement |
hbs.AST.ContentStatement |
hbs.AST.CommentStatement |
hbs.AST.SubExpression |
hbs.AST.PathExpression |
hbs.AST.StringLiteral |
hbs.AST.BooleanLiteral |
hbs.AST.NumberLiteral |
hbs.AST.UndefinedLiteral |
hbs.AST.NullLiteral |
hbs.AST.Hash |
hbs.AST.HashPair;
switch(allthings.type) {
case "MustacheStatement":
let mustacheStatement: hbs.AST.MustacheStatement; let mustacheStatement: hbs.AST.MustacheStatement;
mustacheStatement = allthings; mustacheStatement = allthings;
break; break;
case "BlockStatement": case 'BlockStatement':
let blockStatement: hbs.AST.BlockStatement; let blockStatement: hbs.AST.BlockStatement;
blockStatement = allthings; blockStatement = allthings;
break; break;
case "PartialStatement": case 'PartialStatement':
let partialStatement: hbs.AST.PartialStatement; let partialStatement: hbs.AST.PartialStatement;
partialStatement = allthings; partialStatement = allthings;
break; break;
case "PartialBlockStatement": case 'PartialBlockStatement':
let partialBlockStatement: hbs.AST.PartialBlockStatement; let partialBlockStatement: hbs.AST.PartialBlockStatement;
partialBlockStatement = allthings; partialBlockStatement = allthings;
break; break;
case "ContentStatement": case 'ContentStatement':
let ContentStatement: hbs.AST.ContentStatement; let ContentStatement: hbs.AST.ContentStatement;
ContentStatement = allthings; ContentStatement = allthings;
break; break;
case "CommentStatement": case 'CommentStatement':
let CommentStatement: hbs.AST.CommentStatement; let CommentStatement: hbs.AST.CommentStatement;
CommentStatement = allthings; CommentStatement = allthings;
break; break;
case "SubExpression": case 'SubExpression':
let SubExpression: hbs.AST.SubExpression; let SubExpression: hbs.AST.SubExpression;
SubExpression = allthings; SubExpression = allthings;
break; break;
case "PathExpression": case 'PathExpression':
let PathExpression: hbs.AST.PathExpression; let PathExpression: hbs.AST.PathExpression;
PathExpression = allthings; PathExpression = allthings;
break; break;
case "StringLiteral": case 'StringLiteral':
let StringLiteral: hbs.AST.StringLiteral; let StringLiteral: hbs.AST.StringLiteral;
StringLiteral = allthings; StringLiteral = allthings;
break; break;
case "BooleanLiteral": case 'BooleanLiteral':
let BooleanLiteral: hbs.AST.BooleanLiteral; let BooleanLiteral: hbs.AST.BooleanLiteral;
BooleanLiteral = allthings; BooleanLiteral = allthings;
break; break;
case "NumberLiteral": case 'NumberLiteral':
let NumberLiteral: hbs.AST.NumberLiteral; let NumberLiteral: hbs.AST.NumberLiteral;
NumberLiteral = allthings; NumberLiteral = allthings;
break; break;
case "UndefinedLiteral": case 'UndefinedLiteral':
let UndefinedLiteral: hbs.AST.UndefinedLiteral; let UndefinedLiteral: hbs.AST.UndefinedLiteral;
UndefinedLiteral = allthings; UndefinedLiteral = allthings;
break; break;
case "NullLiteral": case 'NullLiteral':
let NullLiteral: hbs.AST.NullLiteral; let NullLiteral: hbs.AST.NullLiteral;
NullLiteral = allthings; NullLiteral = allthings;
break; break;
case "Hash": case 'Hash':
let Hash: hbs.AST.Hash; let Hash: hbs.AST.Hash;
Hash = allthings; Hash = allthings;
break; break;
case "HashPair": case 'HashPair':
let HashPair: hbs.AST.HashPair; let HashPair: hbs.AST.HashPair;
HashPair = allthings; HashPair = allthings;
break; break;
@@ -196,11 +225,15 @@ switch(allthings.type) {
} }
function testParseWithoutProcessing() { function testParseWithoutProcessing() {
const parsedTemplate: hbs.AST.Program = Handlebars.parseWithoutProcessing('<p>Hello, my name is {{name}}.</p>', { const parsedTemplate: hbs.AST.Program = Handlebars.parseWithoutProcessing(
srcName: "/foo/bar/baz.hbs", '<p>Hello, my name is {{name}}.</p>',
}); {
srcName: '/foo/bar/baz.hbs',
}
);
const parsedTemplateWithoutOptions: hbs.AST.Program = Handlebars.parseWithoutProcessing('<p>Hello, my name is {{name}}.</p>'); const parsedTemplateWithoutOptions: hbs.AST.Program =
Handlebars.parseWithoutProcessing('<p>Hello, my name is {{name}}.</p>');
} }
function testExceptionTypings() { function testExceptionTypings() {
@@ -226,8 +259,8 @@ function testExceptionWithNodeTypings() {
loc: { loc: {
source: 'source', source: 'source',
start: { line: 1, column: 5 }, start: { line: 1, column: 5 },
end: { line: 10, column: 2 } end: { line: 10, column: 2 },
} },
}); });
// Fields // Fields
@@ -247,12 +280,15 @@ function testProtoAccessControlControlOptions() {
{}, {},
{ {
allowedProtoMethods: { allowedMethod: true, forbiddenMethod: false }, allowedProtoMethods: { allowedMethod: true, forbiddenMethod: false },
allowedProtoProperties: { allowedProperty: true, forbiddenProperty: false }, allowedProtoProperties: {
allowedProperty: true,
forbiddenProperty: false,
},
allowProtoMethodsByDefault: true, allowProtoMethodsByDefault: true,
allowProtoPropertiesByDefault: false, allowProtoPropertiesByDefault: false,
partials: { partials: {
link: '<a href="/people/{{id}}">{{name}}</a>' link: '<a href="/people/{{id}}">{{name}}</a>',
} },
} }
); );
} }