Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 6 additions & 161 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,162 +1,7 @@
'use strict';

const OFF = 'off';
const ERROR = 'error';
const WARN = 'warn';
const ALWAYS = 'always';
const NEVER = 'never';

module.exports = {
'parserOptions': {
ecmaVersion: 2017
},
'env': {
es6: true,
node: true,
mocha: true
},
'plugins': [
'mocha'
],
'extends': 'airbnb-base',
'rules': {
'indent': [
ERROR,
4,
{
SwitchCase: 1
}
],
'linebreak-style': ERROR,
'quotes': [
WARN,
'single',
{
avoidEscape: true,
allowTemplateLiterals: true
}
],
'semi': [
ERROR,
ALWAYS
],
'func-names': ERROR,
'no-empty': ERROR,
'no-empty-function': ERROR,
'brace-style': [
ERROR,
'1tbs',
{ allowSingleLine: true }
],
'no-multiple-empty-lines': ERROR,
'no-multi-spaces': ERROR,
'one-var': [
ERROR,
NEVER
],
'quote-props': [
WARN,
'consistent-as-needed'
],
'key-spacing': ERROR,
'space-unary-ops': [
ERROR,
{
words: true,
nonwords: false
}
],
'no-spaced-func': ERROR,
'space-before-function-paren': [
ERROR,
{
anonymous: ALWAYS,
named: NEVER
}
],
'arrow-body-style': [
WARN,
'as-needed'
],
'array-bracket-spacing': ERROR,
'space-in-parens': ERROR,
'comma-dangle': ERROR,
'no-trailing-spaces': ERROR,
'yoda': ERROR,
'max-len': [
ERROR,
120
],
'camelcase': [
ERROR,
{
properties: 'never'
}
],
'new-cap': [
WARN,
{
capIsNewExceptions: ['Q']
}
],
'comma-style': ERROR,
'curly': ERROR,
'object-curly-spacing': [
WARN,
ALWAYS
],
'object-curly-newline': [
ERROR,
{
ObjectExpression: {
minProperties: 1
},
ObjectPattern: {
multiline: true,
minProperties: 5
}
}
],
'object-property-newline': ERROR,
'template-curly-spacing': ERROR,
'dot-notation': ERROR,
'dot-location': [
ERROR,
'property'
],
'func-style': [
ERROR,
'declaration',
{
allowArrowFunctions: true
}
],
'eol-last': ERROR,
'space-infix-ops': ERROR,
'keyword-spacing': ERROR,
'space-before-blocks': ERROR,
'no-invalid-this': ERROR,
'consistent-this': ERROR,
'no-this-before-super': ERROR,
'no-unreachable': ERROR,
'no-sparse-arrays': ERROR,
'array-callback-return': ERROR,
'strict': [
WARN,
'global'
],
'eqeqeq': ERROR,
'no-use-before-define': WARN,
'no-undef': ERROR,
'no-unused-vars': WARN,
'no-mixed-spaces-and-tabs': ERROR,
'operator-linebreak': [
ERROR,
'before'
],
'no-console': [
OFF
],
"mocha/no-exclusive-tests": "error"
}
};
'extends': 'airbnb-base',
'env': {
'mocha': true,
'node': true,
}
};
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 1.2.0 (January 30, 2020)

* Update sailor version to 2.6.1
* Refactor console.log to built in sailor logger
* Change build type to docker

## 1.1.1 (September 25, 2019)

