mirror of
https://github.com/aljazceru/satshkd-vercel.git
synced 2025-12-18 21:54:23 +01:00
generated
This commit is contained in:
3
node_modules/express-handlebars/.eslintignore
generated
vendored
Normal file
3
node_modules/express-handlebars/.eslintignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
coverage/
|
||||
34
node_modules/express-handlebars/.eslintrc.js
generated
vendored
Normal file
34
node_modules/express-handlebars/.eslintrc.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
node: true,
|
||||
jest: true,
|
||||
},
|
||||
extends: [
|
||||
"standard",
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
},
|
||||
rules: {
|
||||
quotes: ["error", "double"],
|
||||
semi: ["error", "always"],
|
||||
"no-warning-comments": "warn",
|
||||
"comma-dangle": ["error", "always-multiline"],
|
||||
indent: ["error", "tab", { SwitchCase: 1 }],
|
||||
"no-tabs": "off",
|
||||
"no-var": "error",
|
||||
"prefer-const": "error",
|
||||
"object-shorthand": "error",
|
||||
"no-restricted-globals": [
|
||||
"error",
|
||||
{
|
||||
name: "fit",
|
||||
message: "Do not commit focused tests.",
|
||||
},
|
||||
{
|
||||
name: "fdescribe",
|
||||
message: "Do not commit focused tests.",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
71
node_modules/express-handlebars/.github/workflows/codeql-analysis.yml
generated
vendored
Normal file
71
node_modules/express-handlebars/.github/workflows/codeql-analysis.yml
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '0 15 * * 4'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ['javascript']
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
101
node_modules/express-handlebars/.github/workflows/main.yml
generated
vendored
Normal file
101
node_modules/express-handlebars/.github/workflows/main.yml
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
name: "Tests"
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
CI: true
|
||||
|
||||
jobs:
|
||||
TestOS:
|
||||
name: Test
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest]
|
||||
node_version: ['lts/*']
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Node
|
||||
uses: dcodeIO/setup-node-nvm@master
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Run tests 👩🏾💻
|
||||
run: npm run test
|
||||
TestNode:
|
||||
name: Test
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node_version: [10, 'lts/*', 'node']
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Node
|
||||
uses: dcodeIO/setup-node-nvm@master
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Run tests 👩🏾💻
|
||||
run: npm run test
|
||||
Coverage:
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Node
|
||||
uses: dcodeIO/setup-node-nvm@master
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Run tests 👩🏾💻
|
||||
run: npm run test:cover
|
||||
Lint:
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Node
|
||||
uses: dcodeIO/setup-node-nvm@master
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- name: NPM install
|
||||
run: npm ci
|
||||
- name: Lint ✨
|
||||
run: npm run lint
|
||||
|
||||
Release:
|
||||
needs: [TestOS, TestNode, Coverage, Lint]
|
||||
if: |
|
||||
github.ref == 'refs/heads/master' &&
|
||||
github.event.repository.fork == false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
- name: NPM install
|
||||
run: npm ci
|
||||
- name: Release 🎉
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npx semantic-release
|
||||
|
||||
Skip:
|
||||
if: contains(github.event.head_commit.message, '[skip ci]')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Skip CI 🚫
|
||||
run: echo skip ci
|
||||
111
node_modules/express-handlebars/CHANGELOG.md
generated
vendored
Normal file
111
node_modules/express-handlebars/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
## [5.3.5](https://github.com/express-handlebars/express-handlebars/compare/v5.3.4...v5.3.5) (2021-11-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update deps ([b516cff](https://github.com/express-handlebars/express-handlebars/commit/b516cff30ba3de90db02b3a3682c9ffbcfb10091))
|
||||
|
||||
## [5.3.4](https://github.com/express-handlebars/express-handlebars/compare/v5.3.3...v5.3.4) (2021-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency glob to ^7.2.0 ([15c77f5](https://github.com/express-handlebars/express-handlebars/commit/15c77f5e7cf31168942adaee8d021870719d9cd8))
|
||||
|
||||
## [5.3.3](https://github.com/express-handlebars/express-handlebars/compare/v5.3.2...v5.3.3) (2021-08-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency graceful-fs to ^4.2.7 ([94a4073](https://github.com/express-handlebars/express-handlebars/commit/94a4073bbea4591b57ea5e3cdae03c8fd861d50e))
|
||||
|
||||
## [5.3.2](https://github.com/express-handlebars/express-handlebars/compare/v5.3.1...v5.3.2) (2021-05-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency glob to ^7.1.7 ([8222f00](https://github.com/express-handlebars/express-handlebars/commit/8222f0015805b1287f62a1c66747a7f831a976db))
|
||||
|
||||
## [5.3.1](https://github.com/express-handlebars/express-handlebars/compare/v5.3.0...v5.3.1) (2021-05-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add note about security ([78c47a2](https://github.com/express-handlebars/express-handlebars/commit/78c47a235c4ad7bc2674bddd8ec2721567ed8c72))
|
||||
|
||||
# [5.3.0](https://github.com/express-handlebars/express-handlebars/compare/v5.2.1...v5.3.0) (2021-03-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add partialsDir.rename option ([#151](https://github.com/express-handlebars/express-handlebars/issues/151)) ([1a6771b](https://github.com/express-handlebars/express-handlebars/commit/1a6771b0f9a3db1cbd516faf79cb5e20a779e456))
|
||||
|
||||
## [5.2.1](https://github.com/express-handlebars/express-handlebars/compare/v5.2.0...v5.2.1) (2021-02-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency handlebars to ^4.7.7 ([1930523](https://github.com/express-handlebars/express-handlebars/commit/1930523103e6c97a3f3e41d6e7b5d6dc329c66f9))
|
||||
|
||||
# [5.2.0](https://github.com/express-handlebars/express-handlebars/compare/v5.1.0...v5.2.0) (2020-10-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow views to be an array ([a9f4aaa](https://github.com/express-handlebars/express-handlebars/commit/a9f4aaabd657221236b7321a4f87df7c9eb9a1bd))
|
||||
|
||||
# [5.1.0](https://github.com/express-handlebars/express-handlebars/compare/v5.0.0...v5.1.0) (2020-07-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add encoding option ([9e516c3](https://github.com/express-handlebars/express-handlebars/commit/9e516c382269b3ab586a6ab0dbd586b3c23110c4))
|
||||
|
||||
# [5.0.0](https://github.com/express-handlebars/express-handlebars/compare/v4.0.6...v5.0.0) (2020-07-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update code to es2015+ ([e5a08ee](https://github.com/express-handlebars/express-handlebars/commit/e5a08eed844f177b0f365f882a20c7b229715bdd))
|
||||
* update node support ([ea30d53](https://github.com/express-handlebars/express-handlebars/commit/ea30d531b2f458c37f65b50bddc504180e774f8f))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Drop support for node versions below v10
|
||||
|
||||
## [4.0.6](https://github.com/express-handlebars/express-handlebars/compare/v4.0.5...v4.0.6) (2020-07-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add runtimeOptions ([b64284f](https://github.com/express-handlebars/express-handlebars/commit/b64284f6f6eab2d184671736c33fc45df5b26246))
|
||||
|
||||
## [4.0.5](https://github.com/express-handlebars/express-handlebars/compare/v4.0.4...v4.0.5) (2020-07-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* overwrite past settings.views ([c27f1b0](https://github.com/express-handlebars/express-handlebars/commit/c27f1b0e8dcf2be974584861433cfb01a10ce1f6))
|
||||
* renderView returns promise when no callback given ([c39ed87](https://github.com/express-handlebars/express-handlebars/commit/c39ed87f2478ed64211821a6ffe1dca7212fb21b))
|
||||
|
||||
## [4.0.4](https://github.com/express-handlebars/express-handlebars/compare/v4.0.3...v4.0.4) (2020-04-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency graceful-fs to ^4.2.4 ([c01661b](https://github.com/express-handlebars/express-handlebars/commit/c01661be5193ea77d9914b71aedcb71d6ad4ab92))
|
||||
|
||||
## [4.0.3](https://github.com/express-handlebars/express-handlebars/compare/v4.0.2...v4.0.3) (2020-04-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency handlebars to ^4.7.6 ([2aa29ab](https://github.com/express-handlebars/express-handlebars/commit/2aa29ab29d5db9becccb5690a6fdef4a46055906))
|
||||
|
||||
## [4.0.2](https://github.com/express-handlebars/express-handlebars/compare/v4.0.1...v4.0.2) (2020-04-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency handlebars to ^4.7.5 ([#6](https://github.com/express-handlebars/express-handlebars/issues/6)) ([e597254](https://github.com/express-handlebars/express-handlebars/commit/e59725426cd6c6ab261127fd96065f30009ea1e1))
|
||||
402
node_modules/express-handlebars/HISTORY.md
generated
vendored
Normal file
402
node_modules/express-handlebars/HISTORY.md
generated
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
Express Handlebars Change History
|
||||
=================================
|
||||
|
||||
4.0.1 (2020-04-01)
|
||||
------------------
|
||||
|
||||
* Update handlebars to fix mimist vulnerability.
|
||||
|
||||
4.0.0 (2020-03-25)
|
||||
------------------
|
||||
|
||||
* Move to repo https://github.com/express-handlebars/express-handlebars/
|
||||
* Update all deps.
|
||||
|
||||
3.1.0 (2019-05-14)
|
||||
------------------
|
||||
|
||||
* `defaultLayout` defaults to main ([#249][])
|
||||
* Upgrade Handlebars to v4.1.2 ([#250][])
|
||||
|
||||
[#249]: https://github.com/ericf/express-handlebars/issues/249
|
||||
[#250]: https://github.com/ericf/express-handlebars/issues/250
|
||||
|
||||
3.0.2 (2019-02-24)
|
||||
------------------
|
||||
|
||||
* Fix configuration `layoutsDir` & `partialsDir`. ([#244][])
|
||||
|
||||
[#244]: https://github.com/ericf/express-handlebars/issues/244
|
||||
|
||||
3.0.1 (2019-02-20)
|
||||
------------------
|
||||
|
||||
* Updated dependencies that are long over due
|
||||
|
||||
3.0.0 (2016-01-26)
|
||||
------------------
|
||||
|
||||
* Upgraded to Handlebars 4.0. ([#142][])
|
||||
|
||||
[#142]: https://github.com/ericf/express-handlebars/issues/142
|
||||
|
||||
2.0.1 (2015-04-23)
|
||||
------------------
|
||||
|
||||
* Guarded against unexpected Handlebars API change that was released in a patch.
|
||||
([#125][])
|
||||
|
||||
|
||||
[#125]: https://github.com/ericf/express-handlebars/issues/125
|
||||
|
||||
|
||||
2.0.0 (2015-03-22)
|
||||
------------------
|
||||
|
||||
* __[!]__ Upgraded to Handlebars 3.0 by default, but still works with Handlebars
|
||||
2.x by using the `handlebars` config option. ([#105][])
|
||||
|
||||
* __[!]__ Removed using prototype properties for default config values. The
|
||||
default values are now embedded in the constructor. ([#105][])
|
||||
|
||||
* __[!]__ Removed `handlebarsVersion` instance property and
|
||||
`getHandlebarsSemver()` static function on the `ExpressHandlebars`
|
||||
constructor. ([#105][])
|
||||
|
||||
* __[!]__ Replaced undocumented `compileTemplate()` hook with the protected but
|
||||
supported `_compileTemplate()` and `_precompileTemplate()` hooks. ([#95][])
|
||||
|
||||
* Fixed layout path resolution on Windows. ([#113][] @Tineler)
|
||||
|
||||
* Added `compilerOptions` config property which is passed along to
|
||||
`Handlebars.compile()` and `Handlebars.precompile()`. ([#95][])
|
||||
|
||||
* Exposed Express Handlebars metadata to the data channel during render. This
|
||||
metadata is accessible via `{{@exphbs.*}}` ([#89][], [#101][])
|
||||
|
||||
* Added new "protected" hooks for AOP-ing template compilation and rendering,
|
||||
all of which can optionally return a Promise: ([#105][])
|
||||
|
||||
* `_compileTemplate()`
|
||||
* `_precompileTemplate()`
|
||||
* `_renderTemplate()`
|
||||
|
||||
|
||||
[#89]: https://github.com/ericf/express-handlebars/issues/89
|
||||
[#95]: https://github.com/ericf/express-handlebars/issues/95
|
||||
[#101]: https://github.com/ericf/express-handlebars/issues/101
|
||||
[#105]: https://github.com/ericf/express-handlebars/issues/105
|
||||
[#113]: https://github.com/ericf/express-handlebars/issues/113
|
||||
|
||||
|
||||
1.2.2 (2015-03-06)
|
||||
------------------
|
||||
|
||||
* Upgraded `glob` dependency to v5 which now officially supports symlinks via
|
||||
the new `follow` option. ([#98][])
|
||||
|
||||
|
||||
1.2.1 (2015-02-17)
|
||||
------------------
|
||||
|
||||
* Locked down `glob` dependency to a v4 version range that is known to work with
|
||||
this package _and_ support symlinks. The `glob` version can be updated when
|
||||
[isaacs/node-glob#139](https://github.com/isaacs/node-glob/issues/139) is
|
||||
resolved. ([#98][] @adgad)
|
||||
|
||||
|
||||
[#98]: https://github.com/ericf/express-handlebars/issues/98
|
||||
|
||||
|
||||
1.2.0 (2015-02-17)
|
||||
------------------
|
||||
|
||||
* Added support for render-level `partials` to be specified when calling
|
||||
`renderView()` (which is the method Express calls). The `options.partials`
|
||||
value matches what Handlebars accepts during template rendering: it should
|
||||
have the shape `{partialName: fn}` or be a Promise for such an object.
|
||||
([#82][])
|
||||
|
||||
|
||||
[#82]: https://github.com/ericf/express-handlebars/issues/82
|
||||
|
||||
|
||||
1.1.0 (2014-09-14)
|
||||
------------------
|
||||
|
||||
* __[!]__ Upgraded Handlebars to 2.0.0 final, it was beta before.
|
||||
|
||||
* Added support for `partialsDir` to be configured with a collection (or promise
|
||||
for a collection) of templates, via the new `templates` prop in `partialDir`
|
||||
config objects. This allows developers to hand Express Handlebars the compiled
|
||||
partials templates to use for a specific partials dir.
|
||||
([#81][] @joanniclaborde)
|
||||
|
||||
* Upgraded Promise dependency.
|
||||
|
||||
|
||||
[#81]: https://github.com/ericf/express-handlebars/issues/81
|
||||
|
||||
|
||||
1.0.3 (2014-09-05)
|
||||
------------------
|
||||
|
||||
* Fixed issue with namespaced partials dirs not actually being namespaces.
|
||||
([#76][] @inerte)
|
||||
|
||||
|
||||
[#76]: https://github.com/ericf/express-handlebars/issues/76
|
||||
|
||||
|
||||
1.0.2 (2014-09-05)
|
||||
------------------
|
||||
|
||||
* Fixed `engines` entry in `package.json` to Node `>=0.10` to reflect this
|
||||
package's requirements. ([#78][])
|
||||
|
||||
|
||||
[#78]: https://github.com/ericf/express-handlebars/issues/78
|
||||
|
||||
|
||||
1.0.1 (2014-08-08)
|
||||
------------------
|
||||
|
||||
* Fixed bug where rendered content was only be returned if a layout template was
|
||||
being used. Now a layout-less render will actually return content. ([#73][])
|
||||
|
||||
|
||||
[#73]: https://github.com/ericf/express-handlebars/issues/73
|
||||
|
||||
|
||||
1.0.0 (2014-08-07)
|
||||
------------------
|
||||
|
||||
* __[!]__ Renamed to: `express-handlebars`. ([#65][])
|
||||
|
||||
* __[!]__ Rewritten to use Promises instead of `async` for asynchronous code.
|
||||
([#68][]) This resulted in the following public API changes:
|
||||
|
||||
* `loadPartials()` --> `getPartials()`, returns a Promise.
|
||||
* `loadTemplate()` --> `getTemplate()`, returns a Promise.
|
||||
* `loadTemplates()` --> `getTemplates()`, returns a Promise.
|
||||
* `render(file, context, [options])`, returns a Promise.
|
||||
|
||||
|
||||
* `partialsDir` can now be set with an array of objects in the following form to
|
||||
support namespaced partials: ([#70][] @joanniclaborde)
|
||||
|
||||
{ dir: 'foo/bar/', namespace: 'bar' }
|
||||
|
||||
* Added support for Handlebars' `data` channel via `options.data`. ([#62][])
|
||||
|
||||
* Added `compileTemplate()` hook for the pre/post compile process, this also
|
||||
supports returning a Promise. ([#39][], [#41][])
|
||||
|
||||
* Added `_renderTemplate()` hook that supports returning a Promise.
|
||||
([#39][], [#41][])
|
||||
|
||||
* Upgraded all dependencies, including Handlebars to 2.x. ([#59][])
|
||||
|
||||
* Added `graceful-fs` dependency to support large numbers of files to avoid
|
||||
EMFILE errors.
|
||||
|
||||
* Reduced complexity of cache code.
|
||||
|
||||
* Updated examples to each be self-contained and have `package.json` files.
|
||||
|
||||
|
||||
[#39]: https://github.com/ericf/express-handlebars/issues/39
|
||||
[#41]: https://github.com/ericf/express-handlebars/issues/41
|
||||
[#59]: https://github.com/ericf/express-handlebars/issues/59
|
||||
[#62]: https://github.com/ericf/express-handlebars/issues/62
|
||||
[#65]: https://github.com/ericf/express-handlebars/issues/65
|
||||
[#68]: https://github.com/ericf/express-handlebars/issues/68
|
||||
[#70]: https://github.com/ericf/express-handlebars/issues/70
|
||||
|
||||
|
||||
0.5.1 (2014-08-05)
|
||||
------------------
|
||||
|
||||
* __[!]__ Last release before `v1.0` which will have breaking changes.
|
||||
|
||||
* Improved `extname` docs in README and added example. ([#30][] @Crashthatch)
|
||||
|
||||
* `extname` can now be specified _without_ the leading `"."`.
|
||||
([#51][] @calvinmetcalf)
|
||||
|
||||
|
||||
[#30]: https://github.com/ericf/express-handlebars/issues/30
|
||||
[#51]: https://github.com/ericf/express-handlebars/issues/51
|
||||
|
||||
|
||||
0.5.0 (2013-07-25)
|
||||
------------------
|
||||
|
||||
* Added `loadTemplates()` method which will load all the templates in a
|
||||
specified directory. ([#21][])
|
||||
|
||||
* Added support for multiple partials directories. This enables the
|
||||
`partialsDir` configuration property to be specified as an *array* of
|
||||
directories, and loads all of the templates in each one.
|
||||
|
||||
This feature allows an app's partials to be split up in multiple directories,
|
||||
which is common if an app has some shared partials which will also be exposed
|
||||
to the client, and some server-side-only partials. ([#20][])
|
||||
|
||||
* Added runnable code examples in this package's "examples/" directory.
|
||||
([#22][])
|
||||
|
||||
* Improved optional argument handling in public methods to treat Express
|
||||
`locals` function objects as `options` and not `callback` params to the method
|
||||
being invoked. ([#27][])
|
||||
|
||||
|
||||
[#20]: https://github.com/ericf/express-handlebars/issues/20
|
||||
[#21]: https://github.com/ericf/express-handlebars/issues/21
|
||||
[#22]: https://github.com/ericf/express-handlebars/issues/22
|
||||
[#27]: https://github.com/ericf/express-handlebars/issues/27
|
||||
|
||||
|
||||
0.4.1 (2013-04-06)
|
||||
------------------
|
||||
|
||||
* Updated `async` dependency to the latest stable minor version: "~0.2".
|
||||
|
||||
|
||||
0.4.0 (2013-03-24)
|
||||
------------------
|
||||
|
||||
* __[!]__ Removed the following "get" -> "load" aliases which kept in v0.2.0 for
|
||||
back-compat:
|
||||
|
||||
* `getPartials()` -> `loadPartials()`
|
||||
* `getTemplate()` -> `loadTemplate()`
|
||||
|
||||
This is the future version where these aliases have been removed.
|
||||
|
||||
* __[!]__ Renamed `lib/express3-handlebars.js` -> `lib/express-handlebars.js`.
|
||||
|
||||
* Exposed `getHandlebarsSemver()` function as a static property on the
|
||||
`ExpressHandlebars` constructor.
|
||||
|
||||
* Rearranged module exports by moving the engine factory function to `index.js`,
|
||||
making the `lib/express3-handlebars.js` module only responsible for exporting
|
||||
the `ExpressHandlebars` constructor.
|
||||
|
||||
|
||||
0.3.3 (2013-03-22)
|
||||
------------------
|
||||
|
||||
* Updated internal `_resolveLayoutPath()` method to take the full
|
||||
`options`/locals objects which the view is rendered with. This makes it easier
|
||||
to override. ([#14][])
|
||||
|
||||
|
||||
[#14]: https://github.com/ericf/express-handlebars/issues/14
|
||||
|
||||
|
||||
0.3.2 (2013-02-20)
|
||||
------------------
|
||||
|
||||
* Transfered ownership and copyright to Yahoo! Inc. This software is still free
|
||||
to use, and is now licensed under the Yahoo! Inc. BSD license.
|
||||
|
||||
|
||||
0.3.1 (2013-02-18)
|
||||
------------------
|
||||
|
||||
* Updated README with info about `options.helpers` for `render()` and
|
||||
`renderView()` docs. ([#7][])
|
||||
|
||||
|
||||
[#7]: https://github.com/ericf/express-handlebars/issues/7
|
||||
|
||||
|
||||
0.3.0 (2013-02-18)
|
||||
------------------
|
||||
|
||||
* Added support for render-level helpers, via `options.helpers`, to the
|
||||
`render()` and `renderView()` methods. Handlebars' `registerHelper()` function
|
||||
now works as expected and does not have to be called before the
|
||||
`ExpressHandlebars` instance is created. Helpers are now merged from:
|
||||
`handlebars.helpers` (global), `helpers` (instance), and `options.helpers`
|
||||
(render-level) before a template is rendered; this provides flexibility at
|
||||
all levels. ([#3][], [#11][])
|
||||
|
||||
* Added `handlebarsVersion` property which is the version number of `handlebars`
|
||||
as a semver. This is used internally to branch on certain operations which
|
||||
differ between Handlebars releases.
|
||||
|
||||
|
||||
[#3]: https://github.com/ericf/express-handlebars/issues/3
|
||||
[#11]: https://github.com/ericf/express-handlebars/issues/11
|
||||
|
||||
|
||||
0.2.3 (2013-02-13)
|
||||
------------------
|
||||
|
||||
* Fixed issue with naming nested partials when using the latest version of
|
||||
Handlebars (1.0.rc.2). Previous versions require a hack to replace "/"s with
|
||||
"."s in partial names, and the latest version of Handlebars fixes that bug.
|
||||
This hack will only be applied to old versions of Handlebars. ([#9][])
|
||||
|
||||
|
||||
[#9]: https://github.com/ericf/express-handlebars/issues/9
|
||||
|
||||
|
||||
0.2.2 (2013-02-04)
|
||||
------------------
|
||||
|
||||
* Updated README with the public method renames which happened v0.2.0.
|
||||
|
||||
|
||||
0.2.1 (2013-02-04)
|
||||
------------------
|
||||
|
||||
* `extname`, `layoutsDir`, and `partialsDir` property values will now reference
|
||||
the values on the prototype unless an `ExpressHandlebars` instance is
|
||||
constructed with config values for these properties.
|
||||
|
||||
* Improved clarity of method implementations, and exposed more override "hooks"
|
||||
via new private methods: `_getPartialName()`, `_renderTemplate()`, and
|
||||
`_resolveLayoutPath()`.
|
||||
|
||||
|
||||
0.2.0 (2013-02-01)
|
||||
------------------
|
||||
|
||||
* __[!]__ Renamed methods prefixed with "get" to "load" for clarity:
|
||||
|
||||
* `getPartials()` -> `loadPartials()`
|
||||
* `getTemplate()` -> `loadTemplate()`
|
||||
|
||||
Aliases for these methods have been created to maintain back-compat, but the
|
||||
old method names are now deprecated will be removed in the future. ([#5][])
|
||||
|
||||
* All paths are resolved before checking in or adding to caches. ([#1][])
|
||||
|
||||
* Force `{precompiled: false}` option within `render()` and `renderView()`
|
||||
methods to prevent trying to render with precompiled templates. ([#2][])
|
||||
|
||||
|
||||
[#1]: https://github.com/ericf/express-handlebars/issues/1
|
||||
[#2]: https://github.com/ericf/express-handlebars/issues/2
|
||||
[#5]: https://github.com/ericf/express-handlebars/issues/5
|
||||
|
||||
|
||||
0.1.2 (2013-01-10)
|
||||
------------------
|
||||
|
||||
* Tweaked formatting of README documentation.
|
||||
|
||||
|
||||
0.1.1 (2013-01-10)
|
||||
------------------
|
||||
|
||||
* Added README documentation.
|
||||
|
||||
|
||||
0.1.0 (2013-01-07)
|
||||
------------------
|
||||
|
||||
* Initial release.
|
||||
31
node_modules/express-handlebars/LICENSE
generated
vendored
Normal file
31
node_modules/express-handlebars/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
Copyright (c) 2014, Yahoo Inc. All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of Yahoo Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of Yahoo Inc.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
599
node_modules/express-handlebars/README.md
generated
vendored
Normal file
599
node_modules/express-handlebars/README.md
generated
vendored
Normal file
@@ -0,0 +1,599 @@
|
||||
Express Handlebars
|
||||
==================
|
||||
|
||||
A [Handlebars][] view engine for [Express][] which doesn't suck.
|
||||
|
||||
[![npm version][npm-badge]][npm]
|
||||
[![dependency status][dep-badge]][dep-status]
|
||||
|
||||
**This package used to be named `express3-handlebars`. The previous `express-handlebars` package by @jneen can be found [here][jneen-exphbs].**
|
||||
|
||||
|
||||
[Express]: https://github.com/expressjs/express
|
||||
[Handlebars]: https://github.com/handlebars-lang/handlebars.js
|
||||
[npm]: https://www.npmjs.org/package/express-handlebars
|
||||
[npm-badge]: https://img.shields.io/npm/v/express-handlebars.svg?style=flat-square
|
||||
[dep-status]: https://david-dm.org/express-handlebars/express-handlebars
|
||||
[dep-badge]: https://img.shields.io/david/express-handlebars/express-handlebars.svg?style=flat-square
|
||||
[jneen-exphbs]: https://github.com/jneen/express-handlebars
|
||||
|
||||
|
||||
## Goals & Design
|
||||
|
||||
I created this project out of frustration with the existing Handlebars view engines for Express. As of version 3.x, Express got out of the business of being a generic view engine — this was a great decision — leaving developers to implement the concepts of layouts, partials, and doing file I/O for their template engines of choice.
|
||||
|
||||
### Goals and Features
|
||||
|
||||
After building a half-dozen Express apps, I developed requirements and opinions about what a Handlebars view engine should provide and how it should be implemented. The following is that list:
|
||||
|
||||
* Add back the concept of "layout", which was removed in Express 3.x.
|
||||
|
||||
* Add back the concept of "partials" via Handlebars' partials mechanism.
|
||||
|
||||
* Support a directory of partials; e.g., `{{> foo/bar}}` which exists on the file system at `views/partials/foo/bar.handlebars`, by default.
|
||||
|
||||
* Smart file system I/O and template caching. When in development, templates are always loaded from disk. In production, raw files and compiled templates are cached, including partials.
|
||||
|
||||
* All async and non-blocking. File system I/O is slow and servers should not be blocked from handling requests while reading from disk. I/O queuing is used to avoid doing unnecessary work.
|
||||
|
||||
* Ability to easily precompile templates and partials for use on the client, enabling template sharing and reuse.
|
||||
|
||||
* Ability to use a different Handlebars module/implementation other than the Handlebars npm package.
|
||||
|
||||
### Package Design
|
||||
|
||||
This package was designed to work great for both the simple and complex use cases. I _intentionally_ made sure the full implementation is exposed and is easily overridable.
|
||||
|
||||
The package exports a function which can be invoked with no arguments or with a `config` object and it will return a function (closed over sensible defaults) which can be registered with an Express app. It's an engine factory function.
|
||||
|
||||
This exported engine factory has two properties which expose the underlying implementation:
|
||||
|
||||
* `ExpressHandlebars()`: The constructor function which holds the internal implementation on its `prototype`. This produces instance objects which store their configuration, `compiled` and `precompiled` templates, and expose an `engine()` function which can be registered with an Express app.
|
||||
|
||||
* `create()`: A convenience factory function for creating `ExpressHandlebars` instances.
|
||||
|
||||
An instance-based approach is used so that multiple `ExpressHandlebars` instances can be created with their own configuration, templates, partials, and helpers.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Install using npm:
|
||||
|
||||
```shell
|
||||
$ npm install express-handlebars
|
||||
```
|
||||
|
||||
## Danger 🔥
|
||||
|
||||
Never put objects on the `req` object straight in as the data, this can allow hackers to run XSS attacks. Always make sure you are destructuring the values on objects like `req.query` and `req.params`. See https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/ for more details.
|
||||
|
||||
## Usage
|
||||
|
||||
This view engine uses sensible defaults that leverage the "Express-way" of structuring an app's views. This makes it trivial to use in basic apps:
|
||||
|
||||
### Basic Usage
|
||||
|
||||
**Directory Structure:**
|
||||
|
||||
```
|
||||
.
|
||||
├── app.js
|
||||
└── views
|
||||
├── home.handlebars
|
||||
└── layouts
|
||||
└── main.handlebars
|
||||
|
||||
2 directories, 3 files
|
||||
```
|
||||
|
||||
**app.js:**
|
||||
|
||||
Creates a super simple Express app which shows the basic way to register a Handlebars view engine using this package.
|
||||
|
||||
```javascript
|
||||
var express = require('express');
|
||||
var exphbs = require('express-handlebars');
|
||||
|
||||
var app = express();
|
||||
|
||||
app.engine('handlebars', exphbs());
|
||||
app.set('view engine', 'handlebars');
|
||||
|
||||
app.get('/', function (req, res) {
|
||||
res.render('home');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
**views/layouts/main.handlebars:**
|
||||
|
||||
The main layout is the HTML page wrapper which can be reused for the different views of the app. `{{{body}}}` is used as a placeholder for where the main content should be rendered.
|
||||
|
||||
```handlebars
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Example App</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{{body}}}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
**views/home.handlebars:**
|
||||
|
||||
The content for the app's home view which will be rendered into the layout's `{{{body}}}`.
|
||||
|
||||
```handlebars
|
||||
<h1>Example App: Home</h1>
|
||||
```
|
||||
|
||||
#### Running the Example
|
||||
|
||||
The above example is bundled in this package's [examples directory][], where it can be run by:
|
||||
|
||||
```shell
|
||||
$ cd examples/basic/
|
||||
$ npm install
|
||||
$ npm start
|
||||
```
|
||||
|
||||
### Using Instances
|
||||
|
||||
Another way to use this view engine is to create an instance(s) of `ExpressHandlebars`, allowing access to the full API:
|
||||
|
||||
```javascript
|
||||
var express = require('express');
|
||||
var exphbs = require('express-handlebars');
|
||||
|
||||
var app = express();
|
||||
var hbs = exphbs.create({ /* config */ });
|
||||
|
||||
// Register `hbs.engine` with the Express app.
|
||||
app.engine('handlebars', hbs.engine);
|
||||
app.set('view engine', 'handlebars');
|
||||
|
||||
// ...still have a reference to `hbs`, on which methods like `getPartials()`
|
||||
// can be called.
|
||||
```
|
||||
|
||||
**Note:** The [Advanced Usage][] example demonstrates how `ExpressHandlebars` instances can be leveraged.
|
||||
|
||||
### Template Caching
|
||||
|
||||
This view engine uses a smart template caching strategy. In development, templates will always be loaded from disk, i.e., no caching. In production, raw files and compiled Handlebars templates are aggressively cached.
|
||||
|
||||
The easiest way to control template/view caching is through Express' [view cache setting][]:
|
||||
|
||||
```javascript
|
||||
app.enable('view cache');
|
||||
```
|
||||
|
||||
Express enables this setting by default when in production mode, i.e.:
|
||||
|
||||
```
|
||||
process.env.NODE_ENV === "production"
|
||||
```
|
||||
|
||||
**Note:** All of the public API methods accept `options.cache`, which gives control over caching when calling these methods directly.
|
||||
|
||||
### Layouts
|
||||
|
||||
A layout is simply a Handlebars template with a `{{{body}}}` placeholder. Usually it will be an HTML page wrapper into which views will be rendered.
|
||||
|
||||
This view engine adds back the concept of "layout", which was removed in Express 3.x. It can be configured with a path to the layouts directory, by default it's set to relative to `express settings.view` + `layouts/`
|
||||
|
||||
There are two ways to set a default layout: configuring the view engine's `defaultLayout` property, or setting [Express locals][] `app.locals.layout`.
|
||||
|
||||
The layout into which a view should be rendered can be overridden per-request by assigning a different value to the `layout` request local. The following will render the "home" view with no layout:
|
||||
|
||||
```javascript
|
||||
app.get('/', function (req, res, next) {
|
||||
res.render('home', {layout: false});
|
||||
});
|
||||
```
|
||||
|
||||
### Helpers
|
||||
|
||||
Helper functions, or "helpers" are functions that can be [registered with Handlebars][] and can be called within a template. Helpers can be used for transforming output, iterating over data, etc. To keep with the spirit of *logic-less* templates, helpers are the place where logic should be defined.
|
||||
|
||||
Handlebars ships with some [built-in helpers][], such as: `with`, `if`, `each`, etc. Most application will need to extend this set of helpers to include app-specific logic and transformations. Beyond defining global helpers on `Handlebars`, this view engine supports `ExpressHandlebars` instance-level helpers via the `helpers` configuration property, and render-level helpers via `options.helpers` when calling the `render()` and `renderView()` methods.
|
||||
|
||||
The following example shows helpers being specified at each level:
|
||||
|
||||
**app.js:**
|
||||
|
||||
Creates a super simple Express app which shows the basic way to register `ExpressHandlebars` instance-level helpers, and override one at the render-level.
|
||||
|
||||
```javascript
|
||||
var express = require('express');
|
||||
var exphbs = require('express-handlebars');
|
||||
|
||||
var app = express();
|
||||
|
||||
var hbs = exphbs.create({
|
||||
// Specify helpers which are only registered on this instance.
|
||||
helpers: {
|
||||
foo: function () { return 'FOO!'; },
|
||||
bar: function () { return 'BAR!'; }
|
||||
}
|
||||
});
|
||||
|
||||
app.engine('handlebars', hbs.engine);
|
||||
app.set('view engine', 'handlebars');
|
||||
|
||||
app.get('/', function (req, res, next) {
|
||||
res.render('home', {
|
||||
showTitle: true,
|
||||
|
||||
// Override `foo` helper only for this rendering.
|
||||
helpers: {
|
||||
foo: function () { return 'foo.'; }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
**views/home.handlebars:**
|
||||
|
||||
The app's home view which uses helper functions to help render the contents.
|
||||
|
||||
```handlebars
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Example App - Home</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Uses built-in `if` helper. -->
|
||||
{{#if showTitle}}
|
||||
<h1>Home</h1>
|
||||
{{/if}}
|
||||
|
||||
<!-- Calls `foo` helper, overridden at render-level. -->
|
||||
<p>{{foo}}</p>
|
||||
|
||||
<!-- Calls `bar` helper, defined at instance-level. -->
|
||||
<p>{{bar}}</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
#### More on Helpers
|
||||
|
||||
Refer to the [Handlebars website][] for more information on defining helpers:
|
||||
|
||||
* [Expression Helpers][]
|
||||
* [Block Helpers][]
|
||||
|
||||
### Metadata
|
||||
|
||||
Handlebars has a data channel feature that propagates data through all scopes, including helpers and partials. Values in the data channel can be accessed via the `{{@variable}}` syntax. Express Handlebars provides metadata about a template it renders on a `{{@exphbs}}` object allowing access to things like the view name passed to `res.render()` via `{{@exphbs.view}}`.
|
||||
|
||||
The following is the list of metadata that's accessible on the `{{@exphbs}}` data object:
|
||||
|
||||
* `cache`: Boolean whether or not the template is cached.
|
||||
* `encoding`: String name of encoding for files.
|
||||
* `view`: String name of the view passed to `res.render()`.
|
||||
* `layout`: String name of the layout view.
|
||||
* `data`: Original data object passed when rendering the template.
|
||||
* `helpers`: Collection of helpers used when rendering the template.
|
||||
* `partials`: Collection of partials used when rendering the template.
|
||||
* `runtimeOptions`: Runtime Options used to render the template.
|
||||
|
||||
|
||||
[examples directory]: https://github.com/express-handlebars/express-handlebars/tree/master/examples
|
||||
[view cache setting]: https://expressjs.com/en/api.html#app.settings.table
|
||||
[Express locals]: https://expressjs.com/en/api.html#app.locals
|
||||
[registered with Handlebars]: https://github.com/wycats/handlebars.js/#registering-helpers
|
||||
[built-in helpers]: https://handlebarsjs.com/guide/builtin-helpers.html
|
||||
[Handlebars website]: https://handlebarsjs.com/
|
||||
[Expression Helpers]: https://handlebarsjs.com/guide/#custom-helpers
|
||||
[Block Helpers]: https://handlebarsjs.com/guide/#block-helpers
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Configuration and Defaults
|
||||
|
||||
There are two main ways to use this package: via its engine factory function, or creating `ExpressHandlebars` instances; both use the same configuration properties and defaults.
|
||||
|
||||
```javascript
|
||||
var exphbs = require('express-handlebars');
|
||||
|
||||
// Using the engine factory:
|
||||
exphbs({ /* config */ });
|
||||
|
||||
// Create an instance:
|
||||
exphbs.create({ /* config */ });
|
||||
```
|
||||
|
||||
The following is the list of configuration properties and their default values (if any):
|
||||
|
||||
#### `handlebars=require('handlebars')`
|
||||
The Handlebars module/implementation. This allows for the `ExpressHandlebars` instance to use a different Handlebars module/implementation than that provided by the Handlebars npm package.
|
||||
|
||||
#### `extname=".handlebars"`
|
||||
The string name of the file extension used by the templates. This value should correspond with the `extname` under which this view engine is registered with Express when calling `app.engine()`.
|
||||
|
||||
The following example sets up an Express app to use `.hbs` as the file extension for views:
|
||||
|
||||
```javascript
|
||||
var express = require('express');
|
||||
var exphbs = require('express-handlebars');
|
||||
|
||||
var app = express();
|
||||
|
||||
app.engine('.hbs', exphbs({extname: '.hbs'}));
|
||||
app.set('view engine', '.hbs');
|
||||
```
|
||||
|
||||
**Note:** Setting the app's `"view engine"` setting will make that value the default file extension used for looking up views.
|
||||
|
||||
#### `encoding="utf8"`
|
||||
Default encoding when reading files.
|
||||
|
||||
#### `layoutsDir`
|
||||
Default layouts directory is relative to `express settings.view` + `layouts/`
|
||||
The string path to the directory where the layout templates reside.
|
||||
|
||||
**Note:** If you configure Express to look for views in a custom location (e.g., `app.set('views', 'some/path/')`), and if your `layoutsDir` is not relative to `express settings.view` + `layouts/`, you will need to reflect that by passing an updated path as the `layoutsDir` property in your configuration.
|
||||
|
||||
#### `partialsDir`
|
||||
Default partials directory is relative to `express settings.view` + `partials/`
|
||||
The string path to the directory where the partials templates reside or object with the following properties:
|
||||
|
||||
* `dir`: The string path to the directory where the partials templates reside.
|
||||
* `namespace`: Optional string namespace to prefix the partial names.
|
||||
* `templates`: Optional collection (or promise of a collection) of templates in the form: `{filename: template}`.
|
||||
* `rename(filePath, namespace)`: Optional function to rename the partials. Takes two arguments: `filePath`, e.g., `partials/some/path/template.handlebars` and `namespace`.
|
||||
|
||||
**Note:** If you configure Express to look for views in a custom location (e.g., `app.set('views', 'some/path/')`), and if your `partialsDir` is not relative to `express settings.view` + `partials/`, you will need to reflect that by passing an updated path as the `partialsDir` property in your configuration.
|
||||
|
||||
**Note:** Multiple partials dirs can be used by making `partialsDir` an array of strings, and/or config objects as described above. The namespacing feature is useful if multiple partials dirs are used and their file paths might clash.
|
||||
|
||||
#### `defaultLayout`
|
||||
The string name or path of a template in the `layoutsDir` to use as the default layout. `main` is used as the default. This is overridden by a `layout` specified in the app or response `locals`. **Note:** A falsy value will render without a layout; e.g., `res.render('home', {layout: false});`. You can also use a falsy value when creating the engine to make using no layout a default e.g. `app.engine('.hbs', exphbs({defaultLayout: false}));`.
|
||||
|
||||
#### `helpers`
|
||||
An object which holds the helper functions used when rendering templates with this `ExpressHandlebars` instance. When rendering a template, a collection of helpers will be generated by merging: `handlebars.helpers` (global), `helpers` (instance), and `options.helpers` (render-level). This allows Handlebars' `registerHelper()` function to operate as expected, will providing two extra levels over helper overrides.
|
||||
|
||||
#### `compilerOptions`
|
||||
An object which holds options that will be passed along to the Handlebars compiler functions: `Handlebars.compile()` and `Handlebars.precompile()`.
|
||||
|
||||
#### `runtimeOptions`
|
||||
An object which holds options that will be passed along to the template function in addition to the `data`, `helpers`, and `partials` options. See [Runtime Options][] for a list of available options.
|
||||
|
||||
### Properties
|
||||
|
||||
The public API properties are provided via `ExpressHandlebars` instances. In additional to the properties listed in the **Configuration and Defaults** section, the following are additional public properties:
|
||||
|
||||
#### `engine`
|
||||
A function reference to the `renderView()` method which is bound to `this` `ExpressHandlebars` instance. This bound function should be used when registering this view engine with an Express app.
|
||||
|
||||
#### `extname`
|
||||
The normalized `extname` which will _always_ start with `.` and defaults to `.handlebars`.
|
||||
|
||||
#### `compiled`
|
||||
An object cache which holds compiled Handlebars template functions in the format: `{"path/to/template": [Function]}`.
|
||||
|
||||
#### `precompiled`
|
||||
An object cache which holds precompiled Handlebars template strings in the format: `{"path/to/template": [String]}`.
|
||||
|
||||
### Methods
|
||||
|
||||
The following is the list of public API methods provided via `ExpressHandlebars` instances:
|
||||
|
||||
**Note:** All of the public methods return a [`Promise`][promise] (with the exception of `renderView()` which is the interface with Express.)
|
||||
|
||||
#### `getPartials([options])`
|
||||
Retrieves the partials in the `partialsDir` and returns a Promise for an object mapping the partials in the form `{name: partial}`.
|
||||
|
||||
By default each partial will be a compiled Handlebars template function. Use `options.precompiled` to receive the partials as precompiled templates — this is useful for sharing templates with client code.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* `[options]`: Optional object containing any of the following properties:
|
||||
|
||||
* `[cache]`: Whether cached templates can be used if they have already been requested. This is recommended for production to avoid unnecessary file I/O.
|
||||
|
||||
* `[encoding]`: File encoding.
|
||||
|
||||
* `[precompiled=false]`: Whether precompiled templates should be provided, instead of compiled Handlebars template functions.
|
||||
|
||||
The name of each partial corresponds to its location in `partialsDir`. For example, consider the following directory structure:
|
||||
|
||||
```
|
||||
views
|
||||
└── partials
|
||||
├── foo
|
||||
│ └── bar.handlebars
|
||||
└── title.handlebars
|
||||
|
||||
2 directories, 2 files
|
||||
```
|
||||
|
||||
`getPartials()` would produce the following result:
|
||||
|
||||
```javascript
|
||||
var hbs = require('express-handlebars').create();
|
||||
|
||||
hbs.getPartials().then(function (partials) {
|
||||
console.log(partials);
|
||||
// => { 'foo/bar': [Function],
|
||||
// => title: [Function] }
|
||||
});
|
||||
```
|
||||
|
||||
#### `getTemplate(filePath, [options])`
|
||||
Retrieves the template at the specified `filePath` and returns a Promise for the compiled Handlebars template function.
|
||||
|
||||
Use `options.precompiled` to receive a precompiled Handlebars template.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* `filePath`: String path to the Handlebars template file.
|
||||
|
||||
* `[options]`: Optional object containing any of the following properties:
|
||||
|
||||
* `[cache]`: Whether a cached template can be used if it have already been requested. This is recommended for production to avoid necessary file I/O.
|
||||
|
||||
* `[encoding]`: File encoding.
|
||||
|
||||
* `[precompiled=false]`: Whether a precompiled template should be provided, instead of a compiled Handlebars template function.
|
||||
|
||||
#### `getTemplates(dirPath, [options])`
|
||||
Retrieves all the templates in the specified `dirPath` and returns a Promise for an object mapping the compiled templates in the form `{filename: template}`.
|
||||
|
||||
Use `options.precompiled` to receive precompiled Handlebars templates — this is useful for sharing templates with client code.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* `dirPath`: String path to the directory containing Handlebars template files.
|
||||
|
||||
* `[options]`: Optional object containing any of the following properties:
|
||||
|
||||
* `[cache]`: Whether cached templates can be used if it have already been requested. This is recommended for production to avoid necessary file I/O.
|
||||
|
||||
* `[encoding]`: File encoding.
|
||||
|
||||
* `[precompiled=false]`: Whether precompiled templates should be provided, instead of a compiled Handlebars template function.
|
||||
|
||||
#### `render(filePath, context, [options])`
|
||||
Renders the template at the specified `filePath` with the `context`, using this instance's `helpers` and partials by default, and returns a Promise for the resulting string.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* `filePath`: String path to the Handlebars template file.
|
||||
|
||||
* `context`: Object in which the template will be executed. This contains all of the values to fill into the template.
|
||||
|
||||
* `[options]`: Optional object which can contain any of the following properties which affect this view engine's behavior:
|
||||
|
||||
* `[cache]`: Whether a cached template can be used if it have already been requested. This is recommended for production to avoid unnecessary file I/O.
|
||||
|
||||
* `[encoding]`: File encoding.
|
||||
|
||||
* `[data]`: Optional object which can contain any data that Handlebars will pipe through the template, all helpers, and all partials. This is a side data channel.
|
||||
|
||||
* `[helpers]`: Render-level helpers that will be used instead of any instance-level helpers; these will be merged with (and will override) any global Handlebars helper functions.
|
||||
|
||||
* `[partials]`: Render-level partials that will be used instead of any instance-level partials. This is used internally as an optimization to avoid re-loading all the partials.
|
||||
|
||||
* `[runtimeOptions]`: Optional object which can contain options passed to the template function.
|
||||
|
||||
#### `renderView(viewPath, options|callback, [callback])`
|
||||
Renders the template at the specified `viewPath` as the `{{{body}}}` within the layout specified by the `defaultLayout` or `options.layout`. Rendering will use this instance's `helpers` and partials, and passes the resulting string to the `callback`.
|
||||
|
||||
This method is called by Express and is the main entry point into this Express view engine implementation. It adds the concept of a "layout" and delegates rendering to the `render()` method.
|
||||
|
||||
The `options` will be used both as the context in which the Handlebars templates are rendered, and to signal this view engine on how it should behave, e.g., `options.cache=false` will _always_ load the templates from disk.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* `viewPath`: String path to the Handlebars template file which should serve as the `{{{body}}}` when using a layout.
|
||||
|
||||
* `[options]`: Optional object which will serve as the context in which the Handlebars templates are rendered. It may also contain any of the following properties which affect this view engine's behavior:
|
||||
|
||||
* `[cache]`: Whether cached templates can be used if they have already been requested. This is recommended for production to avoid unnecessary file I/O.
|
||||
|
||||
* `[encoding]`: File encoding.
|
||||
|
||||
* `[data]`: Optional object which can contain any data that Handlebars will pipe through the template, all helpers, and all partials. This is a side data channel.
|
||||
|
||||
* `[helpers]`: Render-level helpers that will be merged with (and will override) instance and global helper functions.
|
||||
|
||||
* `[partials]`: Render-level partials will be merged with (and will override) instance and global partials. This should be a `{partialName: fn}` hash or a Promise of an object with this shape.
|
||||
|
||||
* `[layout]`: Optional string path to the Handlebars template file to be used as the "layout". This overrides any `defaultLayout` value. Passing a falsy value will render with no layout (even if a `defaultLayout` is defined).
|
||||
|
||||
* `[runtimeOptions]`: Optional object which can contain options passed to the template function.
|
||||
|
||||
* `callback`: Function to call once the template is retrieved.
|
||||
|
||||
### Hooks
|
||||
|
||||
The following is the list of protected methods that are called internally and serve as _hooks_ to override functionality of `ExpressHandlebars` instances. A value or a promise can be returned from these methods which allows them to perform async operations.
|
||||
|
||||
#### `_compileTemplate(template, options)`
|
||||
This hook will be called when a Handlebars template needs to be compiled. This function needs to return a compiled Handlebars template function, or a promise for one.
|
||||
|
||||
By default this hook calls `Handlebars.compile()`, but it can be overridden to preform operations before and/or after Handlebars compiles the template. This is useful if you wanted to first process Markdown within a Handlebars template.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* `template`: String Handlebars template that needs to be compiled.
|
||||
|
||||
* `options`: Object `compilerOptions` that were specified when the `ExpressHandlebars` instance as created. This object should be passed along to the `Handlebars.compile()` function.
|
||||
|
||||
#### `_precompileTemplate(template, options)`
|
||||
This hook will be called when a Handlebars template needs to be precompiled. This function needs to return a serialized Handlebars template spec. string, or a promise for one.
|
||||
|
||||
By default this hook calls `Handlebars.precompile()`, but it can be overridden to preform operations before and/or after Handlebars precompiles the template. This is useful if you wanted to first process Markdown within a Handlebars template.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* `template`: String Handlebars template that needs to be precompiled.
|
||||
|
||||
* `options`: Object `compilerOptions` that were specified when the `ExpressHandlebars` instance as created. This object should be passed along to the `Handlebars.compile()` function.
|
||||
|
||||
#### `_renderTemplate(template, context, options)`
|
||||
This hook will be called when a compiled Handlebars template needs to be rendered. This function needs to returned the rendered output string, or a promise for one.
|
||||
|
||||
By default this hook simply calls the passed-in `template` with the `context` and `options` arguments, but it can be overridden to perform operations before and/or after rendering the template.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* `template`: Compiled Handlebars template function to call.
|
||||
|
||||
* `context`: The context object in which to render the `template`.
|
||||
|
||||
* `options`: Object that contains options and metadata for rendering the template:
|
||||
|
||||
* `data`: Object to define custom `@variable` private variables.
|
||||
|
||||
* `helpers`: Object to provide custom helpers in addition to the globally defined helpers.
|
||||
|
||||
* `partials`: Object to provide custom partials in addition to the globally defined partials.
|
||||
|
||||
* `...runtimeOptions`: Other options specified by the `runtimeOptions` value.
|
||||
|
||||
|
||||
[promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
||||
[Runtime Options]: https://handlebarsjs.com/api-reference/runtime-options.html
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
### [Basic Usage][]
|
||||
|
||||
This example shows the most basic way to use this view engine.
|
||||
|
||||
### [Advanced Usage][]
|
||||
|
||||
This example is more comprehensive and shows how to use many of the features of this view engine, including helpers, partials, multiple layouts, etc.
|
||||
|
||||
As noted in the **Package Design** section, this view engine's implementation is instance-based, and more advanced usages can take advantage of this. The Advanced Usage example demonstrates how to use an `ExpressHandlebars` instance to share templates with the client, among other features.
|
||||
|
||||
|
||||
[Basic Usage]: https://github.com/express-handlebars/express-handlebars/tree/master/examples/basic
|
||||
[Advanced Usage]: https://github.com/express-handlebars/express-handlebars/tree/master/examples/advanced
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This software is free to use under the Yahoo! Inc. BSD license. See the [LICENSE file][] for license text and copyright information.
|
||||
|
||||
|
||||
[LICENSE file]: https://github.com/express-handlebars/express-handlebars/blob/master/LICENSE
|
||||
23
node_modules/express-handlebars/index.js
generated
vendored
Normal file
23
node_modules/express-handlebars/index.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Yahoo Inc. All rights reserved.
|
||||
* Copyrights licensed under the New BSD License.
|
||||
* See the accompanying LICENSE file for terms.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const ExpressHandlebars = require("./lib/express-handlebars");
|
||||
|
||||
exports = module.exports = exphbs;
|
||||
exports.create = create;
|
||||
exports.ExpressHandlebars = ExpressHandlebars;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function exphbs (config) {
|
||||
return create(config).engine;
|
||||
}
|
||||
|
||||
function create (config) {
|
||||
return new ExpressHandlebars(config);
|
||||
}
|
||||
19
node_modules/express-handlebars/jest.config.js
generated
vendored
Normal file
19
node_modules/express-handlebars/jest.config.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
module.exports = {
|
||||
restoreMocks: true,
|
||||
clearMocks: true,
|
||||
collectCoverageFrom: [
|
||||
"lib/**/*.js",
|
||||
"index.js",
|
||||
"!**/node_modules/**",
|
||||
],
|
||||
coverageDirectory: "coverage",
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
branches: 100,
|
||||
functions: 100,
|
||||
lines: 100,
|
||||
statements: 100,
|
||||
},
|
||||
},
|
||||
testRegex: /\.test\.jsx?/.source,
|
||||
};
|
||||
372
node_modules/express-handlebars/lib/express-handlebars.js
generated
vendored
Normal file
372
node_modules/express-handlebars/lib/express-handlebars.js
generated
vendored
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Yahoo Inc. All rights reserved.
|
||||
* Copyrights licensed under the New BSD License.
|
||||
* See the accompanying LICENSE file for terms.
|
||||
*/
|
||||
|
||||
const util = require("util");
|
||||
const glob = util.promisify(require("glob"));
|
||||
const Handlebars = require("handlebars");
|
||||
const fs = require("graceful-fs");
|
||||
const readFile = util.promisify(fs.readFile);
|
||||
const path = require("path");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const defaultConfig = {
|
||||
handlebars: Handlebars,
|
||||
extname: ".handlebars",
|
||||
encoding: "utf8",
|
||||
layoutsDir: undefined, // Default layouts directory is relative to `express settings.view` + `layouts/`
|
||||
partialsDir: undefined, // Default partials directory is relative to `express settings.view` + `partials/`
|
||||
defaultLayout: "main",
|
||||
helpers: undefined,
|
||||
compilerOptions: undefined,
|
||||
runtimeOptions: undefined,
|
||||
};
|
||||
|
||||
class ExpressHandlebars {
|
||||
constructor (config = {}) {
|
||||
// Config properties with defaults.
|
||||
Object.assign(this, defaultConfig, config);
|
||||
|
||||
// save given config to override other settings.
|
||||
this.config = config;
|
||||
|
||||
// Express view engine integration point.
|
||||
this.engine = this.renderView.bind(this);
|
||||
|
||||
// Normalize `extname`.
|
||||
if (this.extname.charAt(0) !== ".") {
|
||||
this.extname = "." + this.extname;
|
||||
}
|
||||
|
||||
// Internal caches of compiled and precompiled templates.
|
||||
this.compiled = {};
|
||||
this.precompiled = {};
|
||||
|
||||
// Private internal file system cache.
|
||||
this._fsCache = {};
|
||||
}
|
||||
|
||||
async getPartials (options) {
|
||||
if (typeof this.partialsDir === "undefined") {
|
||||
return {};
|
||||
}
|
||||
const partialsDirs = Array.isArray(this.partialsDir) ? this.partialsDir : [this.partialsDir];
|
||||
|
||||
const dirs = await Promise.all(partialsDirs.map(async dir => {
|
||||
let dirPath;
|
||||
let dirTemplates;
|
||||
let dirNamespace;
|
||||
let dirRename;
|
||||
|
||||
// Support `partialsDir` collection with object entries that contain a
|
||||
// templates promise and a namespace.
|
||||
if (typeof dir === "string") {
|
||||
dirPath = dir;
|
||||
} else if (typeof dir === "object") {
|
||||
dirTemplates = dir.templates;
|
||||
dirNamespace = dir.namespace;
|
||||
dirRename = dir.rename;
|
||||
dirPath = dir.dir;
|
||||
}
|
||||
|
||||
// We must have some path to templates, or templates themselves.
|
||||
if (!dirPath && !dirTemplates) {
|
||||
throw new Error("A partials dir must be a string or config object");
|
||||
}
|
||||
|
||||
const templates = dirTemplates || await this.getTemplates(dirPath, options);
|
||||
|
||||
return {
|
||||
templates,
|
||||
namespace: dirNamespace,
|
||||
rename: dirRename,
|
||||
};
|
||||
}));
|
||||
|
||||
const partials = {};
|
||||
|
||||
for (const dir of dirs) {
|
||||
const { templates, namespace, rename } = dir;
|
||||
const filePaths = Object.keys(templates);
|
||||
|
||||
const getTemplateNameFn = typeof rename === "function"
|
||||
? rename
|
||||
: this._getTemplateName.bind(this);
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
const partialName = getTemplateNameFn(filePath, namespace);
|
||||
partials[partialName] = templates[filePath];
|
||||
}
|
||||
}
|
||||
|
||||
return partials;
|
||||
}
|
||||
|
||||
async getTemplate (filePath, options = {}) {
|
||||
filePath = path.resolve(filePath);
|
||||
|
||||
const encoding = options.encoding || this.encoding;
|
||||
const cache = options.precompiled ? this.precompiled : this.compiled;
|
||||
let template = options.cache && cache[filePath];
|
||||
|
||||
if (template) {
|
||||
return template;
|
||||
}
|
||||
|
||||
// Optimistically cache template promise to reduce file system I/O, but
|
||||
// remove from cache if there was a problem.
|
||||
try {
|
||||
cache[filePath] = this._getFile(filePath, { cache: options.cache, encoding })
|
||||
.then(file => {
|
||||
const compileTemplate = (options.precompiled ? this._precompileTemplate : this._compileTemplate).bind(this);
|
||||
return compileTemplate(file, this.compilerOptions);
|
||||
});
|
||||
template = await cache[filePath];
|
||||
return template;
|
||||
} catch (err) {
|
||||
delete cache[filePath];
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async getTemplates (dirPath, options = {}) {
|
||||
const cache = options.cache;
|
||||
|
||||
const filePaths = await this._getDir(dirPath, { cache });
|
||||
const templates = await Promise.all(filePaths.map(filePath => {
|
||||
return this.getTemplate(path.join(dirPath, filePath), options);
|
||||
}));
|
||||
|
||||
const hash = {};
|
||||
for (let i = 0; i < filePaths.length; i++) {
|
||||
hash[filePaths[i]] = templates[i];
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
async render (filePath, context, options = {}) {
|
||||
const encoding = options.encoding || this.encoding;
|
||||
const [template, partials] = await Promise.all([
|
||||
this.getTemplate(filePath, { cache: options.cache, encoding }),
|
||||
options.partials || this.getPartials({ cache: options.cache, encoding }),
|
||||
]);
|
||||
const helpers = { ...this.helpers, ...options.helpers };
|
||||
const runtimeOptions = { ...this.runtimeOptions, ...options.runtimeOptions };
|
||||
|
||||
// Add ExpressHandlebars metadata to the data channel so that it's
|
||||
// accessible within the templates and helpers, namespaced under:
|
||||
// `@exphbs.*`
|
||||
const data = {
|
||||
...options.data,
|
||||
exphbs: {
|
||||
...options,
|
||||
filePath,
|
||||
helpers,
|
||||
partials,
|
||||
runtimeOptions,
|
||||
},
|
||||
};
|
||||
|
||||
const html = this._renderTemplate(template, context, {
|
||||
...runtimeOptions,
|
||||
data,
|
||||
helpers,
|
||||
partials,
|
||||
});
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
async renderView (viewPath, options = {}, callback = null) {
|
||||
const context = options;
|
||||
|
||||
let promise;
|
||||
if (!callback) {
|
||||
promise = new Promise((resolve, reject) => {
|
||||
callback = (err, value) => { err !== null ? reject(err) : resolve(value); };
|
||||
});
|
||||
}
|
||||
|
||||
// Express provides `settings.views` which is the path to the views dir that
|
||||
// the developer set on the Express app. When this value exists, it's used
|
||||
// to compute the view's name. Layouts and Partials directories are relative
|
||||
// to `settings.view` path
|
||||
let view;
|
||||
const views = options.settings && options.settings.views;
|
||||
const viewsPath = this._resolveViewsPath(views, viewPath);
|
||||
if (viewsPath) {
|
||||
view = this._getTemplateName(path.relative(viewsPath, viewPath));
|
||||
this.partialsDir = this.config.partialsDir || path.join(viewsPath, "partials/");
|
||||
this.layoutsDir = this.config.layoutsDir || path.join(viewsPath, "layouts/");
|
||||
}
|
||||
|
||||
const encoding = options.encoding || this.encoding;
|
||||
|
||||
// Merge render-level and instance-level helpers together.
|
||||
const helpers = { ...this.helpers, ...options.helpers };
|
||||
|
||||
// Merge render-level and instance-level partials together.
|
||||
const partials = {
|
||||
...await this.getPartials({ cache: options.cache, encoding }),
|
||||
...await (options.partials || {}),
|
||||
};
|
||||
|
||||
// Pluck-out ExpressHandlebars-specific options and Handlebars-specific
|
||||
// rendering options.
|
||||
const renderOptions = {
|
||||
cache: options.cache,
|
||||
encoding,
|
||||
view,
|
||||
layout: "layout" in options ? options.layout : this.defaultLayout,
|
||||
|
||||
data: options.data,
|
||||
helpers,
|
||||
partials,
|
||||
runtimeOptions: options.runtimeOptions,
|
||||
};
|
||||
|
||||
try {
|
||||
let html = await this.render(viewPath, context, renderOptions);
|
||||
const layoutPath = this._resolveLayoutPath(renderOptions.layout);
|
||||
|
||||
if (layoutPath) {
|
||||
html = await this.render(
|
||||
layoutPath,
|
||||
{ ...context, body: html },
|
||||
{ ...renderOptions, layout: undefined },
|
||||
);
|
||||
}
|
||||
callback(null, html);
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
// -- Protected Hooks ----------------------------------------------------------
|
||||
|
||||
_compileTemplate (template, options) {
|
||||
return this.handlebars.compile(template.trim(), options);
|
||||
}
|
||||
|
||||
_precompileTemplate (template, options) {
|
||||
return this.handlebars.precompile(template.trim(), options);
|
||||
}
|
||||
|
||||
_renderTemplate (template, context, options) {
|
||||
return template(context, options).trim();
|
||||
}
|
||||
|
||||
// -- Private ------------------------------------------------------------------
|
||||
|
||||
async _getDir (dirPath, options = {}) {
|
||||
dirPath = path.resolve(dirPath);
|
||||
|
||||
const cache = this._fsCache;
|
||||
let dir = options.cache && cache[dirPath];
|
||||
|
||||
if (dir) {
|
||||
dir = await dir;
|
||||
return dir.concat();
|
||||
}
|
||||
|
||||
const pattern = "**/*" + this.extname;
|
||||
|
||||
// Optimistically cache dir promise to reduce file system I/O, but remove
|
||||
// from cache if there was a problem.
|
||||
|
||||
try {
|
||||
dir = cache[dirPath] = glob(pattern, {
|
||||
cwd: dirPath,
|
||||
follow: true,
|
||||
});
|
||||
if (options._throwTestError) {
|
||||
// FIXME: not sure how to throw error in glob for test coverage
|
||||
throw new Error("test");
|
||||
}
|
||||
dir = await dir;
|
||||
return dir.concat();
|
||||
} catch (err) {
|
||||
delete cache[dirPath];
|
||||
throw err;
|
||||
};
|
||||
}
|
||||
|
||||
async _getFile (filePath, options = {}) {
|
||||
filePath = path.resolve(filePath);
|
||||
|
||||
const cache = this._fsCache;
|
||||
const encoding = options.encoding || this.encoding;
|
||||
let file = options.cache && cache[filePath];
|
||||
|
||||
if (file) {
|
||||
return file;
|
||||
}
|
||||
|
||||
// Optimistically cache file promise to reduce file system I/O, but remove
|
||||
// from cache if there was a problem.
|
||||
try {
|
||||
cache[filePath] = readFile(filePath, encoding || "utf8");
|
||||
file = await cache[filePath];
|
||||
return file;
|
||||
} catch (err) {
|
||||
delete cache[filePath];
|
||||
throw err;
|
||||
};
|
||||
}
|
||||
|
||||
_getTemplateName (filePath, namespace) {
|
||||
let name = filePath;
|
||||
|
||||
if (name.endsWith(this.extname)) {
|
||||
name = name.substring(0, name.length - this.extname.length);
|
||||
}
|
||||
|
||||
if (namespace) {
|
||||
name = namespace + "/" + name;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
_resolveViewsPath (views, file) {
|
||||
if (!Array.isArray(views)) {
|
||||
return views;
|
||||
}
|
||||
|
||||
let lastDir = path.resolve(file);
|
||||
let dir = path.dirname(lastDir);
|
||||
const absoluteViews = views.map(v => path.resolve(v));
|
||||
|
||||
// find the closest parent
|
||||
while (dir !== lastDir) {
|
||||
const index = absoluteViews.indexOf(dir);
|
||||
if (index >= 0) {
|
||||
return views[index];
|
||||
}
|
||||
lastDir = dir;
|
||||
dir = path.dirname(lastDir);
|
||||
}
|
||||
|
||||
// cannot resolve view
|
||||
return null;
|
||||
}
|
||||
|
||||
_resolveLayoutPath (layoutPath) {
|
||||
if (!layoutPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!path.extname(layoutPath)) {
|
||||
layoutPath += this.extname;
|
||||
}
|
||||
|
||||
return path.resolve(this.layoutsDir || "", layoutPath);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ExpressHandlebars;
|
||||
95
node_modules/express-handlebars/package.json
generated
vendored
Normal file
95
node_modules/express-handlebars/package.json
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
{
|
||||
"_from": "express-handlebars@^5.3.4",
|
||||
"_id": "express-handlebars@5.3.5",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-r9pzDc94ZNJ7FVvtsxLfPybmN0eFAUnR61oimNPRpD0D7nkLcezrkpZzoXS5TI75wYHRbflPLTU39B62pwB4DA==",
|
||||
"_location": "/express-handlebars",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "express-handlebars@^5.3.4",
|
||||
"name": "express-handlebars",
|
||||
"escapedName": "express-handlebars",
|
||||
"rawSpec": "^5.3.4",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^5.3.4"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-5.3.5.tgz",
|
||||
"_shasum": "a04a1e670aa97d5b3a8080de8336f79228593540",
|
||||
"_spec": "express-handlebars@^5.3.4",
|
||||
"_where": "/home/runner/work/satshkd-vercel/satshkd-vercel",
|
||||
"author": {
|
||||
"name": "Eric Ferraiuolo",
|
||||
"email": "eferraiuolo@gmail.com",
|
||||
"url": "http://ericf.me/"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/express-handlebars/express-handlebars/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"glob": "^7.2.0",
|
||||
"graceful-fs": "^4.2.8",
|
||||
"handlebars": "^4.7.7"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "A Handlebars view engine for Express which doesn't suck.",
|
||||
"devDependencies": {
|
||||
"@semantic-release/changelog": "^6.0.1",
|
||||
"@semantic-release/commit-analyzer": "^9.0.1",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@semantic-release/github": "^8.0.2",
|
||||
"@semantic-release/npm": "^8.0.3",
|
||||
"@semantic-release/release-notes-generator": "^10.0.2",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-standard": "^16.0.3",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.1.1",
|
||||
"jest-cli": "^27.3.1",
|
||||
"semantic-release": "^18.0.0"
|
||||
},
|
||||
"directories": {
|
||||
"example": "examples"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v10.24.1"
|
||||
},
|
||||
"homepage": "https://github.com/express-handlebars/express-handlebars",
|
||||
"keywords": [
|
||||
"express",
|
||||
"express3",
|
||||
"handlebars",
|
||||
"view",
|
||||
"layout",
|
||||
"partials",
|
||||
"templates"
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"name": "express-handlebars",
|
||||
"release": {
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/changelog",
|
||||
"@semantic-release/npm",
|
||||
"@semantic-release/github",
|
||||
"@semantic-release/git"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/express-handlebars/express-handlebars.git"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "jest --verbose",
|
||||
"test:cover": "jest --coverage"
|
||||
},
|
||||
"version": "5.3.5"
|
||||
}
|
||||
10
node_modules/express-handlebars/renovate.json
generated
vendored
Normal file
10
node_modules/express-handlebars/renovate.json
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"devDependencies": {
|
||||
"automerge": true,
|
||||
"commitMessageTopic": "devDependency {{depName}}"
|
||||
},
|
||||
"rangeStrategy": "bump"
|
||||
}
|
||||
759
node_modules/express-handlebars/spec/express-handlebars.test.js
generated
vendored
Normal file
759
node_modules/express-handlebars/spec/express-handlebars.test.js
generated
vendored
Normal file
@@ -0,0 +1,759 @@
|
||||
const path = require("path");
|
||||
const expressHandlebars = require("../");
|
||||
|
||||
function fixturePath (filePath = "") {
|
||||
return path.resolve(__dirname, "./fixtures", filePath);
|
||||
}
|
||||
|
||||
describe("express-handlebars", () => {
|
||||
test("should nomalize extname", () => {
|
||||
const exphbs1 = expressHandlebars.create({ extname: "ext" });
|
||||
const exphbs2 = expressHandlebars.create({ extname: ".ext" });
|
||||
expect(exphbs1.extname).toBe(".ext");
|
||||
expect(exphbs2.extname).toBe(".ext");
|
||||
});
|
||||
|
||||
describe("getPartials", () => {
|
||||
test("should throw if partialsDir is not correct type", async () => {
|
||||
const exphbs = expressHandlebars.create({ partialsDir: 1 });
|
||||
let error;
|
||||
try {
|
||||
await exphbs.getPartials();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toEqual(expect.any(Error));
|
||||
expect(error.message).toBe("A partials dir must be a string or config object");
|
||||
});
|
||||
|
||||
test("should return empty object if no partialsDir is defined", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const partials = await exphbs.getPartials();
|
||||
expect(partials).toEqual({});
|
||||
});
|
||||
|
||||
test("should return empty object partialsDir does not exist", async () => {
|
||||
const exphbs = expressHandlebars.create({ partialsDir: "does-not-exist" });
|
||||
const partials = await exphbs.getPartials();
|
||||
expect(partials).toEqual({});
|
||||
});
|
||||
|
||||
test("should return partials on string", async () => {
|
||||
const exphbs = expressHandlebars.create({ partialsDir: fixturePath("partials") });
|
||||
const partials = await exphbs.getPartials();
|
||||
expect(partials).toEqual({
|
||||
partial: expect.any(Function),
|
||||
"partial-latin1": expect.any(Function),
|
||||
});
|
||||
});
|
||||
|
||||
test("should return partials on array", async () => {
|
||||
const exphbs = expressHandlebars.create({ partialsDir: [fixturePath("partials")] });
|
||||
const partials = await exphbs.getPartials();
|
||||
expect(partials).toEqual({
|
||||
partial: expect.any(Function),
|
||||
"partial-latin1": expect.any(Function),
|
||||
});
|
||||
});
|
||||
|
||||
test("should return partials on object", async () => {
|
||||
const fn = jest.fn();
|
||||
const exphbs = expressHandlebars.create({
|
||||
partialsDir: {
|
||||
templates: { "partial template": fn },
|
||||
namespace: "partial namespace",
|
||||
dir: fixturePath("partials"),
|
||||
},
|
||||
});
|
||||
const partials = await exphbs.getPartials();
|
||||
expect(partials).toEqual({
|
||||
"partial namespace/partial template": fn,
|
||||
});
|
||||
});
|
||||
|
||||
test("should return renamed partials with rename function", async () => {
|
||||
const fn = jest.fn();
|
||||
const exphbs = expressHandlebars.create({
|
||||
partialsDir: {
|
||||
templates: { "partial/template": fn },
|
||||
namespace: "partial namespace",
|
||||
dir: fixturePath("partials"),
|
||||
rename: (filePath, namespace) => {
|
||||
return `${namespace}/${filePath.split("/")[0]}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
const partials = await exphbs.getPartials();
|
||||
expect(partials).toEqual({
|
||||
"partial namespace/partial": fn,
|
||||
});
|
||||
});
|
||||
|
||||
test("should return partials on path relative to cwd", async () => {
|
||||
const exphbs = expressHandlebars.create({ partialsDir: "spec/fixtures/partials" });
|
||||
const partials = await exphbs.getPartials();
|
||||
expect(partials).toEqual({
|
||||
partial: expect.any(Function),
|
||||
"partial-latin1": expect.any(Function),
|
||||
});
|
||||
});
|
||||
|
||||
test("should return template function", async () => {
|
||||
const exphbs = expressHandlebars.create({ partialsDir: "spec/fixtures/partials" });
|
||||
const partials = await exphbs.getPartials();
|
||||
const html = partials.partial({ text: "test text" });
|
||||
expect(html).toBe("partial test text");
|
||||
});
|
||||
|
||||
test("should return a template with encoding", async () => {
|
||||
const exphbs = expressHandlebars.create({ partialsDir: "spec/fixtures/partials" });
|
||||
const partials = await exphbs.getPartials({ encoding: "latin1" });
|
||||
const html = partials["partial-latin1"]();
|
||||
expect(html).toContain("ñáéíóú");
|
||||
});
|
||||
|
||||
test("should return a template with default encoding", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
encoding: "latin1",
|
||||
partialsDir: "spec/fixtures/partials",
|
||||
});
|
||||
const partials = await exphbs.getPartials();
|
||||
const html = partials["partial-latin1"]();
|
||||
expect(html).toContain("ñáéíóú");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getTemplate", () => {
|
||||
test("should return cached template", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("templates/template.handlebars");
|
||||
const compiledCachedFunction = Symbol("compiledCachedFunction");
|
||||
exphbs.compiled[filePath] = compiledCachedFunction;
|
||||
const precompiledCachedFunction = Symbol("precompiledCachedFunction");
|
||||
exphbs.precompiled[filePath] = precompiledCachedFunction;
|
||||
const template = await exphbs.getTemplate(filePath, { cache: true });
|
||||
expect(template).toBe(compiledCachedFunction);
|
||||
});
|
||||
|
||||
test("should return precompiled cached template", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("templates/template.handlebars");
|
||||
const compiledCachedFunction = Symbol("compiledCachedFunction");
|
||||
exphbs.compiled[filePath] = compiledCachedFunction;
|
||||
const precompiledCachedFunction = Symbol("precompiledCachedFunction");
|
||||
exphbs.precompiled[filePath] = precompiledCachedFunction;
|
||||
const template = await exphbs.getTemplate(filePath, { precompiled: true, cache: true });
|
||||
expect(template).toBe(precompiledCachedFunction);
|
||||
});
|
||||
|
||||
test("should store in precompiled cache", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("templates/template.handlebars");
|
||||
expect(exphbs.compiled[filePath]).toBeUndefined();
|
||||
expect(exphbs.precompiled[filePath]).toBeUndefined();
|
||||
await exphbs.getTemplate(filePath, { precompiled: true });
|
||||
expect(exphbs.compiled[filePath]).toBeUndefined();
|
||||
expect(exphbs.precompiled[filePath]).toBeDefined();
|
||||
});
|
||||
|
||||
test("should store in compiled cache", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("templates/template.handlebars");
|
||||
expect(exphbs.compiled[filePath]).toBeUndefined();
|
||||
expect(exphbs.precompiled[filePath]).toBeUndefined();
|
||||
await exphbs.getTemplate(filePath);
|
||||
expect(exphbs.compiled[filePath]).toBeDefined();
|
||||
expect(exphbs.precompiled[filePath]).toBeUndefined();
|
||||
});
|
||||
|
||||
test("should return a template", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("templates/template.handlebars");
|
||||
const template = await exphbs.getTemplate(filePath);
|
||||
const html = template({ text: "test text" });
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
});
|
||||
|
||||
test("should return a template with encoding", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("templates/template-latin1.handlebars");
|
||||
const template = await exphbs.getTemplate(filePath, { encoding: "latin1" });
|
||||
const html = template();
|
||||
expect(html).toContain("ñáéíóú");
|
||||
});
|
||||
|
||||
test("should return a template with default encoding", async () => {
|
||||
const exphbs = expressHandlebars.create({ encoding: "latin1" });
|
||||
const filePath = fixturePath("templates/template-latin1.handlebars");
|
||||
const template = await exphbs.getTemplate(filePath);
|
||||
const html = template();
|
||||
expect(html).toContain("ñáéíóú");
|
||||
});
|
||||
|
||||
test("should not store in cache on error", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = "does-not-exist";
|
||||
expect(exphbs.compiled[filePath]).toBeUndefined();
|
||||
let error;
|
||||
try {
|
||||
await exphbs.getTemplate(filePath);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toEqual(expect.stringContaining("no such file or directory"));
|
||||
expect(exphbs.compiled[filePath]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("getTemplates", () => {
|
||||
test("should return cached templates", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const dirPath = fixturePath("templates");
|
||||
const fsCache = Promise.resolve([]);
|
||||
exphbs._fsCache[dirPath] = fsCache;
|
||||
const templates = await exphbs.getTemplates(dirPath, { cache: true });
|
||||
expect(templates).toEqual({});
|
||||
});
|
||||
|
||||
test("should return templates", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const dirPath = fixturePath("templates");
|
||||
const templates = await exphbs.getTemplates(dirPath);
|
||||
const html = templates["template.handlebars"]({ text: "test text" });
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
});
|
||||
|
||||
test("should get templates in sub directories", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const dirPath = fixturePath("templates");
|
||||
const templates = await exphbs.getTemplates(dirPath);
|
||||
expect(Object.keys(templates)).toEqual([
|
||||
"subdir/template.handlebars",
|
||||
"template-latin1.handlebars",
|
||||
"template.handlebars",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("render", () => {
|
||||
test("should return cached templates", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("render-cached.handlebars");
|
||||
exphbs.compiled[filePath] = () => "cached";
|
||||
const html = await exphbs.render(filePath, null, { cache: true });
|
||||
expect(html).toBe("cached");
|
||||
});
|
||||
|
||||
test("should use helpers", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
helpers: {
|
||||
help: () => "help",
|
||||
},
|
||||
});
|
||||
const filePath = fixturePath("render-helper.handlebars");
|
||||
const html = await exphbs.render(filePath, { text: "test text" });
|
||||
expect(html).toBe("<p>help</p>");
|
||||
});
|
||||
|
||||
test("should override helpers", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
helpers: {
|
||||
help: () => "help",
|
||||
},
|
||||
});
|
||||
const filePath = fixturePath("render-helper.handlebars");
|
||||
const html = await exphbs.render(filePath, { text: "test text" }, {
|
||||
helpers: {
|
||||
help: (text) => text,
|
||||
},
|
||||
});
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
});
|
||||
|
||||
test("should return html", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("render-text.handlebars");
|
||||
const html = await exphbs.render(filePath, { text: "test text" });
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
});
|
||||
|
||||
test("should return html with encoding", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
partialsDir: fixturePath("partials"),
|
||||
});
|
||||
const filePath = fixturePath("render-latin1.handlebars");
|
||||
const html = await exphbs.render(filePath, null, { encoding: "latin1" });
|
||||
expect(html).toContain("partial ñáéíóú");
|
||||
expect(html).toContain("render ñáéíóú");
|
||||
});
|
||||
|
||||
test("should return html with default encoding", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
encoding: "latin1",
|
||||
partialsDir: fixturePath("partials"),
|
||||
});
|
||||
const filePath = fixturePath("render-latin1.handlebars");
|
||||
const html = await exphbs.render(filePath);
|
||||
expect(html).toContain("partial ñáéíóú");
|
||||
expect(html).toContain("render ñáéíóú");
|
||||
});
|
||||
|
||||
test("should render with partial", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
partialsDir: fixturePath("partials"),
|
||||
});
|
||||
const filePath = fixturePath("render-partial.handlebars");
|
||||
const html = await exphbs.render(filePath, { text: "test text" });
|
||||
expect(html.replace(/\r/g, "")).toBe("<h1>partial test text</h1>\n<p>test text</p>");
|
||||
});
|
||||
|
||||
test("should render with runtimeOptions", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
runtimeOptions: { runtimeOptionTest: "test" },
|
||||
});
|
||||
const filePath = fixturePath("test");
|
||||
const spy = jest.fn(() => { return "test"; });
|
||||
exphbs.compiled[filePath] = spy;
|
||||
await exphbs.render(filePath, null, { cache: true });
|
||||
expect(spy).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ runtimeOptionTest: "test" }));
|
||||
});
|
||||
|
||||
test("should override runtimeOptions", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
runtimeOptions: { runtimeOptionTest: "test" },
|
||||
});
|
||||
const filePath = fixturePath("test");
|
||||
const spy = jest.fn(() => { return "test"; });
|
||||
exphbs.compiled[filePath] = spy;
|
||||
await exphbs.render(filePath, null, {
|
||||
cache: true,
|
||||
runtimeOptions: { runtimeOptionTest: "test2" },
|
||||
});
|
||||
expect(spy).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ runtimeOptionTest: "test2" }));
|
||||
});
|
||||
});
|
||||
|
||||
describe("engine", () => {
|
||||
test("should call renderView", async () => {
|
||||
const arr = Array(100).fill(0).map((_, i) => i);
|
||||
jest.spyOn(expressHandlebars.ExpressHandlebars.prototype, "renderView").mockImplementation(() => {});
|
||||
const exphbs = expressHandlebars.create();
|
||||
exphbs.engine(...arr);
|
||||
expect(expressHandlebars.ExpressHandlebars.prototype.renderView).toHaveBeenCalledWith(...arr);
|
||||
});
|
||||
|
||||
test("should call engine", async () => {
|
||||
const arr = Array(100).fill(0).map((_, i) => i);
|
||||
jest.spyOn(expressHandlebars.ExpressHandlebars.prototype, "renderView").mockImplementation(() => {});
|
||||
expressHandlebars()(...arr);
|
||||
expect(expressHandlebars.ExpressHandlebars.prototype.renderView).toHaveBeenCalledWith(...arr);
|
||||
});
|
||||
|
||||
test("should render html", async () => {
|
||||
const renderView = expressHandlebars({ defaultLayout: null });
|
||||
const viewPath = fixturePath("render-text.handlebars");
|
||||
const html = await renderView(viewPath, { text: "test text" });
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
});
|
||||
});
|
||||
|
||||
describe("renderView", () => {
|
||||
test("should use settings.views", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const viewPath = fixturePath("render-partial.handlebars");
|
||||
const viewsPath = fixturePath();
|
||||
const html = await exphbs.renderView(viewPath, {
|
||||
text: "test text",
|
||||
settings: { views: viewsPath },
|
||||
});
|
||||
expect(html.replace(/\r/g, "")).toBe("<body>\n<h1>partial test text</h1>\n<p>test text</p>\n</body>");
|
||||
});
|
||||
|
||||
test("should use settings.views array", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const viewPath = fixturePath("render-partial.handlebars");
|
||||
const viewsPath = fixturePath();
|
||||
const html = await exphbs.renderView(viewPath, {
|
||||
text: "test text",
|
||||
settings: { views: [viewsPath] },
|
||||
});
|
||||
expect(html.replace(/\r/g, "")).toBe("<body>\n<h1>partial test text</h1>\n<p>test text</p>\n</body>");
|
||||
});
|
||||
|
||||
test("should not use settings.views array when no parent found", async () => {
|
||||
const exphbs = expressHandlebars.create({ defaultLayout: null });
|
||||
const viewPath = fixturePath("render-text.handlebars");
|
||||
const viewsPath = "does-not-exist";
|
||||
const html = await exphbs.renderView(viewPath, {
|
||||
text: "test text",
|
||||
settings: { views: [viewsPath] },
|
||||
});
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
});
|
||||
|
||||
test("should use settings.views when it changes", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const viewPath = fixturePath("render-partial.handlebars");
|
||||
const viewsPath = fixturePath();
|
||||
const html = await exphbs.renderView(viewPath, {
|
||||
text: "test text",
|
||||
settings: { views: viewsPath },
|
||||
});
|
||||
expect(html.replace(/\r/g, "")).toBe("<body>\n<h1>partial test text</h1>\n<p>test text</p>\n</body>");
|
||||
const otherViewsPath = fixturePath("other-views");
|
||||
const otherhtml = await exphbs.renderView(viewPath, {
|
||||
text: "test text",
|
||||
settings: { views: otherViewsPath },
|
||||
});
|
||||
expect(otherhtml.replace(/\r/g, "")).toBe("<body>\nother layout\n<h1>other partial test text</h1>\n<p>test text</p>\n</body>");
|
||||
});
|
||||
|
||||
test("should not overwrite config with settings.views", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
layoutsDir: fixturePath("layouts"),
|
||||
partialsDir: fixturePath("partials"),
|
||||
});
|
||||
const viewPath = fixturePath("render-partial.handlebars");
|
||||
const viewsPath = fixturePath("other-views");
|
||||
const html = await exphbs.renderView(viewPath, {
|
||||
text: "test text",
|
||||
settings: { views: viewsPath },
|
||||
});
|
||||
expect(html.replace(/\r/g, "")).toBe("<body>\n<h1>partial test text</h1>\n<p>test text</p>\n</body>");
|
||||
});
|
||||
|
||||
test("should merge helpers", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
defaultLayout: null,
|
||||
helpers: {
|
||||
help: () => "help",
|
||||
},
|
||||
});
|
||||
const viewPath = fixturePath("render-helper.handlebars");
|
||||
const html = await exphbs.renderView(viewPath, {
|
||||
text: "test text",
|
||||
helpers: {
|
||||
help: (text) => text,
|
||||
},
|
||||
});
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
});
|
||||
|
||||
test("should use layout option", async () => {
|
||||
const exphbs = expressHandlebars.create({ defaultLayout: null });
|
||||
const layoutPath = fixturePath("layouts/main.handlebars");
|
||||
const viewPath = fixturePath("render-text.handlebars");
|
||||
const html = await exphbs.renderView(viewPath, {
|
||||
text: "test text",
|
||||
layout: layoutPath,
|
||||
});
|
||||
expect(html.replace(/\r/g, "")).toBe("<body>\n<p>test text</p>\n</body>");
|
||||
});
|
||||
|
||||
test("should render html", async () => {
|
||||
const exphbs = expressHandlebars.create({ defaultLayout: null });
|
||||
const viewPath = fixturePath("render-text.handlebars");
|
||||
const html = await exphbs.renderView(viewPath, { text: "test text" });
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
});
|
||||
|
||||
test("should render html with encoding", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
defaultLayout: "main-latin1",
|
||||
partialsDir: fixturePath("partials"),
|
||||
layoutsDir: fixturePath("layouts"),
|
||||
});
|
||||
const viewPath = fixturePath("render-latin1.handlebars");
|
||||
const html = await exphbs.renderView(viewPath, { encoding: "latin1" });
|
||||
expect(html).toContain("layout ñáéíóú");
|
||||
expect(html).toContain("partial ñáéíóú");
|
||||
expect(html).toContain("render ñáéíóú");
|
||||
});
|
||||
|
||||
test("should render html with default encoding", async () => {
|
||||
const exphbs = expressHandlebars.create({
|
||||
encoding: "latin1",
|
||||
defaultLayout: "main-latin1",
|
||||
partialsDir: fixturePath("partials"),
|
||||
layoutsDir: fixturePath("layouts"),
|
||||
});
|
||||
const viewPath = fixturePath("render-latin1.handlebars");
|
||||
const html = await exphbs.renderView(viewPath);
|
||||
expect(html).toContain("layout ñáéíóú");
|
||||
expect(html).toContain("partial ñáéíóú");
|
||||
expect(html).toContain("render ñáéíóú");
|
||||
});
|
||||
|
||||
test("should call callback with html", (done) => {
|
||||
const exphbs = expressHandlebars.create({ defaultLayout: null });
|
||||
const viewPath = fixturePath("render-text.handlebars");
|
||||
exphbs.renderView(viewPath, { text: "test text" }, (err, html) => {
|
||||
expect(err).toBe(null);
|
||||
expect(html).toBe("<p>test text</p>");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("should call callback with error", (done) => {
|
||||
const exphbs = expressHandlebars.create({ defaultLayout: null });
|
||||
const viewPath = "does-not-exist";
|
||||
exphbs.renderView(viewPath, {}, (err, html) => {
|
||||
expect(err.message).toEqual(expect.stringContaining("no such file or directory"));
|
||||
expect(html).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("should reject with error", async () => {
|
||||
const exphbs = expressHandlebars.create({ defaultLayout: null });
|
||||
const viewPath = "does-not-exist";
|
||||
let error;
|
||||
try {
|
||||
await exphbs.renderView(viewPath);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toEqual(expect.stringContaining("no such file or directory"));
|
||||
});
|
||||
|
||||
test("should use runtimeOptions", async () => {
|
||||
const exphbs = expressHandlebars.create({ defaultLayout: null });
|
||||
const filePath = fixturePath("test");
|
||||
const spy = jest.fn(() => { return "test"; });
|
||||
exphbs.compiled[filePath] = spy;
|
||||
await exphbs.renderView(filePath, {
|
||||
cache: true,
|
||||
runtimeOptions: { runtimeOptionTest: "test" },
|
||||
});
|
||||
expect(spy).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ runtimeOptionTest: "test" }));
|
||||
});
|
||||
});
|
||||
|
||||
describe("hooks", () => {
|
||||
describe("_compileTemplate", () => {
|
||||
test("should call template with context and options", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
jest.spyOn(exphbs.handlebars, "compile").mockImplementation(() => {});
|
||||
const template = "template";
|
||||
const options = {};
|
||||
exphbs._compileTemplate(template, options);
|
||||
expect(exphbs.handlebars.compile).toHaveBeenCalledWith(template, options);
|
||||
});
|
||||
|
||||
test("should trim template", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
jest.spyOn(exphbs.handlebars, "compile").mockImplementation(() => {});
|
||||
const template = " template\n";
|
||||
const options = {};
|
||||
exphbs._compileTemplate(template, options);
|
||||
expect(exphbs.handlebars.compile).toHaveBeenCalledWith("template", options);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_precompileTemplate", () => {
|
||||
test("should call template with context and options", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
jest.spyOn(exphbs.handlebars, "precompile").mockImplementation(() => {});
|
||||
const template = "template";
|
||||
const options = {};
|
||||
exphbs._precompileTemplate(template, options);
|
||||
expect(exphbs.handlebars.precompile).toHaveBeenCalledWith(template, options);
|
||||
});
|
||||
|
||||
test("should trim template", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
jest.spyOn(exphbs.handlebars, "precompile").mockImplementation(() => {});
|
||||
const template = " template\n";
|
||||
const options = {};
|
||||
exphbs._precompileTemplate(template, options);
|
||||
expect(exphbs.handlebars.precompile).toHaveBeenCalledWith("template", options);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_renderTemplate", () => {
|
||||
test("should call template with context and options", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const template = jest.fn(() => "");
|
||||
const context = {};
|
||||
const options = {};
|
||||
exphbs._renderTemplate(template, context, options);
|
||||
expect(template).toHaveBeenCalledWith(context, options);
|
||||
});
|
||||
|
||||
test("should trim html", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const template = () => " \n";
|
||||
const html = exphbs._renderTemplate(template);
|
||||
expect(html).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("_getDir", () => {
|
||||
test("should get from cache", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("test");
|
||||
exphbs._fsCache[filePath] = "test";
|
||||
const file = await exphbs._getDir(filePath, { cache: true });
|
||||
expect(file).toBe("test");
|
||||
});
|
||||
|
||||
test("should store in cache", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("templates");
|
||||
expect(exphbs._fsCache[filePath]).toBeUndefined();
|
||||
await exphbs._getDir(filePath);
|
||||
expect(exphbs._fsCache[filePath]).toBeDefined();
|
||||
});
|
||||
|
||||
test("should not store in cache on error", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = "test";
|
||||
expect(exphbs._fsCache[filePath]).toBeUndefined();
|
||||
let error;
|
||||
try {
|
||||
await exphbs._getDir(filePath, { _throwTestError: true });
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(exphbs._fsCache[filePath]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_getFile", () => {
|
||||
test("should get from cache", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("test");
|
||||
exphbs._fsCache[filePath] = "test";
|
||||
const file = await exphbs._getFile(filePath, { cache: true });
|
||||
expect(file).toBe("test");
|
||||
});
|
||||
|
||||
test("should store in cache", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("render-text.handlebars");
|
||||
expect(exphbs._fsCache[filePath]).toBeUndefined();
|
||||
await exphbs._getFile(filePath);
|
||||
expect(exphbs._fsCache[filePath]).toBeDefined();
|
||||
});
|
||||
|
||||
test("should not store in cache on error", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = "does-not-exist";
|
||||
expect(exphbs._fsCache[filePath]).toBeUndefined();
|
||||
let error;
|
||||
try {
|
||||
await exphbs._getFile(filePath);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toEqual(expect.stringContaining("no such file or directory"));
|
||||
expect(exphbs._fsCache[filePath]).toBeUndefined();
|
||||
});
|
||||
|
||||
test("should read as utf8", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("render-text.handlebars");
|
||||
const text = await exphbs._getFile(filePath);
|
||||
expect(text.trim()).toBe("<p>{{text}}</p>");
|
||||
});
|
||||
|
||||
test("should read as utf8 by default", async () => {
|
||||
const exphbs = expressHandlebars.create({ encoding: null });
|
||||
const filePath = fixturePath("render-text.handlebars");
|
||||
const text = await exphbs._getFile(filePath);
|
||||
expect(text.trim()).toBe("<p>{{text}}</p>");
|
||||
});
|
||||
|
||||
test("should read as latin1", async () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const filePath = fixturePath("render-latin1.handlebars");
|
||||
const text = await exphbs._getFile(filePath, { encoding: "latin1" });
|
||||
expect(text).toContain("ñáéíóú");
|
||||
});
|
||||
|
||||
test("should read as default encoding", async () => {
|
||||
const exphbs = expressHandlebars.create({ encoding: "latin1" });
|
||||
const filePath = fixturePath("render-latin1.handlebars");
|
||||
const text = await exphbs._getFile(filePath);
|
||||
expect(text).toContain("ñáéíóú");
|
||||
});
|
||||
});
|
||||
|
||||
describe("_getTemplateName", () => {
|
||||
test("should remove extension", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const name = exphbs._getTemplateName("filePath.handlebars");
|
||||
expect(name).toBe("filePath");
|
||||
});
|
||||
|
||||
test("should leave if no extension", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const name = exphbs._getTemplateName("filePath");
|
||||
expect(name).toBe("filePath");
|
||||
});
|
||||
|
||||
test("should add namespace", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const name = exphbs._getTemplateName("filePath.handlebars", "namespace");
|
||||
expect(name).toBe("namespace/filePath");
|
||||
});
|
||||
});
|
||||
|
||||
describe("_resolveViewsPath", () => {
|
||||
test("should return closest parent", () => {
|
||||
const file = "/root/views/file.hbs";
|
||||
const exphbs = expressHandlebars.create();
|
||||
const viewsPath = exphbs._resolveViewsPath([
|
||||
"/root",
|
||||
"/root/views",
|
||||
"/root/views/file",
|
||||
], file);
|
||||
expect(viewsPath).toBe("/root/views");
|
||||
});
|
||||
|
||||
test("should return string views", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const viewsPath = exphbs._resolveViewsPath("./views", "filePath.hbs");
|
||||
expect(viewsPath).toBe("./views");
|
||||
});
|
||||
|
||||
test("should return null views", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const viewsPath = exphbs._resolveViewsPath(null, "filePath.hbs");
|
||||
expect(viewsPath).toBe(null);
|
||||
});
|
||||
|
||||
test("should return null if not found", () => {
|
||||
const file = "/file.hbs";
|
||||
const exphbs = expressHandlebars.create();
|
||||
const viewsPath = exphbs._resolveViewsPath([
|
||||
"/views",
|
||||
], file);
|
||||
expect(viewsPath).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_resolveLayoutPath", () => {
|
||||
test("should add extension", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const layoutPath = exphbs._resolveLayoutPath("filePath");
|
||||
expect(layoutPath).toEqual(expect.stringMatching(/filePath\.handlebars$/));
|
||||
});
|
||||
|
||||
test("should use layoutsDir", () => {
|
||||
const layoutsDir = fixturePath("layouts");
|
||||
const filePath = "filePath.handlebars";
|
||||
const exphbs = expressHandlebars.create({ layoutsDir });
|
||||
const layoutPath = exphbs._resolveLayoutPath(filePath);
|
||||
expect(layoutPath).toBe(path.resolve(layoutsDir, filePath));
|
||||
});
|
||||
|
||||
test("should return null", () => {
|
||||
const exphbs = expressHandlebars.create();
|
||||
const layoutPath = exphbs._resolveLayoutPath(null);
|
||||
expect(layoutPath).toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
3
node_modules/express-handlebars/spec/fixtures/layouts/main-latin1.handlebars
generated
vendored
Normal file
3
node_modules/express-handlebars/spec/fixtures/layouts/main-latin1.handlebars
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
file encoding: Windows 1252 (latin1)
|
||||
<p>layout <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD></p>
|
||||
{{{body}}}
|
||||
3
node_modules/express-handlebars/spec/fixtures/layouts/main.handlebars
generated
vendored
Normal file
3
node_modules/express-handlebars/spec/fixtures/layouts/main.handlebars
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
{{{body}}}
|
||||
</body>
|
||||
4
node_modules/express-handlebars/spec/fixtures/other-views/layouts/main.handlebars
generated
vendored
Normal file
4
node_modules/express-handlebars/spec/fixtures/other-views/layouts/main.handlebars
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<body>
|
||||
other layout
|
||||
{{{body}}}
|
||||
</body>
|
||||
1
node_modules/express-handlebars/spec/fixtures/other-views/partials/partial.handlebars
generated
vendored
Normal file
1
node_modules/express-handlebars/spec/fixtures/other-views/partials/partial.handlebars
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
other partial {{text}}
|
||||
2
node_modules/express-handlebars/spec/fixtures/partials/partial-latin1.handlebars
generated
vendored
Normal file
2
node_modules/express-handlebars/spec/fixtures/partials/partial-latin1.handlebars
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
file encoding: Windows 1252 (latin1)
|
||||
<p>partial <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD></p>
|
||||
1
node_modules/express-handlebars/spec/fixtures/partials/partial.handlebars
generated
vendored
Normal file
1
node_modules/express-handlebars/spec/fixtures/partials/partial.handlebars
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
partial {{text}}
|
||||
1
node_modules/express-handlebars/spec/fixtures/render-cached.handlebars
generated
vendored
Normal file
1
node_modules/express-handlebars/spec/fixtures/render-cached.handlebars
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
not cached
|
||||
1
node_modules/express-handlebars/spec/fixtures/render-helper.handlebars
generated
vendored
Normal file
1
node_modules/express-handlebars/spec/fixtures/render-helper.handlebars
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<p>{{help text}}</p>
|
||||
3
node_modules/express-handlebars/spec/fixtures/render-latin1.handlebars
generated
vendored
Normal file
3
node_modules/express-handlebars/spec/fixtures/render-latin1.handlebars
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{{> partial-latin1}}
|
||||
file encoding: Windows 1252 (latin1)
|
||||
<p>render <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD></p>
|
||||
2
node_modules/express-handlebars/spec/fixtures/render-partial.handlebars
generated
vendored
Normal file
2
node_modules/express-handlebars/spec/fixtures/render-partial.handlebars
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<h1>{{> partial}}</h1>
|
||||
<p>{{text}}</p>
|
||||
1
node_modules/express-handlebars/spec/fixtures/render-text.handlebars
generated
vendored
Normal file
1
node_modules/express-handlebars/spec/fixtures/render-text.handlebars
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<p>{{text}}</p>
|
||||
1
node_modules/express-handlebars/spec/fixtures/templates/subdir/template.handlebars
generated
vendored
Normal file
1
node_modules/express-handlebars/spec/fixtures/templates/subdir/template.handlebars
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<p>{{text}}</p>
|
||||
2
node_modules/express-handlebars/spec/fixtures/templates/template-latin1.handlebars
generated
vendored
Normal file
2
node_modules/express-handlebars/spec/fixtures/templates/template-latin1.handlebars
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
file encoding: Windows 1252 (latin1)
|
||||
<p><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD></p>
|
||||
1
node_modules/express-handlebars/spec/fixtures/templates/template.handlebars
generated
vendored
Normal file
1
node_modules/express-handlebars/spec/fixtures/templates/template.handlebars
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<p>{{text}}</p>
|
||||
Reference in New Issue
Block a user