1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Start documenting apis

This commit is contained in:
Nick O'Leary 2018-08-22 10:00:03 +01:00
parent 19fa69811b
commit 4e21a5e557
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
7 changed files with 207 additions and 11 deletions

View File

@ -420,6 +420,13 @@ module.exports = function(grunt) {
destination: 'docs', destination: 'docs',
configure: './jsdoc.json' configure: './jsdoc.json'
} }
},
nodeREDUtil: {
src: 'packages/node_modules/@node-red/util/**/*.js',
options: {
destination: 'packages/node_modules/@node-red/util/docs',
configure: './jsdoc.json'
}
} }
}, },
jsdoc2md: { jsdoc2md: {
@ -429,6 +436,13 @@ module.exports = function(grunt) {
}, },
src: 'packages/node_modules/@node-red/runtime/lib/api/*.js', src: 'packages/node_modules/@node-red/runtime/lib/api/*.js',
dest: 'docs/runtime-api.md' dest: 'docs/runtime-api.md'
},
nodeREDUtil: {
options: {
separators: true
},
src: 'packages/node_modules/@node-red/util/**/*.js',
dest: 'packages/node_modules/@node-red/util/docs/api.md'
} }
} }
}); });

View File

@ -1,6 +1,6 @@
{ {
"opts": { "opts": {
"template": "./node_modules/ink-docstrap/template", "template": "./node_modules/minami",
"destination": "./docs", "destination": "./docs",
"recurse": true "recurse": true
}, },
@ -9,7 +9,7 @@
"dictionaries": ["jsdoc"] "dictionaries": ["jsdoc"]
}, },
"source": { "source": {
"include": [ "_include": [
"./packages/node_modules/@node-red/runtime/lib/api" "./packages/node_modules/@node-red/runtime/lib/api"
] ]
}, },
@ -18,5 +18,6 @@
"theme":"yeti", "theme":"yeti",
"footer": "", "footer": "",
"copyright": "Released under the Apache License v2.0" "copyright": "Released under the Apache License v2.0"
} },
"plugins": ["plugins/markdown"]
} }

View File

@ -95,8 +95,8 @@
"grunt-simple-mocha": "~0.4.1", "grunt-simple-mocha": "~0.4.1",
"grunt-webdriver": "^2.0.3", "grunt-webdriver": "^2.0.3",
"http-proxy": "^1.16.2", "http-proxy": "^1.16.2",
"ink-docstrap": "^1.3.2",
"istanbul": "0.4.5", "istanbul": "0.4.5",
"minami": "1.2.3",
"mocha": "^5.2.0", "mocha": "^5.2.0",
"should": "^8.4.0", "should": "^8.4.0",
"sinon": "1.17.7", "sinon": "1.17.7",

View File

@ -14,17 +14,26 @@
* limitations under the License. * limitations under the License.
**/ **/
/**
* @namespace @node-red/util
*/
const log = require("./lib/log"); const log = require("./lib/log");
const i18n = require("./lib/i18n"); const i18n = require("./lib/i18n");
const util = require("./lib/util"); const util = require("./lib/util");
module.exports = { module.exports = {
/**
* Initialise the module with the runtime settings
* @param {Object} settings
*/
init: function(settings) { init: function(settings) {
log.init(settings); log.init(settings);
i18n.init(); i18n.init();
}, },
log: log, log: log,
i18n: i18n, i18n: i18n,
/**
* General utilities
*/
util: util util: util
} }

View File

@ -12,6 +12,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* @ignore
**/ **/
var i18n = require("i18next"); var i18n = require("i18next");

View File

@ -12,6 +12,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* @ignore
**/ **/
var util = require("util"); var util = require("util");

View File

