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

conifer

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

conifer - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

--test-async-merge-properties.coffee

2

config/coffeelint.json

@@ -11,5 +11,5 @@ {

"no_throwing_strings": {"level": "error"},
"cyclomatic_complexity": {"level": "warn", "value": 5},
"cyclomatic_complexity": {"level": "warn", "value": 9},
"line_endings": {"level": "error", "value": "unix"},
"no_implicit_parens": {"level": "ignore"}
}
// Generated by CoffeeScript 1.3.3
(function() {
var FileNotFoundError, Store, conifer, fs, handler, util, verifyArg;
var FileNotFoundError, IMPORT_INDICATOR, IOError, Store, async, cleanImportString, conifer, fs, getFileHandlerForPath, handler, importStringRegexp, newFileNotFoundError, newFileReadError, newHandlerNotFoundError, parse, parseObjectImports, parseObjectImportsSync, parseSync, path, propertyIsImportMerge, removeImportMergeProperties, util, valueIsImportProperty, verifyArg, _ref,
__hasProp = {}.hasOwnProperty;
FileNotFoundError = require('er').FileNotFoundError;
async = require('async');
_ref = require('er'), FileNotFoundError = _ref.FileNotFoundError, IOError = _ref.IOError;
fs = require('fs');

@@ -11,2 +14,4 @@

path = require('path');
Store = require('./store').Store;

@@ -24,33 +29,118 @@

conifer.parse = function(filePath, callback) {
parse = function(filePath, callback, returnStore) {
verifyArg.isUnemptyString('filePath', filePath);
verifyArg.isFunction('callback', callback);
return fs.stat(filePath, function(err, stats) {
var fileExtension;
if ((err != null) || !stats.isFile()) {
return callback(null, new FileNotFoundError("Config file at " + filePath + " was not found, or is not a file"));
} else {
fileExtension = util.path.getFileExtension(filePath);
handler = conifer.handler.getHandler(fileExtension);
if (!(handler != null)) {
callback(null, new conifer.handler.HandlerNotFoundError("Handler for '" + fileExtension + "' was not found"));
return;
handler = null;
return async.waterfall([
function(done) {
return fs.stat(filePath, function(error, stats) {
if ((error != null) || !stats.isFile()) {
return done(newFileNotFoundError(filePath));
} else {
return done();
}
});
}, function(done) {
try {
handler = getFileHandlerForPath(filePath);
return done(null, handler);
} catch (error) {
return done(error);
}
return fs.readFile(filePath, 'utf8', function(err, data) {
var parsedData;
try {
parsedData = handler(data);
return callback(new conifer.Store(parsedData), null);
} catch (error) {
return callback(null, error);
}, function(handler, done) {
return fs.readFile(filePath, 'utf8', function(error, fileContent) {
if (error != null) {
return done(newFileReadError(filePath));
} else {
return done(null, handler, fileContent);
}
});
}, function(handler, fileContent, done) {
try {
return done(null, handler(fileContent));
} catch (error) {
return done(error);
}
}, function(parsedContent, done) {
var queue;
try {
queue = async.queue((function(task, taskDone) {
return task(taskDone, done);
}), 3);
queue.drain = function() {
return done(null, parsedContent);
};
parseObjectImports(parsedContent, path.dirname(filePath), queue);
return queue.push(function(taskDone, parseDone) {
return taskDone();
});
} catch (error) {
return done(error);
}
}
], function(error, result) {
if (error) {
return callback(null, error);
} else if (returnStore) {
return callback(new conifer.Store(result), null);
} else {
return callback(result, null);
}
});
};
conifer.parseSync = function(filePath) {
var data, fileError, fileExtension, parsedData, stats;
parseObjectImports = function(object, importBasePath, queue) {
var property, value, _fn;
_fn = function(property, value) {
var importFilePath, _i, _len, _results;
if (propertyIsImportMerge(property, value)) {
_results = [];
for (_i = 0, _len = value.length; _i < _len; _i++) {
importFilePath = value[_i];
_results.push((function(importFilePath) {
importFilePath = path.resolve(importBasePath + '/' + importFilePath);
return queue.push(function(taskDone, parseDone) {
return parse(importFilePath, function(importContent, error) {
if (error) {
return parseDone(error);
} else {
util.mergeObjects(object, importContent);
return taskDone();
}
}, false);
});
})(importFilePath));
}
return _results;
} else if (valueIsImportProperty(value)) {
importFilePath = path.resolve(importBasePath + '/' + cleanImportString(value));
return queue.push(function(taskDone, parseDone) {
return parse(importFilePath, function(importContent, error) {
if (error) {
return parseDone(error);
} else {
object[property] = importContent;
return taskDone();
}
}, false);
});
} else if (typeof value === 'object') {
return parseObjectImports(value, importBasePath, queue);
}
};
for (property in object) {
if (!__hasProp.call(object, property)) continue;
value = object[property];
_fn(property, value);
}
return removeImportMergeProperties(object);
};
conifer.parse = function(filePath, callback) {
return parse(filePath, callback, true);
};
parseSync = function(filePath, returnStore) {
var fileContent, parsedContent, stats;
verifyArg.isUnemptyString('filePath', filePath);
fileError = new FileNotFoundError("Config file at " + filePath + " was not found, or is not a file");
try {

@@ -62,15 +152,111 @@ stats = fs.statSync(filePath);

} catch (error) {
throw fileError;
throw newFileNotFoundError(filePath);
}
handler = getFileHandlerForPath(filePath);
fileContent = null;
try {
fileContent = fs.readFileSync(filePath, 'utf8');
} catch (error) {
throw newFileReadError(filePath);
}
parsedContent = handler(fileContent);
parseObjectImportsSync(parsedContent, path.dirname(filePath));
if (returnStore) {
return new conifer.Store(parsedContent);
} else {
return parsedContent;
}
};
parseObjectImportsSync = function(object, importBasePath) {
var importFilePath, property, value, _i, _len;
for (property in object) {
if (!__hasProp.call(object, property)) continue;
value = object[property];
if (propertyIsImportMerge(property, value)) {
for (_i = 0, _len = value.length; _i < _len; _i++) {
importFilePath = value[_i];
importFilePath = path.resolve(importBasePath + '/' + importFilePath);
util.mergeObjects(object, parseSync(importFilePath, false));
}
} else if (valueIsImportProperty(value)) {
importFilePath = path.resolve(importBasePath + '/' + cleanImportString(value));
object[property] = parseSync(importFilePath, false);
} else if (typeof value === 'object') {
parseObjectImportsSync(value, importBasePath);
}
}
return removeImportMergeProperties(object);
};
conifer.parseSync = function(filePath) {
return parseSync(filePath, true);
};
newFileNotFoundError = function(filePath) {
return new FileNotFoundError("Config file at " + filePath + " was not found, or is not a file");
};
newHandlerNotFoundError = function(fileExtension) {
return new conifer.handler.HandlerNotFoundError("Handler for '" + fileExtension + "' was not found");
};
newFileReadError = function(filePath) {
return new IOError("Config file at " + filePath + " could not be read");
};
getFileHandlerForPath = function(filePath) {
var fileExtension;
fileExtension = util.path.getFileExtension(filePath);
handler = conifer.handler.getHandler(fileExtension);
if (!(handler != null)) {
throw new conifer.handler.HandlerNotFoundError("Handler for '" + fileExtension + "' was not found");
return;
throw newHandlerNotFoundError(fileExtension);
}
data = fs.readFileSync(filePath, 'utf8');
parsedData = handler(data);
return new conifer.Store(parsedData);
return handler;
};
IMPORT_INDICATOR = '<<';
propertyIsImportMerge = function(property, value) {
var item, _i, _len;
if (property === IMPORT_INDICATOR && Array.isArray(value)) {
for (_i = 0, _len = value.length; _i < _len; _i++) {
item = value[_i];
if (typeof item !== 'string') {
return false;
}
}
return true;
} else {
return false;
}
};
removeImportMergeProperties = function(object) {
var property, value, _results;
_results = [];
for (property in object) {
if (!__hasProp.call(object, property)) continue;
value = object[property];
if (propertyIsImportMerge(property, value)) {
_results.push(delete object[property]);
} else if (typeof value === 'object' && !Array.isArray(value)) {
_results.push(removeImportMergeProperties(value));
} else {
_results.push(void 0);
}
}
return _results;
};
importStringRegexp = new RegExp("^" + IMPORT_INDICATOR + "\\s+");
valueIsImportProperty = function(value) {
return typeof value === 'string' && importStringRegexp.test(value);
};
cleanImportString = function(importString) {
return importString.replace(importStringRegexp, '');
};
}).call(this);
// Generated by CoffeeScript 1.3.3
(function() {
var ArgumentError, ArgumentMissingError, ArgumentTypeError, BadConstructionError, path, _ref;
var ArgumentError, ArgumentMissingError, ArgumentTypeError, BadConstructionError, path, _ref,
__hasProp = {}.hasOwnProperty;

@@ -51,2 +52,14 @@ _ref = require('er'), ArgumentError = _ref.ArgumentError, ArgumentMissingError = _ref.ArgumentMissingError, ArgumentTypeError = _ref.ArgumentTypeError, BadConstructionError = _ref.BadConstructionError;

exports.mergeObjects = function(object1, object2) {
var property, value;
exports.verifyArg.isObject('object1', object1);
exports.verifyArg.isObject('object2', object2);
for (property in object2) {
if (!__hasProp.call(object2, property)) continue;
value = object2[property];
object1[property] = value;
}
return object1;
};
}).call(this);
{
"name": "conifer",
"version": "0.2.0",
"version": "0.3.0",
"description": "A multi-format, file-based configuration library for Node.",

@@ -26,2 +26,3 @@ "keywords": [

"dependencies": {
"async": "0.1.x",
"cson": "1.2.x",

@@ -28,0 +29,0 @@ "er": "0.2.x",

@@ -16,2 +16,15 @@

Installing
----------
Install Conifer through `npm`. Either with the command:
```sh
npm install conifer
```
or by adding `conifer` to the dependencies in your project
`package.json`.
Basic Usage

@@ -101,2 +114,86 @@ -----------

Configuration Importing
-----------------------
Your config files are able to import other configurations as
properties, or by merging them into the current object. This
allows for a single entry-point for your configuration, as well
as a more managable and reusable set of config files.
Examples below are mostly in JSON but this will work for all
supported file types, as well as allowing for cross-file-type
importing.
### Import Properties
Import properties allow you to import the contents of another
config file into a property. They work on a property whose
(string) value begins with `<< `. So if we have the following
files:
config/main.json:
```json
{
"name": "Hello World",
"routes": "<< ./routes.json"
}
```
config/routes.json:
```json
{
"/": "controller/index",
"/about": "controller/about",
}
```
Parsing `config/main.json` will result in the following
structure:
```json
{
"name": "Hello World",
"routes": {
"/": "controller/index",
"/about": "controller/about",
}
}
```
### Import Merges
Import merges allow you to merge the contents of another config
file into the current object. Merges are indicated by the `<<`
property of an object, which should be set to an array of file
names. If we have the following files:
config/main.json:
```json
{
"name": "Hello World",
"outputErrors": true,
"<<": [
"./production.json"
]
}
```
config/production.json:
```json
{
"outputErrors": false,
"logErrors": true
}
```
Parsing `config/main.json` will result in the following
structure:
```json
{
"name": "Hello World",
"outputErrors": false,
"logErrors": true
}
```
Extending With File Handlers

@@ -103,0 +200,0 @@ ----------------------------

@@ -18,23 +18,33 @@

Imports
-------
Property Replacement
--------------------
I'd like to allow config files to include other config files.
This is what I'm thinking right now:
I may consider at some point adding the ability to insert the
values of configurations in other configurations. Something like
this:
```json
{
"routes": "<< ./routes.json",
"<<": [
"./other-config.json",
"./other-config.cson"
]
"name": "Hello World!",
"version": "1.2.3",
"author": {
"name": "Foo Bar",
"email": "foo@bar.com"
},
"description": "{{name}} is an app which is currently at version {{version}}. It was written by {{author.name}}."
}
```
In the example above, the contents of `routes.json` would be
parsed and set as the `routes` property in the current config
file. The `other-config.*` files would be merged into the base
object of the current config file.
which would turn into this:
Idea and syntax subject to change. Thoughts?
```json
{
"name": "Hello World!",
"version": "1.2.3",
"author": {
"name": "Foo Bar",
"email": "foo@bar.com"
},
"description": "Hello World! is an app which is currently at version 1.2.3. It was written by Foo Bar."
}
```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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