diff --git a/README.md b/README.md
index 1c93be5f..5e052291 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ Expands expressions in a configuration object
| Param | Type | Description |
| --- | --- | --- |
| config | object
| |
-| [options] | object
| constants object holding additional constants |
+| [options] | object
| constants object holding additional constants functions object holding additional function |
*
diff --git a/src/expander.js b/src/expander.js
index ee3348cb..8e6f7816 100644
--- a/src/expander.js
+++ b/src/expander.js
@@ -17,11 +17,22 @@ import {
}
from './grammar';
+import {
+ functions
+}
+from './functions';
+
+import {
+ createValue
+}
+from './util';
+
/**
* Expands expressions in a configuration object
* @param {object} config
* @param {object} [options]
* constants object holding additional constants
+ * functions object holding additional function
* @returns {Promise} expanded configuration
*/
export function expand(config, options = {}) {
@@ -30,13 +41,14 @@ export function expand(config, options = {}) {
constants: Object.assign({
basedir: '/',
os: os
- }, options.constants)
+ }, options.constants),
+ functions: Object.assign( {}, functions, options.functions)
};
const parser = new ConfigParser();
const ee = createContext({
- evaluate: (expression, _context, path) => {
+ evaluate: (expression, _unusedContext, path) => {
context.path = path;
const ast = parser.parse(expression, context);
return ast.value;
@@ -48,3 +60,5 @@ export function expand(config, options = {}) {
return Promise.reject(e);
}
}
+
+export { createValue };
diff --git a/src/grammar.js b/src/grammar.js
index eb6ecd39..dfe07b8c 100644
--- a/src/grammar.js
+++ b/src/grammar.js
@@ -11,11 +11,6 @@ import {
}
from './util';
-import {
- functions
-}
-from './functions';
-
class AST {
get value() {
return undefined;
@@ -185,7 +180,7 @@ const grammar = {
grammar.advance(')');
- const f = functions[left.value];
+ const f = grammar.context.functions[left.value];
if (f) {
//console.log(`${f.arguments} <> ${args.map(a => a.type)}`);
return new FCall(f, grammar.context, args);
diff --git a/tests/simple_test.js b/tests/simple_test.js
index d23f1ac0..1826a237 100644
--- a/tests/simple_test.js
+++ b/tests/simple_test.js
@@ -10,7 +10,7 @@ const chai = require('chai'),
expect = chai.expect,
should = chai.should();
-const expand = require('../dist/expander').expand;
+const {expand, createValue} = require('../dist/expander');
describe('expander', () => {
@@ -145,6 +145,15 @@ describe('expander', () => {
r, 'secret')));
});
+ describe('user defined functions', () => {
+ it('can call', () => expand(
+ "${myFunction()}", {
+ functions: {
+ myFunction: { apply: (context, args) => { return createValue(77); }}
+ }
+ }).then(r => assert.equal(r, 77)));
+ });
+
describe('promise function args', () => {
it('one promise arg', () => expand(
"${substring(string(document('fixtures/short.txt')),0,4)}", {