diff --git a/lib/Deprecated.js b/lib/Deprecated.js index de696348..e23ad97c 100644 --- a/lib/Deprecated.js +++ b/lib/Deprecated.js @@ -64,16 +64,46 @@ class iPgm { * @param {string | array} data * @param {string} [type] * @param {object} options - * @param {*} inDs */ - addParam(data, type, options, inDs) { - if (!Array.isArray(data) && !type) { - iPgmDeprecate('defaulting parameter type to 1024a has been deprecated. You should specify a type instead.'); - // eslint-disable-next-line no-param-reassign - type = '1024a'; + addParam(data, type, options) { + const parameter = {}; + + if (Array.isArray(data)) { // DS parameter + parameter.type = 'ds'; + parameter.fields = []; + + if (typeof type === 'object') { // options + Object.keys(type).forEach((key) => { + parameter[key] = type[key]; + }); + } + // convert 2D Array into fields [] of data objects + for (let i = 0; i < data.length; i += 1) { + const field = { type: data[i][1], value: data[i][0] }; + if (typeof data[i][2] === 'object') { + Object.keys(data[i][2]).forEach((key) => { // options + field[key] = data[i][2][key]; + }); + } + parameter.fields.push(field); + } + } else { + parameter.type = type; + parameter.value = data; + if (!type) { + iPgmDeprecate('defaulting parameter type to 1024a has been deprecated. You should specify a type instead.'); + parameter.type = '1024a'; + } + + if (typeof options === 'object') { // options + Object.keys(options).forEach((key) => { + parameter[key] = options[key]; + }); + } } + iPgmDeprecate('As of v1.0, \'iPgm.addParam()\' is deprecated. Please use \'ProgramCall.addParam()\' instead.'); - return this.ProgramCall.addParam(data, type, options, inDs); + return this.ProgramCall.addParam(parameter); } /** diff --git a/lib/ProgramCall.js b/lib/ProgramCall.js index 71188c87..fb726d7f 100644 --- a/lib/ProgramCall.js +++ b/lib/ProgramCall.js @@ -16,6 +16,8 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/* eslint-disable no-underscore-dangle */ + class ProgramCall { /** * @description creates a new ProgramCall object @@ -31,59 +33,62 @@ class ProgramCall { } /** - * @description adds a parameter to the program XML - * @param {string | array} data - * @param {string} [type] - * @param {object} options - * @param {*} inDs - */ - addParam(data, type, options, inDs = null) { - let opt; - // DS element has no 'type', so if the second param 'type' is an Object, then it is the options. - if (Array.isArray(data)) { - opt = type; - } else { - opt = options; - if (type === undefined) { - throw new Error('Specifying the parameter type is required.'); - } - } - if (!inDs) { // In recursive mode, if it is an element in DS, then no or needed. - this.xml += ' options - if (opt.io) { this.xml += ` io='${opt.io}'`; } - if (opt.by) { this.xml += ` by='${opt.by}'`; } - } - this.xml += '>'; - } - - if (Array.isArray(data)) { // If it is a struct parameter, recursively parse its children. + * Internal function to handle ds and data within node + * There is an open propsal to add private methods to JS. + * https://github.com/tc39/proposal-private-methods + * We should update to use private methods in the future. + * @param {object} data + */ + __addData__(data = {}) { + if (data.type === 'ds') { this.xml += ' options - if (opt.dim) { this.xml += ` dim='${opt.dim}'`; } - if (opt.dou) { this.xml += ` dou='${opt.dou}'`; } - if (opt.len) { this.xml += ` len='${opt.len}'`; } - if (opt.data) { this.xml += ` data='${opt.data}'`; } - } + // append options + if (data.name) { this.xml += ` name='${data.name}'`; } + if (data.dim) { this.xml += ` dim='${data.dim}'`; } + if (data.dou) { this.xml += ` dou='${data.dou}'`; } + if (data.len) { this.xml += ` len='${data.len}'`; } + if (data.data) { this.xml += ` data='${data.data}'`; } this.xml += '>'; - for (let i = 0; i < data.length; i += 1) { - this.addParam(data[i][0], data[i][1], data[i][2], true); + for (let i = 0; i < data.fields.length; i += 1) { + this.__addData__(data.fields[i]); } this.xml += ''; - } else { // A simple parameter - this.xml += ` options - Object.keys(opt).forEach((key) => { - this.xml += ` ${key}='${opt[key]}'`; - }); - } - this.xml += `>${data}`; + } else { + this.xml += ` options + if (data.name) { this.xml += ` name='${data.name}'`; } + if (data.varying) { this.xml += ` varying='${data.varying}'`; } + if (data.enddo) { this.xml += ` enddo='${data.enddo}'`; } + if (data.setlen) { this.xml += ` setlen='${data.setlen}'`; } + if (data.offset) { this.xml += ` offset='${data.offset}'`; } + if (data.hex) { this.xml += ` hex='${data.hex}'`; } + if (data.trim) { this.xml += ` trim='${data.trim}'`; } + if (data.next) { this.xml += ` next='${data.next}'`; } + this.xml += `>${data.value}`; } + } - if (!inDs) { // In recursive mode, if it is an element in DS, then no or needed. - this.xml += ''; + /** + * @description adds a parameter to the program XML + * @param {object} parmeter + */ + addParam(parameter = {}) { + if (typeof parameter !== 'object') { + throw new Error('Expected the first parameter to be an object'); + } + if (parameter.type === undefined) { + throw new Error('Expected \'type\' key on the parameter object'); } + this.xml += ' { @@ -71,7 +71,7 @@ describe('ProgramCall Class Unit Tests', () => { error: 'fast', }); - pgm.addParam(outBuf, { io: 'out' }); + pgm.addParam({ type: 'ds', io: 'out', fields: outBuf }); let expectedXML = '' + '0' @@ -81,7 +81,7 @@ describe('ProgramCall Class Unit Tests', () => { expect(pgm.toXML()).to.equal(expectedXML); - pgm.addParam(66, '10i0'); + pgm.addParam({ value: 66, type: '10i0' }); expectedXML = '' + '0' @@ -92,7 +92,7 @@ describe('ProgramCall Class Unit Tests', () => { expect(pgm.toXML()).to.equal(expectedXML); - pgm.addParam(1, '10i0'); + pgm.addParam({ value: 1, type: '10i0' }); expectedXML = '' + '0' @@ -104,7 +104,7 @@ describe('ProgramCall Class Unit Tests', () => { expect(pgm.toXML()).to.equal(expectedXML); - pgm.addParam('QCCSID', '10A'); + pgm.addParam({ value: 'QCCSID', type: '10A' }); expectedXML = '' + '0' @@ -117,7 +117,9 @@ describe('ProgramCall Class Unit Tests', () => { expect(pgm.toXML()).to.equal(expectedXML); - pgm.addParam(errno, { io: 'both', len: 'rec2' }); + pgm.addParam({ + type: 'ds', io: 'both', len: 'rec2', fields: errno, + }); expectedXML = '' + '0' @@ -137,8 +139,8 @@ describe('ProgramCall Class Unit Tests', () => { it('regular contains by=\'val\'', () => { const pgm = new ProgramCall('MYPGM', { lib: 'MYLIB', func: 'MY_PROCEDURE' }); - pgm.addParam('', '1A', { by: 'val' }); - pgm.addReturn('', '2A', { name: 'output' }); + pgm.addParam({ value: '', type: '1A', by: 'val' }); + pgm.addReturn('', '2A', 'output'); const lookAtXML = pgm.toXML(); expect(lookAtXML).to.match(//); @@ -148,11 +150,13 @@ describe('ProgramCall Class Unit Tests', () => { const pgm = new ProgramCall('MYPGM', { lib: 'MYLIB', func: 'MY_PROCEDURE' }); const params = [ - [0, '3s0'], - [0, '7s0', { name: 'ds_fld2' }], + { type: '3s0', value: 0 }, + { type: '7s0', value: 0, name: 'ds_fld2' }, ]; - pgm.addParam(params, { name: 'inds', by: 'val' }); + pgm.addParam({ + name: 'inds', type: 'ds', by: 'val', fields: params, + }); pgm.addReturn('', '2A', { name: 'output' }); const lookAtXML = pgm.toXML(); @@ -162,7 +166,9 @@ describe('ProgramCall Class Unit Tests', () => { it('regular contains by=\'val\', with io=\'both\'', () => { const pgm = new ProgramCall('MYPGM', { lib: 'MYLIB', func: 'MY_PROCEDURE' }); - pgm.addParam('', '1A', { by: 'val', io: 'both' }); + pgm.addParam({ + value: '', type: '1A', by: 'val', io: 'both', + }); pgm.addReturn('', '2A', { name: 'output' }); const lookAtXML = pgm.toXML(); @@ -174,11 +180,13 @@ describe('ProgramCall Class Unit Tests', () => { const pgm = new ProgramCall('MYPGM', { lib: 'MYLIB', func: 'MY_PROCEDURE' }); const params = [ - [0, '3s0'], - [0, '7s0', { name: 'ds_fld2' }], + { type: '3s0', value: 0 }, + { type: '7s0', value: 0, name: 'ds_fld2' }, ]; - pgm.addParam(params, { name: 'inds', by: 'val', io: 'both' }); + pgm.addParam({ + name: 'inds', type: 'ds', by: 'val', io: 'both', fields: params, + }); pgm.addReturn('', '2A', { name: 'output' }); const lookAtXML = pgm.toXML();