Skip to content
Open
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

All notable changes to this project will be documented in this file.

# [0.1.0] - 2025-08-19
- Add Manage Dynamic Login on LayerOneConfigs and manage CustomHeader on configuration
> *Warning Breaking Change!* please make backups of flows & Configuration and try in test environment before upgrading
- Add Manage NextLink on ServiceNode
> the node ServiceNode does *not manage “NextLink” directly* as it is very case-dependent, the property is provided and *delegated to the flow for management*
- Bug fix view on PatchSAP Node
- General Bug Fix
- Library Axios & Odata Updated

# [0.0.12] - 2025-08-06
- add Manage UserFieldsMD on you-layerone2-sl-create / you-layerone2-sl-list / you-layerone2-sl-delete
> Not add Manage on you-layerone2-sl-get becose not work on corrent ServiceLayer Version

# [0.0.11] - 2025-07-09
- General Bug Fix on you-layerone2-sl-manipolate-entity and you-layerone2-sl-close

Expand Down
195 changes: 194 additions & 1 deletion node/configs/layerone.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,104 @@
<label for="node-config-input-consumerIdentity"><i class="fa fa-tag"></i> Identity</label>
<input type="text" id="node-config-input-consumerIdentity" />
</div>
<div>
<div class="form-row" style="margin-bottom:0;">
<label><i class="fa fa-list"></i> <span>Headers</span></label>
</div>
<div class="form-row node-input-headers-container-row">
<ol id="node-input-headers-container"></ol>
</div>
</div>
</script>

<script type="text/javascript">
const headerTypes = [
{ value: "Accept", label: "Accept", hasValue: false },
{ value: "Accept-Encoding", label: "Accept-Encoding", hasValue: false },
{ value: "Accept-Language", label: "Accept-Language", hasValue: false },
{ value: "Authorization", label: "Authorization", hasValue: false },
{ value: "Content-Type", label: "Content-Type", hasValue: false },
{ value: "Cache-Control", label: "Cache-Control", hasValue: false },
{ value: "User-Agent", label: "User-Agent", hasValue: false },
{ value: "Location", label: "Location", hasValue: false },
{ value: "x-tunnel-id", label: "TunnelID", hasValue: false },
{ value: "other", label: "Other", hasValue: true, icon: "red/images/typedInput/az.svg" }
//{ value: "msg", label: "msg.", hasValue: true },
]
const headerOptions = {};
const defaultOptions = [
{ value: "other", label: "Other", hasValue: true, icon: "red/images/typedInput/az.svg" },
// { value: "msg", label: "msg.", hasValue: true },
];
headerOptions["accept"] = [
{ value: "text/plain", label: "text/plain", hasValue: false },
{ value: "text/html", label: "text/html", hasValue: false },
{ value: "application/json", label: "application/json", hasValue: false },
{ value: "application/xml", label: "application/xml", hasValue: false },
...defaultOptions,
];
headerOptions["accept-encoding"] = [
{ value: "gzip", label: "gzip", hasValue: false },
{ value: "deflate", label: "deflate", hasValue: false },
{ value: "compress", label: "compress", hasValue: false },
{ value: "br", label: "br", hasValue: false },
{ value: "gzip, deflate", label: "gzip, deflate", hasValue: false },
{ value: "gzip, deflate, br", label: "gzip, deflate, br", hasValue: false },
...defaultOptions,
];
headerOptions["accept-language"] = [
{ value: "*", label: "*", hasValue: false },
{ value: "en-GB, en-US, en;q=0.9", label: "en-GB, en-US, en;q=0.9", hasValue: false },
{ value: "de-AT, de-DE;q=0.9, en;q=0.5", label: "de-AT, de-DE;q=0.9, en;q=0.5", hasValue: false },
{ value: "es-mx,es,en;q=0.5", label: "es-mx,es,en;q=0.5", hasValue: false },
{ value: "fr-CH, fr;q=0.9, en;q=0.8", label: "fr-CH, fr;q=0.9, en;q=0.8", hasValue: false },
{ value: "zh-CN, zh-TW; q = 0.9, zh-HK; q = 0.8, zh; q = 0.7, en; q = 0.6", label: "zh-CN, zh-TW; q = 0.9, zh-HK; q = 0.8, zh; q = 0.7, en; q = 0.6", hasValue: false },
{ value: "ja-JP, jp", label: "ja-JP, jp", hasValue: false },
...defaultOptions,
];
headerOptions["content-type"] = [
{ value: "text/css", label: "text/css", hasValue: false },
{ value: "text/plain", label: "text/plain", hasValue: false },
{ value: "text/html", label: "text/html", hasValue: false },
{ value: "application/json", label: "application/json", hasValue: false },
{ value: "application/octet-stream", label: "application/octet-stream", hasValue: false },
{ value: "application/pdf", label: "application/pdf", hasValue: false },
{ value: "application/xml", label: "application/xml", hasValue: false },
{ value: "application/zip", label: "application/zip", hasValue: false },
{ value: "multipart/form-data", label: "multipart/form-data", hasValue: false },
{ value: "audio/aac", label: "audio/aac", hasValue: false },
{ value: "audio/ac3", label: "audio/ac3", hasValue: false },
{ value: "audio/basic", label: "audio/basic", hasValue: false },
{ value: "audio/mp4", label: "audio/mp4", hasValue: false },
{ value: "audio/ogg", label: "audio/ogg", hasValue: false },
{ value: "image/bmp", label: "image/bmp", hasValue: false },
{ value: "image/gif", label: "image/gif", hasValue: false },
{ value: "image/jpeg", label: "image/jpeg", hasValue: false },
{ value: "image/png", label: "image/png", hasValue: false },
{ value: "image/tiff", label: "image/tiff", hasValue: false },
...defaultOptions,
];
headerOptions["cache-control"] = [
{ value: "max-age=0", label: "max-age=0", hasValue: false },
{ value: "max-age=86400", label: "max-age=86400", hasValue: false },
{ value: "no-cache", label: "no-cache", hasValue: false },
...defaultOptions,
];