* Upload attachments with component commons library
Expand Down
1 change: 1 addition & 0 deletions component.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"title": "XML",
"description": "Component to work with XML files",
"buildType": "docker",
"actions": {
"xmlToJson": {
"title": "XML to JSON",
Expand Down
100 changes: 51 additions & 49 deletions lib/actions/attachmentToJson.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-await-in-loop */
const sizeof = require('object-sizeof');
const { AttachmentProcessor } = require('@elastic.io/component-commons-library');
const { messages } = require('elasticio-node');
Expand All @@ -6,69 +7,70 @@ const xml2Json = require('../xml2Json.js');

const MAX_FILE_SIZE = 5242880; // 5 MiB

function checkFileName(fileName, pattern) {
if (fileName === undefined) {
return false;
}
function checkFileName(self, fileName, pattern) {
if (fileName === undefined) {
return false;
}

if (!pattern.test(fileName)) {
console.log('%s does not match pattern: \'%s\'', fileName, pattern);
return false;
}
if (!pattern.test(fileName)) {
self.logger.debug('%s does not match pattern: \'%s\'', fileName, pattern);
return false;
}

if (fileName.split('.').pop() !== 'xml') {
console.log('%s is not .xml file: ', fileName);
return false;
}
if (fileName.split('.').pop() !== 'xml') {
self.logger.debug('%s is not .xml file: ', fileName);
return false;
}

return true;
return true;
}

module.exports.process = async function processAction(msg, cfg) {
const { attachments } = msg;
const pattern = new RegExp(cfg !== undefined ? cfg.pattern || '(.xml)' : '(.xml)');
let foundXML = false;
const self = this;
const { attachments } = msg;
const pattern = new RegExp(cfg !== undefined ? cfg.pattern || '(.xml)' : '(.xml)');
let foundXML = false;

console.log('Attachment to XML started');
console.log('Found %s attachments', Object.keys(attachments || {}).length);
self.logger.info('Attachment to XML started');
self.logger.info('Found %s attachments', Object.keys(attachments || {}).length);

// eslint-disable-next-line no-restricted-syntax
for (const key of Object.keys(attachments)) {
const attachment = attachments[key];
const fileName = key;
let fileSize = attachment.size; // get file size based attachment object may not be define or be accurate
console.log('Processing attachment=%s', fileName);
// eslint-disable-next-line no-restricted-syntax
for (const key of Object.keys(attachments)) {
const attachment = attachments[key];
const fileName = key;
// get file size based attachment object may not be define or be accurate
let fileSize = attachment.size;
self.logger.info('Processing attachment=%s', fileName);

if (checkFileName(fileName, pattern)) {
if (fileSize === undefined || fileSize < MAX_FILE_SIZE) {
// eslint-disable-next-line no-await-in-loop
const response = await new AttachmentProcessor().getAttachment(attachment.url, 'arraybuffer');
if (checkFileName(self, fileName, pattern)) {
if (fileSize === undefined || fileSize < MAX_FILE_SIZE) {
// eslint-disable-next-line no-await-in-loop
const response = await new AttachmentProcessor().getAttachment(attachment.url, 'arraybuffer');

if (response.status >= 400) {
throw new Error(`Error in making request to ${attachment.url}
if (response.status >= 400) {
throw new Error(`Error in making request to ${attachment.url}
Status code: ${response.status},
Body: ${Buffer.from(response.data, 'binary').toString('base64')}`);
}
}

const responseBodyString = Buffer.from(response.data, 'binary').toString('utf-8');
fileSize = sizeof(responseBodyString);
const responseBodyString = Buffer.from(response.data, 'binary').toString('utf-8');
fileSize = sizeof(responseBodyString);

if (fileSize < MAX_FILE_SIZE) {
// eslint-disable-next-line no-await-in-loop
const returnMsg = await xml2Json.process(responseBodyString);
this.emit('data', messages.newMessageWithBody(returnMsg.body));
foundXML = true;
} else {
throw new Error(`Attachment ${key} is too large to be processed my XML component.`
+ ` File limit is: ${MAX_FILE_SIZE} byte, file given was: ${fileSize} byte.`);
}
} else {
throw new Error(`Attachment ${key} is too large to be processed my XML component.`
+ ` File limit is: ${MAX_FILE_SIZE} byte, file given was: ${fileSize} byte.`);
}
if (fileSize < MAX_FILE_SIZE) {
const returnMsg = await xml2Json.process(this, responseBodyString);
foundXML = true;
await self.emit('data', messages.newMessageWithBody(returnMsg.body));
} else {
throw new Error(`Attachment ${key} is too large to be processed my XML component.`
+ ` File limit is: ${MAX_FILE_SIZE} byte, file given was: ${fileSize} byte.`);
}
} else {
throw new Error(`Attachment ${key} is too large to be processed my XML component.`
+ ` File limit is: ${MAX_FILE_SIZE} byte, file given was: ${fileSize} byte.`);
}
}
if (!foundXML) {
console.log(`No XML files that match the pattern found with in attachments. Pattern: ${pattern}`);
}
}
if (!foundXML) {
self.logger.info(`No XML files that match the pattern found with in attachments. Pattern: ${pattern}`);
}
};
60 changes: 30 additions & 30 deletions lib/actions/jsonToXml.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ const propNameIsInvalid = (key) => /^\d/.test(key);
* @param {String} key
*/
function validateJsonPropNames(value, key) {
if (propNameIsInvalid(key)) {
const message = 'Can\'t create XML element from prop that starts with digit.'
+ 'See XML naming rules https://www.w3schools.com/xml/xml_elements.asp';
throw new Error(`${ERROR}: ${key}. ${message}`);
}
if (propNameIsInvalid(key)) {
const message = 'Can\'t create XML element from prop that starts with digit.'
+ 'See XML naming rules https://www.w3schools.com/xml/xml_elements.asp';
throw new Error(`${ERROR}: ${key}. ${message}`);
}

if (!_.isPlainObject(value)) {
return;
}
if (!_.isPlainObject(value)) {
return;
}

Object.keys(value).forEach((prop) => {
validateJsonPropNames(value[prop], prop);
});
Object.keys(value).forEach((prop) => {
validateJsonPropNames(value[prop], prop);
});
}

/**
Expand All @@ -42,28 +42,28 @@ function validateJsonPropNames(value, key) {
* @param cfg configuration that is account information and configuration field values
*/
function processAction(msg, cfg) {
console.log('Action started, message=%j cfg=%j', msg, cfg);
const options = {
trim: false,
normalize: false,
explicitArray: false,
normalizeTags: false,
attrkey: '_attr',
tagNameProcessors: [
(name) => name.replace(':', '-'),
],
};
const builder = new xml2js.Builder(options);
this.logger.debug('Action started, message=%j cfg=%j', msg, cfg);
const options = {
trim: false,
normalize: false,
explicitArray: false,
normalizeTags: false,
attrkey: '_attr',
tagNameProcessors: [
(name) => name.replace(':', '-'),
],
};
const builder = new xml2js.Builder(options);

const jsonToTransform = msg.body;
const jsonToTransform = msg.body;

validateJsonPropNames(jsonToTransform);
validateJsonPropNames(jsonToTransform);

const result = builder.buildObject(jsonToTransform);
console.log('Successfully converted body to XML result=%s', result);
return eioUtils.newMessageWithBody({
xmlString: result,
});
const result = builder.buildObject(jsonToTransform);
this.logger.debug('Successfully converted body to XML result=%s', result);
return eioUtils.newMessageWithBody({
xmlString: result,
});
}

module.exports.process = processAction;
Loading