Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

onessg

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

onessg - npm Package Compare versions

Comparing version 0.3.1 to 1.0.0

test/expected/nested/folder/no-author-no-editor.html

25

cli.js

@@ -7,2 +7,8 @@ #!/usr/bin/env node

.demand(1, 1, 'Error: You must specify an template engine')
.alias({
s: 'src',
d: 'dist',
l: 'layouts',
})
.string(['s', 'd', 'l'])
.default({

@@ -13,8 +19,2 @@ s: 'src/',

})
.string(['s', 'd', 'l'])
.alias({
s: 'src',
d: 'dist',
l: 'layouts',
})
.describe({

@@ -32,5 +32,12 @@ s: 'Set the src directory',

var onessg = require('./index.js');
onessg(argv._[0], argv.s, argv.d, argv.l, function (err) {
console.error(err);
process.exit(1);
var dirs={
src: argv.s,
dist: argv.d,
layouts: argv.l,
};
onessg(argv._[0], dirs, function (err) {
if (err) {
console.error(err);
process.exit(1);
}
});
var fs = require('fs-extra');
var path = require('path');
var replaceExt=require('replace-ext');
var fm = require('front-matter');
var path = require('path-extra');
var glob = require('glob');
var matter = require('gray-matter');
var cons = require('consolidate');
var glob = require('glob');
var yaml = require('js-yaml');
var marked = require('marked');
var async = require('async');
var _ = require('lodash');
module.exports = function (engine, src, dist, layouts, cb) {
// SANITY CHECKS
// Check that src exists:
fs.access(src, function (err) {
if (err) return cb(err);
// Directory vars:
var src;
var layouts;
var dist;
module.exports = function (engine, dirs, cb) {
// Make dirs available globally
setDirs(dirs, function (err) {
if (err) cb(err);
});

@@ -20,82 +23,74 @@ // Check that engine is a string:

if (typeof cons[engine] !== 'function') return cb(new Error(engine+' is not a valid consolidate.js template engine'));
// MAIN CODE
// For each html file in src:
forGlob(path.join(src, '**/*.html'), function (filePath) {
// For each file in src:
forGlob('**/*.@(html|md|markdown)', function (filePath, cb) {
// Load and parse FM:
loadFile(filePath, function (err, data) {
loadFile(filePath, function (err, file) {
if (err) return cb(err);
// Render it:
render(data, filePath, function (err, html) {
// Run through middleware:
middleware(file.content, path.extname(filePath), function (err, body) {
if (err) return cb(err);
// Get path to write to:
var writePath=path.join(dist, filePath.replace(src, ''));
// Output using fs-extra:
fs.outputFile(writePath, html, function (err) {
if (err) return cb(err);
});
});
});
}, function () {
// Empty for now, since forGlob() is sync
});
// For each markdown file in src:
forGlob(path.join(src, '**/*.@(md|markdown)'), function (filePath) {
// Load and parse FM:
loadFile(filePath, function (err, data) {
if (err) return cb(err);
marked(data.body, function (err, body) {
if (err) return cb(err);
// Overwrite markdown with html:
data.body=body;
// Overwrite body:
file.content=body;
// Render it:
render(data, filePath, function (err, html) {
render(file, engine, filePath, function (err, html) {
if (err) return cb(err);
// Get path to write to:
var writePath=replaceExt(path.join(dist, filePath.replace(src, '')), '.html');
// Output using fs-extra:
fs.outputFile(writePath, html, function (err) {
if (err) return cb(err);
});
// Write to file and pass cb
writeFile(html, filePath, cb);
});
});
});
}, function () {
// Empty for now, since forGlob() is sync
}, function (err) {
cb(err);
});
// IN-SCOPE HELPER FUNCTIONS
// Declare render() inside the main function for access to var engine
function render(data, filePath, cb) {
// Get defaults:
getDefaults(filePath, function (err, defaults) {
if (err) return cb(err);
// Set Defaults:
_.defaultsDeep(data.attributes, defaults);
// If layout, render:
if (data.attributes._layout) {
// Get layouts/layoutName.* :
var layout=glob.sync(path.join(layouts, data.attributes._layout)+'.*')[0];
// Glob doesn't throw an error if the layout path doesn't exist, so we do:
if (!layout) cb(new Error('The file: '+path.join(layouts, data.attributes._layout)+'.'+engine+' does not exist'));
var locals=data.attributes;
locals._body=data.body;
// Render with consolidate.js:
cons[engine](layout, locals, cb);
} else cb(null, data.body); // Else, return body
});
};
// HELPER FUNCTIONS
function render(file, engine, filePath, cb) {
// Get defaults:
getDefaults(path.join(src, filePath), function (err, defaults) {
if (err) return cb(err);
// Set Defaults:
_.defaultsDeep(file.data, defaults);
// If layout, render:
if (file.data._layout) {
// Get layouts/layoutName.* :
var layout=glob.sync(path.join(layouts, file.data._layout)+'.*')[0];
// Glob doesn't throw an error if the layout path doesn't exist, so we do:
if (!layout) cb(new Error('The layout: '+file.data._layout+' cannot be found in '+layouts));
var locals=file.data;
locals._body=file.content;
// Render with consolidate.js:
cons[engine](layout, locals, cb);
} else cb(null, file.content); // Else, return body
});
}
function getDefaults(filePath, cb) {
var dirPath=path.dirname(filePath);
var dirArr=[dirPath];
var defaultArr=[];
recurse(dirPath);
async.eachOf(dirArr, load, function (err) {
if (err) cb(err);
cb(null, _.spread(_.defaultsDeep)(defaultArr));
});
function recurse(dirPath) {
if (path.normalizeTrim(dirPath) === path.normalizeTrim(src)) return;
else {
var newPath=path.dirname(dirPath);
dirArr.push(newPath);
return recurse(newPath);
}
}
// Declare getDefaults inside the main function for access to var src
function getDefaults(filePath, cb, defaults) {
glob(path.join(path.dirname(filePath), '_defaults.*'), function (err, res) {
function load(dirPath, i, cb) {
glob(path.join(dirPath, '_defaults.*'), function (err, res) {
if (err) return cb(err);
if (!defaults) defaults={};
if (!res[0]) return recurse();
var ext=path.extname(res[0]);
var defaults={};
if (!res[0]) return finish();
try {
switch (ext) {
switch (path.extname(res[0])) {
case '.yaml':
case '.yml':
_.defaultsDeep(defaults, yaml.safeLoad(fs.readFileSync(res[0], 'utf8')));
defaults=yaml.safeLoad(fs.readFileSync(res[0], 'utf8'));
break;
case '.json':
_.defaultsDeep(defaults, fs.readJsonSync(res[0]));
defaults=fs.readJsonSync(res[0]);
}

@@ -105,17 +100,34 @@ } catch (e) {

}
recurse();
return finish();
function finish() {
defaultArr[i]=defaults;
cb(null);
return;
}
});
function recurse() {
if (path.dirname(filePath)+path.sep === path.normalize(src+path.sep)) return cb(null, defaults);
else {
var newPath=path.dirname(filePath);
return getDefaults(newPath, cb, defaults);
}
}
}
};
// HELPER FUNCTIONS
}
function middleware(text, ext, cb) {
// Check path's ext:
switch (ext) {
case '.html':
// noop:
return cb(null, text);
case '.md':
case '.markdown':
// Render markdown:
return marked(text, cb);
}
}
function writeFile(html, filePath, cb) {
// Get path to write to using path-extra:
var writePath=path.replaceExt(path.join(dist, filePath), '.html');
// Output using fs-extra:
fs.outputFile(writePath, html, function (err) {
cb(err);
});
}
// loadFile() calls (err, front-matter object)
function loadFile(name, cb) {
fs.readFile(name, 'utf8', function (err, res) {
fs.readFile(path.join(src, name), 'utf8', function (err, res) {
if (err) return cb(err);

@@ -125,3 +137,3 @@ var json;

try {
json=fm(res);
json=matter(res);
} catch (e) {

@@ -135,7 +147,22 @@ return cb(e);

function forGlob(pattern, iter, cb) {
glob(pattern, {nodir: true}, function (err, res) {
glob(pattern, {nodir: true, cwd: src}, function (err, res) {
if (err) return cb(err);
res.forEach(iter);
cb(null);
async.each(res, iter, cb);
});
return;
}
function setDirs(dirs, cb) {
// Check that src exists:
fs.access(dirs.src, function (err) {
if (err) return cb(err);
});
// Check that layouts exists:
fs.access(dirs.layouts, function (err) {
if (err) return cb(err);
});
src=dirs.src;
dist=dirs.dist;
layouts=dirs.layouts;
cb();
}
{
"name": "onessg",
"version": "0.3.1",
"version": "1.0.0",
"description": "The Static Site Generator that does only one thing: compile your html and markdown.",

@@ -13,2 +13,3 @@ "main": "index.js",

"benchmark": "./cli.js ejs -s test/src -d test/dist -l test/layouts",
"toc": "doctoc README.md",
"mocha": "nyc mocha --ui tdd",

@@ -31,18 +32,22 @@ "lint": "eslint --ignore-path .gitignore '**/*.js'"

"dependencies": {
"async": "^2.0.1",
"consolidate": "^0.14.1",
"front-matter": "^2.1.0",
"fs-extra": "^0.30.0",
"glob": "^7.0.5",
"gray-matter": "^2.0.2",
"js-yaml": "^3.6.1",
"lodash": "^4.14.0",
"marked": "^0.3.6",
"replace-ext": "^1.0.0",
"path-extra": "^4.0.0",
"yargs": "^5.0.0"
},
"devDependencies": {
"autoresolve": "0.0.3",
"doctoc": "^1.2.0",
"ejs": "^2.5.1",
"eslint": "~3.4.0",
"eslint": "~3.5.0",
"mocha": "^3.0.2",
"nyc": "^7.1.0"
"nyc": "^8.1.0",
"suppose": "^0.6.1"
}
}

@@ -17,2 +17,15 @@ # onessg

## Contents
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Installation](#installation)
- [Tutorial](#tutorial)
- [CLI Usage & Options](#cli-usage-&-options)
- [Contributing](#contributing)
- [License](#license)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Installation

@@ -26,4 +39,6 @@

## Example
**Note:** We recommend installing onessg as a devDependency (with the `-D` flag) and running it via an npm script. If you choose to install onessg globally, you will also need to install your template engine globally as well.
## Tutorial
Examples will use [ejs](https://github.com/mde/ejs/) as the template engine, you can use any template engine supported by [consolidate.js](https://github.com/tj/consolidate.js/).

@@ -44,4 +59,6 @@

All files can include front-matter (yaml or json).
---
All files in `src/` can include front-matter. YAML is parsed by default, see the [gray-matter docs](https://github.com/jonschlinkert/gray-matter#optionslang) for a list of supported languages.
**src/page-one.md**:

@@ -55,2 +72,3 @@ ```html

```
Notice the underscore before `layout`. _Anything prefixed with an underscore is reserved word for onessg._ All keys in the front-matter will be passed as a local to your templates.

@@ -67,2 +85,4 @@

Layouts are written in the templating language of your choice. We are using EJS here, but you can use any template engine on [this list](https://github.com/tj/consolidate.js/#supported-template-engines).
**layouts/page.ejs** looks like this:

@@ -82,11 +102,15 @@ ```html

```
Notice the local `_body`. This is the contents of the file. For **page-one.html**, it is `<!-- Your HTML -->`.
Notice the local `_body`. This is the local for outputing the contents of each file. For **page-one.md**, it is `Hello World!`.
**Run:**
```bash
onessg ejs
```
(Substitute ejs with the name of your template engine)
onessg will compile all html files in `src/` (and subdirectories), and output them to `dist/` (retaining the directory structure):
(Substitute `ejs` with the name of your template engine)
onessg will compile all the html and markdown files in `src/` (and subdirectories), and output them to `dist/` (retaining the directory structure):
```

@@ -103,3 +127,5 @@ .

```
**dist/page-one.html** looks like this (leading whitespace is removed by ejs due to the `rmWhitespace` option that we set in `_defaults.yaml`):
**dist/page-one.html** looks like this:
```html

@@ -118,5 +144,11 @@ <!DOCTYPE html>

```
- The title (`My first Page`) comes from the front-matter.
- The author's name (`John Smith`) comes from the `_defaults.yaml` file.
- Leading whitespace is removed by ejs due to the `rmWhitespace` option that we set in `_defaults.yaml`.
**Success!!!** :tada:
Now we are going to add a subdirectory to `src/`. Inside the subdirectory, we will add a `_defaults.yaml` and an html page. Now our tree looks like this:
Now we are going to add a subdirectory to `src/`, named `subdirectory` (of course! :wink:). Inside the subdirectory, we will add a `_defaults.yaml` and an html page, named `subpage.html`. Now our directory tree looks like this:
```

@@ -148,3 +180,3 @@ .

- `_layout: page` Here we are setting a default layout. This means we will not have to set `_layout` in each pages' front-matter.
- `author: Jane Smith` Here we are overriding a default set in `src/_defaults.yaml`.
- `author: Jane Smith` Here we are overriding the default author set in `src/_defaults.yaml`.

@@ -155,2 +187,3 @@ **src/subdirectory/subpage.html**:

```
Note that we have omitted the front-matter. The defaults from the `_defaults` file in this directory and parent directories (up to `src/`) will apply.

@@ -181,3 +214,3 @@

**dist/subdirectory/subpage.html**:
**dist/subdirectory/subpage.html** looks like this:
```html

@@ -196,4 +229,9 @@ <!DOCTYPE html>

```
Note that the default title from **src/_defaults.yaml** has been applied. The `rmWhitespace` option also is in effect.
A few things to note:
- The default title from `src/_defaults.yaml` has been applied.
- The default author from `src/_defaults.yaml` has been overridden by the one in `src/subdirectory/_defaults.yaml`.
- The `rmWhitespace` option from `src/_defaults.yaml` is also in effect.
**Hooray!** You are now a certified onessg user! :mortar_board:

@@ -222,6 +260,8 @@

## Development
## Contributing
Contributions welcome; please discuss before making significant changes. All new features should be tested. Run `npm test` to run the tests. You can generate a code coverage report by running `npm run coverage`. The report will be found at `coverage/lcov-report/index.html`.
If you make changes to the headings in `README.md`, please run `npm run toc` to update the table of contents.
For bugs :beetle:, feature requests :bulb:, and questions :speech_balloon:, please file an issue!

@@ -228,0 +268,0 @@

@@ -1,10 +0,10 @@

var execSync=require('child_process').execSync;
var exec=require('child_process').exec;
var fs=require('fs-extra');
var path=require('path');
var path=require('path-extra');
var assert=require('assert');
var replaceExt=require('replace-ext');
var onessg=require('../index.js');
var suppose=require('suppose');
var resolve=require('autoresolve');
var onessg=require(resolve('index.js'));
assert.file=function (fileName) {
fileName=replaceExt(fileName, '.html');
// path-extra:
fileName=path.replaceExt(fileName, '.html');
var expected=fs.readFileSync(path.join('test/expected', fileName), 'utf8');

@@ -17,4 +17,31 @@ var actual=fs.readFileSync(path.join('test/dist', fileName), 'utf8');

fs.removeSync('test/dist/');
// Build with cli:
execSync('./../cli.js ejs', {cwd: 'test'});
suite('cli', function () {
this.timeout(5000);
this.slow(3000);
test('works', function (done) {
// NOTE: This also builds the files for the unit tests below!
suppose(resolve('cli.js'), ['ejs', '-s', 'test/src', '-d', 'test/dist', '-l', 'test/layouts'])
.on('error', function (err) {
done(err);
})
.end(function (code) {
assert.equal(code, 0, 'CLI exited with non-zero exit code');
done();
});
});
test('returns errors', function (done) {
var error='';
// Run cli.js ejs -s noop:
suppose(resolve('cli.js'), ['ejs', '-s', 'noop'])
.on('error', function (err) {
error=err;
})
.end(function (code) {
assert.notEqual(code, 0, 'expected CLI to return non-zero exit code on error');
// Errors:
assert(error, 'expected CLI to print error message');
done();
});
});
});
// Tests:

@@ -28,5 +55,2 @@ suite('plain html', function () {

});
test('empty front-matter', function () {
assert.file('empty-fm.html');
});
});

@@ -82,2 +106,5 @@ suite('markdown', function () {

});
test('works in nested subfolders', function () {
assert.file('nested/folder/no-author-no-editor.html');
});
test('_defaults.json works', function () {

@@ -87,10 +114,23 @@ assert.file('json/no-author.html');

});
suite('errors', function () { // NOTE: This suite should be run last!
test('invalid src', function (done) {
onessg('ejs', 'noop', 'test/dist', 'test/layouts', function (e) {
suite('errors', function () {
var dirs={};
setup(function () {
dirs.src='test/src';
dirs.dist='test/dist';
dirs.layouts='test/layouts';
});
test('invalid src/', function (done) {
dirs.src='noop';
onessg('ejs', dirs, function (e) {
done(assert(e));
});
});
test('invalid layouts/', function (done) {
dirs.layouts='noop';
onessg('ejs', dirs, function (e) {
done(assert(e));
});
});
test('invalid type for engine', function (done) {
onessg(0, 'test/src', 'test/dist', 'test/layouts', function (e) {
onessg(0, dirs, function (e) {
done(assert(e));

@@ -100,13 +140,6 @@ });

test('unsupported engine', function (done) {
onessg('noop', 'test/src', 'test/dist', 'test/layouts', function (e) {
onessg('noop', dirs, function (e) {
done(assert(e));
});
});
test('cli returns errors', function (done) {
this.timeout(5000);
this.retries(4);
exec('./../cli.js ejs -s noop', {cwd: 'test'}, function (e) {
return done(assert(e));
});
});
});

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