@metalsmith/layouts
Advanced tools
Comparing version 2.5.1 to 2.6.0
@@ -7,4 +7,11 @@ ### Changelog | ||
#### [v2.6.0](https://github.com/metalsmith/layouts/compare/v2.5.1...v2.6.0) | ||
- feat: dual bundling ESM/CJS [`771212c`](https://github.com/metalsmith/layouts/commit/771212cfe31197befd8e53e025877341a78ddd20) | ||
- feat: added Typescript support [`507bb47`](https://github.com/metalsmith/layouts/commit/507bb47e15351c7f49818526a8a7fae7f2dad742) | ||
#### [v2.5.1](https://github.com/metalsmith/layouts/compare/v2.5.0...v2.5.1) | ||
> 16 May 2022 | ||
- Resolves #183: pass the transformed list of files to metalsmith.match… [`#184`](https://github.com/metalsmith/layouts/pull/184) | ||
@@ -11,0 +18,0 @@ - Merge pull request #184 from doteco/master [`#183`](https://github.com/metalsmith/layouts/issues/183) |
215
lib/index.js
@@ -1,9 +0,25 @@ | ||
const debug = require('debug')('@metalsmith/layouts') | ||
const path = require('path') | ||
const isUtf8 = require('is-utf8') | ||
const getTransformer = require('./get-transformer') | ||
import createDebug from 'debug'; | ||
import path from 'path'; | ||
import isUtf8 from 'is-utf8'; | ||
import jstransformer from 'jstransformer'; | ||
import toTransformer from 'inputformat-to-jstransformer'; | ||
const cache = {}; | ||
/** | ||
* `@metalsmith/layouts` options | ||
* @typedef {Object} Options | ||
* Gets jstransformer for an extension, and caches them | ||
*/ | ||
function getTransformer(ext) { | ||
if (ext in cache) { | ||
return cache[ext]; | ||
} | ||
const transformer = toTransformer(ext); | ||
cache[ext] = transformer ? jstransformer(transformer) : false; | ||
return cache[ext]; | ||
} | ||
const debug = createDebug('@metalsmith/layouts'); | ||
/** | ||
* @typedef {Object} Options `@metalsmith/layouts` options | ||
* @property {string} [default] A default layout to apply to files, eg `default.njk`. | ||
@@ -23,10 +39,12 @@ * @property {string} [pattern] The directory for the layouts. The default is `layouts`. | ||
function getLayout({ file, settings }) { | ||
function getLayout({ | ||
file, | ||
settings | ||
}) { | ||
if (file.layout || file.layout === false) { | ||
return file.layout | ||
return file.layout; | ||
} | ||
return settings.default | ||
return settings.default; | ||
} | ||
/** | ||
@@ -36,33 +54,36 @@ * Engine, renders file with the appropriate layout | ||
function render({ filename, files, metadata, settings, metalsmith }) { | ||
const file = files[filename] | ||
const layout = getLayout({ file, settings }) | ||
const extension = layout.split('.').pop() | ||
debug(`rendering ${filename} with layout ${layout}`) | ||
function render({ | ||
filename, | ||
files, | ||
metadata, | ||
settings, | ||
metalsmith | ||
}) { | ||
const file = files[filename]; | ||
const layout = getLayout({ | ||
file, | ||
settings | ||
}); | ||
const extension = layout.split('.').pop(); | ||
debug(`rendering ${filename} with layout ${layout}`); // Stringify file contents | ||
// Stringify file contents | ||
const contents = file.contents.toString() | ||
const contents = file.contents.toString(); | ||
const transform = getTransformer(extension); | ||
const locals = { ...metadata, | ||
...file, | ||
contents | ||
}; | ||
const layoutPath = path.join(metalsmith.path(settings.directory), layout); // Transform the contents | ||
const transform = getTransformer(extension) | ||
const locals = { ...metadata, ...file, contents } | ||
const layoutPath = path.join(metalsmith.path(settings.directory), layout) | ||
// Transform the contents | ||
return transform | ||
.renderFileAsync(layoutPath, settings.engineOptions, locals) | ||
.then((rendered) => { | ||
// Update file with results | ||
// eslint-disable-next-line no-param-reassign | ||
file.contents = Buffer.from(rendered.body) | ||
debug(`done rendering ${filename}`) | ||
}) | ||
.catch((err) => { | ||
// Prepend error message with file path | ||
// eslint-disable-next-line no-param-reassign | ||
err.message = `${filename}: ${err.message}` | ||
throw err | ||
}) | ||
return transform.renderFileAsync(layoutPath, settings.engineOptions, locals).then(rendered => { | ||
// Update file with results | ||
file.contents = Buffer.from(rendered.body); | ||
debug(`done rendering ${filename}`); | ||
}).catch(err => { | ||
// Prepend error message with file path | ||
err.message = `${filename}: ${err.message}`; | ||
throw err; | ||
}); | ||
} | ||
/** | ||
@@ -72,37 +93,42 @@ * Validate, checks whether a file should be processed | ||
function validate({ filename, files, settings }) { | ||
const file = files[filename] | ||
const layout = getLayout({ file, settings }) | ||
debug(`validating ${filename}`) | ||
function validate({ | ||
filename, | ||
files, | ||
settings | ||
}) { | ||
const file = files[filename]; | ||
const layout = getLayout({ | ||
file, | ||
settings | ||
}); | ||
debug(`validating ${filename}`); // Files without a layout cannot be processed | ||
// Files without a layout cannot be processed | ||
if (!layout) { | ||
debug(`validation failed, ${filename} does not have a layout set`) | ||
return false | ||
} | ||
debug(`validation failed, ${filename} does not have a layout set`); | ||
return false; | ||
} // Layouts without an extension cannot be processed | ||
// Layouts without an extension cannot be processed | ||
if (!layout.includes('.')) { | ||
debug(`validation failed, layout for ${filename} does not have an extension`) | ||
return false | ||
} | ||
debug(`validation failed, layout for ${filename} does not have an extension`); | ||
return false; | ||
} // Files that are not utf8 are ignored | ||
// Files that are not utf8 are ignored | ||
if (!isUtf8(file.contents)) { | ||
debug(`validation failed, ${filename} is not utf-8`) | ||
return false | ||
} | ||
debug(`validation failed, ${filename} is not utf-8`); | ||
return false; | ||
} // Files without an applicable jstransformer are ignored | ||
// Files without an applicable jstransformer are ignored | ||
const extension = layout.split('.').pop() | ||
const transformer = getTransformer(extension) | ||
const extension = layout.split('.').pop(); | ||
const transformer = getTransformer(extension); | ||
if (!transformer) { | ||
debug(`validation failed, no jstransformer found for layout for ${filename}`) | ||
debug(`validation failed, no jstransformer found for layout for ${filename}`); | ||
} | ||
return transformer | ||
return transformer; | ||
} | ||
/** | ||
@@ -113,5 +139,7 @@ * A metalsmith plugin for rendering layouts | ||
*/ | ||
function initLayouts(options) { | ||
return function layouts(files, metalsmith, done) { | ||
const metadata = metalsmith.metadata() | ||
const metadata = metalsmith.metadata(); | ||
const defaults = { | ||
@@ -122,42 +150,49 @@ pattern: '**', | ||
suppressNoFilesError: false | ||
} | ||
const settings = { ...defaults, ...options } | ||
}; | ||
const settings = { ...defaults, | ||
...options | ||
}; // Check whether the pattern option is valid | ||
// Check whether the pattern option is valid | ||
if (!(typeof settings.pattern === 'string' || Array.isArray(settings.pattern))) { | ||
return done( | ||
new Error( | ||
'invalid pattern, the pattern option should be a string or array of strings. See https://www.npmjs.com/package/@metalsmith/layouts#pattern' | ||
) | ||
) | ||
} | ||
return done(new Error('invalid pattern, the pattern option should be a string or array of strings. See https://www.npmjs.com/package/@metalsmith/layouts#pattern')); | ||
} // Filter files by the pattern | ||
// Filter files by the pattern | ||
const matchedFiles = metalsmith.match(settings.pattern, Object.keys(files)) | ||
// Filter files by validity | ||
const validFiles = matchedFiles.filter((filename) => validate({ filename, files, settings })) | ||
const matchedFiles = metalsmith.match(settings.pattern, Object.keys(files)); // Filter files by validity | ||
// Let the user know when there are no files to process, unless the check is suppressed | ||
const validFiles = matchedFiles.filter(filename => validate({ | ||
filename, | ||
files, | ||
settings | ||
})); // Let the user know when there are no files to process, unless the check is suppressed | ||
if (validFiles.length === 0) { | ||
const message = | ||
'no files to process. See https://www.npmjs.com/package/@metalsmith/layouts#suppressnofileserror' | ||
const message = 'no files to process. See https://www.npmjs.com/package/@metalsmith/layouts#suppressnofileserror'; | ||
if (settings.suppressNoFilesError) { | ||
debug(message) | ||
return done() | ||
debug(message); | ||
return done(); | ||
} | ||
return done(new Error(message)) | ||
} | ||
return done(new Error(message)); | ||
} // Map all files that should be processed to an array of promises and call done when finished | ||
// Map all files that should be processed to an array of promises and call done when finished | ||
return Promise.all( | ||
validFiles.map((filename) => render({ filename, files, metadata, settings, metalsmith })) | ||
) | ||
.then(() => done()) | ||
.catch(/* istanbul ignore next */ (error) => done(error)) | ||
} | ||
} | ||
initLayouts({}) | ||
module.exports = initLayouts | ||
return Promise.all(validFiles.map(filename => render({ | ||
filename, | ||
files, | ||
metadata, | ||
settings, | ||
metalsmith | ||
}))).then(() => done()).catch( | ||
/* istanbul ignore next */ | ||
error => done(error)); | ||
}; | ||
} // ensures non-breaking change: | ||
// import { getTransformer } from '@metalsmith/layouts' instead of | ||
// import getTransformer from '@metalsmith/layouts/get-transformer' | ||
initLayouts.getTransformer = getTransformer; | ||
export { initLayouts as default }; |
{ | ||
"name": "@metalsmith/layouts", | ||
"version": "2.5.1", | ||
"version": "2.6.0", | ||
"description": "A metalsmith plugin for layouts", | ||
@@ -18,3 +18,11 @@ "homepage": "https://github.com/metalsmith/layouts#readme", | ||
], | ||
"main": "lib/index.js", | ||
"source": "src/index.js", | ||
"main": "lib/index.cjs", | ||
"module": "lib/index.js", | ||
"type": "module", | ||
"exports": { | ||
"import": "./lib/index.js", | ||
"require": "./lib/index.cjs" | ||
}, | ||
"types": "lib/index.d.ts", | ||
"directories": { | ||
@@ -31,9 +39,10 @@ "lib": "lib", | ||
"coverage": "nyc report --reporter=text-lcov > ./coverage.info", | ||
"dev": "nodemon --exec 'npm test'", | ||
"release": "release-it .", | ||
"test": "nyc mocha", | ||
"format": "prettier --write \"**/*.{yml,md,js,json}\"", | ||
"format:check": "prettier --list-different \"**/*.{yml,md,js,json}\"", | ||
"lint": "eslint --fix .", | ||
"lint:check": "eslint --fix-dry-run ." | ||
"lint:check": "eslint --fix-dry-run .", | ||
"build": "microbundle --target node --no-sourcemap -f cjs,esm --strict --generateTypes=false", | ||
"pretest": "npm run build", | ||
"test": "nyc mocha" | ||
}, | ||
@@ -49,3 +58,3 @@ "dependencies": { | ||
"auto-changelog": "^2.4.0", | ||
"eslint": "^8.14.0", | ||
"eslint": "^8.23.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
@@ -56,7 +65,8 @@ "eslint-plugin-import": "^2.26.0", | ||
"jstransformer-qejs": "^0.2.0", | ||
"metalsmith": "^2.3.0", | ||
"metalsmith": "^2.4.1", | ||
"microbundle": "^0.15.1", | ||
"mocha": "^9.2.2", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.6.2", | ||
"release-it": "^15.0.0" | ||
"prettier": "^2.7.1", | ||
"release-it": "^15.4.1" | ||
}, | ||
@@ -63,0 +73,0 @@ "peerDependencies": { |
@@ -56,8 +56,9 @@ # @metalsmith/layouts | ||
```js | ||
const layouts = require('@metalsmith/layouts') | ||
import layouts from '@metalsmith/layouts' | ||
metalsmith(__dirname) | ||
.use(layouts({ | ||
metalsmith.use( | ||
layouts({ | ||
default: 'default.hbs' | ||
}) | ||
) | ||
``` | ||
@@ -70,8 +71,9 @@ | ||
```js | ||
const layouts = require('@metalsmith/layouts') | ||
import layouts from '@metalsmith/layouts' | ||
metalsmith(__dirname) | ||
.use(layouts({ | ||
metalsmith.use( | ||
layouts({ | ||
directory: 'templates' | ||
}) | ||
) | ||
``` | ||
@@ -83,9 +85,9 @@ | ||
```js | ||
const layouts = require('@metalsmith/layouts') | ||
import layouts from '@metalsmith/layouts' | ||
metalsmith(__dirname) | ||
.ignore('layouts') | ||
.use(layouts({ | ||
metalsmith.ignore('layouts').use( | ||
layouts({ | ||
directory: 'src/layouts' | ||
}) | ||
) | ||
``` | ||
@@ -98,6 +100,6 @@ | ||
```js | ||
const layouts = require('@metalsmith/layouts') | ||
import layouts from '@metalsmith/layouts' | ||
metalsmith(__dirname) | ||
.use(layouts({ | ||
metalsmith(__dirname).use( | ||
layouts({ | ||
engineOptions: { | ||
@@ -107,2 +109,3 @@ pattern: '**/*.html' | ||
}) | ||
) | ||
``` | ||
@@ -117,6 +120,6 @@ | ||
```js | ||
const layouts = require('@metalsmith/layouts') | ||
import layouts from '@metalsmith/layouts' | ||
metalsmith(__dirname) | ||
.use(layouts({ | ||
metalsmith.use( | ||
layouts({ | ||
engineOptions: { | ||
@@ -126,2 +129,3 @@ cache: false | ||
}) | ||
) | ||
``` | ||
@@ -128,0 +132,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
30680
7
358
214
Yes
14
1