metalsmith-layouts
Advanced tools
Comparing version 1.8.1 to 2.0.0
242
lib/index.js
@@ -1,176 +0,118 @@ | ||
/** | ||
* Dependencies | ||
*/ | ||
var consolidate = require('consolidate'); | ||
var debug = require('debug')('metalsmith-layouts'); | ||
var each = require('async').each; | ||
var extend = require('extend'); | ||
var omit = require('lodash.omit'); | ||
var path = require('path'); | ||
const match = require('multimatch'); | ||
const path = require('path'); | ||
const isUtf8 = require('is-utf8'); | ||
const getTransformer = require('./get-transformer'); | ||
/** | ||
* Helpers | ||
* Resolves layouts, in the following order: | ||
* 1. Layouts in the frontmatter | ||
* 2. Skips file if layout: false in frontmatter | ||
* 3. Default layout in the settings | ||
*/ | ||
var check = require('./helpers/check'); | ||
var readPartials = require('./helpers/read-partials'); | ||
/** | ||
* Expose `plugin`. | ||
*/ | ||
module.exports = plugin; | ||
function getLayout({ file, settings }) { | ||
if (file.layout || file.layout === false) { | ||
return file.layout; | ||
} | ||
/** | ||
* Settings | ||
* | ||
* Options supported by metalsmith-layouts | ||
*/ | ||
var settings = [ | ||
'default', | ||
'directory', | ||
'engine', | ||
'partials', | ||
'partialExtension', | ||
'pattern', | ||
'rename', | ||
'exposeConsolidate' | ||
]; | ||
return settings.default; | ||
} | ||
/** | ||
* Metalsmith plugin to run files through any layout in a layout `dir`. | ||
* | ||
* @param {String or Object} options | ||
* @property {String} default (optional) | ||
* @property {String} directory (optional) | ||
* @property {String} engine | ||
* @property {String} partials (optional) | ||
* @property {String} partialExtension (optional) | ||
* @property {String} pattern (optional) | ||
* @property {Boolean} rename (optional) | ||
* @return {Function} | ||
* Engine, renders file with the appropriate layout | ||
*/ | ||
function plugin(opts){ | ||
/** | ||
* Init | ||
*/ | ||
opts = opts || {}; | ||
// Accept string option to specify the engine | ||
if (typeof opts === 'string') { | ||
opts = {engine: opts}; | ||
} | ||
function render({ file, metadata, settings, metalsmith }) { | ||
return new Promise(resolve => { | ||
const layout = getLayout({ file, settings }); | ||
const extension = layout.split('.').pop(); | ||
// An engine should be specified | ||
if (!opts.engine) { | ||
throw new Error('"engine" option required'); | ||
} | ||
// Stringify file contents | ||
// eslint-disable-next-line no-param-reassign | ||
file.contents = file.contents.toString(); | ||
// Throw an error for unsupported engines or typos | ||
if (!consolidate[opts.engine]) { | ||
throw new Error('Unknown template engine: "' + opts.engine + '"'); | ||
} | ||
const transform = getTransformer(extension); | ||
const locals = Object.assign({}, metadata, file); | ||
const layoutPath = path.join(metalsmith.path(settings.directory), layout); | ||
if (typeof opts.exposeConsolidate === 'function') { | ||
opts.exposeConsolidate(consolidate.requires) | ||
} | ||
// Transform the contents | ||
// eslint-disable-next-line no-param-reassign | ||
file.contents = transform.renderFile(layoutPath, settings.engineOptions, locals).body; | ||
// Map options to local variables | ||
var def = opts.default; | ||
var dir = opts.directory || 'layouts'; | ||
var engine = opts.engine; | ||
var partialExtension = opts.partialExtension; | ||
var partials = opts.partials; | ||
var pattern = opts.pattern; | ||
var rename = opts.rename; | ||
// Update file with results | ||
// eslint-disable-next-line no-param-reassign | ||
file.contents = Buffer.from(file.contents); | ||
return resolve(); | ||
}); | ||
} | ||
// Move all unrecognised options to params | ||
var params = omit(opts, settings); | ||
/** | ||
* Validate, checks whether a file should be processed | ||
*/ | ||
/** | ||
* Main plugin function | ||
*/ | ||
return function(files, metalsmith, done){ | ||
var metadata = metalsmith.metadata(); | ||
var matches = {}; | ||
var templates = {}; | ||
function validate({ file, settings }) { | ||
const layout = getLayout({ file, settings }); | ||
/** | ||
* Process any partials and pass them to consolidate as a partials object | ||
*/ | ||
if (partials) { | ||
if (typeof partials === 'string') { | ||
params.partials = readPartials(partials, partialExtension, dir, metalsmith); | ||
} else { | ||
params.partials = partials; | ||
} | ||
} | ||
// Files without a layout cannot be processed | ||
if (!layout) { | ||
return false; | ||
} | ||
/** | ||
* Stringify files that pass the check, pass to matches | ||
*/ | ||
Object.keys(files).forEach(function(file){ | ||
if (!check(files, file, pattern, def)) { | ||
return; | ||
} | ||
// Layouts without an extension cannot be processed | ||
if (!layout.includes('.')) { | ||
return false; | ||
} | ||
debug('stringifying file: %s', file); | ||
var data = files[file]; | ||
data.contents = data.contents.toString(); | ||
var template = metalsmith.path(dir, data.layout || def); | ||
if (!templates[template]) { | ||
debug('found new template: %s', template); | ||
templates[template] = file; | ||
} else { | ||
matches[file] = data; | ||
} | ||
}); | ||
// Files that are not utf8 are ignored | ||
if (!isUtf8(file.contents)) { | ||
return false; | ||
} | ||
/** | ||
* Render files | ||
*/ | ||
function convert(file, done){ | ||
debug('converting file: %s', file); | ||
var data = files[file]; | ||
// Files without an applicable jstransformer are ignored | ||
const extension = layout.split('.').pop(); | ||
return getTransformer(extension); | ||
} | ||
// Deep clone params (by passing 'true') | ||
var clonedParams = extend(true, {}, params); | ||
var clone = extend({}, clonedParams, metadata, data); | ||
var str = metalsmith.path(dir, data.layout || def); | ||
var render = consolidate[engine]; | ||
/** | ||
* Plugin, the main plugin used by metalsmith | ||
*/ | ||
// Rename file if necessary | ||
var fileInfo; | ||
if (rename) { | ||
delete files[file]; | ||
fileInfo = path.parse(file); | ||
file = path.join(fileInfo.dir, fileInfo.name + '.html'); | ||
debug('renamed file to: %s', file); | ||
} | ||
module.exports = options => (files, metalsmith, done) => { | ||
const metadata = metalsmith.metadata(); | ||
const defaults = { | ||
pattern: '**', | ||
directory: 'layouts', | ||
engineOptions: {} | ||
}; | ||
const settings = Object.assign({}, defaults, options); | ||
render(str, clone, function(err, str){ | ||
if (err) { | ||
return done(err); | ||
} | ||
// Check whether the pattern option is valid | ||
if (!(typeof settings.pattern === 'string' || Array.isArray(settings.pattern))) { | ||
done(new Error('invalid pattern, the pattern option should be a string or array.')); | ||
} | ||
data.contents = new Buffer(str); | ||
debug('converted file: %s', file); | ||
// Filter files by the pattern | ||
const matchedFiles = match(Object.keys(files), settings.pattern); | ||
files[file] = data; | ||
done(); | ||
}); | ||
} | ||
// Filter files by validity | ||
const validFiles = matchedFiles.filter(filename => validate({ file: files[filename], settings })); | ||
/** | ||
* Render all matched files. | ||
*/ | ||
function renderFiles(err) { | ||
if (err) { | ||
return done(err); | ||
} | ||
each(Object.keys(matches), convert, done); | ||
} | ||
// Let the user know when there are no files to process, usually caused by missing jstransformer | ||
if (validFiles.length === 0) { | ||
done(new Error('no files to process, check whether you have a jstransformer installed.')); | ||
} | ||
// Do a first pass to load templates into the consolidate cache. | ||
each(templates, convert, renderFiles); | ||
}; | ||
} | ||
// Map all files that should be processed to an array of promises and call done when finished | ||
Promise.all( | ||
validFiles.map(filename => | ||
render({ | ||
file: files[filename], | ||
metadata, | ||
settings, | ||
metalsmith | ||
}) | ||
) | ||
) | ||
.then(() => done()) | ||
.catch(/* istanbul ignore next */ error => done(error)); | ||
}; |
{ | ||
"name": "metalsmith-layouts", | ||
"author": "superwolff <superwolff@superwolff.nl> (http://superwolff.nl/)", | ||
"author": "ismay", | ||
"description": "A metalsmith plugin for layouts.", | ||
"repository": "git://github.com/superwolff/metalsmith-layouts.git", | ||
"version": "1.8.1", | ||
"license": "MIT", | ||
"main": "lib/index.js", | ||
"name": "metalsmith-layouts", | ||
"repository": "git://github.com/ismay/metalsmith-layouts.git", | ||
"version": "2.0.0", | ||
"scripts": { | ||
"test": "mocha --reporter spec" | ||
"precommit": "lint-staged", | ||
"lint:js": "eslint 'lib/**/*.js'", | ||
"lint:prettier": "prettier --list-different 'lib/**/*.js'", | ||
"test": "jest", | ||
"test:coverage": "jest --coverage && cat ./coverage/lcov.info | coveralls" | ||
}, | ||
"dependencies": { | ||
"async": "^1.3.0", | ||
"consolidate": "^0.14.0", | ||
"debug": "^2.2.0", | ||
"extend": "^3.0.0", | ||
"fs-readdir-recursive": "^1.0.0", | ||
"is-utf8": "^0.2.0", | ||
"lodash.omit": "^4.0.2", | ||
"multimatch": "^2.0.0" | ||
"jest": { | ||
"collectCoverageFrom": [ | ||
"lib/*.js" | ||
] | ||
}, | ||
"greenkeeper": { | ||
"ignore": [ | ||
"eslint", | ||
"eslint-plugin-import" | ||
] | ||
}, | ||
"devDependencies": { | ||
"assert-dir-equal": "^1.0.1", | ||
"handlebars": "^4.0.2", | ||
"metalsmith": "^2.0.1", | ||
"mocha": "^2.2.5", | ||
"swig": "^1.4.2" | ||
"assert-dir-equal": "^1.1.0", | ||
"coveralls": "^3.0.0", | ||
"eslint": "^4.8.0", | ||
"eslint-config-airbnb-base": "^12.0.2", | ||
"eslint-config-prettier": "^2.9.0", | ||
"eslint-plugin-import": "^2.7.0", | ||
"husky": "^0.14.3", | ||
"jest": "^22.0.4", | ||
"jstransformer-handlebars": "^1.0.0", | ||
"lint-staged": "^6.0.0", | ||
"metalsmith": "^2.3.0", | ||
"prettier": "^1.9.2", | ||
"rimraf": "^2.6.2" | ||
}, | ||
"dependencies": { | ||
"inputformat-to-jstransformer": "^1.2.1", | ||
"is-utf8": "^0.2.1", | ||
"jstransformer": "^1.0.0", | ||
"multimatch": "^2.1.0" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
4
1
25199
13
8
360
210
2
+ Addedjstransformer@^1.0.0
+ Addedasap@2.0.6(transitive)
+ Addedinputformat-to-jstransformer@1.4.0(transitive)
+ Addedis-promise@2.2.2(transitive)
+ Addedjstransformer@1.0.0(transitive)
+ Addedpromise@7.3.1(transitive)
+ Addedrequire-one@1.0.3(transitive)
- Removedasync@^1.3.0
- Removedconsolidate@^0.14.0
- Removeddebug@^2.2.0
- Removedextend@^3.0.0
- Removedfs-readdir-recursive@^1.0.0
- Removedlodash.omit@^4.0.2
- Removedasync@1.5.2(transitive)
- Removedbluebird@3.7.2(transitive)
- Removedconsolidate@0.14.5(transitive)
- Removeddebug@2.6.9(transitive)
- Removedextend@3.0.2(transitive)
- Removedfs-readdir-recursive@1.1.0(transitive)
- Removedlodash.omit@4.5.0(transitive)
- Removedms@2.0.0(transitive)
Updatedis-utf8@^0.2.1
Updatedmultimatch@^2.1.0