Skip to content

Commit

Permalink
* works on files matching pattern
Browse files Browse the repository at this point in the history
* can specify default for when key unspecified
* can test for existence or for lack thereof
* can validate against type or array of types using [check-types](https://github.com/philbooth/check-types.js)
* can match against pattern as RegExp, string, or callback(value) returning boolean
  • Loading branch information
mikestopcontinues committed Aug 30, 2014
0 parents commit 60f6aef
Show file tree
Hide file tree
Showing 43 changed files with 539 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
7 changes: 7 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
0.1.0 - August 30, 2014
-----------------------
* works on files matching pattern
* can specify default for when key unspecified
* can test for existence or for lack thereof
* can validate against type or array of types using [check-types](https://github.com/philbooth/check-types.js)
* can match against pattern as RegExp, string, or callback(value) returning boolean
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

node_modules: package.json
@npm install

test: node_modules
@./node_modules/.bin/mocha --reporter spec

.PHONY: test
98 changes: 98 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# metalsmith-validate

A [Metalsmith](https://github.com/segmentio/metalsmith) plugin that allows you to validate file metadata. You can check existence, type, and regex pattern. Neat.

## Features

- works on files matching pattern
- can specify default for when key unspecified
- can test for existence or for lack thereof
- can validate against type or array of types using [check-types](https://github.com/philbooth/check-types.js)
- can match against pattern as RegExp, string, or callback(value) returning boolean

## Installation

$ npm install metalsmith-validate

## Usage

### Validate all files

Pass hash of file metadata keys and rules.

```js
var validate = require('metalsmith-validate');

metalsmith.use(validate({
title: {
exists: true,
type: 'String'
},
date: {
exists: true,
pattern: /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/
},
tag: {
default: 'news'
},
draft: {
exists: false
}
}));
```

### Validate pattern-matching files

Pass array of hashes with file-matching pattern and metadata validation hash:

```js
var validate = require('metalsmith-validate');

metalsmith.use(validate([
{
pattern: 'post/*',
metadata: {
title: true, // shorthand for title: { exists: true }
date: true,
invalid: false
}
},
{
// pattern defaults to '**/*'
metadata: {
template: {
default: 'default.jade'
pattern: function (value) {
return value.match(/\.jade$/);
}
}
}
}
));
```

## CLI Usage

All of the same options apply, just add them to the `"plugins"` key in your `metalsmith.json` configuration:

```json
{
"plugins": {
"metalsmith-validate": [
{
"pattern": "page/*",
"metadata": {
"title": {
"exists": true,
"type": "String"
}
}
}
]
}
}
```

## License

MIT
110 changes: 110 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
'use strict';

var debug = require('debug')('metalsmith-validate');
var Matcher = require('minimatch').Minimatch;
var typeCheck = require('type-check').typeCheck;

/**
* Expose `plugin`.
*/

module.exports = plugin;

/**
* Metalsmith plugin that allows you to easily validate file metadata, checking existence, type, and regex pattern. Can also supply default value.
*
* @param {Array|Object} matchers array of rules applied to pattern-matched files, or hash of metadata validators to apply to all files
* @option {*} matchers[key].default set key to value if unset
* @option {Boolean} matchers[key].exists whether the key should exist
* @option {Array|string} matchers[key].type array of strings (or single string) of types which key must match at least one of
* @option {RegExp|string|Function} matchers[key].pattern regex pattern as RegExp or string to compare against key, or callback(value) returning Boolean
* @return {Function}
*/

function plugin(matchers) {
if (!Array.isArray(matchers)) {
matchers = [
{
metadata: matchers,
}
];
}

matchers = matchers.map(function (rule) {
rule.pattern = rule.pattern || '**/*';
debug('Normalize rule with pattern %s', rule.pattern);
rule.matcher = new Matcher(rule.pattern);
rule.metadata = rule.metadata || {};

Object.keys(rule.metadata).forEach(function (key) {
rule.metadata[key] = typeof rule.metadata[key] === 'object' ? rule.metadata[key] : {
exists: rule.metadata[key],
};

var validator = rule.metadata[key];

if (validator.type && !Array.isArray(validator.type)) {
validator.type = [validator.type];
}

if (typeof validator.pattern === 'string') {
validator.pattern = new RegExp(validator.pattern);
}
});

return rule;
});

return function (files, metalsmith, done) {
var err;

Object.keys(files).forEach(function (file) {
debug('Validate file %s', file);
var data = files[file];

matchers.forEach(function (rule) {
if (rule.matcher.match(file)) {
debug('Validate against rule with matching pattern %s', rule.pattern);
Object.keys(rule.metadata).every(function (key) {
var validator = rule.metadata[key];

if ('default' in validator && !(key in data)) {
return data[key] = validator.default;
}

if ('exists' in validator && validator.exists != key in data) {
err = new Error('File "' + file + '" ' + (validator.exists ? 'does not have' : 'has') + ' value "' + key + '".');
return false;
}

if ('type' in validator && validator.type.indexOf(typeof data[key]) === -1) {
var valid = false;

validator.type.some(function (type) {
return valid = typeCheck(type, data[key]);
});

if (!valid) {
err = new Error('File "' + file + '" value "' + key + '" must be of type [' + validator.type.join(', ') + '].');
return false;
}
}

if ('pattern' in validator && key in data && ((typeof validator.pattern === 'function' && !validator.pattern(data[key])) || !data[key].match(validator.pattern))) {
err = new Error('File "' + file + '" value "' + key + '" does not match ' + validator.pattern + '.');
return false;
}

return true;
});
}

if (err) {
return false;
}
});
});

done(err);
};
}
18 changes: 18 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "metalsmith-validate",
"description": "A Metalsmith plugin that allows you to easily validate file metadata, checking existence, type, and regex pattern.",
"repository": "git://github.com/mikestopcontinues/metalsmith-validate.git",
"version": "0.1.0",
"author": "Mike Stop Continues <mikestopcontinues@gmail.com>",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"debug": "~0.7.4",
"minimatch": "^0.3.0",
"type-check": "^0.3.1"
},
"devDependencies": {
"metalsmith": "0.x",
"mocha": "1.x"
}
}
2 changes: 2 additions & 0 deletions test/fixtures/callback/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/callback/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
5 changes: 5 additions & 0 deletions test/fixtures/callback/src/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
pattern: match
---

one
5 changes: 5 additions & 0 deletions test/fixtures/callback/src/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
pattern: unmatched
---

one
2 changes: 2 additions & 0 deletions test/fixtures/default/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/default/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
5 changes: 5 additions & 0 deletions test/fixtures/default/src/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: specified
---

one
4 changes: 4 additions & 0 deletions test/fixtures/default/src/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

one
2 changes: 2 additions & 0 deletions test/fixtures/exists/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/exists/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
5 changes: 5 additions & 0 deletions test/fixtures/exists/src/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
exists: true
---

one
4 changes: 4 additions & 0 deletions test/fixtures/exists/src/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

one
2 changes: 2 additions & 0 deletions test/fixtures/hash/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/hash/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
5 changes: 5 additions & 0 deletions test/fixtures/hash/src/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: specified
---

one
4 changes: 4 additions & 0 deletions test/fixtures/hash/src/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

one
2 changes: 2 additions & 0 deletions test/fixtures/missing/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/missing/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
5 changes: 5 additions & 0 deletions test/fixtures/missing/src/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
exists: true
---

one
4 changes: 4 additions & 0 deletions test/fixtures/missing/src/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

one
2 changes: 2 additions & 0 deletions test/fixtures/pattern/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/pattern/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
5 changes: 5 additions & 0 deletions test/fixtures/pattern/src/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
pattern: match
---

one
5 changes: 5 additions & 0 deletions test/fixtures/pattern/src/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
pattern: unmatched
---

one
2 changes: 2 additions & 0 deletions test/fixtures/regex/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/regex/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
5 changes: 5 additions & 0 deletions test/fixtures/regex/src/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
pattern: match
---

one
5 changes: 5 additions & 0 deletions test/fixtures/regex/src/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
pattern: unmatched
---

one
2 changes: 2 additions & 0 deletions test/fixtures/type/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/type/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
5 changes: 5 additions & 0 deletions test/fixtures/type/src/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
type: string
---

one
7 changes: 7 additions & 0 deletions test/fixtures/type/src/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
type:
- string
- array
---

one
2 changes: 2 additions & 0 deletions test/fixtures/types/build/one.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
2 changes: 2 additions & 0 deletions test/fixtures/types/build/two.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

one
Loading

0 comments on commit 60f6aef

Please sign in to comment.