diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..4fe2b0e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +node_js: +- '7' +- '8' +sudo: false +language: node_js +env: + - CXX=g++-4.8 +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-4.8 +script: npm run test \ No newline at end of file diff --git a/example/index.js b/example/index.js index 7cb539f..fc6fff1 100644 --- a/example/index.js +++ b/example/index.js @@ -1,14 +1,16 @@ +var nanocontent = require('../') var css = require('sheetify') -var hypha = require('hypha') var choo = require('choo') -css('./src/design/index.js') -var site = hypha.readSiteSync('./content', { +var site = nanocontent.readSiteSync('./content', { parent: '/content' }) var app = choo() +// design +css('./src/design/index.js') + // content and routes app.use(require('./src/stores/content')(site)) app.route('*', require('./src/views/notfound')) diff --git a/example/package.json b/example/package.json index c23f003..9cfbd07 100644 --- a/example/package.json +++ b/example/package.json @@ -1,5 +1,5 @@ { - "name": "hypha-example", + "name": "nanocontent-example", "version": "1.0.0", "description": "nice", "main": "index.js", @@ -10,13 +10,13 @@ "author": "", "license": "ISC", "dependencies": { - "bel": "^5.1.3", + "bel": "^6.0.0", "choo": "^6.5.1", "gr8": "^3.1.3", "markdown-it": "^8.4.0", "object-keys": "^1.0.11", - "object-values": "^1.0.0", - "sheetify": "^6.2.0", + "object-values": "^2.0.0", + "sheetify": "^7.3.2", "xtend": "^4.0.1" }, "devDependencies": { diff --git a/greenkeeper.json b/greenkeeper.json new file mode 100644 index 0000000..798c8fa --- /dev/null +++ b/greenkeeper.json @@ -0,0 +1,10 @@ +{ + "groups": { + "default": { + "packages": [ + "example/package.json", + "package.json" + ] + } + } +} diff --git a/lib/readFile.js b/lib/readFile.js index 61cb880..31d220e 100644 --- a/lib/readFile.js +++ b/lib/readFile.js @@ -1,7 +1,13 @@ +var promisify = require('promisify-node') var assert = require('assert') +var smarkt = require('smarkt') +var xtend = require('xtend') +var path = require('path') var utilFile = require('../utils/file') +var utilPage = require('../utils/page') var readPage = require('./readPage') +var defaults = require('./defaults') module.exports = readFile @@ -10,9 +16,40 @@ async function readFile (pathFile, opts) { assert.equal(typeof opts, 'object', 'arg2: opts must be type object') assert.equal(typeof opts.fs, 'object', 'arg2: opts.fs must be type object') - if (!utilFile.isFile(pathFile)) { - return readPage(pathFile, opts) - } else { - return false + // pages + if (utilPage.isPage(pathFile)) return readPage(pathFile, opts) + + var fs = opts.fs + var parse = typeof opts.parse === 'function' ? opts.parse : smarkt.parse + var fileIndex = opts.file || defaults.file + var fileExtname = path.extname(fileIndex).toLowerCase() + var filetypes = opts.filetypes || defaults.filetypes + var pathRoot = opts.pathRoot || '' + var encoding = opts.encoding || defaults.encoding + var fileParsed = utilFile.getFileMeta({ + pathFile: pathFile, + pathRoot: pathRoot, + filetypes: filetypes, + pathSource: opts.source, + pathSiteParent: opts.parent + }) + + // skip text files + if (fileExtname === fileParsed.extension) return false + + try { + var pathMeta = pathFile + fileExtname + var text = isAsync(fs.readFile) + ? await fs.readFile(pathMeta, encoding) + : await promisify(fs.readFile)(pathMeta, encoding) + return xtend(parse(text), fileParsed) + } catch (err) { + // console.log(fileParsed.filename, err.message) + if (fileParsed.filename) return Promise.resolve(fileParsed) + else return Promise.resolve(false) } } + +function isAsync (fn) { + return fn.constructor.name === 'AsyncFunction' +} diff --git a/lib/readFileSync.js b/lib/readFileSync.js index af09883..d38a67b 100644 --- a/lib/readFileSync.js +++ b/lib/readFileSync.js @@ -1,7 +1,12 @@ var assert = require('assert') +var smarkt = require('smarkt') +var xtend = require('xtend') +var path = require('path') var readPageSync = require('./readPageSync') var utilFile = require('../utils/file') +var utilPage = require('../utils/page') +var defaults = require('./defaults') module.exports = readFileSync @@ -10,9 +15,32 @@ function readFileSync (pathFile, opts) { assert.equal(typeof opts, 'object', 'arg2: opts must be type object') assert.equal(typeof opts.fs, 'object', 'arg2: opts.fs must be type object') - if (!utilFile.isFile(pathFile)) { - return readPageSync(pathFile, opts) - } else { - return false + // page + if (utilPage.isPage(pathFile)) return readPageSync(pathFile, opts) + + var fs = opts.fs + var parse = typeof opts.parse === 'function' ? opts.parse : smarkt.parse + var fileIndex = opts.file || defaults.file + var fileExtname = path.extname(fileIndex).toLowerCase() + var filetypes = opts.filetypes || defaults.filetypes + var pathRoot = opts.pathRoot || '' + var encoding = opts.encoding || defaults.encoding + var fileParsed = utilFile.getFileMeta({ + pathFile: pathFile, + pathRoot: pathRoot, + filetypes: filetypes, + pathSiteParent: opts.parent + }) + + // skip text files + if (fileExtname === fileParsed.extension) return false + + try { + var pathMeta = pathFile + fileExtname + var text = fs.readFileSync(pathMeta, encoding) + return xtend(parse(text), fileParsed) + } catch (err) { + if (fileParsed.filename) return fileParsed + else return false } } diff --git a/lib/readFiles.js b/lib/readFiles.js index 2f692ab..ef76649 100644 --- a/lib/readFiles.js +++ b/lib/readFiles.js @@ -23,7 +23,13 @@ async function readFiles (files, pathSite, opts) { async function read (pathFile) { var content = await readFile(pathFile, opts) if (content && !content.name.match(defaults.ignore)) { - output[content.url] = content + var key = content.url + + // temp cleanup + content.url = content.extension ? content.path : content.url + delete content.path + + output[key] = content } return content } diff --git a/lib/readFilesSync.js b/lib/readFilesSync.js index 9e4fa9c..eb89d98 100644 --- a/lib/readFilesSync.js +++ b/lib/readFilesSync.js @@ -21,7 +21,13 @@ function readFilesSync (files, pathSite, opts) { if (typeof opts.onFile === 'function') opts.onFile(pathFile) var content = readFileSync(pathFile, opts) if (content && !content.name.match(defaults.ignore)) { - output[content.url] = content + var key = content.url + + // temp cleanup + content.url = content.extension ? content.path : content.url + delete content.path + + output[key] = content } }) diff --git a/lib/readPage.js b/lib/readPage.js index 3bcee63..daca18a 100644 --- a/lib/readPage.js +++ b/lib/readPage.js @@ -18,9 +18,8 @@ async function readPage (pathPage, opts) { var fs = opts.fs.url ? opts.fs : pify(opts.fs) // web api or node var parse = typeof opts.parse === 'function' ? opts.parse : smarkt.parse var fileIndex = opts.file || defaults.file - var fileExtname = path.extname(fileIndex) - var filetypes = opts.filetypes || defaults.filetypes var pathRoot = opts.pathRoot || '' + var filetypes = opts.filetypes || defaults.filetypes var pathUrl = utilFile.formatUrl(pathPage, pathRoot, opts.parent) var encoding = opts.encoding || defaults.encoding var content = await getContent() @@ -39,22 +38,20 @@ async function readPage (pathPage, opts) { pages: pages }) - async function getChildren () { + async function getContent () { try { - return await fs.readdir(pathPage) + var content = await fs.readFile(slash(path.join(pathPage, fileIndex)), encoding) + return parse(content) } catch (err) { - return [] + return '' } } - async function getContent () { + async function getChildren () { try { - var content - content = await fs.readFile(slash(path.join(pathPage, fileIndex)), encoding) - content = parse(content) - return content + return await fs.readdir(pathPage) } catch (err) { - return '' + return [] } } @@ -73,22 +70,8 @@ async function readPage (pathPage, opts) { pathSiteParent: opts.parent }) - try { - var fileMeta = pathFile + fileExtname - var pathMeta = path.join(pathPage, fileMeta) - var text = await fs.readFile(pathMeta, encoding) - // set - result[fileParsed.filename] = xtend(parse(text), fileParsed) - files.splice(files.indexOf(fileMeta), 1) - // cleanup - delete result[fileMeta] - return text - } catch (err) { - if (fileParsed.filename) { - result[fileParsed.filename] = fileParsed - } - return Promise.resolve() - } + if (!utilFile.filterFile(pathFile, fileIndex)) return false + else result[fileParsed.filename] = fileParsed.url } } @@ -102,7 +85,7 @@ async function readPage (pathPage, opts) { pathSiteParent: opts.parent }) - if (fileParsed.name) result[fileParsed.name] = fileParsed + if (fileParsed.name) result[fileParsed.name] = fileParsed.url return result }, {}) } diff --git a/lib/readPageSync.js b/lib/readPageSync.js index e81901b..8968b9d 100644 --- a/lib/readPageSync.js +++ b/lib/readPageSync.js @@ -17,7 +17,6 @@ function readPageSync (pathPage, opts) { var fs = opts.fs var parse = typeof opts.parse === 'function' ? opts.parse : smarkt.parse var fileIndex = opts.file || defaults.file - var fileExtname = path.extname(fileIndex) var filetypes = opts.filetypes || defaults.filetypes var pathRoot = opts.pathRoot || '' var pathUrl = utilFile.formatUrl(pathPage, pathRoot, opts.parent) @@ -47,10 +46,8 @@ function readPageSync (pathPage, opts) { function getContent () { try { - var content - content = fs.readFileSync(slash(path.join(pathPage, fileIndex)), encoding) - content = parse(content) - return content + var content = fs.readFileSync(slash(path.join(pathPage, fileIndex)), encoding) + return parse(content) } catch (err) { return '' } @@ -66,20 +63,8 @@ function readPageSync (pathPage, opts) { pathSiteParent: opts.parent }) - try { - var fileMeta = pathFile + fileExtname - var text = fs.readFileSync(slash(path.join(pathPage, fileMeta)), encoding) - // set - result[fileParsed.filename] = xtend(parse(text), fileParsed) - files.splice(files.indexOf(fileMeta), 1) - // cleanup - delete result[fileMeta] - } catch (err) { - if (fileParsed.filename) { - result[fileParsed.filename] = fileParsed - } - } - + if (!utilFile.filterFile(pathFile, fileIndex)) return false + else result[fileParsed.filename] = fileParsed.url return result }, { }) } @@ -95,7 +80,7 @@ function readPageSync (pathPage, opts) { pathSiteParent: opts.parent }) - if (fileParsed.name) result[fileParsed.name] = fileParsed + if (fileParsed.name) result[fileParsed.name] = fileParsed.url return result }, { }) } diff --git a/package.json b/package.json index e448511..0255394 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "nanocontent", - "version": "0.4.5", + "version": "1.0.0-next3", "description": "read a directory of content into an object", "main": "index.js", "scripts": { - "test": "standard --fix; ava" + "test": "standard; ava" }, "keywords": [], "author": "Jon-Kyle (http://jon-kyle.com)", @@ -20,17 +20,18 @@ "dependencies": { "glob": "^7.1.2", "js-yaml": "^3.10.0", - "normalize-path": "^2.1.1", + "normalize-path": "^3.0.0", "object-keys": "^1.0.11", - "object-values": "^1.0.0", + "object-values": "^2.0.0", "pify": "^3.0.0", + "promisify-node": "^0.4.0", "smarkt": "0.0.6", - "static-module": "^1.5.0", + "static-module": "^2.2.5", "through2": "^2.0.3", "xtend": "^4.0.1" }, "devDependencies": { "ava": "^0.25.0", - "standard": "^10.0.3" + "standard": "^11.0.1" } } diff --git a/readme.md b/readme.md index 06f696e..c9726c7 100644 --- a/readme.md +++ b/readme.md @@ -63,12 +63,13 @@ var site = nanocontent.readSiteSync('./content') Each directory becomes a path containing a sub-object of the content in your text file. -``` +```js { '/': { }, '/about': { }, '/blog': { }, '/blog/30-01-19-technopastoral': { } + '/blog/30-01-19-technopastoral/header.jpg': { } } ``` diff --git a/test.js b/test.js index 8449756..cf642b7 100644 --- a/test.js +++ b/test.js @@ -1,38 +1,38 @@ var test = require('ava') -var hypha = require('.') +var nanocontent = require('.') test('readPageSync works', function (t) { - var page = hypha.readPageSync('example/content/about') + var page = nanocontent.readPageSync('example/content/about') t.is(page.title, 'About') t.is(page.view, 'custom') }) test('readPage works', async function (t) { - var page = await hypha.readPage('example/content/about') + var page = await nanocontent.readPage('example/content/about') t.is(page.title, 'About') t.is(page.view, 'custom') }) test('readPageSync and readPage outputs are the same', async function (t) { - var syncPage = hypha.readPageSync('example/content/about') - var asyncPage = await hypha.readPage('example/content/about') + var syncPage = nanocontent.readPageSync('example/content/about') + var asyncPage = await nanocontent.readPage('example/content/about') t.deepEqual(syncPage, asyncPage) }) test('readSiteSync works', function (t) { - var site = hypha.readSiteSync('example/content') + var site = nanocontent.readSiteSync('example/content') t.is(site['/example/content'].title, 'Example') t.is(site['/example/content/about'].title, 'About') }) test('readSiteSync and readSite outputs are the same', async function (t) { - var syncSite = hypha.readSiteSync('example/content') - var asyncSite = await hypha.readSite('example/content') + var syncSite = nanocontent.readSiteSync('example/content') + var asyncSite = await nanocontent.readSite('example/content') t.deepEqual(syncSite, asyncSite) }) test('readSiteSync and readSite outputs are the same with parent option', async function (t) { - var syncSite = hypha.readSiteSync('example/content', { parent: true }) - var asyncSite = await hypha.readSite('example/content', { parent: true }) + var syncSite = nanocontent.readSiteSync('example/content', { parent: true }) + var asyncSite = await nanocontent.readSite('example/content', { parent: true }) t.deepEqual(syncSite, asyncSite) }) diff --git a/transform.js b/transform.js index be02b01..f075b4e 100644 --- a/transform.js +++ b/transform.js @@ -2,7 +2,7 @@ var staticModule = require('static-module') var through = require('through2') var path = require('path') -var hypha = require('.') +var nanocontent = require('.') module.exports = transform @@ -15,13 +15,13 @@ function transform (filename) { } var sm = staticModule({ - hypha: { + nanocontent: { readPageSync: function (pathPage, opts) { opts = opts || { } opts.pathRoot = opts.pathRoot || vars.__dirname var pathDir = path.isAbsolute(pathPage) ? pathPage : path.join(vars.__dirname, pathPage) - var pageSync = hypha.readPageSync(pathDir, opts) + var pageSync = nanocontent.readPageSync(pathDir, opts) var stream = through() stream.push(JSON.stringify(pageSync, { }, 2)) @@ -37,7 +37,7 @@ function transform (filename) { } var pathDir = path.isAbsolute(pathSite) ? pathSite : path.join(vars.__dirname, pathSite) - var siteSync = hypha.readSiteSync(pathDir, opts) + var siteSync = nanocontent.readSiteSync(pathDir, opts) var stream = through() stream.push(JSON.stringify(siteSync, { }, 2)) diff --git a/utils/file.js b/utils/file.js index dc1d121..2f1a6c8 100644 --- a/utils/file.js +++ b/utils/file.js @@ -1,6 +1,6 @@ var objectKeys = require('object-keys') -var assert = require('assert') var slash = require('normalize-path') +var assert = require('assert') var path = require('path') module.exports = { @@ -27,8 +27,7 @@ function sortChildren (result, active) { function filterFile (file, index) { if (file === '.DS_Store') return false if (/(^[.#]|(?:__|~)$)/.test(file)) return false - if (file.indexOf(index) >= 0) return false - if (file.indexOf('src') >= 0) return false + if (path.extname(file) === path.extname(index)) return false return true } @@ -49,23 +48,24 @@ function getFileType (extension, filetypes) { } function isFile (pathFile) { - assert.equal(typeof pathFile, 'string', 'enoki: arg1 pathFile must be type string') + assert.equal(typeof pathFile, 'string', 'arg1 pathFile must be type string') return path.extname(pathFile) !== '' } function getFileMeta (opts) { - assert.equal(typeof opts, 'object', 'enoki: arg1 opts must be type object') - assert.equal(typeof opts.pathFile, 'string', 'enoki: arg1 opts.pathFile must be type string') - assert.equal(typeof opts.pathParent, 'string', 'enoki: arg1 opts.pathParent must be type string') - assert.equal(typeof opts.pathRoot, 'string', 'enoki: arg1 opts.pathRoot must be type string') - assert.equal(typeof opts.filetypes, 'object', 'enoki: arg1 opts.filetypes must be type string') + assert.equal(typeof opts, 'object', 'arg1 opts must be type object') + assert.equal(typeof opts.pathFile, 'string', 'arg1 opts.pathFile must be type string') + assert.equal(typeof opts.pathRoot, 'string', 'arg1 opts.pathRoot must be type string') + assert.equal(typeof opts.filetypes, 'object', 'arg1 opts.filetypes must be type string') var output = { } var ext = path.extname(opts.pathFile) + var pathFile = slash(path.join(opts.pathParent || '', opts.pathFile)) + output.name = path.basename(opts.pathFile, ext) - output.path = formatUrl(path.join('/', opts.pathParent, '/', opts.pathFile), opts.pathRoot) - output.url = formatUrl(path.join('/', opts.pathParent, '/', opts.pathFile), opts.pathRoot, opts.pathSiteParent) - output.source = opts.pathSource ? (opts.pathSource + output.path) : output.path + output.path = formatUrl(pathFile, opts.pathRoot) + output.url = formatUrl(pathFile, opts.pathRoot, opts.pathSiteParent) + // output.source = opts.pathSource ? (opts.pathSource + output.path) : output.path if (ext) { output.extension = ext.toLowerCase() diff --git a/utils/page.js b/utils/page.js index e69de29..37eca7a 100644 --- a/utils/page.js +++ b/utils/page.js @@ -0,0 +1,11 @@ +var assert = require('assert') +var path = require('path') + +module.exports = { + isPage: isPage +} + +function isPage (pathPage) { + assert.equal(typeof pathPage, 'string', 'arg1 pathPage must be type string') + return path.extname(pathPage) === '' +}