All files jura.js

100% Statements 30/30
100% Branches 4/4
100% Functions 5/5
100% Lines 28/28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117                                1x 1x 1x 1x 1x       1x                                   3x           3x 3x 3x   3x 3x                         3x                             1x   1x         1x   1x 1x 1x 1x 1x 1x 1x 1x 1x                     1x 1x         1x  
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
'use strict';
 
const Engine=require('./juracore.js');
const Fs = require('fs');
const Path = require('path');
const Moment = require('moment');
const CTOParser = require('composer-common/lib/introspect/parser');
 
const {
    VM
} = require('vm2');
 
/**
 * Utility class that implements the internals for Jura.
 * @class
 */
class Jura {
    /**
     * Compile Jura to JavaScript
     *
     * @param {string} juraText text for Jura code
     * @param {string} contractName of the contract to compile
     * @param {string} clauseName of the clause to compile
     * @param {bool} withDispatch whether to generate dispatch function
     * @returns {string} The compiled JavaScript code
     */
    static compileToJavaScript(juraText,contractName,clauseName,withDispatch) {
        // Built-in config
        const config= {
            'source' : 'jura',
            'target' : 'javascript',
            'withdispatch' : withDispatch
        };
        // Clean-up naming for Sexps
        config.jura = juraText;
        if (contractName !== null) { config.contract = contractName; }
        if (clauseName !== null) { config.clause = clauseName; }
        // Call compiler
        const compiled = Engine.Jura.compile(config).result;
        return compiled;
    }
 
    /**
     * Compile Jura
     *
     * @param {string} juraText text for Jura code
     * @param {string} contractName of the contract to compile
     * @param {string} clauseName of the clause to compile
     * @param {bool} withDispatch whether to generate dispatch function
     * @returns {object} Promise to the compiled JavaScript code
     */
    static compile(juraText,contractName,clauseName,withDispatch) {
        return Promise.resolve(this.compileToJavaScript(juraText,contractName,clauseName,withDispatch));
    }
 
    /**
     * Execute Jura
     *
     * @param {string} juraText text for Jura code
     * @param {object} clauseJson path to the clause data in JSON
     * @param {object} requestJson path to the request transaction in JSON
     * @param {string} contractName of the contract to execute
     * @param {string} clauseName of the clause to execute
     * @param {bool} withDispatch whether to generate dispatch function
     * @returns {object} Promise to the result of execution
     */
    static execute(juraText,clauseJson,requestJson,contractName,clauseName,withDispatch) {
        const jurRuntime = Fs.readFileSync(Path.join(__dirname,'juraruntime.js'), 'utf8');
 
        const vm = new VM({
            timeout: 1000,
            sandbox: { moment: Moment }
        });
 
        return (this.compile(juraText,null,null,withDispatch)).then((juraCode) => {
            // add immutables to the context
            const params = { 'this': clauseJson, 'request': requestJson, 'now': Moment() };
            vm.freeze(params, 'params'); // Add the context
            vm.run(jurRuntime); // Load the runtime
            vm.run(juraCode); // Load the generated logic
            const contract = 'let contract = new ' + contractName+ '();'; // Instantiate the contract
            const functionName = 'contract.' + clauseName;
            const clauseCall = functionName+'(params);'; // Create the clause call
            const res = vm.run(contract + clauseCall); // Call the logic
            return res;
        });
    }
 
    /**
     * Parse CTO to JSON
     *
     * @param {string} ctoText text for CTO model
     * @returns {object} The parsed CTO model syntax tree in JSON
     */
    static parseCTO(ctoText) {
        const result = CTOParser.parse(ctoText);
        return Promise.resolve(result);
    }
 
}
 
module.exports = Jura;