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

blake

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

blake - npm Package Compare versions

Comparing version 0.9.3 to 1.0.0

test/blake.js

49

bin/cli.js
#!/usr/bin/env node
var blake = require('../index')
, cop = require('cop')
, files = require('../lib/read').fstream
, copy = require('../lib/copy')
, join = require('path').join
var cop = require('cop')
var fs = require('fs')
var path = require('path')
;(function () {
var arg = process.argv.splice(2)
, isValid = arg && arg.length >= 2
if (!isValid) {
return console.error('Usage: blake source_directory target_directory [source_file ...]');
if (!arg.length) {
return console.error('Usage: blake [source_directory] target_directory [source_file ...]')
}
var cwd = process.cwd()
function isFile () {
var p = path.resolve(cwd, arg[1])
return fs.statSync(p).isFile()
}
var sansSource = arg.length === 1 || isFile()
if (sansSource) {
arg.unshift(cwd)
}
var source = arg.shift()
, target = arg.shift()
var target = arg.shift()
function onerror (er) {
console.error(er.message)
}
var b = blake(source, target)
if (!arg.length) {
copy(join(source, 'resources'), target)
.on('error', console.error)
blake.copy(b.resources, target)
.on('error', onerror)
.on('end', bake)

@@ -28,15 +36,10 @@ .pipe(process.stdout)

}
function bake () {
files(source, arg)
.pipe(cop('path'))
.pipe(blake(source, target))
.pipe(cop(format))
var p = arg instanceof Array && arg.length ? arg : b.data
blake.files(p)
.pipe(b)
.on('error', onerror)
.pipe(cop(function (str) { return str + '\n' }))
.pipe(process.stdout)
}
})()
function format (str) {
return str += '\n'
}

@@ -1,48 +0,301 @@

// blake - generate site
var Transform = require('stream').Transform
, fs = require('fs')
, mkdirp = require('mkdirp')
, dirname = require('path').dirname
, writeFile = require('fs').writeFile
, StringDecoder = require('string_decoder').StringDecoder
, read = require('./lib/read.js').readItems
, conf = require('./lib/read.js').conf
module.exports = Blake
module.exports = function (s, target) {
var c = s && target ? conf(s, target) : s
, decoder = new StringDecoder('utf8')
, stream = new Transform({ objectMode:true })
module.exports.copy = copy
module.exports.files = files
stream._transform = function (chunk, encoding, cb) {
var filename = decoder.write(chunk)
read(c)(filename, function (er, item) {
bake(item, function (er) {
stream.push(item.path)
cb(er)
var LRU = require('lru-cache')
var createHash = require('crypto').createHash
var cop = require('cop')
var fs = require('fs')
var fstream = require('fstream')
var mkdirp = require('mkdirp')
var path = require('path')
var readArray = require('event-stream').readArray
var stream = require('stream')
var string_decoder = require('string_decoder')
var util = require('util')
function Blake (source, target) {
if (!(this instanceof Blake)) return new Blake(source, target)
stream.Transform.call(this, { objectMode: true })
this._conf = conf(source, target)
this._reader = new ItemReader(this._conf)
this._decoder = new string_decoder.StringDecoder()
var me = this
Object.defineProperty(this, 'resources', {
get: function () { return me._conf.paths.resources }
})
Object.defineProperty(this, 'data', {
get: function () { return me._conf.paths.data }
})
}
util.inherits(Blake, stream.Transform)
function write (p, data, cb) {
mkdirp(path.dirname(p), function (er, made) {
er ? cb(er) : fs.writeFile(p, data, cb)
})
}
Blake.prototype._transform = function (chunk, enc, cb) {
var me = this
var filename = this._decoder.write(chunk)
function view (item, cb) {
if (!item.view) {
cb(new Error('blake: ' + item.name + ' misses view function'))
return
}
item.read = function (p, cb) {
me.items(p, cb)
}
item.view(item, function (error, result) {
if (error) {
var msg = ['blake', 'view error', item.path, error.message].join(': ')
var er = new Error(msg)
er.item = item
return me.emit('error', er)
}
write(item.path, result, function (error) {
if (error) {
cb(new Error('blake: write error: ' + error.message))
} else {
cb()
}
})
})
}
function bake (item, cb) {
if (!item.bake) {
cb(new Error('Undefined bake function for ' + item.name))
return
me._reader.read(filename, function (er, item) {
if (er) return cb(er)
view(item, function (er) {
me.push(item.path)
cb(er)
})
})
}
Blake.prototype.items = function (p, cb) {
this._reader.read(p, cb)
}
function item (conf, file, str) {
var marker = '\n\n'
var tokens = str.split(marker)
var paths = conf.paths
var h = header(tokens.shift(), file, paths)
var body = tokens.join(marker)
var views = conf.views
return new Item(
h,
body,
paths,
h.title,
h.name,
h.date,
path.join(paths.templates, h.template),
path.join(paths.target, h.path, h.name),
path.join(h.path, h.name),
views[h.template] // view
)
}
function header (data, file, paths) {
var h = null
try {
h = JSON.parse(data)
} catch (error) {
throw new Error('blake: header error: ' + file + ': ' + error.message)
}
if (!h.template) {
throw new Error('blake: template required: ' + file)
}
if (!h.name) {
var name = path.basename(file).split('.')[0]
var extension = name === 'atom' || name === 'rss' ? 'xml' : 'html'
h.name = [name, '.', extension].join('')
}
h.title = h.title || null
h.date = h.date ? new Date(h.date) : new Date()
h.path = h.path || path.dirname(file).split(paths.posts)[1] || ''
return h
}
function Item (
header
, body
, paths
, title
, name
, date
, templatePath
, path
, link
, view) {
this.header = header
this.body = body
this.paths = paths
this.title = title
this.name = name
this.date = date
this.templatePath = templatePath
this.path = path
this.link = link
this.view = view
}
function files (p) {
if (p instanceof Array && p.length) {
return readArray(p)
} else {
var filter = cop(function (entry) { return entry.path })
var reader = new fstream.Reader({ path: p })
return reader.pipe(filter)
}
}
function Paths (resources, data, templates, posts, target) {
this.resources = resources
this.data = data
this.templates = templates
this.posts = posts
this.target = target
}
function paths (source, target, conf) {
var p = conf.paths
var resources = p.resources ? path.join(source, p.resources) : null
var data = p.data ? path.join(source, p.data) : null
var templates = p.templates ? path.join(source, p.templates) : null
var posts = p.posts ? path.join(source, p.posts) : null
return new Paths(resources, data, templates, posts, target)
}
function conf (source, target) {
if (typeof source === 'string') {
if (typeof target !== 'string') {
target = source
source = process.cwd()
}
item.read = read(c)
item.bake(item, function (er, result) {
if (er) {
stream.emit('error', er)
return
}
var uc = require(source)
var res = Object.create(null)
res.paths = paths(source, target, uc)
res.views = uc.views
return res
}
function ItemReader (conf) {
if (!(this instanceof ItemReader)) return new ItemReader(conf)
this.conf = conf
this.decoder = new string_decoder.StringDecoder()
this.cache = new LRU({ max: 500, maxAge: 1000 * 60 * 3 })
}
ItemReader.prototype.read = function (p, cb) {
if (!p) {
cb(new Error('blake: read error: no path'))
return
}
var me = this
fs.stat(p, function (er, stats) {
if (stats.isDirectory()) {
me.readDirectory(p, cb)
} else {
me.readFile(p, cb)
}
})
}
function hash (str) {
return createHash('md5').update(str).digest('hex')
}
ItemReader.prototype.readFile = function (filename, cb) {
var k = hash(filename)
if (this.cache.has(k)) {
return cb(null, this.cache.get(k))
}
var me = this
var cache = this.cache
fs.readFile(filename, function (er, data) {
var it = item(me.conf, filename, me.decoder.write(data))
Object.defineProperty(it, 'template', {
get: function () {
var k = hash(it.templatePath)
if (cache.has(k)) return cache.get(k)
var buf = fs.readFileSync(it.templatePath)
cache.set(k, buf)
return buf
}
write(item.path, result, cb)
})
cache.set(k, it)
return cb(er, it)
})
}
ItemReader.prototype.readDirectory = function (p, cb) {
var reader = fstream.Reader({ path: p })
var s = new stream.Writable()
var items = []
var me = this
s.add = function (entry) {
if (entry.type === 'Directory') {
entry.on('entry', s.add)
return true
}
me.readFile(entry.path, function (er, item) {
items.push(item)
entry.depth === 1 ? s.end() : reader.resume()
})
return false
}
return stream
s.end = function () {
cb(null, items)
}
reader.pipe(s)
}
function write (path, data, callback) {
mkdirp(dirname(path), function (err, made) {
writeFile(path, data, callback)
function filter (entry) {
return !entry.basename.match(/^\./)
}
function copy (source, target, cb) {
var reader = fstream.Reader({ path: source, filter: filter })
var writer = fstream.Writer({ path: target, type: 'Directory' })
var s = new stream.PassThrough()
function push (entry) {
if (entry.type === 'File') {
var p = path.join(target, entry.path.split(source)[1] || '')
s.push(p + '\n')
} else {
entry.on('entry', push)
}
}
reader.on('error', function (err) {
s.emit('error', err)
})
reader.on('entry', function (entry) {
push(entry)
})
writer.on('error', function (err) {
s.emit('error', err)
})
writer.on('end', function () {
s.push(null)
if (cb) cb()
})
reader.pipe(writer)
return s
}
if (parseInt(process.env.NODE_TEST, 10) === 1) {
module.exports.ItemReader = ItemReader
module.exports.conf = conf
module.exports.header = header
module.exports.item = item
module.exports.paths = paths
module.exports.write = write
}
{
"name": "blake",
"version": "0.9.3",
"description": "Simple, blog aware infrastructure to generate static sites",
"version": "1.0.0",
"description": "Generate static sites",
"main": "index.js",
"directories": {
"lib": "lib",
"example": "example",
"test": "test"
},
"scripts": {
"test": "tap test/*.js"
"test": "NODE_TEST=1 tap test/*.js",
"posttest": "rm -rf /tmp/blake-[1-9]*"
},

@@ -26,3 +25,3 @@ "repository": {

"generator",
"infrastructure"
"build"
],

@@ -34,17 +33,15 @@ "bin": {

"cop": "^0.3.6",
"event-stream": "^3.1.7",
"fstream": "^0.1.31",
"lru-cache": "^2.5.0",
"mkdirp": "^0.4.2",
"popfun": "^0.1.2",
"event-stream": "^3.3.1",
"fstream": "^1.0.7",
"lru-cache": "^2.6.5",
"mkdirp": "^0.5.1",
"popfun": "^1.0.0",
"prettydate": "0.0.1"
},
"devDependencies": {
"jade": "^1.8.1",
"markdown": "^0.5.0",
"rimraf": "^2.2.8",
"tap": "^0.4.13"
"rimraf": "^2.4.3",
"tap": "^1.4.0"
},
"engines": {
"node": "0.10.x"
"node": ">0.10"
},

@@ -51,0 +48,0 @@ "author": {

@@ -1,253 +0,214 @@

# blake - generate site
# blake - generate anything
The `blake` [Node.js](http://nodejs.org/) module provides a simple, blog aware infrastructure to generate [static sites](http://troubled.pro/2012/05/static-websites.html). For unrestricted choice of input formats and template languages, `blake` confines itself to IO and template routing; it delegates artifact generation to user-written functions.
The **blake** [Node](https://nodejs.org/) package provides a file generation pipeline. I wrote it to generate my [site](http://troubled.pro/). Separating IO from data transformation—by using an intermediate representation—**blake** takes care of IO, and lets you get on with generating your stuff. Of course, [gulp](http://gulpjs.com/) puts itself forward as a streaming build system, but if you—like me—experience slight framework fatigue, and prefer plain Node, you might want to give **blake** a shot.
[![Build Status](https://travis-ci.org/michaelnisi/blake.png)](http://travis-ci.org/michaelnisi/blake) [![David DM](https://david-dm.org/michaelnisi/blake.png)](http://david-dm.org/michaelnisi/blake)
[![Build Status](https://travis-ci.org/michaelnisi/blake.png)](http://travis-ci.org/michaelnisi/blake)
## CLI Usage
## Example
Alas, I don't have a silly example yet, however, you can generate my site to get an understanding of how to use **blake**:
```
blake source_directory target_directory
blake source_directory target_directory source_file ...
git clone https://github.com/michaelnisi/troubled.git
cd troubled
npm install
blake /tmp/troubled
```
In the first form, `blake` writes all files generated from input data in the `source_directory` to the `target_directory`. In the second synopsis form, output is generated from the specified source files only.
## Library Usage
Start an HTTP server in the target directory:
### Generate from directory
```js
var blake = require('blake')
, source = 'blake-site'
, target = '/tmp/blake-site'
, join = require('path').join
, Reader = require('fstream').Reader
, props = { path:join(source, 'data') }
, cop = require('cop')
new Reader(props)
.pipe(cop('path'))
.pipe(blake(source, target))
.pipe(cop(function (filename) { return filename + '\n' }))
.pipe(process.stdout)
```
### Copy static resources and generate from directory
```js
var blake = require('blake')
, join = require('path').join
, source = join(process.cwd(), './blake-site')
, target = '/tmp/blake-site'
, Reader = require('fstream').Reader
, props = { path:join(source, 'data') }
, cop = require('cop')
, copy = require('../lib/copy.js')
copy(join(source, 'resources'), target)
.on('error', console.error)
.on('end', function () {
new Reader(props)
.pipe(cop('path'))
.pipe(blake(source, target))
.pipe(cop(function (filename) { return filename + '\n' }))
.pipe(process.stdout)
})
.pipe(process.stdout)
cd /tmp/troubled
python -m SimpleHTTPServer 8081
```
### Generate from files
```js
var blake = require('blake')
, cop = require('cop')
, readArray = require('event-stream').readArray
, filenames = ['first/file', 'second/file', 'third/file']
, source = 'source_directory'
, target = 'target_directory'
readArray(filenames)
.pipe(blake(source, target))
.pipe(cop(function (filename) { return filename + '\n' }))
.pipe(process.stdout)
Point your browser to `http://localhost:8081` to inspect the result.
## CLI
```
### Generate and push to S3
blake [source_directory] target_directory [source_file ...]
```
Since the `blake` function returns a [Transform](http://nodejs.org/api/stream.html#stream_class_stream_transform) stream that emits the paths of the generated artifacts, we can pipe to [pushup](https://github.com/michaelnisi/pushup), and upload the files directly to S3.
```js
var resolve = require('path').resolve
, cop = require('cop')
, getProps = require('pushup/lib/getProps')
, blake = require('blake')
, pushup = require('pushup')
, Reader = require('fstream').Reader
, sep = require('path').sep
, source = 'source_directory'
, target = '/tmp/target_directory'
, reader = new Reader({ path:resolve(source, 'data') })
, props = getProps()
If you skip passing the source directory, and give the target only, like in the example, **blake** will use the current working directory as source.
process.chdir(target)
reader
.pipe(cop('path'))
.pipe(blake(source, target))
.pipe(cop(adjustPath))
.pipe(pushup(props))
.pipe(process.stdout)
To generate specific files exclusively, you can pass arbitary source file paths.
function adjustPath (p) {
return p.split(sep).slice(3).join(sep)
}
```
## Types
### str()
Optional String type, which can be `String()`, `null`, or `undefined`.
### err()
Optional error type: `Error()`, `null`, or `undefined`.
### paths()
An object to configure paths.
- `resources` `str()` An optional path for static resources.
- `data` `String()` The path to the content directory.
- `templates` `String()` The folder to load templates from.
- `posts` `str()` An optional posts directory for bloglike sites.
- `target` `String()` The target directory.
### header()
Just a bag of things, passed to your **view function**, you can put anything you want in here; just remember that **blake** uses these properties internally:
- `template` `String()` The filename of the template.
- `title` `str()` The title of the item or `null`.
- `date` `str()` This optional date overrides the current date.
- `path` `str()` If this optional target path is not provided, **blake** will mirror the path of the source file.
- `name` `str()` A target filename to override the default source filename.
### item()
The item object, an intermediate representation of each file to generate, forms the core of **blake**; it is constructed internally and passed to the **view function**, in which you use its properties to produce the final output.
- `header` `header()` The original header.
- `paths` `paths()` The paths object populated by **blake**.
- `body` `str()` Everything after the header in the source file.
- `title` `str()` The title of the item.
- `name` `String()` The target file name.
- `date` `Date()` The current date or the date set in `header()`.
- `templatePath` `String()` The absolute path to the template file.
- `path` The absolute target file path.
- `link` The relative target file path applicable as local link on the site.
- `template` `Buffer()` The template data.
- `read` `read()`
`read(path, cb)`
Reads all source files in the given path recursively to apply the callback with an optional error and the resulting items—handy to create archives, feeds, etc.
- `path` `String()`
- `cb` `Function(er, items)`
- `er` `err()` An optional Error.
- `items` `[item()]` The resulting items.
### views()
An object that maps **view functions** by template filename.
## API
### blake(source, target)
The **blake** module exports the constructor of the `Blake` Transform stream. To use it do `require('blake')`. A `Blake` stream has two additional getters providing access to parts of the configuration:
The `blake` module exports a single function that returns a [Transform](http://nodejs.org/api/stream.html#stream_class_stream_transform) stream. While writing source filenames to it, you can read target filenames (of written arfifacts) from it.
- `resources` `str()` The optional path to the resources directory.
- `data` `String()` The path to the data source directory.
- `source` The source directory.
- `target` The target directory.
This constructor—the solely exported function by the module—is decorated with two stateless functions, given `var blake = require('blake')`:
## Configuration
`blake.files(path)`
`blake` requires a configuration module at `source_directory/config.js`, which exports `paths`, and `views` (a map of generator functions):
Returns a readable stream of all filenames in the given directory. The filenames are read recursively, directory names are skipped.
- `path` `String()` The path of the directory to read.
`blake.copy(source, target)`
Recursively copies all files from the `source` directory to the `target` directory; returns a readable stream of the copied target filenames.
- `source` `String()` The source directory.
- `target` `String()` The target directory.
### Configuring a site
The source directory has to contain a source module, which has to export `paths()` and `views()`:
```js
exports.paths = {
data: 'data'
, templates: 'templates'
, resources: 'resources'
, posts: 'data/posts'
data: 'data',
templates: 'templates',
resources: 'resources',
posts: 'data/posts'
}
// Associate your view functions with template names.
exports.views = {
'rss.jade': require('./rss.js')
, 'article.jade': require('./article.js')
, 'home.jade': require('./home.js')
, 'about.jade': require('./about.js')
, 'archive.jade': require('./archive.js')
'rss.jade': rss,
'article.jade': article,
'home.jade': home,
'about.jade': about,
'error.jade': about,
'archive.jade': archive,
'likes.jade': likes,
'tweet.jade': tweet
}
```
The `paths` object defines input paths, with two required directories: `data` and `templates`. From `data` blake loads general input data, `templates` is the directory for templates. The two optional directories are `resources` and `posts`. The content of `resources` is copied to the `target_directory' unchanged. The `posts` directory hosts blog posts.
The `views` object is a map of user-written functions that implement the actual generation of output artifacts. Here, these functions are mapped by template name.
### Writing a view
## Input
`view (item, cb)`
At the top of each input file blake expects a JSON string that is interpreted as header providing transformation parameters. Besides it can contain additional user defined data—the `item` parameter, passed to the view functions, provides a reference to the raw header. Input data for a blog entry could look like so:
```
{
"title": "Example",
"description": "An example article",
"template": "article.jade",
"date": "2012-03-21"
}
- `item` `item()`
- `cb` `Function(error, result)`
- `error` `err()` Pass an error if something went wrong.
- `result` `Buffer()` The resulting artifact generated by this view.
Your highness, when I said that you are like a stream of bat's piss,
I only mean that you shine out like a shaft of gold when all around
it is dark.
```
The end of the header is marked by an empty line. Everything that follows is interpreted as content and is passed to the views untouched.
Each `item()` is associated with a **view function** by a template name in the configuration. This function—implemented by you—is responsible to generate the artifact. It is in this function where the actual work is done. Here you use values from the item and your template, also provided via the item, to generate the final output, which you apply to the callback once you are done—so it can be written to disk by **blake**.
### Header
### Creating a new instance
JSON at the top of an input file:
```js
{
"title": "Example",
"description": "An example article",
"template": "article.jade",
"date": "2012-03-21",
"path": "2012/03",
"name": "example"
}
```
* `title` is the title of the page (optional)
* `description` is the description of the page or rather the post (optional)
* `template`is the filename of the template to use (required)
* `date` is the publish date, if not provided it's set to `NOW` (optional)
* `path` is the output path, if not provided the path of the input file is used (optional)
* `name` is used as filename of the output file, if not provided the filename of the input file is used (optional)
`blake(source, target)`
The source object, passed to the views, provides a reference to the raw header object. Thus, the header is extendable with arbritrary fields, which can be interpreted by the generators (written by you).
- `source` `str()` The source directory.
- `target` `String()` The target directory.
If you decide to mirror the input paths in your output, you can omit path and name. In that case a typical header of a blog post might look like the following:
```js
{
"title": "Example",
"description": "An example article",
"template": "article.jade",
"date": "2012-03-21",
}
var blake = require('blake')
var b = blake('./test/data', '/tmp/blake-example')
```
Input data with this header, located at `source_directory/data/posts/2012/03/example.md`, would produce `2012/03/article.html`.
An input file can consist of just a header (without content) to generate, for example, an RSS feed.
```js
{
"title": "Blog",
"description": "Stuff I write",
"link": "http://my.blog",
"template": "rss.jade",
"name": "rss.xml"
}
### Copying static resources
`blake.copy(resources, target)`
- `resources` `String()` A directory containing static resources.
- `target` `String()` The target directory.
``` js
var b = blake(source, target)
blake.copy(b.resources, target)
```
### Views
The views—alternative naming would be: transformers, generators, or bakers—are the functions that generate your artifacts; they have the following signature:
### Generating a site
For a complete build, you would typically generate the site after copying static resources:
```js
function (item, callback)
var b = blake(source, target)
blake.copy(b.resources, target).on('end', function () {
blake.files(b.data).pipe(b)
}).resume()
```
The passed in 'item' provides the input data to generate the artifact (or most likely the page).
Here, for example, an `item` representing a blog post:
```js
{ header:
{ title: 'Static Websites',
description: '...',
template: 'article.jade',
data: Thu May 17 2012 02:00:00 GMT +0200 (CEST),
path: '2012/05',
name: 'static-websites.html' }
body: '...',
paths:
{ target: '/tmp/michaelnisi-site',
resources: '/Users/michael/workspace/michaelnisi/resources',
data: '/Users/michael/workspace/michaelnisi/data',
templates: '/Users/michael/workspace/michaelnisi/templates',
posts: '/Users/michael/workspace/michaelnisi/data/posts' },
title: 'Static Websites',
name: 'static-websites.html',
date: Thu May 17 2012 02:00:00 GMT+0200 (CEST),
templatePath: '/Users/michael/workspace/michaelnisi/templates/article.jade',
path: '/tmp/michaelnisi-site/2012/05/static-websites.html',
link: '2012/05/static-websites',
dateString: 'Thu May 17 2012',
bake: [Function],
template: <Buffer 0a 20 20 20 20 64 69 76 ...> }
### Generating specific files
Since **blake** is a Transform stream, you can easily generate only specific files:
```
To see a simple example:
var b = blake(source, target)
b.end('path/to/a/file')
```
git clone git://github.com/michaelnisi/blake.git
cd blake/example
npm install
node generate.js
open /tmp/blake-site/index.html
```
To evaluate a more elaborate example, you might generate my [blog](http://troubled.pro), for which I use [Jade](http://jade-lang.com/) and [Markdown](http://daringfireball.net/projects/markdown/):
```
npm install -g blake
git clone git://github.com/michaelnisi/troubled.git
cd troubled
npm install
blake . /tmp/troubled-site
```
## Deployment
Of course you can build your site locally, and upload it to your webserver manually; but I recommend to run blake on a server, using [post-receive hooks](http://help.github.com/post-receive-hooks/) to automatically generate your site, post to each push your input data repository receives.
## Install
## Installation
With [npm](https://npmjs.org/package/blake) do:
[![npm](https://nodei.co/npm/blake.png?compact=true)](https://npmjs.org/package/blake)
```
npm install blake
```
To use the command-line interface:
```
npm install -g blake
```
## License
[MIT License](https://raw.github.com/michaelnisi/blake/master/LICENSE)

@@ -0,30 +1,36 @@

var cop = require('cop')
var copy = require('../').copy
var es = require('event-stream')
var fs = require('fs')
var fstream = require('fstream')
var rimraf = require('rimraf')
var path = require('path')
var test = require('tap').test
, copy = require('../lib/copy.js')
, join = require('path').join
, fs = require('fs')
, rimraf = require('rimraf')
, source = '../example/blake-site/resources'
, target = '/tmp/blake-' + Math.floor(Math.random() * (1<<24))
, fstream = require('fstream')
, es = require('event-stream')
, cop = require('cop')
var common = require('./lib/common')
var source = common.source(__dirname, 'resources')
var target = common.freshTarget()
function paths (p, cb) {
return fstream.Reader({ path: p })
.pipe(cop('path'))
.pipe(es.writeArray(cb))
}
test('directory', function (t) {
copy(source, target, function (err) {
var paths = [
join(target, 'css', 'style.css')
, join(target, 'img', 'bg.png')
copy(source, target, function (er) {
if (er) throw er
t.ok(fs.statSync(target).isDirectory(), 'should exist')
var wanted = [
path.join(target, 'bye'),
path.join(target, 'hello')
]
t.ok(fs.statSync(target).isDirectory(), 'should exist')
paths.forEach(function (p) {
wanted.forEach(function (p) {
t.ok(fs.statSync(p), 'should exist')
})
fstream.Reader({ path:target })
.pipe(cop('path'))
.pipe(es.writeArray(function (err, lines) {
t.deepEqual(lines, paths, 'should equal paths')
t.end()
}))
paths(target, function (er, found) {
if (er) throw er
t.deepEqual(found, wanted, 'should have copied all files')
t.end()
})
})

@@ -34,8 +40,6 @@ })

test('teardown', function (t) {
rimraf(target, function (err) {
fs.stat(target, function (err) {
t.ok(!!err, 'should error')
t.end()
})
rimraf(target, function (er) {
if (er) throw er
t.end()
})
})

@@ -1,25 +0,31 @@

var blake = require('../index.js')
, es = require('event-stream')
, path = require('path')
, cop = require('cop')
, fstream = require('fstream')
, test = require('tap').test
, config = require('./config.js')
, source = config.source
, target = config.target
var blake = require('../')
var common = require('./lib/common')
var cop = require('cop')
var es = require('event-stream')
var fstream = require('fstream')
var path = require('path')
var test = require('tap').test
var wanted = [
path.join(target, 'index.html')
]
var source = common.source(__dirname)
var target = common.freshTarget()
test('files', function (t) {
var p = path.resolve(source, 'data')
var s = blake.files(p)
t.plan(1)
s.on('data', function (chunk) {
var wanted = path.resolve(p, 'index.md')
t.is(chunk, wanted)
})
})
test('read array of filenames', function (t) {
var filenames = [
path.join(source, 'data', 'index.md')
]
var filenames = [path.join(source, 'data', 'index.md')]
es.readArray(filenames)
.pipe(blake(source, target))
.pipe(es.writeArray(function (err, array) {
t.equal(array.length, wanted.length)
t.deepEqual(array, wanted)
.pipe(es.writeArray(function (er, names) {
if (er) throw er
var wanted = [path.join(target, 'index.html')]
t.is(names.length, wanted.length)
t.deepEqual(names, wanted)
t.end()

@@ -30,9 +36,10 @@ }))

test('files written', function (t) {
fstream.Reader({ path:target })
fstream.Reader({ path: target })
.pipe(cop('path'))
.pipe(es.writeArray(function (err, lines) {
.pipe(es.writeArray(function (er, lines) {
if (er) throw er
var wanted = [path.join(target, 'index.html')]
t.deepEqual(lines, wanted, 'should equal paths')
t.end()
}))
t.end()
})

@@ -0,24 +1,26 @@

var blake = require('../')
var common = require('./lib/common')
var path = require('path')
var readFileSync = require('fs').readFileSync
var string_decoder = require('string_decoder')
var test = require('tap').test
, item = require('../lib/item').item
, header = require('../lib/item').header
, strftime = require('prettydate').strftime
, path = require('path')
, readFileSync = require('fs').readFileSync
, config = require('./config.js')
, target = config.target
, props = config.props
, paths = props.paths
var source = common.source(__dirname)
var target = common.freshTarget()
var config = blake.conf(source, target)
var paths = config.paths
test('header', function (t) {
var f = blake.header
var file = path.join(paths.data, 'index.md')
t.throws(function () {
header(null, file, paths)
f(null, file, paths)
})
t.throws(function () {
var data = '{"title":"Title"}'
header(data, file, paths)
f(data, file, paths)
})
t.doesNotThrow(function () {
var data = '{"template":"x", "name":"y"}'
header(data, file, paths)
f(data, file, paths)
})

@@ -30,5 +32,7 @@ t.end()

var filename = path.join(paths.data, 'index.md')
, file = readFileSync(filename)
, it = item(props, filename, file.toString())
var buf = readFileSync(filename)
var str = new string_decoder.StringDecoder().write(buf)
var it = blake.item(config, filename, str)
var h = it.header

@@ -45,8 +49,5 @@ t.equal(h.template, 'index.jade')

t.same(it.date, h.date)
t.equal(it.pubDate, strftime(h.date, '%a, %d %b %Y %T %z'))
t.equal(it.dateString, h.date.toDateString())
t.ok(it.template instanceof Buffer, 'should be instance of Buffer')
t.equal(it.title, h.title)
t.equal(it.link, 'index.html')
t.ok(typeof it.bake === 'function', 'should be function type')
t.ok(typeof it.view === 'function', 'should be function type')
t.equal(it.name, 'index.html')

@@ -53,0 +54,0 @@ t.equal(it.path, path.join(target, h.name))

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

var blake = require('../')
var common = require('./lib/common')
var path = require('path')
var test = require('tap').test
, path = require('path')
, read = require('../lib/read').readItems
, config = require('./config')
, props = config.props
var source = common.source(__dirname)
var target = common.freshTarget()
var b = blake(source, target)
test('read file', function (t) {
var file = path.join(props.paths.data, 'index.md')
read(props)(file, function (err, item) {
var p = path.resolve(source, 'data', 'index.md')
b.items(p, function (er, item) {
if (er) throw er
t.ok(item.header, 'should have header')

@@ -17,3 +21,5 @@ t.ok(item.body, 'should have body')

test('read directory', function (t) {
read(props)(props.paths.data, function (err, items) {
var p = path.resolve(source, 'data')
b.items(p, function (er, items) {
if (er) throw er
items.forEach(function (item) {

@@ -20,0 +26,0 @@ t.ok(item.header, 'should have header')

Sorry, the diff of this file is not supported yet

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