headerOptions["user-agent"] = [
{ value: "Mozilla/5.0", label: "Mozilla/5.0", hasValue: false },
...defaultOptions,
];

function getHeaderOptions(headerName) {
const lc = (headerName || "").toLowerCase();
let opts = headerOptions[lc];
return opts || defaultOptions;
}




RED.nodes.registerType('you-layerone2', {
category: 'config',
color:"#139ce9",
Expand All @@ -56,10 +151,108 @@
companyUser: { value: '', required: true },
companyPassword: { value: '', required: true },
consumerIdentity: { value: 'NTH', required: true },
headers: { value: [] }
},
label: function() {
return this.name || ` ${this.databaseName} - ${this.host}`
}
},
oneditprepare: function() {
const node = this;
const hasMatch = function (arr, value) {
return arr.some(function (ht) {
return ht.value === value
});
}
const headerList = $("#node-input-headers-container").css('min-height', '150px').css('min-width', '450px').editableList({
addItem: function (container, i, header) {
const row = $('<div/>').css({
overflow: 'hidden',
whiteSpace: 'nowrap',
display: 'flex'
}).appendTo(container);
const propertNameCell = $('<div/>').css({ 'flex-grow': 1 }).appendTo(row);
const propertyName = $('<input/>', { class: "node-input-header-name", type: "text", style: "width: 100%" })
.appendTo(propertNameCell)
.typedInput({ types: headerTypes });

const propertyValueCell = $('<div/>').css({ 'flex-grow': 1, 'margin-left': '10px' }).appendTo(row);
const propertyValue = $('<input/>', { class: "node-input-header-value", type: "text", style: "width: 100%" })
.appendTo(propertyValueCell)
.typedInput({
types: getHeaderOptions(header.keyType)
});

const setup = function(_header) {
const headerTypeIsAPreset = function(h) {return hasMatch(headerTypes, h) };
const headerValueIsAPreset = function(h, v) {return hasMatch(getHeaderOptions(h), v) };
const {keyType, keyValue, valueType, valueValue} = header;
if(keyType == "msg" || keyType == "other") {
propertyName.typedInput('type', keyType);
propertyName.typedInput('value', keyValue);
} else if (headerTypeIsAPreset(keyType)) {
propertyName.typedInput('type', keyType);
} else {
propertyName.typedInput('type', "other");
propertyName.typedInput('value', keyValue);
}
if(valueType == "msg" || valueType == "other") {
propertyValue.typedInput('type', valueType);
propertyValue.typedInput('value', valueValue);
} else if (headerValueIsAPreset(propertyName.typedInput('type'), valueType)) {
propertyValue.typedInput('type', valueType);
} else {
propertyValue.typedInput('type', "other");
propertyValue.typedInput('value', valueValue);
}
}
setup(header);

propertyName.on('change', function (event) {
propertyValue.typedInput('types', getHeaderOptions(propertyName.typedInput('type')));
});

},
sortable: true,
removable: true
});
if (node.headers) {
for (let index = 0; index < node.headers.length; index++) {
const element = node.headers[index];
headerList.editableList('addItem', node.headers[index]);
}
}
},
oneditsave: function() {
const node = this;
const headers = $("#node-input-headers-container").editableList('items');
node.headers = [];
headers.each(function(i) {
const header = $(this);
const keyType = header.find(".node-input-header-name").typedInput('type');
const keyValue = header.find(".node-input-header-name").typedInput('value');
const valueType = header.find(".node-input-header-value").typedInput('type');
const valueValue = header.find(".node-input-header-value").typedInput('value');
if (keyType !== '' || keyType === 'other' || keyType === 'msg') {
node.headers.push({
keyType, keyValue, valueType, valueValue
})
}
});
},
oneditresize: function(size) {
const dlg = $("#dialog-form");
const expandRow = dlg.find('.node-input-headers-container-row');
let height = dlg.height() - 5;
if(expandRow && expandRow.length){
const siblingRows = dlg.find('> .form-row:not(.node-input-headers-container-row)');
for (let i = 0; i < siblingRows.size(); i++) {
const cr = $(siblingRows[i]);
if(cr.is(":visible"))
height -= cr.outerHeight(true);
}
$("#node-input-headers-container").editableList('height',height);
}
}
});
</script>

Expand Down
17 changes: 17 additions & 0 deletions node/configs/layerone.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { PREFIXNAME } = require('../../utils/reqengine');
module.exports = function (RED) {
function LayerOne2ConfigsNode(n) {
RED.nodes.createNode(this, n);
Expand All @@ -11,7 +12,23 @@ module.exports = function (RED) {
companyUser: n.companyUser,
companyPassword: n.companyPassword,
consumerIdentity: n.consumerIdentity,
headers: n.headers
}

const globalContext = this.context().global;
let globalName = `${PREFIXNAME}_CONFIG.${n.host.replaceAll('.', '')}_${n.databaseName}_${n.companyUser}`;
globalContext.set(globalName, {
id: n.id,
configs: {
options: {
...this.options,
companyPassword: undefined
}
},
host: n.host || "",
databaseName: n.databaseName,
companyUser: n.companyUser
});
}

RED.nodes.registerType('you-layerone2', LayerOne2ConfigsNode);
Expand Down
Loading