UNPKG

rtc-client

Version:

Nodejs client for the RTC(Rational Team Concert) Reportable REST API.

224 lines (201 loc) 6.97 kB
const moment = require('moment'); class Utils { } /** * Convert a list of fields to a JSON Object. * * @param {Array} fields list of fields. * * Input: * * ['fieldName/(*)','fieldName2'] * * Output: * * { * fieldName: { * selector: 'fieldName/(*)' * }, * fieldName2: { * selector: 'fieldName2' * } * } */ Utils.convertFieldList2JSON = function (fields) { const result = {}; for (let index = 0; index < fields.length; index++) { const field = fields[index]; if (field.indexOf('/') !== -1) { const fieldName = field.split('/')[0]; result[fieldName] = { selector: field } } else { result[field] = { selector: field } } } return result; } /** * Extract field names from a list of fields. * * @param {Array} fields list of fields. * * Input: * * ['fieldName/(*)','fieldName2'] * * Output * * ['fieldName','fieldName2'] */ Utils.extractFieldNames = function (fields) { const result = []; for (let index = 0; index < fields.length; index++) { const field = fields[index]; if (field.indexOf('/') !== -1) { const fieldName = field.split('/')[0]; result.push(fieldName); } else { result.push(field); } } return result; } /** * Convert filters to RTC url format. * * @param {Object} filters Object with key and value specifying filters. * * Input: * * { * 'id': 123 * } * * Output: * * '[id=123]' */ Utils.parseFilters = function (filters) { const result = []; if (filters) { for (const key in filters) { if (filters.hasOwnProperty(key)) { const value = filters[key]; result.push(`${key}=${value}`); } } } return result.length ? `[${result.join(' and ')}]/` : '/'; } /** * Build the url to workItems based on params. * * @param {string} urlBase url part regards to RTC resource, * e.g., workitem: https://localhost/ccm/rpt/repository/workitem?fields=workItem/workItem * @param {Object} params object with the following properties: * @params.filters: JSON object specifying filters. * Ex: * { * 'type/id': 123 * } * @params.fields: array of field names. It define workItem fields to be retrived from server. * Ex: * ['id', 'type/name', 'owner/(*)'] * @param {Object} BUILT_IN_FIELDS built-in fields of the resource (workitem, foundation, etc.). */ Utils.getURL = function (urlBase, params, BUILT_IN_FIELDS) { const filters = Utils.parseFilters(params.filters); const fieldNames = params.fields ? Utils.extractFieldNames(params.fields) : Object.keys(BUILT_IN_FIELDS); const fields = params.fields ? Utils.convertFieldList2JSON(params.fields) : BUILT_IN_FIELDS; const builtInFields = []; const customFields = []; const customSelectors = []; for (let index = 0; index < fieldNames.length; index++) { const fieldName = fieldNames[index]; if (BUILT_IN_FIELDS[fieldName] !== undefined) { if (fields[fieldName]) { builtInFields.push(fields[fieldName].selector); } else { builtInFields.push(BUILT_IN_FIELDS[fieldName].selector); } } else { customFields.push(fieldName); if (fields[fieldName].selector !== fieldName) { fields[fieldName].selector.split('/')[1]; if (customSelectors.indexOf(fields[fieldName].selector) === -1) { const selector = fields[fieldName].selector; const selectorPrefix = selector.split('/')[0] + '/'; const selectorFields = selector.substring(selectorPrefix.length, selector.length); if (selectorFields !== '(*)'){ customSelectors.push(selectorFields); } } } } } const formattedFields = builtInFields.join('|'); const formattedCustomFields = customFields.length ? `|allExtensions[key=${customFields.join(' or key=')}]/(${customSelectors.join('|') || '*'}))` : ')'; const url = `${urlBase}${filters}(${formattedFields}${formattedCustomFields}`; return url; } /** * Parse a extension field. Data retrived from RTC server is polluted, so that is necessary to * parse extensions to build a new extension object. * * @param {Object} field field object to be parsed. */ Utils.parseExtension = function (field) { const literalTypes = ['booleanValue','integerValue','longValue','doubleValue','smallStringValue', 'mediumStringValue','largeStringValue','timestampValue','decimalValue']; const numberTypes = ['integerValue','longValue','doubleValue','decimalValue']; const fieldType = field.type; const obj = { key: field.key, type: fieldType, helperId: field.helperId } if (literalTypes.indexOf(fieldType) !== -1) { if (numberTypes.indexOf(fieldType) !== -1){ obj[fieldType] = Number(field[fieldType]); } else if (fieldType === 'timestampValue') { obj[fieldType] = field[fieldType] ? moment(field[fieldType]).toDate() : null; } else { obj[fieldType] = field[fieldType]; } obj['displayValue'] = field['displayValue']; } else { if (fieldType === 'itemValue') { obj['itemValue'] = field.itemValue ? field.itemValue.itemId : null; obj['itemType'] = field.itemValue ? field.itemValue.itemType : null; } else { for (const prop in field) { if (field.hasOwnProperty(prop)) { obj[prop] = field[prop]; } } } } return obj; } Utils.parseBuiltInField = function (fieldName, fieldValue, BUILT_IN_FIELDS) { const numberTypes = ['xs:integer','xs:long']; const dateTypes = ['xs:time','xs:date']; const fieldType = BUILT_IN_FIELDS[fieldName] ? BUILT_IN_FIELDS[fieldName].type : ''; if (fieldValue && numberTypes.indexOf(fieldType) !== -1) { return Number(fieldValue); } else if (fieldValue && dateTypes.indexOf(fieldType) !== -1) { return moment(fieldValue).toDate(); } else if (fieldValue && fieldType === 'xs:boolean'){ return fieldValue === 'true' ? true : false; } else { return fieldValue; } } module.exports = Utils;