From 7acceec2c147cc22ae263957c626d494974d29ea Mon Sep 17 00:00:00 2001 From: Johnbastian Date: Mon, 20 Jan 2020 12:55:50 +0000 Subject: [PATCH 1/8] Added alias for smartSubstitution on top level --- smartSubstitution.js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 smartSubstitution.js diff --git a/smartSubstitution.js b/smartSubstitution.js new file mode 100644 index 0000000..c5de544 --- /dev/null +++ b/smartSubstitution.js @@ -0,0 +1,5 @@ +/* + Top level alias for exposing substitue.js + This enables a lib to simply do `require('@trayio/threadneedle/smartSubstitution')` +*/ +module.exports = require('./lib/addMethod/substitute.js'); From ac6a4a3a5319294484dd08534e725914aed2d7bd Mon Sep 17 00:00:00 2001 From: Johnbastian Date: Mon, 20 Jan 2020 13:54:07 +0000 Subject: [PATCH 2/8] Added smartSubstitution.md --- lib/addMethod/identifySimpleMustache.js | 2 +- smartSubstitution.md | 44 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 smartSubstitution.md diff --git a/lib/addMethod/identifySimpleMustache.js b/lib/addMethod/identifySimpleMustache.js index 6cc376f..decb97e 100644 --- a/lib/addMethod/identifySimpleMustache.js +++ b/lib/addMethod/identifySimpleMustache.js @@ -5,7 +5,7 @@ mustache and is the only thing present in the string. E.g: `url: '{{url}}'` is simple. - `url: test.com/{{endpint}}` is not simple, since `{{endpint}}` is not on + `url: test.com/{{endpoint}}` is not simple, since `{{endpint}}` is not on its own. This also means any extra whitespace prefixing or suffixing the mustache is not simple. */ diff --git a/smartSubstitution.md b/smartSubstitution.md new file mode 100644 index 0000000..0b94198 --- /dev/null +++ b/smartSubstitution.md @@ -0,0 +1,44 @@ +# Smart Substitution +Smart substitution is Threadneedle's logic for resolving mustaching and functions where applicable in configurations, such `options`, `query`, and `data` in REST method configuration. + +Smart substitution can be utilised outside of Threadneedle via the following: +`const smartSubstitution = require('@trayio/threadneedle/smartSubstitution');` + +## Overview +Unlike simple templating, smart substitution aims to preserve data types when possible, and as such checks when simple mustaching has been specified. In the event smart substitution is not possible, Threadneedle falls back to [mustache.js](https://github.com/janl/mustache.js/). + +## Simple mustaching +Simple mustaching are string values that contain only a single mustache template. +Example: +- The following is a simple mustache, as the string value contains simply a template: +```js +{ + url: '{{url}}' +} +``` +In this case, Threadneedle will attempt smart substitution. + +- The following is not a simple mustache: +```js +{ + url: 'example.com/{{endpoint}}' +} +``` +In this case, Threadneedle will fallback to mustache.js. + +### Pathing +Smart substitution accepts pathing as part of the template configuration in a mustache. [Lodash](https://lodash.com/docs/)'s `_.get` is utilised to resolve paths. +Example: +```js +{ + data: { + address: { + street: '{{billing_address.street}}' + } + } +} +``` +This will resolve the `billing_address.street` and fetch the nested value from `params`. + +## # Hash properties +Top level properties of the `params`/input that begin with `#` are known as hash properties. This is intended to provide a way of supplying data as part of `params` which is not user input and is meant to be hidden. Threadneedle will identify these properties and attempt smart substitution. From 1aed96ffcd56bbbc6604595c8f8c6ddd290d63f7 Mon Sep 17 00:00:00 2001 From: Johnbastian Date: Mon, 20 Jan 2020 13:55:36 +0000 Subject: [PATCH 3/8] Added link to smartSubstitution.md from README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 921babd..f66352b 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ threadneedle.getLists({ * [addMethod](#addmethod) * [global](#global) * [SOAP Mode](#soap-mode) +* [Smart Substitution](smartSubstitution.md) ## addMethod From da987ce4d1cfe61ea09fbfb3e2be33d4983f5775 Mon Sep 17 00:00:00 2001 From: Johnbastian Date: Mon, 20 Jan 2020 14:00:32 +0000 Subject: [PATCH 4/8] Added further description to overview --- smartSubstitution.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/smartSubstitution.md b/smartSubstitution.md index 0b94198..c3878a3 100644 --- a/smartSubstitution.md +++ b/smartSubstitution.md @@ -7,6 +7,11 @@ Smart substitution can be utilised outside of Threadneedle via the following: ## Overview Unlike simple templating, smart substitution aims to preserve data types when possible, and as such checks when simple mustaching has been specified. In the event smart substitution is not possible, Threadneedle falls back to [mustache.js](https://github.com/janl/mustache.js/). +Furthermore, smart substitution will resolve functions by providing `params` +/input as the first and only argument, and then setting the function result as the value. + +Finally, smart substitution will attempt to traverse objects and arrays. resolving templates which are nested. + ## Simple mustaching Simple mustaching are string values that contain only a single mustache template. Example: From 86a411263260c0c1c8fcd02692b3ff1670ab0cef Mon Sep 17 00:00:00 2001 From: Johnbastian Date: Tue, 21 Jan 2020 11:37:12 +0000 Subject: [PATCH 5/8] Added validation for params --- smartSubstitution.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/smartSubstitution.js b/smartSubstitution.js index c5de544..76bcd46 100644 --- a/smartSubstitution.js +++ b/smartSubstitution.js @@ -1,5 +1,14 @@ /* - Top level alias for exposing substitue.js + Top level alias for exposing substitute.js This enables a lib to simply do `require('@trayio/threadneedle/smartSubstitution')` */ -module.exports = require('./lib/addMethod/substitute.js'); +const _ = require('lodash'); + +const substitute = require('./lib/addMethod/substitute.js'); + +module.exports = (target, params = {}) => { + if (!_.isPlainObject(params)) { + throw new Error('`params` must be an object'); + } + return substitute(target, params); +}; From 7cdc31b30256f2410e6d4b364c63dfef170e57ab Mon Sep 17 00:00:00 2001 From: Johnbastian Date: Tue, 21 Jan 2020 11:39:34 +0000 Subject: [PATCH 6/8] Updated docs to show function spec --- smartSubstitution.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/smartSubstitution.md b/smartSubstitution.md index c3878a3..424f5d9 100644 --- a/smartSubstitution.md +++ b/smartSubstitution.md @@ -12,6 +12,14 @@ Furthermore, smart substitution will resolve functions by providing `params` Finally, smart substitution will attempt to traverse objects and arrays. resolving templates which are nested. +## smartSubstitution(target, params) +The function accepts two arguments: +- **target** (any)- the target template to perform smart substitution on. +- **params** (object) - the data source for performing the smart substitution. + +The function will return the resolved target. + + ## Simple mustaching Simple mustaching are string values that contain only a single mustache template. Example: From 34eaad245094468296936e5537afaf52300b22ef Mon Sep 17 00:00:00 2001 From: Johnbastian Date: Tue, 21 Jan 2020 14:03:41 +0000 Subject: [PATCH 7/8] typo --- lib/addMethod/identifySimpleMustache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/addMethod/identifySimpleMustache.js b/lib/addMethod/identifySimpleMustache.js index decb97e..33ae3f9 100644 --- a/lib/addMethod/identifySimpleMustache.js +++ b/lib/addMethod/identifySimpleMustache.js @@ -5,7 +5,7 @@ mustache and is the only thing present in the string. E.g: `url: '{{url}}'` is simple. - `url: test.com/{{endpoint}}` is not simple, since `{{endpint}}` is not on + `url: test.com/{{endpoint}}` is not simple, since `{{endpoint}}` is not on its own. This also means any extra whitespace prefixing or suffixing the mustache is not simple. */ From f3a41437e3077506b343fe78c5998cdbf501cb17 Mon Sep 17 00:00:00 2001 From: Johnbastian Date: Tue, 21 Jan 2020 14:09:02 +0000 Subject: [PATCH 8/8] Added function example for smart substitution --- smartSubstitution.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/smartSubstitution.md b/smartSubstitution.md index 424f5d9..ea05837 100644 --- a/smartSubstitution.md +++ b/smartSubstitution.md @@ -39,6 +39,19 @@ In this case, Threadneedle will attempt smart substitution. ``` In this case, Threadneedle will fallback to mustache.js. +## Function substitution +If a function is specified as the value, smart substitution will pass in the `params` and set the response as the value for the property. +Example: +```js +{ + url: (params) => { + return params.url; + } +} +``` + +**NOTE**: smart substitution does not work with async functions/promises. + ### Pathing Smart substitution accepts pathing as part of the template configuration in a mustache. [Lodash](https://lodash.com/docs/)'s `_.get` is utilised to resolve paths. Example: