cloud-red
Version:
Serverless Node-RED for your cloud integration needs
768 lines (747 loc) • 29.3 kB
HTML
<script type="text/x-red" data-template-name="lambda-handler">
<!-- <div class="form-row">
<label for="node-input-config"><i class="fa fa-tag"></i> <span data-i18n="aws.config"></span></label>
<input type="text" id="node-input-config" data-i18n="[placeholder]aws.config">
</div> -->
<div class="form-row">
<label for="node-input-name">
<i class="fa fa-tag"></i>
<span data-i18n="common.label.name"></span>
</label>
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div>
<div class="form-row node-input-rule-container-row">
<label for="node-input-name"><i class="fa fa-tag"></i><span> Event</span></label>
<ol id="node-input-rule-container"></ol>
</div>
</script>
<script type="text/x-red" data-help-name="lambda-handler">
<p>Creates a handler for your Lambda function that processes events. When you invoke a lambda, the runtime runs this handler node. When the handler exits or returns a response, it becomes available to handle another event.</p>
<h3>Outputs</h3>
<ol class="node-ports">
<li>APIGateway Event
<dl class="message-properties">
<dt>payload <span class="property-type">string</span></dt>
<dd>the standard output of the command.</dd>
</dl>
</li>
<li>S3 Event
<dl class="message-properties">
<dt>payload <span class="property-type">string</span></dt>
<dd>the standard error of the command.</dd>
</dl>
</li>
</ol>
<h3>Details</h3>
<p><code>msg.payload</code> is used as the payload of the published message.
If it contains an Object it will be converted to a JSON string before being sent.
If it contains a binary Buffer the message will be published as-is.</p>
<p>The topic used can be configured in the node or, if left blank, can be set
by <code>msg.topic</code>.</p>
<p>Likewise the QoS and retain values can be configured in the node or, if left
blank, set by <code>msg.qos</code> and <code>msg.retain</code> respectively.</p>
<h3>References</h3>
<ul>
<li><a>AWS Lambda Handler in Node.JS</a> - full description of <code>msg.tweet</code> property</li>
<li><a>GitHub</a> - the nodes github repository</li>
</ul>
</script>
<script type="text/x-red" data-template-name="lambda-response">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div>
<div class="form-row">
<label for="node-input-statusCode"><i class="fa fa-long-arrow-left"></i> <span data-i18n="httpin.label.status"></span></label>
<input type="text" id="node-input-statusCode" placeholder="msg.statusCode">
</div>
<div class="form-row" style="margin-bottom:0;">
<label><i class="fa fa-list"></i> <span data-i18n="httpin.label.headers"></span></label>
</div>
<div class="form-row node-input-headers-container-row">
<ol id="node-input-headers-container"></ol>
</div>
<div class="form-tips"><span data-i18n="[html]httpin.tip.res"></span></div>
</script>
<script type="text/javascript">
(function() {
var operators = [
{ v: 'S3 Event', t: 'S3 Event', kind: 'V' },
{ v: 'APIGateway Event', t: 'APIGateway Event', kind: 'V' },
{ v: 'SNS Event', t: 'SNS Event', kind: 'V' },
{ v: 'SQS Event', t: 'SQS Event', kind: 'V' },
{ v: 'DynamoDBStream Event', t: 'DynamoDBStream Event', kind: 'V' },
{ v: 'CognitoUserPool Event', t: 'CognitoUserPool Event', kind: 'V' },
{ v: 'Scheduled Event', t: 'Scheduled Event', kind: 'V' }
];
function clipValueLength(v) {
if (v.length > 15) {
return v.substring(0, 15) + '...';
}
return v;
}
function prop2name(key) {
var result = RED.utils.parseContextKey(key);
return result.key;
}
function getValueLabel(t, v) {
if (t === 'str') {
return '"' + clipValueLength(v) + '"';
} else if (t === 'msg') {
return t + '.' + clipValueLength(v);
} else if (t === 'flow' || t === 'global') {
return t + '.' + clipValueLength(prop2name(v));
}
return clipValueLength(v);
}
RED.nodes.registerType('lambda-handler', {
category: 'input',
color: 'rgb(231, 231, 174)',
defaults: {
// config: { value: '', type: 'aws-config' },
name: { value: '' },
url: { value: '/*', required: true },
method: { value: 'POST', required: true },
rules: { value: [{ t: 'eq', v: '', vt: 'str' }] },
outputs: { value: 1 }
},
inputs: 0,
outputs: 1,
outputLabels: function(index) {
var rule = this.rules[index];
var label = '';
if (rule) {
for (var i = 0; i < operators.length; i++) {
if (operators[i].v === rule.t) {
label = /^switch/.test(operators[i].t)
? this._(operators[i].t)
: operators[i].t;
break;
}
}
if (rule.t === 'btwn' || rule.t === 'index') {
label +=
' ' +
getValueLabel(rule.vt, rule.v) +
' & ' +
getValueLabel(rule.v2t, rule.v2);
} else if (
rule.t !== 'true' &&
rule.t !== 'false' &&
rule.t !== 'null' &&
rule.t !== 'nnull' &&
rule.t !== 'empty' &&
rule.t !== 'nempty' &&
rule.t !== 'else'
) {
label += ' ' + getValueLabel(rule.vt, rule.v);
}
return label;
}
},
icon: 'white-globe.png',
label: function() {
return 'AWS handler';
},
labelStyle: function() {
return this.name ? 'node_label_italic' : '';
},
oneditprepare: function() {
var node = this;
var previousValueType = {
value: 'prev',
label: this._('inject.previous'),
hasValue: false
};
$('#node-input-property').typedInput({
default: this.propertyType || 'msg',
types: ['msg', 'flow', 'global', 'jsonata']
});
var outputCount = $('#node-input-outputs').val('{}');
var andLabel = this._('switch.and');
var caseLabel = this._('switch.ignorecase');
function resizeRule(rule) {
var newWidth = rule.width();
var selectField = rule.find('select');
var type = selectField.val() || '';
var valueField = rule.find('.node-input-rule-value');
var typeField = rule.find('.node-input-rule-type-value');
var numField = rule.find('.node-input-rule-num-value');
var expField = rule.find('.node-input-rule-exp-value');
var btwnField1 = rule.find('.node-input-rule-btwn-value');
var btwnField2 = rule.find('.node-input-rule-btwn-value2');
var selectWidth = 220;
// if (type.length < 4) {
// selectWidth = 60;
// } else if (type === "regex") {
// selectWidth = 160;
// } else {
// selectWidth = 220;
// }
selectField.width(selectWidth);
if (type === 'btwn' || type === 'index') {
btwnField1.typedInput('width', newWidth - selectWidth - 70);
btwnField2.typedInput('width', newWidth - selectWidth - 70);
} else if (type === 'head' || type === 'tail') {
numField.typedInput('width', newWidth - selectWidth - 70);
} else if (type === 'jsonata_exp') {
expField.typedInput('width', newWidth - selectWidth - 70);
} else if (type === 'istype') {
typeField.typedInput('width', newWidth - selectWidth - 70);
} else {
if (
type === 'true' ||
type === 'false' ||
type === 'null' ||
type === 'nnull' ||
type === 'empty' ||
type === 'nempty' ||
type === 'else'
) {
// valueField.hide();
} else {
valueField.typedInput('width', newWidth - selectWidth - 70);
}
}
}
$('#node-input-rule-container')
.css('min-height', '250px')
.css('min-width', '450px')
.editableList({
addItem: function(container, i, opt) {
if (!opt.hasOwnProperty('r')) {
opt.r = {};
}
var rule = opt.r;
if (!rule.hasOwnProperty('t')) {
rule.t = 'eq';
}
if (!opt.hasOwnProperty('i')) {
opt._i = Math.floor(
(0x99999 - 0x10000) * Math.random()
).toString();
}
container.css({
overflow: 'hidden',
whiteSpace: 'nowrap'
});
var row = $('<div/>').appendTo(container);
var row2 = $('<div/>', {
style: 'padding-top: 5px; padding-left: 175px;'
}).appendTo(container);
var row3 = $('<div/>', {
style: 'padding-top: 5px; padding-left: 102px;'
}).appendTo(container);
var selectField = $('<select/>', {
style: 'width:120px; margin-left: 5px; text-align: center;'
}).appendTo(row);
var group0 = $('<optgroup/>', { label: 'value rules' }).appendTo(
selectField
);
for (var d in operators) {
if (operators[d].kind === 'V') {
group0.append(
$('<option></option>')
.val(operators[d].v)
.text(
/^switch/.test(operators[d].t)
? node._(operators[d].t)
: operators[d].t
)
);
}
}
var group1 = $('<optgroup/>', {
label: 'sequence rules'
}).appendTo(selectField);
for (var d in operators) {
if (operators[d].kind === 'S') {
group1.append(
$('<option></option>')
.val(operators[d].v)
.text(
/^switch/.test(operators[d].t)
? node._(operators[d].t)
: operators[d].t
)
);
}
}
for (var d in operators) {
if (operators[d].kind === 'O') {
selectField.append(
$('<option></option>')
.val(operators[d].v)
.text(
/^switch/.test(operators[d].t)
? node._(operators[d].t)
: operators[d].t
)
);
}
}
var valueField = $('<input/>', {
class: 'node-input-rule-value',
type: 'text',
style: 'margin-left: 5px;'
})
.appendTo(row)
.typedInput({
default: 'str',
types: [
'msg',
'flow',
'global',
'str',
'num',
'jsonata',
'env',
previousValueType
]
});
var numValueField = $('<input/>', {
class: 'node-input-rule-num-value',
type: 'text',
style: 'margin-left: 5px;'
})
.appendTo(row)
.typedInput({
default: 'num',
types: ['flow', 'global', 'num', 'jsonata', 'env']
});
var expValueField = $('<input/>', {
class: 'node-input-rule-exp-value',
type: 'text',
style: 'margin-left: 5px;'
})
.appendTo(row)
.typedInput({ default: 'jsonata', types: ['jsonata'] });
var btwnValueField = $('<input/>', {
class: 'node-input-rule-btwn-value',
type: 'text',
style: 'margin-left: 5px;'
})
.appendTo(row)
.typedInput({
default: 'num',
types: [
'msg',
'flow',
'global',
'str',
'num',
'jsonata',
'env',
previousValueType
]
});
var btwnAndLabel = $('<span/>', {
class: 'node-input-rule-btwn-label'
})
.text(' ' + andLabel + ' ')
.appendTo(row3);
var btwnValue2Field = $('<input/>', {
class: 'node-input-rule-btwn-value2',
type: 'text',
style: 'margin-left:2px;'
})
.appendTo(row3)
.typedInput({
default: 'num',
types: [
'msg',
'flow',
'global',
'str',
'num',
'jsonata',
'env',
previousValueType
]
});
var typeValueField = $('<input/>', {
class: 'node-input-rule-type-value',
type: 'text',
style: 'margin-left: 5px;'
})
.appendTo(row)
.typedInput({
default: 'string',
types: [
{ value: 'string', label: 'string', hasValue: false },
{ value: 'number', label: 'number', hasValue: false },
{ value: 'boolean', label: 'boolean', hasValue: false },
{ value: 'array', label: 'array', hasValue: false },
{ value: 'buffer', label: 'buffer', hasValue: false },
{ value: 'object', label: 'object', hasValue: false },
{ value: 'json', label: 'JSON string', hasValue: false },
{ value: 'undefined', label: 'undefined', hasValue: false },
{ value: 'null', label: 'null', hasValue: false }
]
});
var finalspan = $('<span/>', {
style: 'float: right;margin-top: 6px;'
}).appendTo(row);
finalspan.append(
' → <span class="node-input-rule-index">' +
(i + 1) +
'</span> '
);
var caseSensitive = $('<input/>', {
id: 'node-input-rule-case-' + i,
class: 'node-input-rule-case',
type: 'checkbox',
style: 'width:auto;vertical-align:top'
}).appendTo(row2);
$('<label/>', {
for: 'node-input-rule-case-' + i,
style: 'margin-left: 3px;'
})
.text(caseLabel)
.appendTo(row2);
selectField.change(function() {
resizeRule(container);
var type = selectField.val();
typeValueField.typedInput('hide');
valueField.typedInput('hide');
expValueField.typedInput('hide');
numValueField.typedInput('hide');
btwnValueField.typedInput('hide');
btwnValue2Field.typedInput('hide');
row2.hide();
row3.hide();
});
selectField.val(rule.t);
if (rule.t == 'btwn' || rule.t == 'index') {
btwnValueField.typedInput('value', rule.v);
btwnValueField.typedInput('type', rule.vt || 'num');
btwnValue2Field.typedInput('value', rule.v2);
btwnValue2Field.typedInput('type', rule.v2t || 'num');
} else if (rule.t === 'head' || rule.t === 'tail') {
numValueField.typedInput('value', rule.v);
numValueField.typedInput('type', rule.vt || 'num');
} else if (rule.t === 'istype') {
typeValueField.typedInput('value', rule.vt);
typeValueField.typedInput('type', rule.vt);
} else if (rule.t === 'jsonata_exp') {
expValueField.typedInput('value', rule.v);
expValueField.typedInput('type', rule.vt || 'jsonata');
} else if (typeof rule.v != 'undefined') {
valueField.typedInput('value', rule.v);
valueField.typedInput('type', rule.vt || 'str');
}
if (rule.case) {
caseSensitive.prop('checked', true);
} else {
caseSensitive.prop('checked', false);
}
selectField.change();
var currentOutputs = JSON.parse(outputCount.val() || '{}');
currentOutputs[opt.hasOwnProperty('i') ? opt.i : opt._i] = i;
outputCount.val(JSON.stringify(currentOutputs));
},
removeItem: function(opt) {
var currentOutputs = JSON.parse(outputCount.val() || '{}');
if (opt.hasOwnProperty('i')) {
currentOutputs[opt.i] = -1;
} else {
delete currentOutputs[opt._i];
}
var rules = $('#node-input-rule-container').editableList('items');
rules.each(function(i) {
$(this)
.find('.node-input-rule-index')
.html(i + 1);
var data = $(this).data('data');
currentOutputs[data.hasOwnProperty('i') ? data.i : data._i] = i;
});
outputCount.val(JSON.stringify(currentOutputs));
},
resizeItem: resizeRule,
sortItems: function(rules) {
var currentOutputs = JSON.parse(outputCount.val() || '{}');
var rules = $('#node-input-rule-container').editableList('items');
rules.each(function(i) {
$(this)
.find('.node-input-rule-index')
.html(i + 1);
var data = $(this).data('data');
currentOutputs[data.hasOwnProperty('i') ? data.i : data._i] = i;
});
outputCount.val(JSON.stringify(currentOutputs));
},
sortable: true,
removable: true
});
for (var i = 0; i < this.rules.length; i++) {
var rule = this.rules[i];
$('#node-input-rule-container').editableList('addItem', {
r: rule,
i: i
});
}
},
oneditsave: function() {
var rules = $('#node-input-rule-container').editableList('items');
var ruleset;
var node = this;
node.rules = [];
rules.each(function(i) {
var ruleData = $(this).data('data');
var rule = $(this);
var type = rule.find('select').val();
var r = { t: type };
if (
!(
type === 'true' ||
type === 'false' ||
type === 'null' ||
type === 'nnull' ||
type === 'empty' ||
type === 'nempty' ||
type === 'else'
)
) {
if (type === 'btwn' || type === 'index') {
r.v = rule
.find('.node-input-rule-btwn-value')
.typedInput('value');
r.vt = rule
.find('.node-input-rule-btwn-value')
.typedInput('type');
r.v2 = rule
.find('.node-input-rule-btwn-value2')
.typedInput('value');
r.v2t = rule
.find('.node-input-rule-btwn-value2')
.typedInput('type');
} else if (type === 'head' || type === 'tail') {
r.v = rule.find('.node-input-rule-num-value').typedInput('value');
r.vt = rule.find('.node-input-rule-num-value').typedInput('type');
} else if (type === 'istype') {
r.v = rule.find('.node-input-rule-type-value').typedInput('type');
r.vt = rule
.find('.node-input-rule-type-value')
.typedInput('type');
} else if (type === 'jsonata_exp') {
r.v = rule.find('.node-input-rule-exp-value').typedInput('value');
r.vt = rule.find('.node-input-rule-exp-value').typedInput('type');
} else {
r.v = rule.find('.node-input-rule-value').typedInput('value');
r.vt = rule.find('.node-input-rule-value').typedInput('type');
}
if (type === 'regex') {
r.case = rule.find('.node-input-rule-case').prop('checked');
}
}
node.rules.push(r);
});
this.propertyType = $('#node-input-property').typedInput('type');
},
oneditresize: function(size) {
var rows = $('#dialog-form>div:not(.node-input-rule-container-row)');
var height = size.height;
for (var i = 0; i < rows.size(); i++) {
height -= $(rows[i]).outerHeight(true);
}
var editorRow = $('#dialog-form>div.node-input-rule-container-row');
height -=
parseInt(editorRow.css('marginTop')) +
parseInt(editorRow.css('marginBottom'));
$('#node-input-rule-container').editableList('height', height);
}
});
var headerTypes = [
{ value: 'content-type', label: 'Content-Type', hasValue: false },
{ value: 'location', label: 'Location', hasValue: false },
{
value: 'other',
label: 'application/lambda-handler-other',
icon: 'red/images/typedInput/az.png'
}
];
var contentTypes = [
{ value: 'application/json', label: 'application/json', hasValue: false },
{ value: 'application/xml', label: 'application/xml', hasValue: false },
{ value: 'text/css', label: 'text/css', hasValue: false },
{ value: 'text/html', label: 'text/html', hasValue: false },
{ value: 'text/plain', label: 'text/plain', hasValue: false },
{ value: 'image/gif', label: 'image/gif', hasValue: false },
{ value: 'image/png', label: 'image/png', hasValue: false },
{
value: 'other',
label: 'application/lambda-handler-other',
icon: 'red/images/typedInput/az.png'
}
];
RED.nodes.registerType('lambda-response', {
category: 'output',
color: 'rgb(231, 231, 174)',
defaults: {
name: { value: '' },
statusCode: { value: '', validate: RED.validators.number(true) },
headers: { value: {} }
},
inputs: 1,
outputs: 0,
align: 'right',
icon: 'white-globe.png',
label: function() {
return (
this.name ||
'http' + (this.statusCode ? ' (' + this.statusCode + ')' : '')
);
},
labelStyle: function() {
return this.name ? 'node_label_italic' : '';
},
oneditprepare: function() {
function resizeRule(rule) {
var newWidth = rule.width();
rule
.find('.red-ui-typedInput')
.typedInput('width', (newWidth - 15) / 2);
}
var headerList = $('#node-input-headers-container')
.css('min-height', '150px')
.css('min-width', '450px')
.editableList({
addItem: function(container, i, header) {
var row = $('<div/>')
.css({
overflow: 'hidden',
whiteSpace: 'nowrap'
})
.appendTo(container);
var propertyName = $('<input/>', {
class: 'node-input-header-name',
type: 'text'
})
.appendTo(row)
.typedInput({ types: headerTypes });
var propertyValue = $('<input/>', {
class: 'node-input-header-value',
type: 'text',
style: 'margin-left: 10px'
})
.appendTo(row)
.typedInput({
types:
header.h === 'content-type'
? contentTypes
: [
{
value: 'other',
label: 'other',
icon: 'red/images/typedInput/az.png'
}
]
});
var matchedType = headerTypes.filter(function(ht) {
return ht.value === header.h;
});
if (matchedType.length === 0) {
propertyName.typedInput('type', 'other');
propertyName.typedInput('value', header.h);
propertyValue.typedInput('value', header.v);
} else {
propertyName.typedInput('type', header.h);
if (header.h === 'content-type') {
matchedType = contentTypes.filter(function(ct) {
return ct.value === header.v;
});
if (matchedType.length === 0) {
propertyValue.typedInput('type', 'other');
propertyValue.typedInput('value', header.v);
} else {
propertyValue.typedInput('type', header.v);
}
} else {
propertyValue.typedInput('value', header.v);
}
}
matchedType = headerTypes.filter(function(ht) {
return ht.value === header.h;
});
if (matchedType.length === 0) {
propertyName.typedInput('type', 'other');
propertyName.typedInput('value', header.h);
} else {
propertyName.typedInput('type', header.h);
}
propertyName.on('change', function(event) {
var type = propertyName.typedInput('type');
if (type === 'content-type') {
propertyValue.typedInput('types', contentTypes);
} else {
propertyValue.typedInput('types', [
{
value: 'other',
label: 'other',
icon: 'red/images/typedInput/az.png'
}
]);
}
});
resizeRule(container);
},
resizeItem: resizeRule,
removable: true
});
if (this.headers) {
for (var key in this.headers) {
if (this.headers.hasOwnProperty(key)) {
headerList.editableList('addItem', {
h: key,
v: this.headers[key]
});
}
}
}
},
oneditsave: function() {
var headers = $('#node-input-headers-container').editableList('items');
var node = this;
node.headers = {};
headers.each(function(i) {
var header = $(this);
var keyType = header
.find('.node-input-header-name')
.typedInput('type');
var keyValue = header
.find('.node-input-header-name')
.typedInput('value');
var valueType = header
.find('.node-input-header-value')
.typedInput('type');
var valueValue = header
.find('.node-input-header-value')
.typedInput('value');
var key = keyType;
var value = valueType;
if (keyType === 'other') {
key = keyValue;
}
if (valueType === 'other') {
value = valueValue;
}
if (key !== '') {
node.headers[key] = value;
}
});
},
oneditresize: function(size) {
var rows = $('#dialog-form>div:not(.node-input-headers-container-row)');
var height = size.height;
for (var i = 0; i < rows.size(); i++) {
height -= $(rows[i]).outerHeight(true);
}
var editorRow = $('#dialog-form>div.node-input-headers-container-row');
height -=
parseInt(editorRow.css('marginTop')) +
parseInt(editorRow.css('marginBottom'));
$('#node-input-headers-container').editableList('height', height);
}
});
})();
</script>