New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

customize

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

customize - npm Package Compare versions

Comparing version 0.2.2 to 0.2.3

.thought/partials/api.md.hbs

10

CHANGELOG.md

@@ -5,2 +5,10 @@ # Change Log

## v0.2.3 - 2015-07-17
### Change
* If the input configuration of an engine is a Promise, it is resolved
before passing it to the engine's preprocessor. Inner Promises are not resolved.
## v0.2.2 - 2015-07-15

@@ -25,3 +33,3 @@

### Devel
- Internal renaming of RideOver (this over name) to Customize.
- Internal renaming of RideOver (old name) to Customize.

@@ -28,0 +36,0 @@

@@ -12,5 +12,13 @@ /*!

* The file helper resolves the directory filename to the contents of the included files (promised).
*
*
* @type {function(string,object=): Promise<object<Promise<string>>>}
* @param {string} baseDir the name of the directory
* @return {Promise<object<Promise<string>>>} an object, containing one entry for each file.
* The key of each entry is the path to the file (relative to the baseDir). The value is
* a promise that resolves to the file-contents when the `.then()` method is called.
*
* @function
* @api public
*/
module.exports.files = require('./lib/files')

2

index.js

@@ -101,3 +101,3 @@ /*!

var preprocessor = engine.preprocessConfig || _.identity
return Q(preprocessor(Q(value))).then(function (config) {
return Q(value).then(preprocessor).then(function (config) {
debug('Merging preprocessed config', config)

@@ -104,0 +104,0 @@ return config

{
"name": "customize",
"version": "0.2.2",
"version": "0.2.3",
"description": "A simple framework to create customizable engines",

@@ -5,0 +5,0 @@ "repository": {

@@ -24,5 +24,195 @@ # customize

## Usage
The following example should demonstrate the usage of Customize and the `files`
io-helper. Consider the following file tree
<pre><code>file-example/
├── dir1/
│ ├── a.md
│ └── b.md
├── dir2/
│ └── a.md
├── engine-concat-files.js
├── example-build.js
├── example1.js
└── example2.js</code></pre>
### Creating an engine
The first thing we need, is an engine. For now, we create an engine that just
concatenates the contents of all files in a directory. We put this engine into
the file `engine-concat-files.js`
```js
var files = require('customize/helpers-io').files
module.exports = {
// Initial configuration when registering the engine.
defaultConfig: null,
// This function is called for any `.merge` input.
// It converts the input into its mergable form
preprocessConfig: function (config) {
return files(config)
},
// Runs the engine with a resolved configuration.
// The config contains no Promises anymore.
run: function (config) {
var result = ''
for (var filename in config) {
if (config.hasOwnProperty(filename)) {
result += config[filename].contents + '\n'
}
}
return result
}
}
```
* The engine provides an empty default configuration. This configuration is used
as long as no `.merge` and `.load` function is called.
* The `preprocessor` of the engine assumes that the input configuration for this
engine a path to a directory. It then uses the `files` io-helper to convert
this path into an object of lazy promises.
* The `run`-function concatenates and returns the contents of each file.
### Loading a configuration
In order to see, how the preprocessor and the `files`-helper works, we can display
the configuration after a merge:
```js
var customize = require('customize')
// Load files from one directory and merge with second
customize()
.registerEngine('files', require('./engine-concat-files'))
.merge({
files: 'dir1'
})
.build()
.done(console.log)
```
The example creates a new Customize-instances, registers our engine under the name
`files` and provides the path to a directory as configuration for the `files` engine
(i.e. as property `files` within the configuration object). It then uses the
`.build` function convert all nested promises to a single promise for the whole
config. This example prints the following result.
```js
{ files:
{ 'a.md': { path: 'dir1/a.md', contents: 'First file (from dir1)' },
'b.md': { path: 'dir1/b.md', contents: 'Second file (from dir1)' } } }
```
We can see that the `files`-call of the preprocessor converted the directory path into
an object containing a one property for each file in the directory.
### Running the engine
So far, we have loaded and displayed the preprocessed configuration. Now replace the
`.build()`-call by `.run()`
```js
var customize = require('customize')
// Load files from one directory
customize()
.registerEngine('files', require('./engine-concat-files'))
.merge({
files: 'dir1'
})
.run()
.get('files')
.done(console.log)
```
The engines `run()`-method will now be executed with the resolved configuration,
which yields the following output:
```
First file (from dir1)
Second file (from dir1)
```
### Merging another configuration
We now have a working customizable configuration. The only thing we have not tried
yet is to customize it. We are going to assume that someone, maybe Bob, wants to reuse
the configuration for my own purposes, because he really likes it, and it really does
exactly what he was looking for. Almost... Except, that the contents of the first file (`a.md`)
needs to be replace by something else. In reality this might be a Handlebars partial to include
different contents, or an additional Less-file that changes some styles to follow Bob'
company's style-guide.
We can do this, by merging another configuration:
```js
var customize = require('customize')
// Load files from one directory and merge with second
customize()
.registerEngine('files', require('./engine-concat-files'))
.merge({
files: 'dir1'
})
.merge({
files: 'dir2'
})
.run()
.get("files")
.done(console.log)
```
Notice the additional `.merge()`-call? Its input is also passed to the 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), so that in the above
example, the property `a.md` is replace by the value in the second configuration. So the output
of this example is
```
First file (from dir2)
Second file (from dir1)
```
### Advanced usage
This is the essence of `customize`. Actually, things are a bit more complicated.
A custom overrider ensures (in this order)
* that nested objects can provide there own overrider function in a `_customize_custom_overrider`-property,
* that array-values are concatenated rather than replaced
* and that promises are correctly merged.
Finally, the `.files()`-helper does not return the file contents directly. It returns a promise for the
file contents. This promise is lazy and only evaluated when the `.then()`-method is called. And it uses the
`Customize.leaf()` method to attach custom overrider, so that a file-promise replaces its predecessor
without `.then()` being called.
This means that files, whose contents is overridden by other files, are *not* opened for reading.
### Application of the principles
Currently, there is only the [thought](https://npmjs.com/package/thought) package uses customize, but [bootprint](https://npmjs.com/package/bootprint) uses the same principle.
In `thought` the `.thought/partials` directory is included to allow the user to override default Handlebars-partials with
custom verison.
In `bootprint` the user can create packages with Handlebars-partials and Less-definitions, which include and override
partials and definitions from other packages.
## API-reference
The exported module is a function that creates a new empty Customize-instance.
### Global

@@ -134,2 +324,41 @@

## IO/Helpers
### Global
* * *
##### files(baseDir)
The file helper resolves the directory filename to the contents of the included files (promised).
**Parameters**
**baseDir**: `string`, the name of the directory
**Returns**: `Promise.&lt;object.&lt;Promise.&lt;string&gt;&gt;&gt;`, an object, containing one entry for each file.
The key of each entry is the path to the file (relative to the baseDir). The value is
a promise that resolves to the file-contents when the `.then()` method is called.
* * *
## License

@@ -136,0 +365,0 @@

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