create SyncDish and wrap results in it.
This commit is contained in:
parent
d00b9e0928
commit
45d2fbc5fc
@ -393,7 +393,7 @@ module.exports = function (grunt) {
|
||||
"mkdir -p src/core/config/modules",
|
||||
"echo 'export default {};\n' > src/core/config/modules/OpModules.mjs",
|
||||
"echo '[]\n' > src/core/config/OperationConfig.json",
|
||||
"node --experimental-modules src/core/config/scripts/generateNodeIndex.mjs",
|
||||
"node --experimental-modules src/node/config/scripts/generateNodeIndex.mjs",
|
||||
"echo '--- Node index finished. ---\n'"
|
||||
].join(";"),
|
||||
},
|
||||
|
@ -1,12 +1,12 @@
|
||||
/**
|
||||
* Wrap operations for consumption in Node
|
||||
* Wrap operations for consumption in Node.
|
||||
*
|
||||
* @author d98762625 [d98762625@gmail.com]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Dish from "../core/Dish";
|
||||
import SyncDish from "./SyncDish";
|
||||
|
||||
/**
|
||||
* Extract default arg value from operation argument
|
||||
@ -59,61 +59,36 @@ function transformArgs(originalArgs, newArgs) {
|
||||
* @returns {Function} The operation's run function, wrapped in
|
||||
* some type conversion logic
|
||||
*/
|
||||
export function wrap(Operation) {
|
||||
export function wrap(opClass) {
|
||||
/**
|
||||
* Wrapped operation run function
|
||||
* @param {*} input
|
||||
* @param {Object[]} args
|
||||
* @returns {SyncDish} operation's output, on a Dish.
|
||||
* @throws {OperationError} if the operation throws one.
|
||||
*/
|
||||
return async (input, args=null, callback) => {
|
||||
return (input, args=null) => {
|
||||
const operation = new opClass();
|
||||
|
||||
if (callback && typeof callback !== "function") {
|
||||
throw TypeError("Expected callback to be a function");
|
||||
let dish;
|
||||
if (input instanceof SyncDish) {
|
||||
dish = input;
|
||||
} else {
|
||||
dish = new SyncDish();
|
||||
const type = SyncDish.typeEnum(input.constructor.name);
|
||||
dish.set(input, type);
|
||||
}
|
||||
|
||||
if (!callback && typeof args === "function") {
|
||||
callback = args;
|
||||
args = null;
|
||||
}
|
||||
|
||||
const operation = new Operation();
|
||||
const dish = new Dish();
|
||||
|
||||
const type = Dish.typeEnum(input.constructor.name);
|
||||
dish.set(input, type);
|
||||
|
||||
args = transformArgs(operation.args, args);
|
||||
const transformedInput = await dish.get(operation.inputType);
|
||||
|
||||
// Allow callback or promsise / async-await
|
||||
if (callback) {
|
||||
try {
|
||||
const out = operation.run(transformedInput, args);
|
||||
callback(null, out);
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
} else {
|
||||
return operation.run(transformedInput, args);
|
||||
}
|
||||
const transformedInput = dish.get(operation.inputType);
|
||||
const result = operation.run(transformedInput, args);
|
||||
return new SyncDish({
|
||||
value: result,
|
||||
type: operation.outputType
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* First draft
|
||||
* @namespace Api
|
||||
* @param input
|
||||
* @param type
|
||||
*/
|
||||
export async function translateTo(input, type) {
|
||||
const dish = new Dish();
|
||||
|
||||
const initialType = Dish.typeEnum(input.constructor.name);
|
||||
|
||||
dish.set(input, initialType);
|
||||
return await dish.get(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract properties from an operation by instantiating it and
|
||||
* returning some of its properties for reference.
|
||||
|
@ -13,8 +13,8 @@
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import * as operations from "../../operations/index";
|
||||
import { decapitalise } from "../../../node/apiUtils";
|
||||
import * as operations from "../../../core/operations/index";
|
||||
import { decapitalise } from "../../apiUtils";
|
||||
|
||||
const dir = path.join(`${process.cwd()}/src/node`);
|
||||
if (!fs.existsSync(dir)) {
|
||||
@ -36,7 +36,7 @@ let code = `/**
|
||||
|
||||
|
||||
import "babel-polyfill";
|
||||
import { wrap, translateTo } from "./apiUtils";
|
||||
import { wrap } from "./apiUtils";
|
||||
import {
|
||||
`;
|
||||
|
||||
@ -76,7 +76,6 @@ code += ` };
|
||||
}
|
||||
|
||||
const chef = generateChef();
|
||||
chef.translateTo = translateTo;
|
||||
`;
|
||||
|
||||
Object.keys(operations).forEach((op) => {
|
151
src/node/syncDish.mjs
Normal file
151
src/node/syncDish.mjs
Normal file
@ -0,0 +1,151 @@
|
||||
/**
|
||||
* @author d98762625 [d98762625@gmail.com]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Utils from "../core/Utils";
|
||||
import Dish from "../core/Dish";
|
||||
import BigNumber from "bignumber.js";
|
||||
import log from "loglevel";
|
||||
|
||||
/**
|
||||
* Subclass of Dish where `get` and `_translate` are synchronous.
|
||||
* Also define functions to improve coercion behaviour.
|
||||
*/
|
||||
class SyncDish extends Dish {
|
||||
|
||||
/**
|
||||
* Synchronously returns the value of the data in the type format specified.
|
||||
*
|
||||
* @param {number} type - The data type of value, see Dish enums.
|
||||
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
|
||||
* @returns {*} - The value of the output data.
|
||||
*/
|
||||
get(type, notUTF8=false) {
|
||||
if (typeof type === "string") {
|
||||
type = Dish.typeEnum(type);
|
||||
}
|
||||
if (this.type !== type) {
|
||||
this._translate(type, notUTF8);
|
||||
}
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* alias for get
|
||||
* @param args see get args
|
||||
*/
|
||||
to(...args) {
|
||||
return this.get(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoid coercion to a String primitive.
|
||||
*/
|
||||
toString() {
|
||||
return this.get(Dish.typeEnum("string"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Log only the value to the console in node.
|
||||
*/
|
||||
inspect() {
|
||||
return this.get(Dish.typeEnum("string"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoid coercion to a Number primitive.
|
||||
*/
|
||||
valueOf() {
|
||||
return this.get(Dish.typeEnum("number"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously translates the data to the given type format.
|
||||
*
|
||||
* @param {number} toType - The data type of value, see Dish enums.
|
||||
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
|
||||
*/
|
||||
_translate(toType, notUTF8=false) {
|
||||
log.debug(`Translating Dish from ${Dish.enumLookup(this.type)} to ${Dish.enumLookup(toType)}`);
|
||||
const byteArrayToStr = notUTF8 ? Utils.byteArrayToChars : Utils.byteArrayToUtf8;
|
||||
|
||||
// Convert data to intermediate byteArray type
|
||||
switch (this.type) {
|
||||
case Dish.STRING:
|
||||
this.value = this.value ? Utils.strToByteArray(this.value) : [];
|
||||
break;
|
||||
case Dish.NUMBER:
|
||||
this.value = typeof this.value === "number" ? Utils.strToByteArray(this.value.toString()) : [];
|
||||
break;
|
||||
case Dish.HTML:
|
||||
this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
|
||||
break;
|
||||
case Dish.ARRAY_BUFFER:
|
||||
// Array.from() would be nicer here, but it's slightly slower
|
||||
this.value = Array.prototype.slice.call(new Uint8Array(this.value));
|
||||
break;
|
||||
case Dish.BIG_NUMBER:
|
||||
this.value = this.value instanceof BigNumber ? Utils.strToByteArray(this.value.toFixed()) : [];
|
||||
break;
|
||||
case Dish.JSON:
|
||||
this.value = this.value ? Utils.strToByteArray(JSON.stringify(this.value)) : [];
|
||||
break;
|
||||
// case Dish.FILE:
|
||||
// this.value = Utils.readFileSync(this.value);
|
||||
// this.value = Array.prototype.slice.call(this.value);
|
||||
// break;
|
||||
// case Dish.LIST_FILE:
|
||||
// this.value = this.value.map(f => Utils.readFileSync(f));
|
||||
// this.value = this.value.map(b => Array.prototype.slice.call(b));
|
||||
// this.value = [].concat.apply([], this.value);
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this.type = Dish.BYTE_ARRAY;
|
||||
|
||||
// Convert from byteArray to toType
|
||||
switch (toType) {
|
||||
case Dish.STRING:
|
||||
case Dish.HTML:
|
||||
this.value = this.value ? byteArrayToStr(this.value) : "";
|
||||
this.type = Dish.STRING;
|
||||
break;
|
||||
case Dish.NUMBER:
|
||||
this.value = this.value ? parseFloat(byteArrayToStr(this.value)) : 0;
|
||||
this.type = Dish.NUMBER;
|
||||
break;
|
||||
case Dish.ARRAY_BUFFER:
|
||||
this.value = new Uint8Array(this.value).buffer;
|
||||
this.type = Dish.ARRAY_BUFFER;
|
||||
break;
|
||||
case Dish.BIG_NUMBER:
|
||||
try {
|
||||
this.value = new BigNumber(byteArrayToStr(this.value));
|
||||
} catch (err) {
|
||||
this.value = new BigNumber(NaN);
|
||||
}
|
||||
this.type = Dish.BIG_NUMBER;
|
||||
break;
|
||||
case Dish.JSON:
|
||||
this.value = JSON.parse(byteArrayToStr(this.value));
|
||||
this.type = Dish.JSON;
|
||||
break;
|
||||
// case Dish.FILE:
|
||||
// this.value = new File(this.value, "unknown");
|
||||
// break;
|
||||
// case Dish.LIST_FILE:
|
||||
// this.value = [new File(this.value, "unknown")];
|
||||
// this.type = Dish.LIST_FILE;
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default SyncDish;
|
Loading…
Reference in New Issue
Block a user