@ -12,17 +12,32 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* @ignore
**/ **/
var clone = require("clone"); const clone = require("clone");
var jsonata = require("jsonata"); const jsonata = require("jsonata");
var safeJSONStringify = require("json-stringify-safe"); const safeJSONStringify = require("json-stringify-safe");
var util = require("util"); const util = require("util");
/**
* Generates a psuedo-unique-random id.
*
* @return {String} a random-ish id
* @memberof @node-red/util.util
*/
function generateId() { function generateId() {
return (1+Math.random()*4294967295).toString(16); return (1+Math.random()*4294967295).toString(16);
} }
/**
* Converts the provided argument to a String, using type-dependent
* methods.
*
* @param {any} o - the property to convert to a String
* @return {String} the stringified version
* @memberof @node-red/util.util
*/
function ensureString(o) { function ensureString(o) {
if (Buffer.isBuffer(o)) { if (Buffer.isBuffer(o)) {
return o.toString(); return o.toString();
@ -34,6 +49,14 @@ function ensureString(o) {
return ""+o; return ""+o;
} }
/**
* Converts the provided argument to a Buffer, using type-dependent
* methods.
*
* @param {any} o - the property to convert to a Buffer
* @return {String} the Buffer version
* @memberof @node-red/util.util
*/
function ensureBuffer(o) { function ensureBuffer(o) {
if (Buffer.isBuffer(o)) { if (Buffer.isBuffer(o)) {
return o; return o;
@ -45,6 +68,14 @@ function ensureBuffer(o) {
return new Buffer(o); return new Buffer(o);
} }
/**
* Safely clones a message object. This handles msg.req/msg.res objects that must
* not be cloned.
*
* @param {any} msg - the message object to clone
* @return {Object} the cloned message
* @memberof @node-red/util.util
*/
function cloneMessage(msg) { function cloneMessage(msg) {
// Temporary fix for #97 // Temporary fix for #97
// TODO: remove this http-node-specific fix somehow // TODO: remove this http-node-specific fix somehow
@ -64,6 +95,14 @@ function cloneMessage(msg) {
return m; return m;
} }
/**
* Compares two objects, handling various JavaScript types.
*
* @param {any} obj1
* @param {any} obj2
* @return {boolean} whether the two objects are the same
* @memberof @node-red/util.util
*/
function compareObjects(obj1,obj2) { function compareObjects(obj1,obj2) {
var i; var i;
if (obj1 === obj2) { if (obj1 === obj2) {
@ -130,6 +169,17 @@ function compareObjects(obj1,obj2) {
return true; return true;
} }
/**
* Parses a property expression, such as `msg.foo.bar[3]` to validate it
* and convert it to a canonical version expressed as an Array of property
* names.
*
* For example, `a["b"].c` returns `['a','b','c']`
*
* @param {String} str - the property expression
* @return {Array} the normalised expression
* @memberof @node-red/util.util
*/
function normalisePropertyExpression(str) { function normalisePropertyExpression(str) {
// This must be kept in sync with validatePropertyExpression // This must be kept in sync with validatePropertyExpression
// in editor/js/ui/utils.js // in editor/js/ui/utils.js
@ -234,12 +284,32 @@ function normalisePropertyExpression(str) {
return parts; return parts;
} }
/**
* Gets a property of a message object.
*
* Unlike {@link @node-red/util.util.getObjectProperty}, this function will strip `msg.` from the
* front of the property expression if present.
*
* @param {Object} msg - the message object
* @param {String} str - the property expression
* @return {any} the message property, or undefined if it does not exist
* @memberof @node-red/util.util
*/
function getMessageProperty(msg,expr) { function getMessageProperty(msg,expr) {
if (expr.indexOf('msg.')===0) { if (expr.indexOf('msg.')===0) {
expr = expr.substring(4); expr = expr.substring(4);
} }
return getObjectProperty(msg,expr); return getObjectProperty(msg,expr);
} }
/**
* Gets a property of an object.
*
* @param {Object} msg - the object
* @param {String} str - the property expression
* @return {any} the object property, or undefined if it does not exist
* @memberof @node-red/util.util
*/
function getObjectProperty(msg,expr) { function getObjectProperty(msg,expr) {
var result = null; var result = null;
var msgPropParts = normalisePropertyExpression(expr); var msgPropParts = normalisePropertyExpression(expr);
@ -251,12 +321,34 @@ function getObjectProperty(msg,expr) {
return result; return result;
} }
/**
* Sets a property of a message object.
*
* Unlike {@link @node-red/util.util.setObjectProperty}, this function will strip `msg.` from the
* front of the property expression if present.
*
* @param {Object} msg - the message object
* @param {String} prop - the property expression
* @param {any} value - the value to set
* @param {boolean} createMissing - whether to create missing parent properties
* @memberof @node-red/util.util
*/
function setMessageProperty(msg,prop,value,createMissing) { function setMessageProperty(msg,prop,value,createMissing) {
if (prop.indexOf('msg.')===0) { if (prop.indexOf('msg.')===0) {
prop = prop.substring(4); prop = prop.substring(4);
} }
return setObjectProperty(msg,prop,value,createMissing); return setObjectProperty(msg,prop,value,createMissing);
} }
/**
* Sets a property of an object.
*
* @param {Object} msg - the object
* @param {String} prop - the property expression
* @param {any} value - the value to set
* @param {boolean} createMissing - whether to create missing parent properties
* @memberof @node-red/util.util
*/
function setObjectProperty(msg,prop,value,createMissing) { function setObjectProperty(msg,prop,value,createMissing) {
if (typeof createMissing === 'undefined') { if (typeof createMissing === 'undefined') {
createMissing = (typeof value !== 'undefined'); createMissing = (typeof value !== 'undefined');
@ -311,6 +403,16 @@ function setObjectProperty(msg,prop,value,createMissing) {
} }
} }
/**
* Checks if a String contains any Environment Variable specifiers and returns
* it with their values substituted in place.
*
* For example, if the env var `WHO` is set to `Joe`, the string `Hello ${WHO}!`
* will return `Hello Joe!`.
* @param {String} value - the string to parse
* @return {String} The parsed string
* @memberof @node-red/util.util
*/
function evaluateEnvProperty(value) { function evaluateEnvProperty(value) {
if (/^\${[^}]+}$/.test(value)) { if (/^\${[^}]+}$/.test(value)) {
// ${ENV_VAR} // ${ENV_VAR}
@ -328,7 +430,18 @@ function evaluateEnvProperty(value) {
return value; return value;
} }
var parseContextStore = function(key) {
/**
* Parses a context property string, as generated by the TypedInput, to extract
* the store name if present.
*
* For example, `#:(file)::foo` results in ` { store: "file", key: "foo" }`.
*
* @param {String} value - the context property string to parse
* @return {Object} The parsed property
* @memberof @node-red/util.util
*/
function parseContextStore(key) {
var parts = {}; var parts = {};
var m = /^#:\((\S+?)\)::(.*)$/.exec(key); var m = /^#:\((\S+?)\)::(.*)$/.exec(key);
if (m) { if (m) {
@ -340,6 +453,18 @@ var parseContextStore = function(key) {
return parts; return parts;
} }
/**
* Evaluates a property value according to its type.
*
* @param {String} value - the raw value
* @param {String} type - the type of the value
* @param {Node} node - the node evaluating the property
* @param {Object} msg - the message object to evaluate against
* @param {Function} callback - (optional) called when the property is evaluated
* @return {any} The evaluted property, if no `callback` is provided
* @memberof @node-red/util.util
*/
function evaluateNodeProperty(value, type, node, msg, callback) { function evaluateNodeProperty(value, type, node, msg, callback) {
var result = value; var result = value;
if (type === 'str') { if (type === 'str') {
@ -387,6 +512,16 @@ function evaluateNodeProperty(value, type, node, msg, callback) {
} }
} }
/**
* Prepares a JSONata expression for evaluation.
* This attaches Node-RED specific functions to the expression.
*
* @param {String} value - the JSONata expression
* @param {Node} node - the node evaluating the property
* @return {Object} The JSONata expression that can be evaluated
* @memberof @node-red/util.util
*/
function prepareJSONataExpression(value,node) { function prepareJSONataExpression(value,node) {
var expr = jsonata(value); var expr = jsonata(value);
expr.assign('flowContext',function(val) { expr.assign('flowContext',function(val) {
@ -404,6 +539,17 @@ function prepareJSONataExpression(value,node) {
return expr; return expr;
} }
/**
* Evaluates a JSONata expression.
* The expression must have been prepared with {@link @node-red/util.util.prepareJSONataExpression}
* before passing to this function.
*
* @param {Object} expr - the prepared JSONata expression
* @param {Object} msg - the message object to evaluate against
* @param {Function} callback - (optional) called when the expression is evaluated
* @return {any} If no callback was provided, the result of the expression
* @memberof @node-red/util.util
*/
function evaluateJSONataExpression(expr,msg,callback) { function evaluateJSONataExpression(expr,msg,callback) {
var context = msg; var context = msg;
if (expr._legacyMode) { if (expr._legacyMode) {
@ -440,7 +586,15 @@ function evaluateJSONataExpression(expr,msg,callback) {
return expr.evaluate(context, bindings, callback); return expr.evaluate(context, bindings, callback);
} }
/**
* Normalise a node type name to camel case.
*
* For example: `a-random node type` will normalise to `aRandomNodeType`
*
* @param {String} name - the node type
* @return {String} The normalised name
* @memberof @node-red/util.util
*/
function normaliseNodeTypeName(name) { function normaliseNodeTypeName(name) {
var result = name.replace(/[^a-zA-Z0-9]/g, " "); var result = name.replace(/[^a-zA-Z0-9]/g, " ");
result = result.trim(); result = result.trim();
@ -454,6 +608,17 @@ function normaliseNodeTypeName(name) {
return result; return result;
} }
/**
* Encode an object to JSON without losing information about non-JSON types
* such as Buffer and Function.
*
* *This function is closely tied to its reverse within the editor*
*
* @param {Object} msg
* @param {Object} opts
* @return {Object} the encoded object
* @memberof @node-red/util.util
*/
function encodeObject(msg,opts) { function encodeObject(msg,opts) {
var debuglength = 1000; var debuglength = 1000;
if (opts && opts.hasOwnProperty('maxLength')) { if (opts && opts.hasOwnProperty('maxLength')) {
@ -581,6 +746,11 @@ function encodeObject(msg,opts) {
return msg; return msg;
} }
/**
* General utilities
* @namespace util
* @memberof @node-red/util
*/
module.exports = { module.exports = {
encodeObject: encodeObject, encodeObject: encodeObject,
ensureString: ensureString, ensureString: ensureString,