diff --git a/src/node/apiUtils.mjs b/src/node/apiUtils.mjs
index 4ee8a2c0..7be5e5b3 100644
--- a/src/node/apiUtils.mjs
+++ b/src/node/apiUtils.mjs
@@ -77,7 +77,7 @@ function transformArgs(originalArgs, newArgs) {
* @returns {Function} The operation's run function, wrapped in
* some type conversion logic
*/
-export function wrap(opClass) {
+export function wrap(OpClass) {
/**
* Wrapped operation run function
* @param {*} input
@@ -86,7 +86,7 @@ export function wrap(opClass) {
* @throws {OperationError} if the operation throws one.
*/
return (input, args=null) => {
- const operation = new opClass();
+ const operation = new OpClass();
let dish;
if (input instanceof SyncDish) {
@@ -107,48 +107,6 @@ export function wrap(opClass) {
};
}
-/**
- * Extract properties from an operation by instantiating it and
- * returning some of its properties for reference.
- * @param {Operation} Operation - the operation to extract info from
- * @returns {Object} operation properties
- */
-function extractOperationInfo(Operation) {
- const operation = new Operation();
- return {
- name: operation.name,
- module: operation.module,
- description: operation.description,
- inputType: operation.inputType,
- outputType: operation.outputType,
- // Make arg names lowercase, no spaces to encourage non-sentence
- // caps in repl
- args: Object.assign([], operation.args).map((s) => {
- s.name = decapitalise(s.name).replace(/ /g, "");
- return s;
- })
- };
-}
-
-
-/**
- * @namespace Api
- * @param {Object} operations - an object filled with operations.
- * @param {String} searchTerm - the name of the operation to get help for.
- * Case and whitespace are ignored in search.
- * @returns {Object} listing properties of function
- */
-export function help(operations, searchTerm) {
- if (typeof searchTerm === "string") {
- const operation = operations[Object.keys(operations).find(o =>
- o.toLowerCase() === searchTerm.replace(/ /g, "").toLowerCase())];
- if (operation) {
- return extractOperationInfo(operation);
- }
- }
- return null;
-}
-
/**
* SomeName => someName
@@ -167,3 +125,50 @@ export function decapitalise(name) {
return `${name.charAt(0).toLowerCase()}${name.substr(1)}`;
}
+
+
+/**
+ * Extract properties from an operation by instantiating it and
+ * returning some of its properties for reference.
+ * @param {Operation} Operation - the operation to extract info from
+ * @returns {Object} operation properties
+ */
+function extractOperationInfo(Operation) {
+ const operation = new Operation();
+ return {
+ name: decapitalise(operation.name).replace(/ /g, ""),
+ module: operation.module,
+ description: operation.description,
+ inputType: operation.inputType,
+ outputType: operation.outputType,
+ // Make arg names lowercase, no spaces to encourage non-sentence
+ // caps in repl
+ args: Object.assign([], operation.args).map((s) => {
+ s.name = decapitalise(s.name).replace(/ /g, "");
+ return s;
+ })
+ };
+}
+
+
+/**
+ * @namespace Api
+ * @param {Operation[]} operations - an object filled with operations.
+ * @param {String} searchTerm - the name of the operation to get help for.
+ * Case and whitespace are ignored in search.
+ * @returns {Function} taking search term and outputting description.
+ */
+export function help(operations) {
+ return function(searchTerm) {
+ if (typeof searchTerm === "string") {
+ const operation = operations
+ .find(o => o.name.toLowerCase() === searchTerm.replace(/ /g, "").toLowerCase());
+ if (operation) {
+ return extractOperationInfo(operation);
+ }
+ return null;
+ }
+ return null;
+ };
+}
+
diff --git a/src/node/config/scripts/generateNodeIndex.mjs b/src/node/config/scripts/generateNodeIndex.mjs
index 8998aef4..ffc321fb 100644
--- a/src/node/config/scripts/generateNodeIndex.mjs
+++ b/src/node/config/scripts/generateNodeIndex.mjs
@@ -39,7 +39,7 @@ let code = `/**
import "babel-polyfill";
-import { wrap } from "./apiUtils";
+import { wrap, help } from "./apiUtils";
import {
`;
@@ -79,6 +79,14 @@ code += ` };
}
const chef = generateChef();
+chef.help = help([\n`;
+
+includedOperations.forEach((op) => {
+ code += ` core_${op},\n`;
+});
+
+code +=`]);
+
`;
includedOperations.forEach((op) => {
diff --git a/test/tests/nodeApi/nodeApi.mjs b/test/tests/nodeApi/nodeApi.mjs
index 3e817fe9..3535996d 100644
--- a/test/tests/nodeApi/nodeApi.mjs
+++ b/test/tests/nodeApi/nodeApi.mjs
@@ -108,4 +108,23 @@ TestRegister.addApiTests([
const result = chef.fromBase32(chef.toBase32("32"));
assert.equal(3 + result, 35);
}),
+
+ it("chef.help: should exist", () => {
+ assert(chef.help);
+ }),
+
+ it("chef.help: should describe a operation", () => {
+ const result = chef.help("tripleDESDecrypt");
+ assert.strictEqual(result.name, "tripleDESDecrypt");
+ assert.strictEqual(result.module, "Ciphers");
+ assert.strictEqual(result.inputType, "string");
+ assert.strictEqual(result.outputType, "string");
+ assert.strictEqual(result.description, "Triple DES applies DES three times to each block to increase key size.
Key: Triple DES uses a key length of 24 bytes (192 bits).
DES uses a key length of 8 bytes (64 bits).
IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.
Padding: In CBC and ECB mode, PKCS#7 padding will be used.");
+ assert.strictEqual(result.args.length, 5);
+ }),
+
+ it("chef.help: null for invalid operation", () => {
+ const result = chef.help("some invalid function name");
+ assert.strictEqual(result, null);
+ }),
]);