diff options
Diffstat (limited to 'node_modules/express-handlebars')
| -rw-r--r-- | node_modules/express-handlebars/.eslintignore | 3 | ||||
| -rw-r--r-- | node_modules/express-handlebars/.eslintrc.js | 31 | ||||
| -rw-r--r-- | node_modules/express-handlebars/.github/workflows/main.yml | 76 | ||||
| -rw-r--r-- | node_modules/express-handlebars/CHANGELOG.md | 20 | ||||
| -rw-r--r-- | node_modules/express-handlebars/HISTORY.md | 402 | ||||
| -rw-r--r-- | node_modules/express-handlebars/LICENSE | 31 | ||||
| -rw-r--r-- | node_modules/express-handlebars/README.md | 570 | ||||
| -rw-r--r-- | node_modules/express-handlebars/index.js | 23 | ||||
| -rw-r--r-- | node_modules/express-handlebars/jest.config.js | 21 | ||||
| -rw-r--r-- | node_modules/express-handlebars/lib/express-handlebars.js | 343 | ||||
| -rw-r--r-- | node_modules/express-handlebars/lib/utils.js | 29 | ||||
| -rw-r--r-- | node_modules/express-handlebars/package.json | 99 | ||||
| -rw-r--r-- | node_modules/express-handlebars/renovate.json | 10 | ||||
| -rw-r--r-- | node_modules/express-handlebars/spec/express-handlebars.test.js | 7 |
14 files changed, 1665 insertions, 0 deletions
diff --git a/node_modules/express-handlebars/.eslintignore b/node_modules/express-handlebars/.eslintignore new file mode 100644 index 0000000..8586b05 --- /dev/null +++ b/node_modules/express-handlebars/.eslintignore @@ -0,0 +1,3 @@ +node_modules/ +npm-debug.log +coverage/ diff --git a/node_modules/express-handlebars/.eslintrc.js b/node_modules/express-handlebars/.eslintrc.js new file mode 100644 index 0000000..030c10b --- /dev/null +++ b/node_modules/express-handlebars/.eslintrc.js @@ -0,0 +1,31 @@ +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-restricted-globals": [ + "error", + { + name: "fit", + message: "Do not commit focused tests." + }, + { + name: "fdescribe", + message: "Do not commit focused tests." + }, + ], + }, +} diff --git a/node_modules/express-handlebars/.github/workflows/main.yml b/node_modules/express-handlebars/.github/workflows/main.yml new file mode 100644 index 0000000..2543255 --- /dev/null +++ b/node_modules/express-handlebars/.github/workflows/main.yml @@ -0,0 +1,76 @@ +name: "Tests" +on: + pull_request: + push: + branches: + - master + +env: + CI: true + +jobs: + Test: + if: "!contains(github.event.head_commit.message, '[skip ci]')" + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout Code + uses: actions/checkout@v2 + - name: Install Node + uses: actions/setup-node@v1 + with: + node-version: '12.x' + - 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: actions/setup-node@v1 + with: + node-version: '13.x' + - 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: NPM install + run: npm ci + - name: Lint ✨ + run: npm run lint + + Release: + needs: [Test, 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 diff --git a/node_modules/express-handlebars/CHANGELOG.md b/node_modules/express-handlebars/CHANGELOG.md new file mode 100644 index 0000000..f17eb87 --- /dev/null +++ b/node_modules/express-handlebars/CHANGELOG.md @@ -0,0 +1,20 @@ +## [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)) diff --git a/node_modules/express-handlebars/HISTORY.md b/node_modules/express-handlebars/HISTORY.md new file mode 100644 index 0000000..24a663d --- /dev/null +++ b/node_modules/express-handlebars/HISTORY.md @@ -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. diff --git a/node_modules/express-handlebars/LICENSE b/node_modules/express-handlebars/LICENSE new file mode 100644 index 0000000..58708e7 --- /dev/null +++ b/node_modules/express-handlebars/LICENSE @@ -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.
\ No newline at end of file diff --git a/node_modules/express-handlebars/README.md b/node_modules/express-handlebars/README.md new file mode 100644 index 0000000..9cdaaa6 --- /dev/null +++ b/node_modules/express-handlebars/README.md @@ -0,0 +1,570 @@ +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/visionmedia/express +[Handlebars]: https://github.com/wycats/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 +``` + + +## 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 `loadPartials()` +// 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. +* `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. + + +[examples directory]: https://github.com/express-handlebars/express-handlebars/tree/master/examples +[view cache setting]: http://expressjs.com/api.html#app-settings +[Express locals]: http://expressjs.com/api.html#app.locals +[registered with Handlebars]: https://github.com/wycats/handlebars.js/#registering-helpers +[built-in helpers]: http://handlebarsjs.com/#builtins +[Handlebars website]: http://handlebarsjs.com/ +[Expression Helpers]: http://handlebarsjs.com/expressions.html#helpers +[Block Helpers]: http://handlebarsjs.com/block_helpers.html + + +## 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. + +#### `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 `partialsDir` 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}`. + +**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});`. + +#### `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()`. + +### 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. + + * `[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. + + * `[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. + + * `[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. + + * `[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. + +#### `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 load _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. + + * `[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). + +* `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. + + +[promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise + + +## 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 diff --git a/node_modules/express-handlebars/index.js b/node_modules/express-handlebars/index.js new file mode 100644 index 0000000..8f87865 --- /dev/null +++ b/node_modules/express-handlebars/index.js @@ -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"; + +var 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); +} diff --git a/node_modules/express-handlebars/jest.config.js b/node_modules/express-handlebars/jest.config.js new file mode 100644 index 0000000..2036051 --- /dev/null +++ b/node_modules/express-handlebars/jest.config.js @@ -0,0 +1,21 @@ +module.exports = { + restoreMocks: true, + clearMocks: true, + // collectCoverage: true, + collectCoverageFrom: [ + "lib/**/*.js", + "!**/node_modules/**", + ], + coverageDirectory: "coverage", + /* + coverageThreshold: { + global: { + branches: 100, + functions: 100, + lines: 100, + statements: 100, + }, + }, + */ + testRegex: /\.test\.jsx?/.source, +}; diff --git a/node_modules/express-handlebars/lib/express-handlebars.js b/node_modules/express-handlebars/lib/express-handlebars.js new file mode 100644 index 0000000..69d8f4a --- /dev/null +++ b/node_modules/express-handlebars/lib/express-handlebars.js @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2015, Yahoo Inc. All rights reserved. + * Copyrights licensed under the New BSD License. + * See the accompanying LICENSE file for terms. + */ + +"use strict"; + +var Promise = global.Promise || require("promise"); + +var glob = require("glob"); +var Handlebars = require("handlebars"); +var fs = require("graceful-fs"); +var path = require("path"); + +var utils = require("./utils"); + +module.exports = ExpressHandlebars; + +// ----------------------------------------------------------------------------- + +function ExpressHandlebars (config) { + // Config properties with defaults. + utils.assign(this, { + handlebars: Handlebars, + extname: ".handlebars", + 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, + }, 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 = Object.create(null); + this.precompiled = Object.create(null); + + // Private internal file system cache. + this._fsCache = Object.create(null); +} + +ExpressHandlebars.prototype.getPartials = function (options) { + var partialsDirs = Array.isArray(this.partialsDir) + ? this.partialsDir : [this.partialsDir]; + + partialsDirs = partialsDirs.map(function (dir) { + var dirPath; + var dirTemplates; + var dirNamespace; + + // 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; + 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"); + } + + // Make sure we're have a promise for the templates. + var templatesPromise = dirTemplates ? Promise.resolve(dirTemplates) + : this.getTemplates(dirPath, options); + + return templatesPromise.then(function (templates) { + return { + templates: templates, + namespace: dirNamespace, + }; + }); + }, this); + + return Promise.all(partialsDirs).then(function (dirs) { + var getTemplateName = this._getTemplateName.bind(this); + + return dirs.reduce(function (partials, dir) { + var templates = dir.templates; + var namespace = dir.namespace; + var filePaths = Object.keys(templates); + + filePaths.forEach(function (filePath) { + var partialName = getTemplateName(filePath, namespace); + partials[partialName] = templates[filePath]; + }); + + return partials; + }, {}); + }.bind(this)); +}; + +ExpressHandlebars.prototype.getTemplate = function (filePath, options) { + filePath = path.resolve(filePath); + options || (options = {}); + + var precompiled = options.precompiled; + var cache = precompiled ? this.precompiled : this.compiled; + var 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. + template = cache[filePath] = this._getFile(filePath, { cache: options.cache }) + .then(function (file) { + if (precompiled) { + return this._precompileTemplate(file, this.compilerOptions); + } + + return this._compileTemplate(file, this.compilerOptions); + }.bind(this)); + + return template.catch(function (err) { + delete cache[filePath]; + throw err; + }); +}; + +ExpressHandlebars.prototype.getTemplates = function (dirPath, options) { + options || (options = {}); + var cache = options.cache; + + return this._getDir(dirPath, { cache: cache }).then(function (filePaths) { + var templates = filePaths.map(function (filePath) { + return this.getTemplate(path.join(dirPath, filePath), options); + }, this); + + return Promise.all(templates).then(function (templates) { + return filePaths.reduce(function (hash, filePath, i) { + hash[filePath] = templates[i]; + return hash; + }, {}); + }); + }.bind(this)); +}; + +ExpressHandlebars.prototype.render = function (filePath, context, options) { + options || (options = {}); + + return Promise.all([ + this.getTemplate(filePath, { cache: options.cache }), + options.partials || this.getPartials({ cache: options.cache }), + ]).then(function (templates) { + var template = templates[0]; + var partials = templates[1]; + var helpers = options.helpers || this.helpers; + + // Add ExpressHandlebars metadata to the data channel so that it's + // accessible within the templates and helpers, namespaced under: + // `@exphbs.*` + var data = utils.assign({}, options.data, { + exphbs: utils.assign({}, options, { + filePath: filePath, + helpers: helpers, + partials: partials, + }), + }); + + return this._renderTemplate(template, context, { + data: data, + helpers: helpers, + partials: partials, + }); + }.bind(this)); +}; + +ExpressHandlebars.prototype.renderView = function (viewPath, options, callback) { + options || (options = {}); + + var context = options; + + // 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 + var view; + var viewsPath = options.settings && options.settings.views; + if (viewsPath) { + view = this._getTemplateName(path.relative(viewsPath, viewPath)); + this.partialsDir = this.partialsDir || path.join(viewsPath, "partials/"); + this.layoutsDir = this.layoutsDir || path.join(viewsPath, "layouts/"); + } + + // Merge render-level and instance-level helpers together. + var helpers = utils.assign({}, this.helpers, options.helpers); + + // Merge render-level and instance-level partials together. + var partials = Promise.all([ + this.getPartials({ cache: options.cache }), + Promise.resolve(options.partials), + ]).then(function (partials) { + return utils.assign.apply(null, [{}].concat(partials)); + }); + + // Pluck-out ExpressHandlebars-specific options and Handlebars-specific + // rendering options. + options = { + cache: options.cache, + view: view, + layout: "layout" in options ? options.layout : this.defaultLayout, + + data: options.data, + helpers: helpers, + partials: partials, + }; + + this.render(viewPath, context, options) + .then(function (body) { + var layoutPath = this._resolveLayoutPath(options.layout); + + if (layoutPath) { + return this.render( + layoutPath, + utils.assign({}, context, { body: body }), + utils.assign({}, options, { layout: undefined }), + ); + } + + return body; + }.bind(this)) + .then(utils.passValue(callback)) + .catch(utils.passError(callback)); +}; + +// -- Protected Hooks ---------------------------------------------------------- + +ExpressHandlebars.prototype._compileTemplate = function (template, options) { + return this.handlebars.compile(template.trim(), options); +}; + +ExpressHandlebars.prototype._precompileTemplate = function (template, options) { + return this.handlebars.precompile(template, options); +}; + +ExpressHandlebars.prototype._renderTemplate = function (template, context, options) { + return template(context, options).trim(); +}; + +// -- Private ------------------------------------------------------------------ + +ExpressHandlebars.prototype._getDir = function (dirPath, options) { + dirPath = path.resolve(dirPath); + options || (options = {}); + + var cache = this._fsCache; + var dir = options.cache && cache[dirPath]; + + if (dir) { + return dir.then(function (dir) { + return dir.concat(); + }); + } + + var pattern = "**/*" + this.extname; + + // Optimistically cache dir promise to reduce file system I/O, but remove + // from cache if there was a problem. + dir = cache[dirPath] = new Promise(function (resolve, reject) { + glob(pattern, { + cwd: dirPath, + follow: true, + }, function (err, dir) { + if (err) { + reject(err); + } else { + resolve(dir); + } + }); + }); + + return dir.then(function (dir) { + return dir.concat(); + }).catch(function (err) { + delete cache[dirPath]; + throw err; + }); +}; + +ExpressHandlebars.prototype._getFile = function (filePath, options) { + filePath = path.resolve(filePath); + options || (options = {}); + + var cache = this._fsCache; + var 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. + file = cache[filePath] = new Promise(function (resolve, reject) { + fs.readFile(filePath, "utf8", function (err, file) { + if (err) { + reject(err); + } else { + resolve(file); + } + }); + }); + + return file.catch(function (err) { + delete cache[filePath]; + throw err; + }); +}; + +ExpressHandlebars.prototype._getTemplateName = function (filePath, namespace) { + var extRegex = new RegExp(this.extname + "$"); + var name = filePath.replace(extRegex, ""); + + if (namespace) { + name = namespace + "/" + name; + } + + return name; +}; + +ExpressHandlebars.prototype._resolveLayoutPath = function (layoutPath) { + if (!layoutPath) { + return null; + } + + if (!path.extname(layoutPath)) { + layoutPath += this.extname; + } + + return path.resolve(this.layoutsDir, layoutPath); +}; diff --git a/node_modules/express-handlebars/lib/utils.js b/node_modules/express-handlebars/lib/utils.js new file mode 100644 index 0000000..55a9da6 --- /dev/null +++ b/node_modules/express-handlebars/lib/utils.js @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014, Yahoo Inc. All rights reserved. + * Copyrights licensed under the New BSD License. + * See the accompanying LICENSE file for terms. + */ + +"use strict"; + +exports.assign = Object.assign || require("object.assign"); +exports.passError = passError; +exports.passValue = passValue; + +// ----------------------------------------------------------------------------- + +function passError (callback) { + return function (reason) { + setImmediate(function () { + callback(reason); + }); + }; +} + +function passValue (callback) { + return function (value) { + setImmediate(function () { + callback(null, value); + }); + }; +} diff --git a/node_modules/express-handlebars/package.json b/node_modules/express-handlebars/package.json new file mode 100644 index 0000000..b0abd26 --- /dev/null +++ b/node_modules/express-handlebars/package.json @@ -0,0 +1,99 @@ +{ + "_from": "express-handlebars", + "_id": "[email protected]", + "_inBundle": false, + "_integrity": "sha512-WxbQorVc7V9ORzp9YpG3fLAzrfIrKcScSezuFxTZRFJSx/P2f7QJ9ZyADV8cyPuomyzUxAJnw6t8dnriLfBNvg==", + "_location": "/express-handlebars", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "express-handlebars", + "name": "express-handlebars", + "escapedName": "express-handlebars", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-4.0.4.tgz", + "_shasum": "b42b6bc09f4c7fe35f4afbda7aedadd6c2527fae", + "_spec": "express-handlebars", + "_where": "E:\\Documents\\GitHub\\uppity", + "author": { + "name": "Eric Ferraiuolo", + "email": "[email protected]", + "url": "http://ericf.me/" + }, + "bugs": { + "url": "https://github.com/express-handlebars/express-handlebars/issues" + }, + "bundleDependencies": false, + "dependencies": { + "glob": "^7.1.6", + "graceful-fs": "^4.2.4", + "handlebars": "^4.7.6", + "object.assign": "^4.1.0", + "promise": "^8.1.0" + }, + "deprecated": false, + "description": "A Handlebars view engine for Express which doesn't suck.", + "devDependencies": { + "@semantic-release/changelog": "^5.0.1", + "@semantic-release/commit-analyzer": "^8.0.1", + "@semantic-release/git": "^9.0.0", + "@semantic-release/github": "^7.0.5", + "@semantic-release/npm": "^7.0.5", + "@semantic-release/release-notes-generator": "^9.0.1", + "eslint": "^6.8.0", + "eslint-config-standard": "^14.1.1", + "eslint-plugin-import": "^2.20.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.0.1", + "jest-cli": "^25.5.1", + "semantic-release": "^17.0.7" + }, + "directories": { + "example": "examples" + }, + "engines": { + "node": ">=0.10" + }, + "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": "4.0.4" +} diff --git a/node_modules/express-handlebars/renovate.json b/node_modules/express-handlebars/renovate.json new file mode 100644 index 0000000..cefdcbc --- /dev/null +++ b/node_modules/express-handlebars/renovate.json @@ -0,0 +1,10 @@ +{ + "extends": [ + "config:base" + ], + "devDependencies": { + "automerge": true, + "commitMessageTopic": "devDependency {{depName}}" + }, + "rangeStrategy": "bump" +} diff --git a/node_modules/express-handlebars/spec/express-handlebars.test.js b/node_modules/express-handlebars/spec/express-handlebars.test.js new file mode 100644 index 0000000..7913347 --- /dev/null +++ b/node_modules/express-handlebars/spec/express-handlebars.test.js @@ -0,0 +1,7 @@ +const expressHandlebars = require("../lib/express-handlebars.js"); + +describe("express-handlebars", () => { + test("should add tests", () => { + expect(expressHandlebars).toEqual(expect.any(Function)); + }); +}); |