Socket
Socket
Sign inDemoInstall

fabricator-assemble

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fabricator-assemble - npm Package Compare versions

Comparing version 1.0.6 to 1.1.0

test/expected/material-key.html

192

index.js
// modules
var _ = require('lodash');
var beautifyHtml = require('js-beautify').html;
var changeCase = require('change-case');
var chalk = require('chalk');
var fs = require('fs');
var globby = require('globby');
var Handlebars = require('handlebars');
var inflect = require('i')();
var matter = require('gray-matter');

@@ -64,2 +65,12 @@ var md = require('markdown-it')({ html: true, linkify: true });

/**
* Keywords used to access items in views
* @type {Object}
*/
keys: {
materials: 'materials',
views: 'views',
docs: 'docs'
},
/**
* Location to write files

@@ -69,2 +80,3 @@ * @type {String}

dest: 'dist',
/**

@@ -78,3 +90,15 @@ * beautifier options

indent_with_tabs: true
}
},
/**
* Function to call when an error occurs
* @type {Function}
*/
onError: null,
/**
* Whether or not to log errors to console
* @type {Boolean}
*/
logErrors: false
};

@@ -136,6 +160,10 @@

* @param {String} filePath
* @example
* './src/materials/structures/foo.html' -> 'foo'
* './src/materials/structures/02-bar.html' -> 'bar'
* @return {String}
*/
var getFileName = function (filePath) {
return path.basename(filePath).replace(/\.[^\/.]+$/, '');
var getName = function (filePath, preserveNumbers) {
var name = path.basename(filePath, path.extname(filePath));
return (preserveNumbers) ? name : name.replace(/^[0-9|\.\-]+/, '');
};

@@ -145,2 +173,51 @@

/**
* Attempt to read front matter, handle errors
* @param {String} file Path to file
* @return {Object}
*/
var getMatter = function (file) {
return matter.read(file, {
parser: require('js-yaml').safeLoad
});
};
/**
* Handle errors
* @param {Object} e Error object
*/
var handleError = function (e) {
// default to exiting process on error
var exit = true;
// construct error object by combining argument with defaults
var error = _.assign({}, {
name: 'Error',
reason: '',
message: 'An error occurred',
}, e);
// call onError
if (_.isFunction(options.onError)) {
options.onError(error);
exit = false;
}
// log errors
if (options.logErrors) {
console.error(chalk.bold.red('Error (fabricator-assemble): ' + e.message));
exit = false;
}
// break the build if desired
if (exit) {
console.error(chalk.bold.red('Error (fabricator-assemble): ' + e.message));
process.exit(1);
}
};
/**
* Build the template context by merging context-specific data with assembly data

@@ -151,3 +228,15 @@ * @param {Object} data

var buildContext = function (data) {
return _.assign({}, data, assembly.data, assembly.materialData, { materials: assembly.materials }, { views: assembly.views }, { docs: assembly.docs });
// set keys to whatever is defined
var materials = {};
materials[options.keys.materials] = assembly.materials;
var views = {};
views[options.keys.views] = assembly.views;
var docs = {};
docs[options.keys.docs] = assembly.docs;
return _.assign({}, data, assembly.data, assembly.materialData, materials, views, docs);
};

@@ -157,2 +246,14 @@

/**
* Convert a file name to title case
* @param {String} str
* @return {String}
*/
var toTitleCase = function(str) {
return str.replace(/(\-|_)/g, ' ').replace(/\w\S*/g, function(word) {
return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase();
});
};
/**
* Insert the page into a layout

@@ -188,4 +289,4 @@ * @param {String} page

var parent = path.normalize(path.dirname(file)).split(path.sep).slice(-2, -1)[0];
var collection = path.normalize(path.dirname(file)).split(path.sep).pop();
var parent = getName(path.normalize(path.dirname(file)).split(path.sep).slice(-2, -1)[0]);
var collection = getName(path.normalize(path.dirname(file)).split(path.sep).pop());
var isSubCollection = (dirs.indexOf(parent) > -1);

@@ -195,3 +296,3 @@

assembly.materials[collection] = assembly.materials[collection] || {
name: changeCase.titleCase(collection),
name: toTitleCase(collection),
items: {}

@@ -201,3 +302,3 @@ };

assembly.materials[parent].items[collection] = assembly.materials[parent].items[collection] || {
name: changeCase.titleCase(collection),
name: toTitleCase(collection),
items: {}

@@ -214,7 +315,8 @@ };

// get info
var fileMatter = matter.read(file);
var collection = path.normalize(path.dirname(file)).split(path.sep).pop();
var fileMatter = getMatter(file);
var collection = getName(path.normalize(path.dirname(file)).split(path.sep).pop());
var parent = path.normalize(path.dirname(file)).split(path.sep).slice(-2, -1)[0];
var isSubCollection = (dirs.indexOf(parent) > -1);
var id = (isSubCollection) ? collection + '.' + getFileName(file) : getFileName(file);
var id = (isSubCollection) ? collection + '.' + getName(file) : getName(file);
var key = (isSubCollection) ? collection + '.' + getName(file, true) : getName(file, true);

@@ -230,9 +332,9 @@ // get material front-matter, omit `notes`

if (!isSubCollection) {
assembly.materials[collection].items[id] = {
name: changeCase.titleCase(id),
assembly.materials[collection].items[key] = {
name: toTitleCase(id),
notes: (fileMatter.data.notes) ? md.render(fileMatter.data.notes) : ''
};
} else {
assembly.materials[parent].items[collection].items[id] = {
name: changeCase.titleCase(id.split('.')[1]),
assembly.materials[parent].items[collection].items[key] = {
name: toTitleCase(id.split('.')[1]),
notes: (fileMatter.data.notes) ? md.render(fileMatter.data.notes) : ''

@@ -260,3 +362,2 @@ };

// register the partial

@@ -269,6 +370,6 @@ Handlebars.registerPartial(id, content);

// sort materials object alphabetically
assembly.materials = sortObj(assembly.materials);
assembly.materials = sortObj(assembly.materials, 'order');
for (var collection in assembly.materials) {
assembly.materials[collection].items = sortObj(assembly.materials[collection].items);
assembly.materials[collection].items = sortObj(assembly.materials[collection].items, 'order');
}

@@ -293,7 +394,7 @@

var id = getFileName(file);
var id = getName(file);
// save each as unique prop
assembly.docs[id] = {
name: changeCase.titleCase(id),
name: toTitleCase(id),
content: md.render(fs.readFileSync(file, 'utf-8'))

@@ -320,3 +421,3 @@ };

files.forEach(function (file) {
var id = getFileName(file);
var id = getName(file);
var content = fs.readFileSync(file, 'utf-8');

@@ -339,3 +440,3 @@ assembly.layouts[id] = content;

files.forEach(function (file) {
var id = getFileName(file);
var id = getName(file);
var content = fs.readFileSync(file, 'utf-8');

@@ -361,3 +462,3 @@ Handlebars.registerPartial(id, content);

files.forEach(function (file) {
var id = getFileName(file);
var id = getName(file);
var content = yaml.safeLoad(fs.readFileSync(file, 'utf-8'));

@@ -383,3 +484,3 @@ assembly.data[id] = content;

var id = getFileName(file);
var id = getName(file);

@@ -390,3 +491,3 @@ // determine if view is part of a collection (subdir)

var fileMatter = matter.read(file),
var fileMatter = getMatter(file),
fileData = _.omit(fileMatter.data, 'notes');

@@ -399,3 +500,3 @@

assembly.views[collection] = assembly.views[collection] || {
name: changeCase.titleCase(collection),
name: toTitleCase(collection),
items: {}

@@ -406,3 +507,3 @@ };

assembly.views[collection].items[id] = {
name: changeCase.titleCase(id),
name: toTitleCase(id),
data: fileData

@@ -451,12 +552,18 @@ };

* @description Like a normal partial include (`{{> partialName }}`),
* but with some additional templating logic to help with nested block iterations
* but with some additional templating logic to help with nested block iterations.
* The name of the helper is the singular form of whatever is defined as the `options.keys.materials`
* @example
* {{material name context}}
*/
Handlebars.registerHelper('material', function (name, context) {
Handlebars.registerHelper(inflect.singularize(options.keys.materials), function (name, context) {
var template = Handlebars.partials[name],
// remove leading numbers from name keyword
// partials are always registered with the leading numbers removed
var key = name.replace(/^([a-z][a-z0-9]*\.)?([0-9\.-]+)(.*)$/i, '$1$3');
// attempt to find pre-compiled partial
var template = Handlebars.partials[key],
fn;
// check to see if template is already compiled
// compile partial if not already compiled
if (!_.isFunction(template)) {

@@ -468,2 +575,3 @@ fn = Handlebars.compile(template);

// return beautified html with trailing whitespace removed
return beautifyHtml(fn(buildContext(context)).replace(/^\s+/, ''), options.beautifier);

@@ -483,3 +591,3 @@

// merge user options with defaults
options = _.assign({}, defaults, userOptions);
options = _.merge({}, defaults, userOptions);

@@ -512,3 +620,3 @@ // setup steps

var id = getFileName(file);
var id = getName(file);

@@ -521,3 +629,3 @@ // build filePath

// get page gray matter and content
var pageMatter = matter(fs.readFileSync(file, 'utf-8')),
var pageMatter = getMatter(file),
pageContent = pageMatter.content;

@@ -549,8 +657,14 @@

// setup assembly
setup(options);
try {
// assemble
assemble();
// setup assembly
setup(options);
// assemble
assemble();
} catch(e) {
handleError(e);
}
};
{
"name": "fabricator-assemble",
"version": "1.0.6",
"version": "1.1.0",
"description": "The assembly engine behind Fabricator",

@@ -20,11 +20,11 @@ "main": "index.js",

"dependencies": {
"change-case": "^2.2.0",
"globby": "^1.2.0",
"gray-matter": "^1.2.6",
"handlebars": "^2.0.0",
"html-minifier": "^0.6.9",
"chalk": "^1.0.0",
"globby": "^2.0.0",
"gray-matter": "^2.0.0",
"handlebars": "^3.0.3",
"i": "^0.3.3",
"js-beautify": "^1.5.5",
"js-yaml": "^3.2.7",
"lodash": "^2.4.1",
"markdown-it": "^3.1.0",
"lodash": "^3.8.0",
"markdown-it": "^4.2.1",
"mkdirp": "^0.5.0",

@@ -36,4 +36,5 @@ "sort-object": "^1.0.0"

"helper-markdown": "^0.1.1",
"html-minifier": "^0.7.2",
"mocha": "^2.1.0"
}
}

@@ -81,3 +81,10 @@ # Fabricator Assemble

docs: 'src/docs/**/*.md',
keys: {
materials: 'materials',
views: 'views',
docs: 'docs'
}
helpers: {},
logErrors: false,
onError: function(error) {},
dest: 'dist'

@@ -136,5 +143,37 @@ }

### options.keys
Type: `Objects`
Default: `materials/views/docs`
Object keywords for accessing "materials", "views", and "docs" in a view templating context. Fabricator uses some specific terms like "materials" to describe what are really "partials" in Handelbars. This option give you the flexibility to define your own terms for `materials`, `views`, and `docs`.
For example:
```
assemble({
keys: {
materials: 'patterns'
}
});
```
```
<!-- formerly `{{#each materials}}` -->
{{#each patterns}}
<h1>{{name}}</h1>
{{#each items}}
<h2>{{name}}</h2>
{{/each}}
{{/each}}
```
**Note**: this will also change the built-in `{{material <foo>}}` helper to use the **singular** form of whatever is defined for the `materials` key. e.g. `materialKey: 'patterns'` -> `{{pattern <foo>}}`. If you set a new key for `materials`, you will also need to update the `f-item-content.html` include to use the new helper name.
### options.helpers
Type: `Object`
Type: `Object`
Default: `{}`

@@ -153,5 +192,19 @@

### options.logErrors
Type: `Boolean`
Default: `false`
Whether or not to log errors to console. If set to false, the app will exit on error.
### options.onError
Type: `Function`
Default: `null`
Error handler function. Receives an `error` object param.
### options.dest
Type: `String`
Type: `String`
Default: `dist`

@@ -161,3 +214,3 @@

## API
## Usage

@@ -260,2 +313,30 @@ ### Definitions

#### Ordering
You can manually order materials by prefixing the file name with numbers:
```
01-foo.html
01.01-bar.html
02-qux.html
```
This defines the order in which materials will appear in the side menu or other places the `materials.items` context is used.
**Note**: The number prefixes are ignored when registering partials, so you'll still be able to access them using the material name per usual. e.g.:
```
{{> foo}}
{{> bar}}
{{> qux}}
```
The numbers are also ignored in the `.name` property. The materials above would list as:
```
Foo
Bar
Qux
```
#### Data

@@ -262,0 +343,0 @@

@@ -0,1 +1,2 @@

var _ = require('lodash');
var assert = require('assert');

@@ -21,3 +22,4 @@ var assemble = require('../');

markdown: require('helper-markdown')
}
},
logErrors: true
};

@@ -95,2 +97,18 @@

it('should use a custom material key', function (done) {
assemble(_.assign({}, options, {
keys: {
materials: 'patterns'
}
}));
var output = minify(fs.readFileSync('./test/output/material-key.html', 'utf-8'), { collapseWhitespace: true });
var expected = minify(fs.readFileSync('./test/expected/material-key.html', 'utf-8'), { collapseWhitespace: true });
assert.equal(output, expected);
done();
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc