+21
-0
@@ -6,2 +6,23 @@ # Change Log | ||
| <a name="current-release"></a> | ||
| # Version 2.0.1 (Sat, 08 Apr 2017 21:27:05 GMT) | ||
| * [0eea4eb](https://github.com/bootprint/customize/commit/0eea4eb) Fix files-helpers for directories with subdirectories - Nils Knappmeier | ||
| # Version 2.0.0 (Sat, 08 Apr 2017 20:58:34 GMT) | ||
| Breaking changes: | ||
| * Support for node version below 6 has been dropped. | ||
| Other changes: | ||
| * [09331ce](https://github.com/bootprint/customize/commit/09331ce) Update documentation - Nils Knappmeier | ||
| * [69cbd21](https://github.com/bootprint/customize/commit/69cbd21) Remove obsolete precommit-hook (and husky) - Nils Knappmeier | ||
| * [7f7e1d4](https://github.com/bootprint/customize/commit/7f7e1d4) Fix tests, remove dependency on "m-io" in favour of "glob" - Nils Knappmeier | ||
| * [94a8038](https://github.com/bootprint/customize/commit/94a8038) Remove dependency on "q" (now completely) - Nils Knappmeier | ||
| * [631ec00](https://github.com/bootprint/customize/commit/631ec00) Remove obsolete "trace" from dev-dependencies - Nils Knappmeier | ||
| * [2f91605](https://github.com/bootprint/customize/commit/2f91605) Customize now uses .mergeWith, not .merge - Nils Knappmeier | ||
| * [a5c5e13](https://github.com/bootprint/customize/commit/a5c5e13) docs(readme): add Greenkeeper badge - greenkeeper[bot] | ||
| * [18c137a](https://github.com/bootprint/customize/commit/18c137a) chore(package): update dependencies - greenkeeper[bot] | ||
| # Version 2.0.0-alpha1 (Fri, 24 Mar 2017 15:36:34 GMT) | ||
@@ -8,0 +29,0 @@ |
+26
-41
| /*! | ||
| * customize <https://github.com/nknapp/ride-over> | ||
| * customize <https://github.com/bootprint/customize> | ||
| * | ||
| * Copyright (c) 2015 Nils Knappmeier. | ||
| * Copyright (c) 2017 Nils Knappmeier. | ||
| * Released under the MIT license. | ||
@@ -14,4 +14,4 @@ */ | ||
| var fs = require('fs') | ||
| var Q = require('q') | ||
| var qfs = require('m-io/fs') | ||
| var util = require('./lib/util') | ||
| var glob = require('glob') | ||
@@ -42,18 +42,28 @@ module.exports = { | ||
| var _options = options || {} | ||
| var result = qfs.listTree(directoryPath, isFileMatching(directoryPath, _options.glob)) | ||
| .then(function (filePaths) { | ||
| return filePaths.reduce(function (result, filePath) { | ||
| var key = path.relative(directoryPath, filePath).split(path.sep).join('/') | ||
| var value = leaf(lazy(function () { | ||
| // Collect all files | ||
| var result = util.asPromise((cb) => glob(_options.glob || '**', {cwd: directoryPath, mark: true}, cb)) | ||
| .then(function (relativePaths) { | ||
| var set = relativePaths | ||
| // Ignore directories | ||
| .filter((relativePath) => !relativePath.match(/\/$/)) | ||
| // Convert to a set based on relative paths | ||
| // (i.e. {'dir/file.txt': 'dir/file.txt'} | ||
| .reduce((set, relativePath) => { | ||
| set[relativePath] = relativePath | ||
| return set | ||
| }, {}) | ||
| // Create lazy promises (only resolve when .then() is called) acting | ||
| // as leafs (do not dive inside when merging) | ||
| return util.mapValues(set, (relativePath) => { | ||
| var fullPath = path.resolve(directoryPath, relativePath) | ||
| return leaf(lazy(() => { | ||
| return { | ||
| path: path.relative(process.cwd(), filePath), | ||
| path: path.relative(process.cwd(), fullPath), | ||
| contents: _options.stream | ||
| ? fs.createReadStream(filePath, {encoding: _options.encoding}) | ||
| : Q.ninvoke(fs, 'readFile', filePath, {encoding: _options.encoding}) | ||
| ? fs.createReadStream(fullPath, {encoding: _options.encoding}) | ||
| : util.asPromise((cb) => fs.readFile(fullPath, {encoding: _options.encoding}, cb)) | ||
| } | ||
| })) | ||
| result[key] = value | ||
| return result | ||
| }, {}) | ||
| }) | ||
| }) | ||
@@ -82,26 +92,1 @@ result.watch = directoryPath | ||
| } | ||
| /** | ||
| * Returns a guard function for list tree, that checks whether a file is a real file (not a directory) | ||
| * and whether the path relative to a root-dir matches a glob pattern | ||
| * @param glob | ||
| * @param rootDir | ||
| * @returns {Function} | ||
| * @private | ||
| */ | ||
| function isFileMatching (rootDir, glob) { | ||
| var mm = null | ||
| if (glob) { | ||
| // Save minimatch class, if glob is provided | ||
| var Minimatch = require('minimatch').Minimatch | ||
| mm = new Minimatch(glob) | ||
| } | ||
| return function (filePath, stat) { | ||
| if (!stat.isFile()) { | ||
| return false | ||
| } | ||
| // Must match the glob, if provided | ||
| return !mm || mm.match(path.relative(rootDir, filePath)) | ||
| } | ||
| } |
+19
-9
@@ -15,4 +15,4 @@ /*! | ||
| var debugState = require('debug')('customize:state') | ||
| var Q = require('q') | ||
| var deep = require('deep-aplus')(Q.Promise) | ||
| var debugVersions = require('debug')('customize:versions') | ||
| var deep = require('deep-aplus')(Promise) | ||
| var mergeWith = require('lodash.mergewith') | ||
@@ -97,7 +97,7 @@ | ||
| if (debugState.enabled) { | ||
| deep(_config).done(function (config) { | ||
| deep(_config).then(function (config) { | ||
| debugState('New configuration', config) | ||
| }, /* istanbul ignore next */ | ||
| function (e) { | ||
| console.error('Error while debug-logging the built configuration ' + e.stack) | ||
| console.error('Error while debug-logging the built configuration ' + e.stack) // eslint-disable-line no-console | ||
| }) | ||
@@ -195,3 +195,3 @@ } | ||
| return Q(engineConf).then(function (engineConf) { | ||
| return Promise.resolve(engineConf).then(function (engineConf) { | ||
| if (engine.schema) { | ||
@@ -247,3 +247,3 @@ debug('Validating schema for ', engineName) | ||
| if (customizeModule.package) { | ||
| console.log('Loading', customizeModule.package.name, customizeModule.package.version) | ||
| debugVersions('Loading', customizeModule.package.name, customizeModule.package.version) | ||
| _metadata.config.modules.push(customizeModule.package) | ||
@@ -291,3 +291,3 @@ } | ||
| * @param {object=} options optional paramters | ||
| * @param {string=} options.onlyEngine optionally the name of an engine, if only a single engine should | ||
| * @param {string=} options.onlyEngine the name of an engine if only a single engine should | ||
| * be executed | ||
@@ -369,4 +369,4 @@ * @return {Promise<object>} an object containing on property per registered engine | ||
| // Merge values resolving promises, if they are not leaf-promises | ||
| if (Q.isPromiseAlike(a) || Q.isPromiseAlike(b)) { | ||
| return Q.all([a, b]).spread(function (_a, _b) { | ||
| if (isPromiseAlike(a) || isPromiseAlike(b)) { | ||
| return Promise.all([a, b]).then(function ([_a, _b]) { | ||
| // Merge the promise results | ||
@@ -378,1 +378,11 @@ return mergeWith({}, {x: _a}, {x: _b}, customOverrider).x | ||
| } | ||
| /** | ||
| * Check if this is something like a promise (taken from the Q-module) | ||
| * @param {*} obj the object to check for being a promise | ||
| * @returns {boolean} true, if the object is a promise | ||
| * @private | ||
| */ | ||
| function isPromiseAlike (obj) { | ||
| return obj === Object(obj) && typeof obj.then === 'function' | ||
| } |
+15
-41
@@ -1,48 +0,22 @@ | ||
| /* | ||
| This file is take from nailguns q-lazy package at | ||
| https://raw.githubusercontent.com/nailgun/q-lazy/master/index.js | ||
| The MIT License (MIT) | ||
| Copyright (c) 2013-2014 Dmitry Bashkatov | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in | ||
| all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| THE SOFTWARE. | ||
| /** | ||
| * Create a promise that resolves to the return value of `fn`. | ||
| * `fn` is only called, if the `.then`-method of the promise is called. | ||
| * And it is called only once. | ||
| * @param fn | ||
| */ | ||
| 'use strict' | ||
| var Q = require('q') | ||
| module.exports = function (fn) { | ||
| var deferred = Q.defer() | ||
| var promise = deferred.promise | ||
| var initiated = false | ||
| var then = promise.then | ||
| var _resolve, _reject, innerPromise | ||
| var promise = new Promise((resolve, reject) => { | ||
| _resolve = resolve | ||
| _reject = reject | ||
| }) | ||
| var oldThen = promise.then | ||
| promise.then = function () { | ||
| if (!initiated) { | ||
| Q(fn()).then(deferred.resolve, deferred.reject, deferred.notify) | ||
| initiated = true | ||
| if (!innerPromise) { | ||
| innerPromise = Promise.resolve().then(fn) | ||
| } | ||
| return then.apply(promise, arguments) | ||
| innerPromise.then(_resolve, _reject) | ||
| return oldThen.apply(promise, arguments) | ||
| } | ||
| return promise | ||
| } |
+1
-2
@@ -7,3 +7,2 @@ /*! | ||
| */ | ||
| var Q = require('q') | ||
@@ -17,3 +16,3 @@ /** | ||
| module.exports = function leaf (promiseOrValue) { | ||
| var result = Q(promiseOrValue) | ||
| var result = Promise.resolve(promiseOrValue) | ||
| result._customize_custom_overrider = function (a, b) { | ||
@@ -20,0 +19,0 @@ // Leafs are overridden completely by the newer version |
+27
-4
@@ -9,6 +9,7 @@ /*! | ||
| module.exports = { | ||
| mapValues: mapValues, | ||
| identity: identity, | ||
| isString: isString, | ||
| constant: constant | ||
| mapValues, | ||
| identity, | ||
| isString, | ||
| constant, | ||
| asPromise | ||
| } | ||
@@ -63,1 +64,23 @@ | ||
| } | ||
| /** | ||
| * Return a promise for a functon with node-style callback | ||
| * Usage: | ||
| * | ||
| * ``` | ||
| * asPromise((callback) => fs.readFile('name', callback)) | ||
| * `` | ||
| * ` | ||
| * @param {function(callback:function(Error, any))} fn the function to generate the promise from | ||
| * @returns {Promise<any>} | ||
| */ | ||
| function asPromise (fn) { | ||
| return new Promise((resolve, reject) => { | ||
| fn((err, result) => { | ||
| if (err) { | ||
| return reject(err) | ||
| } | ||
| resolve(result) | ||
| }) | ||
| }) | ||
| } |
+19
-19
| { | ||
| "name": "customize", | ||
| "version": "2.0.0-alpha1", | ||
| "version": "2.0.1", | ||
| "description": "A simple framework to create customizable engines", | ||
@@ -20,9 +20,10 @@ "repository": { | ||
| "scripts": { | ||
| "test": "mocha && standard", | ||
| "format": "standard --fix", | ||
| "lint": "eslint --fix .", | ||
| "test": "mocha && npm run lint", | ||
| "coverage": "istanbul cover ./node_modules/.bin/_mocha", | ||
| "postcoverage": "istanbul check-coverage coverage/coverage.json --statements 100", | ||
| "prethought": "thought --version || npm -g install thought", | ||
| "thought": "thought run -a", | ||
| "prethoughtcheck": "thought --version || npm -g install thought", | ||
| "thoughtcheck": "thought check-engines", | ||
| "version": "thoughtful changelog -o -a && npm run thought", | ||
| "preversion": "npm run thoughtcheck" | ||
| "preversion": "thought --version || npm -g install thought", | ||
| "version": "thoughtful changelog -o -a && npm run thought" | ||
| }, | ||
@@ -32,7 +33,5 @@ "dependencies": { | ||
| "deep-aplus": "^1.0.4", | ||
| "glob": "^7.1.1", | ||
| "jsonschema": "^1.0.2", | ||
| "lodash.mergewith": "^4.6.0", | ||
| "m-io": "^0.5.0", | ||
| "minimatch": "^3.0.0", | ||
| "q": "^1.4.1" | ||
| "lodash.mergewith": "^4.6.0" | ||
| }, | ||
@@ -50,7 +49,2 @@ "standard": { | ||
| "keywords": [], | ||
| "config": { | ||
| "ghooks": { | ||
| "pre-commit": "standard" | ||
| } | ||
| }, | ||
| "devDependencies": { | ||
@@ -61,11 +55,17 @@ "chai": "^3.3.0", | ||
| "dirty-chai": "^1.2.2", | ||
| "ghooks": "^2.0.0", | ||
| "eslint": "^3.17.1", | ||
| "eslint-config-standard": "^7.0.1", | ||
| "eslint-plugin-import": "^2.2.0", | ||
| "eslint-plugin-mocha": "^4.8.0", | ||
| "eslint-plugin-node": "^4.2.1", | ||
| "eslint-plugin-promise": "^3.5.0", | ||
| "eslint-plugin-standard": "^2.1.1", | ||
| "istanbul": "^0.4.5", | ||
| "mocha": "^3.2.0", | ||
| "standard": "^9.0.2", | ||
| "stream-to-string": "^1.1.0", | ||
| "thought": "^1.1.0", | ||
| "thought-plugin-jsdoc": "^1.0.0", | ||
| "thoughtful-release": "^0.3.0", | ||
| "trace": "^2.3.0", | ||
| "trace-and-clarify-if-possible": "^1.0.0" | ||
| } | ||
| } |
+44
-35
@@ -14,4 +14,4 @@ # customize | ||
| At its core, it uses [lodash#merge](https://lodash.com/docs#merge) to merge configurations, | ||
| but it uses a customizer-function that also supports promises and custom overrider functions | ||
| At its core, it uses [lodash#mergeWith](https://lodash.com/docs#mergeWith) to merge configurations. | ||
| It uses a customizer-function that supports promises and custom overrider functions | ||
| attached to the object. | ||
@@ -43,11 +43,11 @@ | ||
| <pre><code> | ||
| ├─┬ dir1/ | ||
| │ ├── a.md | ||
| │ └── b.md | ||
| ├─┬ dir2/ | ||
| │ └── a.md | ||
| ├── engine-concat-files.js | ||
| ├── example-buildConfig.js | ||
| ├── example1.js | ||
| └── example2.js | ||
| ├─┬ <a href="examples/file-example/dir1">dir1/</a> | ||
| │ ├── <a href="examples/file-example/dir1/a.md">a.md</a> | ||
| │ └── <a href="examples/file-example/dir1/b.md">b.md</a> | ||
| ├─┬ <a href="examples/file-example/dir2">dir2/</a> | ||
| │ └── <a href="examples/file-example/dir2/a.md">a.md</a> | ||
| ├── <a href="examples/file-example/engine-concat-files.js">engine-concat-files.js</a> | ||
| ├── <a href="examples/file-example/example-buildConfig.js">example-buildConfig.js</a> | ||
| ├── <a href="examples/file-example/example1.js">example1.js</a> | ||
| └── <a href="examples/file-example/example2.js">example2.js</a> | ||
| </code></pre> | ||
@@ -59,3 +59,3 @@ | ||
| concatenates the contents of all files in a directory. We put this engine into | ||
| the file `engine-concat-files.js` | ||
| the file `engine-concat-files.js` | ||
@@ -131,3 +131,3 @@ ```js | ||
| write such files to disk in a node environment. In order to this to work, | ||
| the contents must either be a string, a buffer or a [raadable stream](https://nodejs.org/api/stream.html#stream_class_stream_readable). | ||
| the contents must either be a string, a buffer or a [readable stream](https://nodejs.org/api/stream.html#stream_class_stream_readable). | ||
| Strings will be stored in `utf-8` encoding. | ||
@@ -150,3 +150,3 @@ | ||
| .buildConfig() | ||
| .done(console.log) | ||
| .then((result) => console.log(result.files)) | ||
| ``` | ||
@@ -161,5 +161,4 @@ | ||
| ```js | ||
| { files: | ||
| { 'a.md': { path: 'dir1/a.md', contents: 'First file (from dir1)' }, | ||
| 'b.md': { path: 'dir1/b.md', contents: 'Second file (from dir1)' } } } | ||
| { 'a.md': { contents: 'First file (from dir1)', path: 'dir1/a.md' }, | ||
| 'b.md': { contents: 'Second file (from dir1)', path: 'dir1/b.md' } } | ||
| ``` | ||
@@ -185,4 +184,3 @@ | ||
| .run() | ||
| .get('files') | ||
| .done(console.log) | ||
| .then((result) => console.log(result.files)) | ||
| ``` | ||
@@ -211,11 +209,11 @@ | ||
| <pre><code> | ||
| ├─┬ dir1/ | ||
| │ ├── a.md | ||
| │ └── b.md | ||
| ├─┬ dir2/ | ||
| │ └── a.md | ||
| ├── engine-concat-files.js | ||
| ├── example-buildConfig.js | ||
| ├── example1.js | ||
| └── example2.js | ||
| ├─┬ <a href="examples/file-example/dir1">dir1/</a> | ||
| │ ├── <a href="examples/file-example/dir1/a.md">a.md</a> | ||
| │ └── <a href="examples/file-example/dir1/b.md">b.md</a> | ||
| ├─┬ <a href="examples/file-example/dir2">dir2/</a> | ||
| │ └── <a href="examples/file-example/dir2/a.md">a.md</a> | ||
| ├── <a href="examples/file-example/engine-concat-files.js">engine-concat-files.js</a> | ||
| ├── <a href="examples/file-example/example-buildConfig.js">example-buildConfig.js</a> | ||
| ├── <a href="examples/file-example/example1.js">example1.js</a> | ||
| └── <a href="examples/file-example/example2.js">example2.js</a> | ||
| </code></pre> | ||
@@ -239,4 +237,3 @@ | ||
| .run() | ||
| .get('files') | ||
| .done(console.log) | ||
| .then((result) => console.log(result.files)) | ||
| ``` | ||
@@ -246,3 +243,3 @@ | ||
| engine's preprocessor, so now we get two objects containing files and their contents | ||
| and those are merged by the [`.merge`-function of the lodash library](https://lodash.com/docs#merge), | ||
| and those are merged by the [`.mergeWith`-function of the lodash library](https://lodash.com/docs#mergeWith), | ||
| so that in the above example, the property `a.md` is replace by the value in the | ||
@@ -281,4 +278,9 @@ second configuration. So the output of this example is | ||
| ### Troubleshooting | ||
| Customize uses the [debug](https://npmjs.com/package/debug) module for debug logging. You can use the following channels to enable debugging: | ||
| * `DEBUG=customize:versions` logs versions of loaded modules (like it was the default in version 1.x) | ||
| * `DEBUG=customize:state` logs the resolved state after a merge | ||
| * `DEBUG=customize:base` logs errors and status changes | ||
@@ -289,2 +291,9 @@ | ||
| ## API-reference | ||
@@ -492,3 +501,3 @@ | ||
| | [options] | <code>object</code> | optional paramters | | ||
| | [options.onlyEngine] | <code>string</code> | optionally the name of an engine, if only a single engine should be executed | | ||
| | [options.onlyEngine] | <code>string</code> | the name of an engine if only a single engine should be executed | | ||
@@ -560,3 +569,3 @@ <a name="module_customize..customize"></a> | ||
| ## License | ||
| # License | ||
@@ -568,8 +577,8 @@ `customize` is published under the MIT-license. | ||
| ## Release-Notes | ||
| # Release-Notes | ||
| For release notes, see [CHANGELOG.md](CHANGELOG.md) | ||
| ## Contributing guidelines | ||
| # Contributing guidelines | ||
| See [CONTRIBUTING.md](CONTRIBUTING.md). |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
53737
4.73%5
-28.57%581
0.35%1
-50%569
1.61%18
50%3
50%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed