@blazedpath/commons 0.0.11 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blz-base/index.js +893 -895
- package/blz-cache/index.js +25 -14
- package/blz-core/index.js +347 -349
- package/blz-cryptography/index.js +47 -49
- package/blz-datetimes/index.js +348 -350
- package/blz-file/index.js +83 -88
- package/blz-hazelcast/index.js +100 -103
- package/blz-iterable/index.js +404 -406
- package/blz-json-schema/index.js +6 -8
- package/blz-jwt/index.js +89 -92
- package/blz-kafka/index.js +106 -108
- package/blz-math/index.js +127 -129
- package/blz-mongodb/index.js +33 -35
- package/blz-rds/index.js +44 -46
- package/blz-rds-mysql/index.js +9 -11
- package/blz-rds-mysqlx/index.js +10 -12
- package/blz-rds-oracle/index.js +99 -104
- package/blz-rds-postgres/index.js +11 -13
- package/blz-redis/index.js +123 -125
- package/blz-regex/index.js +22 -24
- package/blz-strings/index.js +165 -167
- package/blz-uuid/index.js +2 -4
- package/blz-yaml/index.js +16 -19
- package/package.json +1 -1
package/blz-base/index.js
CHANGED
|
@@ -105,14 +105,14 @@ const beginNested = function (stack) {
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
const beginNotSupported = function
|
|
108
|
+
const beginNotSupported = function(stack) {
|
|
109
109
|
stack.push({
|
|
110
110
|
propagationType: "not-supported",
|
|
111
111
|
connection: null
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
const beginSupports = function
|
|
115
|
+
const beginSupports = function(stack) {
|
|
116
116
|
if (_.isEmpty(stack)) {
|
|
117
117
|
stack.push({
|
|
118
118
|
propagationType: "supports",
|
|
@@ -134,7 +134,7 @@ const beginSupports = function (stack) {
|
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
const beginMandatory = function
|
|
137
|
+
const beginMandatory = function(stack) {
|
|
138
138
|
if (_.isEmpty(stack)) {
|
|
139
139
|
throw new MandatoryTransactionViolation();
|
|
140
140
|
}
|
|
@@ -465,20 +465,20 @@ const normalizeConfig = function (config = {}) {
|
|
|
465
465
|
}
|
|
466
466
|
}
|
|
467
467
|
const deepClone = (obj) => {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
468
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
469
|
+
return obj;
|
|
470
|
+
}
|
|
471
|
+
let clone = Array.isArray(obj) ? [] : {};
|
|
472
|
+
for (let key in obj) {
|
|
473
|
+
if (obj.hasOwnProperty(key)) {
|
|
474
|
+
clone[key] = deepClone(obj[key]);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return clone;
|
|
478
478
|
}
|
|
479
479
|
let cache = new LRUCache({ max: 500, maxSize: 5000, ttl: 1000 * 60 * 60 * 3, sizeCalculation: (value, key) => { return 1 } })
|
|
480
480
|
|
|
481
|
-
const safeRequire = function
|
|
481
|
+
const safeRequire = function(path) {
|
|
482
482
|
try {
|
|
483
483
|
require.resolve(path);
|
|
484
484
|
return require(path);
|
|
@@ -495,974 +495,972 @@ const safeRequire = function (path) {
|
|
|
495
495
|
}
|
|
496
496
|
|
|
497
497
|
module.exports = {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
if (source) {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
return await reader.read(callContext, transformation.sourceCodePaths, async function (sourceItem) { return await writer.write(callContext, await transformationExecutor(callContext, sourceItem)); });
|
|
545
|
-
}
|
|
546
|
-
else {
|
|
547
|
-
return await reader.read(callContext, transformation.sourceCodePaths, async function (sourceItem) { return await transformationExecutor(callContext, sourceItem); });
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
else if (Array.isArray(source)) { // list
|
|
551
|
-
if (writer) {
|
|
552
|
-
let target = [];
|
|
553
|
-
for (let i = 0; i < source.length; i++) {
|
|
554
|
-
let sourceItem = source[i];
|
|
555
|
-
target.push(await writer.write(callContext, await transformationExecutor(callContext, sourceItem)));
|
|
556
|
-
}
|
|
557
|
-
return target;
|
|
558
|
-
}
|
|
559
|
-
else {
|
|
560
|
-
let target = [];
|
|
561
|
-
for (let i = 0; i < source.length; i++) {
|
|
562
|
-
let sourceItem = source[i];
|
|
563
|
-
target.push(await transformationExecutor(callContext, sourceItem));
|
|
564
|
-
}
|
|
565
|
-
return target;
|
|
566
|
-
}
|
|
498
|
+
deepClone,
|
|
499
|
+
beginTransaction,
|
|
500
|
+
commitTransaction,
|
|
501
|
+
rollbackTransaction,
|
|
502
|
+
closeTransaction,
|
|
503
|
+
compare,
|
|
504
|
+
stringifyObject,
|
|
505
|
+
checkDuplicateKeysInEnv,
|
|
506
|
+
normalizeConfig,
|
|
507
|
+
setMetadata: function (metadata) {
|
|
508
|
+
_metadata = metadata;
|
|
509
|
+
},
|
|
510
|
+
getMetadataItem: function (metadataItemName) {
|
|
511
|
+
if (_metadata[metadataItemName] === undefined)
|
|
512
|
+
return null;
|
|
513
|
+
return _metadata[metadataItemName];
|
|
514
|
+
},
|
|
515
|
+
getConnection: function (connectionName) {
|
|
516
|
+
if (!_connections[connectionName]) {
|
|
517
|
+
console.log(`The connectionName: "${connectionName}" does not seem to be defined. Please review the .env or yaml build configuration.`);
|
|
518
|
+
} return _connections[connectionName];
|
|
519
|
+
},
|
|
520
|
+
setConnections: function (connections) {
|
|
521
|
+
_connections = connections;
|
|
522
|
+
},
|
|
523
|
+
getConfigParameterValue: function (configParameterName) {
|
|
524
|
+
if (_configParameters[configParameterName] === undefined) {
|
|
525
|
+
console.log(`The configParameter: "${configParameterName}" does not seem to be defined. Please review the .env or yaml build configuration.`);
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
return _configParameters[configParameterName];
|
|
529
|
+
},
|
|
530
|
+
setConfigParameters: function (configParameters) {
|
|
531
|
+
_configParameters = configParameters;
|
|
532
|
+
},
|
|
533
|
+
setTransformations: function (transformations) {
|
|
534
|
+
_transformations = transformations;
|
|
535
|
+
},
|
|
536
|
+
transform: async function (callContext, transformationName, source, writer) {
|
|
537
|
+
let transformation = _metadata[transformationName];
|
|
538
|
+
let transformationExecutor = require(Path.join(_metadata.appPath,'../sources/', transformation.sourceFileName));
|
|
539
|
+
if (source) {
|
|
540
|
+
if (source._blz_reader) { // reader
|
|
541
|
+
let reader = source;
|
|
542
|
+
if (writer) {
|
|
543
|
+
return await reader.read(callContext, transformation.sourceCodePaths, async function (sourceItem) { return await writer.write(callContext, await transformationExecutor(callContext, sourceItem)); });
|
|
567
544
|
}
|
|
568
|
-
else {
|
|
569
|
-
|
|
570
|
-
return await writer.write(callContext, transformationExecutor(callContext, source));
|
|
571
|
-
}
|
|
572
|
-
else {
|
|
573
|
-
return await transformationExecutor(callContext, source);
|
|
574
|
-
}
|
|
545
|
+
else {
|
|
546
|
+
return await reader.read(callContext, transformation.sourceCodePaths, async function (sourceItem) { return await transformationExecutor(callContext, sourceItem); });
|
|
575
547
|
}
|
|
576
548
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
}
|
|
584
|
-
catch (err) {
|
|
585
|
-
throw this.error('InvalidFunction', { functionName: functionName });
|
|
586
|
-
}
|
|
587
|
-
return {
|
|
588
|
-
isWriter: true,
|
|
589
|
-
fn: fn,
|
|
590
|
-
extraArgs: extraArgs,
|
|
591
|
-
write: async function (callContext, obj) {
|
|
592
|
-
if (this.extraArgs) {
|
|
593
|
-
return await this.fn(callContext, obj, ...this.extraArgs);
|
|
594
|
-
}
|
|
595
|
-
else {
|
|
596
|
-
return await this.fn(callContext, obj);
|
|
549
|
+
else if (Array.isArray(source)) { // list
|
|
550
|
+
if (writer) {
|
|
551
|
+
let target = [];
|
|
552
|
+
for (let i = 0; i < source.length; i++) {
|
|
553
|
+
let sourceItem = source[i];
|
|
554
|
+
target.push(await writer.write(callContext, await transformationExecutor(callContext, sourceItem)));
|
|
597
555
|
}
|
|
556
|
+
return target;
|
|
598
557
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
if (bind || bind === 0) {
|
|
605
|
-
let rootType = toString.call(root);
|
|
606
|
-
if (rootType === '[object Object]' || rootType === '[object Error]') {
|
|
607
|
-
let bindParts = bind.split('.');
|
|
608
|
-
let current = root;
|
|
609
|
-
for (let i = 0; i < bindParts.length; i++) {
|
|
610
|
-
let bindPart = bindParts[i];
|
|
611
|
-
if (current[bindPart] === null || current[bindPart] === undefined)
|
|
612
|
-
return null;
|
|
613
|
-
current = current[bindPart];
|
|
558
|
+
else {
|
|
559
|
+
let target = [];
|
|
560
|
+
for (let i = 0; i < source.length; i++) {
|
|
561
|
+
let sourceItem = source[i];
|
|
562
|
+
target.push(await transformationExecutor(callContext, sourceItem));
|
|
614
563
|
}
|
|
615
|
-
return
|
|
564
|
+
return target;
|
|
616
565
|
}
|
|
617
|
-
|
|
618
|
-
|
|
566
|
+
}
|
|
567
|
+
else { // obj
|
|
568
|
+
if (writer) {
|
|
569
|
+
return await writer.write(callContext, transformationExecutor(callContext, source));
|
|
619
570
|
}
|
|
620
571
|
else {
|
|
621
|
-
return
|
|
572
|
+
return await transformationExecutor(callContext, source);
|
|
622
573
|
}
|
|
623
574
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
else {
|
|
647
|
-
return dividend / divisor;
|
|
648
|
-
}
|
|
649
|
-
},
|
|
650
|
-
remainder: function (dividend, divisor) {
|
|
651
|
-
if (divisor === null || divisor === 0) {
|
|
652
|
-
let err = new Error();
|
|
653
|
-
err.code = 'RemainderByZero';
|
|
654
|
-
err.data = { dividend: dividend, divisor: divisor };
|
|
655
|
-
throw err;
|
|
656
|
-
}
|
|
657
|
-
else {
|
|
658
|
-
return dividend % divisor;
|
|
575
|
+
}
|
|
576
|
+
return null;
|
|
577
|
+
},
|
|
578
|
+
writer: function (callContext, functionName, extraArgs) {
|
|
579
|
+
let fn
|
|
580
|
+
try {
|
|
581
|
+
fn = require(Path.join(_metadata.appPath,'../sources/', module.exports.ensureDashedFormat(functionName) + '.js'))
|
|
582
|
+
}
|
|
583
|
+
catch (err) {
|
|
584
|
+
throw this.error('InvalidFunction', { functionName: functionName });
|
|
585
|
+
}
|
|
586
|
+
return {
|
|
587
|
+
isWriter: true,
|
|
588
|
+
fn: fn,
|
|
589
|
+
extraArgs: extraArgs,
|
|
590
|
+
write: async function (callContext, obj) {
|
|
591
|
+
if (this.extraArgs) {
|
|
592
|
+
return await this.fn(callContext, obj, ...this.extraArgs);
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
return await this.fn(callContext, obj);
|
|
596
|
+
}
|
|
659
597
|
}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
500: 'InternalServerError',
|
|
676
|
-
501: 'NotImplemented',
|
|
677
|
-
502: 'BadGateway',
|
|
678
|
-
503: 'ServiceUnavailable',
|
|
679
|
-
504: 'GatewayTimeout',
|
|
680
|
-
524: 'Timeout'
|
|
681
|
-
},
|
|
682
|
-
httpStatuses: {
|
|
683
|
-
'BadRequest': 400,
|
|
684
|
-
'Unauthorized': 401,
|
|
685
|
-
'PaymentRequired': 402,
|
|
686
|
-
'Forbidden': 403,
|
|
687
|
-
'NotFound': 404,
|
|
688
|
-
'MethodNotAllowed': 405,
|
|
689
|
-
'NotAcceptable': 406,
|
|
690
|
-
'ProxyAuthenticationRequired': 407,
|
|
691
|
-
'RequestTimeout': 408,
|
|
692
|
-
'Conflict': 409,
|
|
693
|
-
'Gone': 410,
|
|
694
|
-
'LengthRequired': 411,
|
|
695
|
-
'PreconditionFailed': 412,
|
|
696
|
-
'InternalServerError': 500,
|
|
697
|
-
'NotImplemented': 501,
|
|
698
|
-
'BadGateway': 502,
|
|
699
|
-
'ServiceUnavailable': 503,
|
|
700
|
-
'GatewayTimeout': 504,
|
|
701
|
-
'Timeout': 524
|
|
702
|
-
},
|
|
703
|
-
getHttpStatus: function (err) {
|
|
704
|
-
return this.httpStatuses[err.code];
|
|
705
|
-
},
|
|
706
|
-
httpCall: async function (httpRequest) {
|
|
707
|
-
let requestUrl = httpRequest.url;
|
|
708
|
-
let requestOptions = {
|
|
709
|
-
method: httpRequest.method,
|
|
710
|
-
headers: {},
|
|
711
|
-
throwHttpErrors: false
|
|
712
|
-
};
|
|
713
|
-
if (httpRequest.method !== 'GET')
|
|
714
|
-
requestOptions.body = httpRequest.body;
|
|
715
|
-
if (httpRequest.headers)
|
|
716
|
-
for (let i = 0; i < httpRequest.headers.length; i++) {
|
|
717
|
-
let httpHeader = httpRequest.headers[i];
|
|
718
|
-
requestOptions.headers[httpHeader.name] = httpHeader.value;
|
|
598
|
+
};
|
|
599
|
+
},
|
|
600
|
+
getValue: function (root, bind) {
|
|
601
|
+
if (root === null)
|
|
602
|
+
return null;
|
|
603
|
+
if (bind || bind === 0) {
|
|
604
|
+
let rootType = toString.call(root);
|
|
605
|
+
if (rootType === '[object Object]' || rootType === '[object Error]') {
|
|
606
|
+
let bindParts = bind.split('.');
|
|
607
|
+
let current = root;
|
|
608
|
+
for (let i = 0; i < bindParts.length; i++) {
|
|
609
|
+
let bindPart = bindParts[i];
|
|
610
|
+
if (current[bindPart] === null || current[bindPart] === undefined)
|
|
611
|
+
return null;
|
|
612
|
+
current = current[bindPart];
|
|
719
613
|
}
|
|
720
|
-
|
|
721
|
-
requestOptions = {
|
|
722
|
-
...requestOptions,
|
|
723
|
-
https: {
|
|
724
|
-
requestCert: true, // Request a certificate from clients that connect and attempt to verify that certificate.
|
|
725
|
-
rejectUnauthorized: false, // The server will reject any connection which is not authorized with the list of supplied CAs.
|
|
726
|
-
agent: false // Is responsible for managing connection persistence and reuse for https clients.
|
|
727
|
-
}
|
|
728
|
-
};
|
|
614
|
+
return current;
|
|
729
615
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
if (httpErrorCode) {
|
|
733
|
-
let err = new Error();
|
|
734
|
-
err.code = httpErrorCode;
|
|
735
|
-
try { err.data = JSON.parse(response.body); } catch (err2) { }
|
|
736
|
-
throw err;
|
|
616
|
+
else if (rootType === '[object Array]') {
|
|
617
|
+
return root[bind];
|
|
737
618
|
}
|
|
738
619
|
else {
|
|
739
|
-
return { status: response.statusCode, body: response.body };
|
|
740
|
-
}
|
|
741
|
-
},
|
|
742
|
-
internalCall: async function (callContext, functionName, args) {
|
|
743
|
-
let fn = null;
|
|
744
|
-
try {
|
|
745
|
-
fn = require(Path.join(_metadata.appPath,'../sources/', module.exports.Dual.ensureDashedFormat(functionName) + '.js'))
|
|
746
|
-
}
|
|
747
|
-
catch (err) {
|
|
748
|
-
throw this.error('InvalidFunction', { functionName: functionName });
|
|
749
|
-
}
|
|
750
|
-
if (args)
|
|
751
|
-
return await fn(callContext, ...args);
|
|
752
|
-
else
|
|
753
|
-
return await fn(callContext);
|
|
754
|
-
},
|
|
755
|
-
externalCall: async function (callContext, connection, functionName, values) {
|
|
756
|
-
if (connection.type === 'Microservice' || connection.type === 'RestApi' || connection.type === 'ProcessEngine') {
|
|
757
|
-
let restMappings = _metadata['_rest_mappings'];
|
|
758
|
-
return await module.exports.Dual.callRest(connection, restMappings[connection.name], functionName, values, null, _configParameters, callContext);
|
|
759
|
-
}
|
|
760
|
-
else if (connection.type === 'SoapApi') {
|
|
761
|
-
let soapMappings = _metadata['_soap_mappings'];
|
|
762
|
-
return await module.exports.Dual.callSoap(connection, soapMappings[connection.name], functionName, values, null, _configParameters, callContext);
|
|
763
|
-
}
|
|
764
|
-
},
|
|
765
|
-
error: function (code, data, innerError) {
|
|
766
|
-
let err = new Error();
|
|
767
|
-
err.code = code;
|
|
768
|
-
if (data)
|
|
769
|
-
err.data = data;
|
|
770
|
-
if (innerError)
|
|
771
|
-
err.innerError = innerError;
|
|
772
|
-
return err;
|
|
773
|
-
},
|
|
774
|
-
convertToString: function (value) {
|
|
775
|
-
if (value === null || value === undefined)
|
|
776
|
-
return null;
|
|
777
|
-
let valueType = toString.call(value);
|
|
778
|
-
if (valueType === '[object String]')
|
|
779
|
-
return value;
|
|
780
|
-
if (valueType === '[object Number]')
|
|
781
|
-
return value.toString();
|
|
782
|
-
if (valueType === '[object Boolean]')
|
|
783
|
-
return value ? 'true' : 'false';
|
|
784
|
-
if (valueType === '[object Date]')
|
|
785
|
-
return value.toJSON();
|
|
786
|
-
if (valueType === '[object Object]' && value.type === 'Buffer' && value.data)
|
|
787
|
-
return Buffer.from(value.data).toString();
|
|
788
|
-
if (Buffer.isBuffer(value))
|
|
789
|
-
return value.toString();
|
|
790
|
-
throw this.error('InvalidConversion', { value: value, targetType: 'string' });
|
|
791
|
-
},
|
|
792
|
-
convertToInteger: function (value) {
|
|
793
|
-
if (value === null)
|
|
794
|
-
return null;
|
|
795
|
-
let valueType = toString.call(value);
|
|
796
|
-
if (valueType === '[object String]' && !isNaN(value))
|
|
797
|
-
return Math.round(Number(value));
|
|
798
|
-
if (valueType === '[object Number]')
|
|
799
|
-
return Math.round(value);
|
|
800
|
-
if (valueType === '[object Boolean]')
|
|
801
|
-
return value ? 1 : 0;
|
|
802
|
-
throw this.error('InvalidConversion', { value: value, targetType: 'integer' });
|
|
803
|
-
},
|
|
804
|
-
convertToDecimal: function (value) {
|
|
805
|
-
if (value === null)
|
|
806
|
-
return null;
|
|
807
|
-
let valueType = toString.call(value);
|
|
808
|
-
if (valueType === '[object String]' && !isNaN(value))
|
|
809
|
-
return Number(value);
|
|
810
|
-
if (valueType === '[object Number]')
|
|
811
|
-
return value;
|
|
812
|
-
if (valueType === '[object Boolean]')
|
|
813
|
-
return value ? 1 : 0;
|
|
814
|
-
throw this.error('InvalidConversion', { value: value, targetType: 'decimal' });
|
|
815
|
-
},
|
|
816
|
-
convertToBoolean: function (value) {
|
|
817
|
-
if (value === null)
|
|
818
620
|
return null;
|
|
819
|
-
let valueType = toString.call(value);
|
|
820
|
-
if (valueType === '[object String]') {
|
|
821
|
-
if (value === '1' || value.toUpperCase() === 'T' || value.toUpperCase() === 'TRUE' || value.toUpperCase() === 'Y' || value.toUpperCase() === 'YES')
|
|
822
|
-
return true;
|
|
823
|
-
if (value === '0' || value.toUpperCase() === 'F' || value.toUpperCase() === 'FALSE' || value.toUpperCase() === 'N' || value.toUpperCase() === 'NO')
|
|
824
|
-
return false;
|
|
825
621
|
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
return root;
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
setValue: function (root, bind, value) {
|
|
628
|
+
let bindParts = bind.split('.');
|
|
629
|
+
let current = root;
|
|
630
|
+
for (let i = 0; i < (bindParts.length - 1); i++) {
|
|
631
|
+
let bindPart = bindParts[i];
|
|
632
|
+
if (current[bindPart] === null || current[bindPart] === undefined)
|
|
633
|
+
current[bindPart] = {};
|
|
634
|
+
current = current[bindPart];
|
|
635
|
+
}
|
|
636
|
+
current[bindParts[bindParts.length - 1]] = value;
|
|
637
|
+
},
|
|
638
|
+
divide: function (dividend, divisor) {
|
|
639
|
+
if (divisor === null || divisor === 0) {
|
|
640
|
+
let err = new Error();
|
|
641
|
+
err.code = 'DivisionByZero';
|
|
642
|
+
err.data = { dividend: dividend, divisor: divisor };
|
|
643
|
+
throw err;
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
return dividend / divisor;
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
remainder: function (dividend, divisor) {
|
|
650
|
+
if (divisor === null || divisor === 0) {
|
|
651
|
+
let err = new Error();
|
|
652
|
+
err.code = 'RemainderByZero';
|
|
653
|
+
err.data = { dividend: dividend, divisor: divisor };
|
|
654
|
+
throw err;
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
return dividend % divisor;
|
|
658
|
+
}
|
|
659
|
+
},
|
|
660
|
+
httpErrors: {
|
|
661
|
+
400: 'BadRequest',
|
|
662
|
+
401: 'Unauthorized',
|
|
663
|
+
402: 'PaymentRequired',
|
|
664
|
+
403: 'Forbidden',
|
|
665
|
+
404: 'NotFound',
|
|
666
|
+
405: 'MethodNotAllowed',
|
|
667
|
+
406: 'NotAcceptable',
|
|
668
|
+
407: 'ProxyAuthenticationRequired',
|
|
669
|
+
408: 'RequestTimeout',
|
|
670
|
+
409: 'Conflict',
|
|
671
|
+
410: 'Gone',
|
|
672
|
+
411: 'LengthRequired',
|
|
673
|
+
412: 'PreconditionFailed',
|
|
674
|
+
500: 'InternalServerError',
|
|
675
|
+
501: 'NotImplemented',
|
|
676
|
+
502: 'BadGateway',
|
|
677
|
+
503: 'ServiceUnavailable',
|
|
678
|
+
504: 'GatewayTimeout',
|
|
679
|
+
524: 'Timeout'
|
|
680
|
+
},
|
|
681
|
+
httpStatuses: {
|
|
682
|
+
'BadRequest': 400,
|
|
683
|
+
'Unauthorized': 401,
|
|
684
|
+
'PaymentRequired': 402,
|
|
685
|
+
'Forbidden': 403,
|
|
686
|
+
'NotFound': 404,
|
|
687
|
+
'MethodNotAllowed': 405,
|
|
688
|
+
'NotAcceptable': 406,
|
|
689
|
+
'ProxyAuthenticationRequired': 407,
|
|
690
|
+
'RequestTimeout': 408,
|
|
691
|
+
'Conflict': 409,
|
|
692
|
+
'Gone': 410,
|
|
693
|
+
'LengthRequired': 411,
|
|
694
|
+
'PreconditionFailed': 412,
|
|
695
|
+
'InternalServerError': 500,
|
|
696
|
+
'NotImplemented': 501,
|
|
697
|
+
'BadGateway': 502,
|
|
698
|
+
'ServiceUnavailable': 503,
|
|
699
|
+
'GatewayTimeout': 504,
|
|
700
|
+
'Timeout': 524
|
|
701
|
+
},
|
|
702
|
+
getHttpStatus: function (err) {
|
|
703
|
+
return this.httpStatuses[err.code];
|
|
704
|
+
},
|
|
705
|
+
httpCall: async function (httpRequest) {
|
|
706
|
+
let requestUrl = httpRequest.url;
|
|
707
|
+
let requestOptions = {
|
|
708
|
+
method: httpRequest.method,
|
|
709
|
+
headers: {},
|
|
710
|
+
throwHttpErrors: false
|
|
711
|
+
};
|
|
712
|
+
if (httpRequest.method !== 'GET')
|
|
713
|
+
requestOptions.body = httpRequest.body;
|
|
714
|
+
if (httpRequest.headers)
|
|
715
|
+
for (let i = 0; i < httpRequest.headers.length; i++) {
|
|
716
|
+
let httpHeader = httpRequest.headers[i];
|
|
717
|
+
requestOptions.headers[httpHeader.name] = httpHeader.value;
|
|
831
718
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
719
|
+
if (requestUrl.match(/https.*/)) {
|
|
720
|
+
requestOptions = {
|
|
721
|
+
...requestOptions,
|
|
722
|
+
https: {
|
|
723
|
+
requestCert: true, // Request a certificate from clients that connect and attempt to verify that certificate.
|
|
724
|
+
rejectUnauthorized: false, // The server will reject any connection which is not authorized with the list of supplied CAs.
|
|
725
|
+
agent: false // Is responsible for managing connection persistence and reuse for https clients.
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
let response = await Got(requestUrl, requestOptions);
|
|
730
|
+
let httpErrorCode = this.httpErrors[response.statusCode];
|
|
731
|
+
if (httpErrorCode) {
|
|
732
|
+
let err = new Error();
|
|
733
|
+
err.code = httpErrorCode;
|
|
734
|
+
try { err.data = JSON.parse(response.body); } catch (err2) { }
|
|
735
|
+
throw err;
|
|
736
|
+
}
|
|
737
|
+
else {
|
|
738
|
+
return { status: response.statusCode, body: response.body };
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
internalCall: async function (callContext, functionName, args) {
|
|
742
|
+
let fn = null;
|
|
743
|
+
try {
|
|
744
|
+
fn = require(Path.join(_metadata.appPath,'../sources/', module.exports.ensureDashedFormat(functionName) + '.js'))
|
|
745
|
+
}
|
|
746
|
+
catch (err) {
|
|
747
|
+
throw this.error('InvalidFunction', { functionName: functionName });
|
|
748
|
+
}
|
|
749
|
+
if (args)
|
|
750
|
+
return await fn(callContext, ...args);
|
|
751
|
+
else
|
|
752
|
+
return await fn(callContext);
|
|
753
|
+
},
|
|
754
|
+
externalCall: async function (callContext, connection, functionName, values) {
|
|
755
|
+
if (connection.type === 'Microservice' || connection.type === 'RestApi' || connection.type === 'ProcessEngine') {
|
|
756
|
+
let restMappings = _metadata['_rest_mappings'];
|
|
757
|
+
return await module.exports.callRest(connection, restMappings[connection.name], functionName, values, null, _configParameters, callContext);
|
|
758
|
+
}
|
|
759
|
+
else if (connection.type === 'SoapApi') {
|
|
760
|
+
let soapMappings = _metadata['_soap_mappings'];
|
|
761
|
+
return await module.exports.callSoap(connection, soapMappings[connection.name], functionName, values, null, _configParameters, callContext);
|
|
762
|
+
}
|
|
763
|
+
},
|
|
764
|
+
error: function (code, data, innerError) {
|
|
765
|
+
let err = new Error();
|
|
766
|
+
err.code = code;
|
|
767
|
+
if (data)
|
|
768
|
+
err.data = data;
|
|
769
|
+
if (innerError)
|
|
770
|
+
err.innerError = innerError;
|
|
771
|
+
return err;
|
|
772
|
+
},
|
|
773
|
+
convertToString: function (value) {
|
|
774
|
+
if (value === null || value === undefined)
|
|
775
|
+
return null;
|
|
776
|
+
let valueType = toString.call(value);
|
|
777
|
+
if (valueType === '[object String]')
|
|
778
|
+
return value;
|
|
779
|
+
if (valueType === '[object Number]')
|
|
780
|
+
return value.toString();
|
|
781
|
+
if (valueType === '[object Boolean]')
|
|
782
|
+
return value ? 'true' : 'false';
|
|
783
|
+
if (valueType === '[object Date]')
|
|
784
|
+
return value.toJSON();
|
|
785
|
+
if (valueType === '[object Object]' && value.type === 'Buffer' && value.data)
|
|
786
|
+
return Buffer.from(value.data).toString();
|
|
787
|
+
if (Buffer.isBuffer(value))
|
|
788
|
+
return value.toString();
|
|
789
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'string' });
|
|
790
|
+
},
|
|
791
|
+
convertToInteger: function (value) {
|
|
792
|
+
if (value === null)
|
|
793
|
+
return null;
|
|
794
|
+
let valueType = toString.call(value);
|
|
795
|
+
if (valueType === '[object String]' && !isNaN(value))
|
|
796
|
+
return Math.round(Number(value));
|
|
797
|
+
if (valueType === '[object Number]')
|
|
798
|
+
return Math.round(value);
|
|
799
|
+
if (valueType === '[object Boolean]')
|
|
800
|
+
return value ? 1 : 0;
|
|
801
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'integer' });
|
|
802
|
+
},
|
|
803
|
+
convertToDecimal: function (value) {
|
|
804
|
+
if (value === null)
|
|
805
|
+
return null;
|
|
806
|
+
let valueType = toString.call(value);
|
|
807
|
+
if (valueType === '[object String]' && !isNaN(value))
|
|
808
|
+
return Number(value);
|
|
809
|
+
if (valueType === '[object Number]')
|
|
810
|
+
return value;
|
|
811
|
+
if (valueType === '[object Boolean]')
|
|
812
|
+
return value ? 1 : 0;
|
|
813
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'decimal' });
|
|
814
|
+
},
|
|
815
|
+
convertToBoolean: function (value) {
|
|
816
|
+
if (value === null)
|
|
817
|
+
return null;
|
|
818
|
+
let valueType = toString.call(value);
|
|
819
|
+
if (valueType === '[object String]') {
|
|
820
|
+
if (value === '1' || value.toUpperCase() === 'T' || value.toUpperCase() === 'TRUE' || value.toUpperCase() === 'Y' || value.toUpperCase() === 'YES')
|
|
821
|
+
return true;
|
|
822
|
+
if (value === '0' || value.toUpperCase() === 'F' || value.toUpperCase() === 'FALSE' || value.toUpperCase() === 'N' || value.toUpperCase() === 'NO')
|
|
823
|
+
return false;
|
|
824
|
+
}
|
|
825
|
+
if (valueType === '[object Number]') {
|
|
826
|
+
if (value === 1)
|
|
827
|
+
return true;
|
|
828
|
+
if (value === 0)
|
|
829
|
+
return false;
|
|
830
|
+
}
|
|
831
|
+
if (valueType === '[object Boolean]')
|
|
832
|
+
return value;
|
|
833
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'boolean' });
|
|
834
|
+
},
|
|
835
|
+
convertToDatetime: function (value) {
|
|
836
|
+
if (value === null)
|
|
837
|
+
return null;
|
|
838
|
+
let valueType = toString.call(value);
|
|
839
|
+
if (valueType === '[object String]') {
|
|
840
|
+
let matchDatetime = /^(\d{4})-(\d{1,2})-(\d{1,2})[T,\s](\d{1,2})\:(\d{1,2})\:(\d{1,2})\.?(\d+)?Z?$/.exec(value);
|
|
841
|
+
if (matchDatetime)
|
|
842
|
+
return new Date(Date.UTC(Number(matchDatetime[1]), Number(matchDatetime[2]) - 1, Number(matchDatetime[3]), Number(matchDatetime[4]), Number(matchDatetime[5]), Number(matchDatetime[6] || 0), convertMilliseconds(matchDatetime[7])));
|
|
843
|
+
}
|
|
844
|
+
if (valueType === '[object Date]') {
|
|
845
|
+
return value;
|
|
846
|
+
}
|
|
847
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'datetime' });
|
|
848
|
+
},
|
|
849
|
+
convertToDate: function (value) {
|
|
850
|
+
if (value === null)
|
|
851
|
+
return null;
|
|
852
|
+
let valueType = toString.call(value);
|
|
853
|
+
if (valueType === '[object String]') {
|
|
854
|
+
let matchDate = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(value);
|
|
855
|
+
if (matchDate)
|
|
856
|
+
return new Date(Date.UTC(Number(matchDate[1]), Number(matchDate[2]) - 1, Number(matchDate[3]), 0, 0, 0, 0));
|
|
857
|
+
let matchDatetime = /^(\d{4})-(\d{1,2})-(\d{1,2})[T,\s](\d{1,2})\:(\d{1,2})\:(\d{1,2})\.?(\d+)?Z?$/.exec(value);
|
|
858
|
+
if (matchDatetime)
|
|
859
|
+
return new Date(Date.UTC(Number(matchDatetime[1]), Number(matchDatetime[2]) - 1, Number(matchDatetime[3]), 0, 0, 0, 0));
|
|
860
|
+
}
|
|
861
|
+
if (valueType === '[object Date]') {
|
|
862
|
+
return new Date(Date.UTC(value.getUTCFullYear(), value.getUTCMonth(), value.getUTCDate(), 0, 0, 0, 0));
|
|
863
|
+
}
|
|
864
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'date' });
|
|
865
|
+
},
|
|
866
|
+
convertToTime: function (value) {
|
|
867
|
+
if (value === null)
|
|
868
|
+
return null;
|
|
869
|
+
let valueType = toString.call(value);
|
|
870
|
+
if (valueType === '[object String]') {
|
|
871
|
+
let matchTime = /^(\d{1,2})\:(\d{1,2})\:(\d{1,2})\.?(\d+)?$/.exec(value);
|
|
872
|
+
if (matchTime)
|
|
873
|
+
return new Date(Date.UTC(1970, 0, 1, Number(matchTime[1]), Number(matchTime[2]), Number(matchTime[3]), convertMilliseconds(matchTime[4])));
|
|
874
|
+
let matchDatetime = /^(\d{4})-(\d{1,2})-(\d{1,2})[T,\s](\d{1,2})\:(\d{1,2})\:(\d{1,2})\.?(\d+)?Z?$/.exec(value);
|
|
875
|
+
if (matchDatetime)
|
|
876
|
+
return new Date(Date.UTC(1970, 0, 1, Number(matchDatetime[4]), Number(matchDatetime[5]), Number(matchDatetime[6] || 0), convertMilliseconds(matchDatetime[7])));
|
|
877
|
+
}
|
|
878
|
+
if (valueType === '[object Date]') {
|
|
879
|
+
return new Date(Date.UTC(1970, 0, 1, value.getUTCHours(), value.getUTCMinutes(), value.getUTCSeconds(), value.getUTCMilliseconds()));
|
|
880
|
+
}
|
|
881
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'time' });
|
|
882
|
+
},
|
|
883
|
+
ensureDashedFormat: function (str) {
|
|
884
|
+
if (str === null)
|
|
885
|
+
return null;
|
|
886
|
+
let result = '';
|
|
887
|
+
let lastChar = '';
|
|
888
|
+
for (let i = 0; i < str.length; i++) {
|
|
889
|
+
let char = str[i];
|
|
890
|
+
if (char.match(/[0-9]/)) {
|
|
891
|
+
result += char;
|
|
844
892
|
}
|
|
845
|
-
if (
|
|
846
|
-
|
|
893
|
+
else if (lastChar.match(/[A-Z]/) && char.match(/[A-Z]/)) {
|
|
894
|
+
result += char.toLowerCase();
|
|
847
895
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
convertToDate: function (value) {
|
|
851
|
-
if (value === null)
|
|
852
|
-
return null;
|
|
853
|
-
let valueType = toString.call(value);
|
|
854
|
-
if (valueType === '[object String]') {
|
|
855
|
-
let matchDate = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(value);
|
|
856
|
-
if (matchDate)
|
|
857
|
-
return new Date(Date.UTC(Number(matchDate[1]), Number(matchDate[2]) - 1, Number(matchDate[3]), 0, 0, 0, 0));
|
|
858
|
-
let matchDatetime = /^(\d{4})-(\d{1,2})-(\d{1,2})[T,\s](\d{1,2})\:(\d{1,2})\:(\d{1,2})\.?(\d+)?Z?$/.exec(value);
|
|
859
|
-
if (matchDatetime)
|
|
860
|
-
return new Date(Date.UTC(Number(matchDatetime[1]), Number(matchDatetime[2]) - 1, Number(matchDatetime[3]), 0, 0, 0, 0));
|
|
896
|
+
else if (lastChar.match(/[A-Z]/) && char.match(/[a-z]/)) {
|
|
897
|
+
result += char;
|
|
861
898
|
}
|
|
862
|
-
if (
|
|
863
|
-
|
|
899
|
+
else if (lastChar.match(/[a-z]/) && char.match(/[A-Z]/)) {
|
|
900
|
+
result += '-' + char.toLowerCase();
|
|
864
901
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
convertToTime: function (value) {
|
|
868
|
-
if (value === null)
|
|
869
|
-
return null;
|
|
870
|
-
let valueType = toString.call(value);
|
|
871
|
-
if (valueType === '[object String]') {
|
|
872
|
-
let matchTime = /^(\d{1,2})\:(\d{1,2})\:(\d{1,2})\.?(\d+)?$/.exec(value);
|
|
873
|
-
if (matchTime)
|
|
874
|
-
return new Date(Date.UTC(1970, 0, 1, Number(matchTime[1]), Number(matchTime[2]), Number(matchTime[3]), convertMilliseconds(matchTime[4])));
|
|
875
|
-
let matchDatetime = /^(\d{4})-(\d{1,2})-(\d{1,2})[T,\s](\d{1,2})\:(\d{1,2})\:(\d{1,2})\.?(\d+)?Z?$/.exec(value);
|
|
876
|
-
if (matchDatetime)
|
|
877
|
-
return new Date(Date.UTC(1970, 0, 1, Number(matchDatetime[4]), Number(matchDatetime[5]), Number(matchDatetime[6] || 0), convertMilliseconds(matchDatetime[7])));
|
|
902
|
+
else if (lastChar.match(/[a-z]/) && char.match(/[a-z]/)) {
|
|
903
|
+
result += char;
|
|
878
904
|
}
|
|
879
|
-
if (
|
|
880
|
-
|
|
905
|
+
else if (char.match(/[A-Z]/)) {
|
|
906
|
+
result += char.toLowerCase();
|
|
881
907
|
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
ensureDashedFormat: function (str) {
|
|
885
|
-
if (str === null)
|
|
886
|
-
return null;
|
|
887
|
-
let result = '';
|
|
888
|
-
let lastChar = '';
|
|
889
|
-
for (let i = 0; i < str.length; i++) {
|
|
890
|
-
let char = str[i];
|
|
891
|
-
if (char.match(/[0-9]/)) {
|
|
892
|
-
result += char;
|
|
893
|
-
}
|
|
894
|
-
else if (lastChar.match(/[A-Z]/) && char.match(/[A-Z]/)) {
|
|
895
|
-
result += char.toLowerCase();
|
|
896
|
-
}
|
|
897
|
-
else if (lastChar.match(/[A-Z]/) && char.match(/[a-z]/)) {
|
|
898
|
-
result += char;
|
|
899
|
-
}
|
|
900
|
-
else if (lastChar.match(/[a-z]/) && char.match(/[A-Z]/)) {
|
|
901
|
-
result += '-' + char.toLowerCase();
|
|
902
|
-
}
|
|
903
|
-
else if (lastChar.match(/[a-z]/) && char.match(/[a-z]/)) {
|
|
904
|
-
result += char;
|
|
905
|
-
}
|
|
906
|
-
else if (char.match(/[A-Z]/)) {
|
|
907
|
-
result += char.toLowerCase();
|
|
908
|
-
}
|
|
909
|
-
else if (char.match(/[a-z]/)) {
|
|
910
|
-
result += char;
|
|
911
|
-
}
|
|
912
|
-
lastChar = char;
|
|
908
|
+
else if (char.match(/[a-z]/)) {
|
|
909
|
+
result += char;
|
|
913
910
|
}
|
|
914
|
-
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
if (value) {
|
|
942
|
-
if (routingParameter.type === 'string')
|
|
943
|
-
this.setValue(result, routingParameter.bind, this.convertToString(value));
|
|
944
|
-
else if (routingParameter.type === 'integer')
|
|
945
|
-
this.setValue(result, routingParameter.bind, this.convertToInteger(value));
|
|
946
|
-
else if (routingParameter.type === 'decimal')
|
|
947
|
-
this.setValue(result, routingParameter.bind, this.convertToDecimal(value));
|
|
948
|
-
else if (routingParameter.type === 'boolean')
|
|
949
|
-
this.setValue(result, routingParameter.bind, this.convertToBoolean(value));
|
|
950
|
-
else if (routingParameter.type === 'datetime')
|
|
951
|
-
this.setValue(result, routingParameter.bind, this.convertToDatetime(value));
|
|
952
|
-
else if (routingParameter.type === 'date')
|
|
953
|
-
this.setValue(result, routingParameter.bind, this.convertToDate(value));
|
|
954
|
-
else if (routingParameter.type === 'time')
|
|
955
|
-
this.setValue(result, routingParameter.bind, this.convertToTime(value));
|
|
956
|
-
else if (routingParameter.type === 'list(string)')
|
|
957
|
-
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToString));
|
|
958
|
-
else if (routingParameter.type === 'list(integer)')
|
|
959
|
-
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToInteger));
|
|
960
|
-
else if (routingParameter.type === 'list(decimal)')
|
|
961
|
-
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToDecimal));
|
|
962
|
-
else if (routingParameter.type === 'list(boolean)')
|
|
963
|
-
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToBoolean));
|
|
964
|
-
else if (routingParameter.type === 'list(datetime)')
|
|
965
|
-
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToDatetime));
|
|
966
|
-
else if (routingParameter.type === 'list(date)')
|
|
967
|
-
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToDate));
|
|
968
|
-
else if (routingParameter.type === 'list(time)')
|
|
969
|
-
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToTime));
|
|
911
|
+
lastChar = char;
|
|
912
|
+
}
|
|
913
|
+
return result;
|
|
914
|
+
},
|
|
915
|
+
mapRoutingParameters: function (request, routingParameters) {
|
|
916
|
+
let result = {};
|
|
917
|
+
if (routingParameters) {
|
|
918
|
+
const lowerCaseHeadersKeysEntries = Object.keys(request.headers || {}).map(headerKey => [headerKey.toLowerCase(), headerKey])
|
|
919
|
+
const lowerCaseHeadersKeysMap = Object.fromEntries(lowerCaseHeadersKeysEntries)
|
|
920
|
+
for (let i = 0; i < routingParameters.length; i++) {
|
|
921
|
+
let routingParameter = routingParameters[i];
|
|
922
|
+
if (routingParameter.name && routingParameter.type) {
|
|
923
|
+
if (routingParameter.in === 'Path' || routingParameter.in === 'Query' || routingParameter.in === 'Header') {
|
|
924
|
+
let value = null;
|
|
925
|
+
if (routingParameter.in === 'Path') {
|
|
926
|
+
if (request.params && request.params[routingParameter.name])
|
|
927
|
+
value = request.params[routingParameter.name];
|
|
928
|
+
}
|
|
929
|
+
else if (routingParameter.in === 'Query') {
|
|
930
|
+
if (request.query && request.query[routingParameter.name])
|
|
931
|
+
value = request.query[routingParameter.name];
|
|
932
|
+
}
|
|
933
|
+
else if (routingParameter.in === 'Header') {
|
|
934
|
+
const headerKey = lowerCaseHeadersKeysMap[routingParameter.name.toLowerCase()]
|
|
935
|
+
const headerValue = headerKey && request.headers && request.headers[headerKey]
|
|
936
|
+
if (headerValue) {
|
|
937
|
+
value = headerValue
|
|
970
938
|
}
|
|
971
939
|
}
|
|
972
|
-
|
|
973
|
-
|
|
940
|
+
if (value) {
|
|
941
|
+
if (routingParameter.type === 'string')
|
|
942
|
+
this.setValue(result, routingParameter.bind, this.convertToString(value));
|
|
943
|
+
else if (routingParameter.type === 'integer')
|
|
944
|
+
this.setValue(result, routingParameter.bind, this.convertToInteger(value));
|
|
945
|
+
else if (routingParameter.type === 'decimal')
|
|
946
|
+
this.setValue(result, routingParameter.bind, this.convertToDecimal(value));
|
|
947
|
+
else if (routingParameter.type === 'boolean')
|
|
948
|
+
this.setValue(result, routingParameter.bind, this.convertToBoolean(value));
|
|
949
|
+
else if (routingParameter.type === 'datetime')
|
|
950
|
+
this.setValue(result, routingParameter.bind, this.convertToDatetime(value));
|
|
951
|
+
else if (routingParameter.type === 'date')
|
|
952
|
+
this.setValue(result, routingParameter.bind, this.convertToDate(value));
|
|
953
|
+
else if (routingParameter.type === 'time')
|
|
954
|
+
this.setValue(result, routingParameter.bind, this.convertToTime(value));
|
|
955
|
+
else if (routingParameter.type === 'list(string)')
|
|
956
|
+
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToString));
|
|
957
|
+
else if (routingParameter.type === 'list(integer)')
|
|
958
|
+
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToInteger));
|
|
959
|
+
else if (routingParameter.type === 'list(decimal)')
|
|
960
|
+
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToDecimal));
|
|
961
|
+
else if (routingParameter.type === 'list(boolean)')
|
|
962
|
+
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToBoolean));
|
|
963
|
+
else if (routingParameter.type === 'list(datetime)')
|
|
964
|
+
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToDatetime));
|
|
965
|
+
else if (routingParameter.type === 'list(date)')
|
|
966
|
+
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToDate));
|
|
967
|
+
else if (routingParameter.type === 'list(time)')
|
|
968
|
+
this.setValue(result, routingParameter.bind, convertToListOf(value, this.convertToTime));
|
|
974
969
|
}
|
|
975
970
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
return result;
|
|
979
|
-
},
|
|
980
|
-
decodeApiKey: function (request, apiKeyIn, apiKeyName) {
|
|
981
|
-
switch (apiKeyIn) {
|
|
982
|
-
case 'Header': {
|
|
983
|
-
if (request.headers) {
|
|
984
|
-
let headerValue = request.headers[apiKeyName];
|
|
985
|
-
if (headerValue) {
|
|
986
|
-
return { key: headerValue };
|
|
987
|
-
}
|
|
971
|
+
else if (routingParameter.in === 'Body') {
|
|
972
|
+
this.setValue(result, routingParameter.bind, request.payload);
|
|
988
973
|
}
|
|
989
|
-
break;
|
|
990
974
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
return result;
|
|
978
|
+
},
|
|
979
|
+
decodeApiKey: function (request, apiKeyIn, apiKeyName) {
|
|
980
|
+
switch (apiKeyIn) {
|
|
981
|
+
case 'Header': {
|
|
982
|
+
if (request.headers) {
|
|
983
|
+
let headerValue = request.headers[apiKeyName];
|
|
984
|
+
if (headerValue) {
|
|
985
|
+
return { key: headerValue };
|
|
997
986
|
}
|
|
998
|
-
break;
|
|
999
987
|
}
|
|
988
|
+
break;
|
|
1000
989
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
if (headerValue && headerValue.startsWith('Basic')) {
|
|
1007
|
-
try {
|
|
1008
|
-
let buffer = Buffer.from(headerValue.split(' ')[1], 'base64');
|
|
1009
|
-
let plain = buffer.toString();
|
|
1010
|
-
let credentials = plain.split(':');
|
|
1011
|
-
return { user: credentials[0], password: credentials[1] };
|
|
990
|
+
case 'Query': {
|
|
991
|
+
if (request.query) {
|
|
992
|
+
let queryValue = request.query[apiKeyName];
|
|
993
|
+
if (queryValue) {
|
|
994
|
+
return { key: queryValue };
|
|
1012
995
|
}
|
|
1013
|
-
catch (err2) { }
|
|
1014
996
|
}
|
|
997
|
+
break;
|
|
1015
998
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
999
|
+
}
|
|
1000
|
+
return null;
|
|
1001
|
+
},
|
|
1002
|
+
decodeBasicAuth: function (request) {
|
|
1003
|
+
if (request.headers) {
|
|
1004
|
+
let headerValue = request.headers['authorization'];
|
|
1005
|
+
if (headerValue && headerValue.startsWith('Basic')) {
|
|
1006
|
+
try {
|
|
1007
|
+
let buffer = Buffer.from(headerValue.split(' ')[1], 'base64');
|
|
1008
|
+
let plain = buffer.toString();
|
|
1009
|
+
let credentials = plain.split(':');
|
|
1010
|
+
return { user: credentials[0], password: credentials[1] };
|
|
1023
1011
|
}
|
|
1012
|
+
catch (err2) { }
|
|
1024
1013
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
}
|
|
1034
|
-
catch (fserr) {
|
|
1035
|
-
if (fserr.code !== 'ENOENT')
|
|
1036
|
-
throw fserr
|
|
1037
|
-
}
|
|
1038
|
-
let err = new Error();
|
|
1039
|
-
err.code = 'ResourceNotFound';
|
|
1040
|
-
err.data = { path: path };
|
|
1041
|
-
throw err;
|
|
1042
|
-
},
|
|
1043
|
-
callRest: async function (connection, restMapping, functionName, values, request, configParameters, callContext) {
|
|
1044
|
-
let restMappingFunction = restMapping[functionName];
|
|
1045
|
-
let requestUrl = connection.url.trim();
|
|
1046
|
-
let requestUrlIndex = requestUrl.length - 1;
|
|
1047
|
-
while (requestUrlIndex >= 0 && requestUrl[requestUrlIndex] === '/') {
|
|
1048
|
-
requestUrlIndex--;
|
|
1049
|
-
}
|
|
1050
|
-
requestUrl = requestUrl.substring(0, requestUrlIndex + 1) + restMappingFunction.path;
|
|
1051
|
-
let requestOptions = {
|
|
1052
|
-
method: restMappingFunction.method,
|
|
1053
|
-
headers: { 'Content-Type': 'application/json' },
|
|
1054
|
-
throwHttpErrors: false
|
|
1055
|
-
};
|
|
1056
|
-
if (restMappingFunction.timeout && restMappingFunction.timeout > 0) {
|
|
1057
|
-
requestOptions.timeout = restMappingFunction.timeout;
|
|
1014
|
+
}
|
|
1015
|
+
return null;
|
|
1016
|
+
},
|
|
1017
|
+
decodeBearerToken: function (request) {
|
|
1018
|
+
if (request.headers) {
|
|
1019
|
+
let headerValue = request.headers['authorization'];
|
|
1020
|
+
if (headerValue && headerValue.startsWith('Bearer')) {
|
|
1021
|
+
return { token: headerValue.split(' ')[1] };
|
|
1058
1022
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1023
|
+
}
|
|
1024
|
+
return null;
|
|
1025
|
+
},
|
|
1026
|
+
loadResource: async function (path) {
|
|
1027
|
+
try {
|
|
1028
|
+
let resourceContent = await Fs.readFile(Path.join(_metadata.appPath, '../resources', path), 'utf8');
|
|
1029
|
+
if (path.endsWith('.json') ) return JSON.parse(resourceContent)
|
|
1030
|
+
else if (path.endsWith('.yaml') || path.endsWith('.yml'))return jsyaml.load(resourceContent)
|
|
1031
|
+
else return resourceContent;
|
|
1032
|
+
}
|
|
1033
|
+
catch (fserr) {
|
|
1034
|
+
if (fserr.code !== 'ENOENT')
|
|
1035
|
+
throw fserr
|
|
1036
|
+
}
|
|
1037
|
+
let err = new Error();
|
|
1038
|
+
err.code = 'ResourceNotFound';
|
|
1039
|
+
err.data = { path: path };
|
|
1040
|
+
throw err;
|
|
1041
|
+
},
|
|
1042
|
+
callRest: async function (connection, restMapping, functionName, values, request, configParameters, callContext) {
|
|
1043
|
+
let restMappingFunction = restMapping[functionName];
|
|
1044
|
+
let requestUrl = connection.url.trim();
|
|
1045
|
+
let requestUrlIndex = requestUrl.length - 1;
|
|
1046
|
+
while (requestUrlIndex >= 0 && requestUrl[requestUrlIndex] === '/') {
|
|
1047
|
+
requestUrlIndex--;
|
|
1048
|
+
}
|
|
1049
|
+
requestUrl = requestUrl.substring(0, requestUrlIndex + 1) + restMappingFunction.path;
|
|
1050
|
+
let requestOptions = {
|
|
1051
|
+
method: restMappingFunction.method,
|
|
1052
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1053
|
+
throwHttpErrors: false
|
|
1054
|
+
};
|
|
1055
|
+
if (restMappingFunction.timeout && restMappingFunction.timeout > 0) {
|
|
1056
|
+
requestOptions.timeout = restMappingFunction.timeout;
|
|
1057
|
+
}
|
|
1058
|
+
var isFirstQueryParameter = true;
|
|
1059
|
+
if (restMappingFunction.parameters) {
|
|
1060
|
+
for (let i = 0; i < restMappingFunction.parameters.length; i++) {
|
|
1061
|
+
let routingParameter = restMappingFunction.parameters[i];
|
|
1062
|
+
let bindParts = routingParameter.bind.split('.');
|
|
1063
|
+
let value = values;
|
|
1064
|
+
for (let j = 0; j < bindParts.length; j++) {
|
|
1065
|
+
let bindPart = bindParts[j];
|
|
1066
|
+
if (value)
|
|
1067
|
+
value = value[bindPart];
|
|
1068
|
+
}
|
|
1069
|
+
if (value === null && routingParameter.in === 'Path')
|
|
1070
|
+
throw new Error('Error trying to call [' + connection.url + restMappingFunction.path + ']. The parameter [' + routingParameter.name + '] is mandatory.');
|
|
1071
|
+
if (value !== null && value !== undefined) {
|
|
1072
|
+
if (routingParameter.in === 'Path') {
|
|
1073
|
+
requestUrl = requestUrl.split('{' + routingParameter.name + '}').join(encodeURIComponent(this.convertToString(value)));
|
|
1069
1074
|
}
|
|
1070
|
-
if (
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
requestUrl = requestUrl.split('{' + routingParameter.name + '}').join(encodeURIComponent(this.convertToString(value)));
|
|
1075
|
-
}
|
|
1076
|
-
else if (routingParameter.in === 'Query') {
|
|
1077
|
-
if (Array.isArray(value)) {
|
|
1078
|
-
for (let k = 0; k < value.length; k++) {
|
|
1079
|
-
requestUrl += (isFirstQueryParameter ? '?' : '&') + encodeURIComponent(routingParameter.name) + '=' + encodeURIComponent(this.convertToString(value[k]));
|
|
1080
|
-
isFirstQueryParameter = false;
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
else {
|
|
1084
|
-
requestUrl += (isFirstQueryParameter ? '?' : '&') + encodeURIComponent(routingParameter.name) + '=' + encodeURIComponent(this.convertToString(value));
|
|
1075
|
+
else if (routingParameter.in === 'Query') {
|
|
1076
|
+
if (Array.isArray(value)) {
|
|
1077
|
+
for (let k = 0; k < value.length; k++) {
|
|
1078
|
+
requestUrl += (isFirstQueryParameter ? '?' : '&') + encodeURIComponent(routingParameter.name) + '=' + encodeURIComponent(this.convertToString(value[k]));
|
|
1085
1079
|
isFirstQueryParameter = false;
|
|
1086
1080
|
}
|
|
1087
1081
|
}
|
|
1088
|
-
else
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
else if (routingParameter.in === 'Body') {
|
|
1092
|
-
requestOptions.body = JSON.stringify(value);
|
|
1082
|
+
else {
|
|
1083
|
+
requestUrl += (isFirstQueryParameter ? '?' : '&') + encodeURIComponent(routingParameter.name) + '=' + encodeURIComponent(this.convertToString(value));
|
|
1084
|
+
isFirstQueryParameter = false;
|
|
1093
1085
|
}
|
|
1094
1086
|
}
|
|
1087
|
+
else if (routingParameter.in === 'Header') {
|
|
1088
|
+
requestOptions.headers[routingParameter.name] = this.convertToString(value);
|
|
1089
|
+
}
|
|
1090
|
+
else if (routingParameter.in === 'Body') {
|
|
1091
|
+
requestOptions.body = JSON.stringify(value);
|
|
1092
|
+
}
|
|
1095
1093
|
}
|
|
1096
1094
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1095
|
+
}
|
|
1096
|
+
if (restMappingFunction.security) {
|
|
1097
|
+
let securityApplied = false;
|
|
1098
|
+
for (let i = 0; i < restMappingFunction.security.length; i++) {
|
|
1099
|
+
if (!securityApplied) {
|
|
1100
|
+
let securityItem = restMappingFunction.security[i];
|
|
1101
|
+
let securityItemOk = true;
|
|
1102
|
+
let securityItemValues = [];
|
|
1103
|
+
for (let j = 0; j < securityItem.length; j++) {
|
|
1104
|
+
let securityConditionItem = securityItem[j];
|
|
1105
|
+
let value = null;
|
|
1106
|
+
switch (securityConditionItem.source) {
|
|
1107
|
+
case 'ConfigParameter': {
|
|
1108
|
+
value = configParameters[securityConditionItem.configParameterName];
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
1111
|
+
case 'AccessToken': {
|
|
1112
|
+
const SESSION_STATE = securityService.getCookieName('session_state')
|
|
1113
|
+
let sessionState = request.state[SESSION_STATE];
|
|
1114
|
+
// For backward compatibility with previous versions, the session_state is searched if the name of the configured cookie was not found.
|
|
1115
|
+
if (!sessionState) {
|
|
1116
|
+
sessionState = request.state['session_state'];
|
|
1117
|
+
}
|
|
1118
|
+
// If sessionState still does not exists, then token is on the header as it should
|
|
1119
|
+
// Removed since sessionState is now also required in Azure
|
|
1120
|
+
// if(!sessionState) {
|
|
1121
|
+
// value = await securityService.extractTokenhNoDecode(request);
|
|
1122
|
+
// break;
|
|
1123
|
+
// }
|
|
1124
|
+
// added request on getUseToken in case we use hapi modules full stack
|
|
1125
|
+
const token = await securityService.getUseToken(sessionState, request);
|
|
1126
|
+
if (token) {
|
|
1127
|
+
value = token;
|
|
1128
|
+
} else {
|
|
1129
|
+
const ACCESS_TOKEN = securityService.getCookieName('access_token')
|
|
1130
|
+
value = request.state[ACCESS_TOKEN];
|
|
1131
|
+
}
|
|
1132
|
+
break;
|
|
1133
|
+
}
|
|
1134
|
+
case 'Cookie': {
|
|
1135
|
+
value = request.state[securityConditionItem.cookieName];
|
|
1136
|
+
break;
|
|
1137
|
+
}
|
|
1138
|
+
case 'CallVariable': {
|
|
1139
|
+
value = callContext.callVariables[securityConditionItem.callVariableName];
|
|
1140
|
+
break;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
if (value)
|
|
1144
|
+
securityItemValues.push(value);
|
|
1145
|
+
else
|
|
1146
|
+
securityItemOk = false;
|
|
1147
|
+
}
|
|
1148
|
+
if (securityItemOk) {
|
|
1104
1149
|
for (let j = 0; j < securityItem.length; j++) {
|
|
1105
1150
|
let securityConditionItem = securityItem[j];
|
|
1106
|
-
let value =
|
|
1107
|
-
switch (securityConditionItem.
|
|
1108
|
-
case '
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
// If sessionState still does not exists, then token is on the header as it should
|
|
1120
|
-
// Removed since sessionState is now also required in Azure
|
|
1121
|
-
// if(!sessionState) {
|
|
1122
|
-
// value = await securityService.extractTokenhNoDecode(request);
|
|
1123
|
-
// break;
|
|
1124
|
-
// }
|
|
1125
|
-
// added request on getUseToken in case we use hapi modules full stack
|
|
1126
|
-
const token = await securityService.getUseToken(sessionState, request);
|
|
1127
|
-
if (token) {
|
|
1128
|
-
value = token;
|
|
1129
|
-
} else {
|
|
1130
|
-
const ACCESS_TOKEN = securityService.getCookieName('access_token')
|
|
1131
|
-
value = request.state[ACCESS_TOKEN];
|
|
1151
|
+
let value = securityItemValues[j];
|
|
1152
|
+
switch (securityConditionItem.securityType) {
|
|
1153
|
+
case 'ApiKey': {
|
|
1154
|
+
switch (securityConditionItem.apiKeyIn) {
|
|
1155
|
+
case 'Query': {
|
|
1156
|
+
requestUrl += (isFirstQueryParameter ? '?' : '&') + encodeURIComponent(securityConditionItem.apiKeyName) + '=' + encodeURIComponent(value);
|
|
1157
|
+
isFirstQueryParameter = false;
|
|
1158
|
+
break;
|
|
1159
|
+
}
|
|
1160
|
+
case 'Header': {
|
|
1161
|
+
requestOptions.headers[securityConditionItem.apiKeyName] = value;
|
|
1162
|
+
break;
|
|
1163
|
+
}
|
|
1132
1164
|
}
|
|
1133
1165
|
break;
|
|
1134
1166
|
}
|
|
1135
|
-
case '
|
|
1136
|
-
|
|
1167
|
+
case 'BasicAuth': {
|
|
1168
|
+
requestOptions.headers['Authorization'] = 'Basic ' + Buffer.from(value.user + ':' + value.password, 'ascii').toString('base64');
|
|
1137
1169
|
break;
|
|
1138
1170
|
}
|
|
1139
|
-
case '
|
|
1140
|
-
|
|
1171
|
+
case 'BearerToken': {
|
|
1172
|
+
requestOptions.headers['Authorization'] = 'Bearer ' + value;
|
|
1141
1173
|
break;
|
|
1142
1174
|
}
|
|
1143
1175
|
}
|
|
1144
|
-
if (value)
|
|
1145
|
-
securityItemValues.push(value);
|
|
1146
|
-
else
|
|
1147
|
-
securityItemOk = false;
|
|
1148
|
-
}
|
|
1149
|
-
if (securityItemOk) {
|
|
1150
|
-
for (let j = 0; j < securityItem.length; j++) {
|
|
1151
|
-
let securityConditionItem = securityItem[j];
|
|
1152
|
-
let value = securityItemValues[j];
|
|
1153
|
-
switch (securityConditionItem.securityType) {
|
|
1154
|
-
case 'ApiKey': {
|
|
1155
|
-
switch (securityConditionItem.apiKeyIn) {
|
|
1156
|
-
case 'Query': {
|
|
1157
|
-
requestUrl += (isFirstQueryParameter ? '?' : '&') + encodeURIComponent(securityConditionItem.apiKeyName) + '=' + encodeURIComponent(value);
|
|
1158
|
-
isFirstQueryParameter = false;
|
|
1159
|
-
break;
|
|
1160
|
-
}
|
|
1161
|
-
case 'Header': {
|
|
1162
|
-
requestOptions.headers[securityConditionItem.apiKeyName] = value;
|
|
1163
|
-
break;
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
break;
|
|
1167
|
-
}
|
|
1168
|
-
case 'BasicAuth': {
|
|
1169
|
-
requestOptions.headers['Authorization'] = 'Basic ' + Buffer.from(value.user + ':' + value.password, 'ascii').toString('base64');
|
|
1170
|
-
break;
|
|
1171
|
-
}
|
|
1172
|
-
case 'BearerToken': {
|
|
1173
|
-
requestOptions.headers['Authorization'] = 'Bearer ' + value;
|
|
1174
|
-
break;
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
securityApplied = true;
|
|
1179
1176
|
}
|
|
1177
|
+
securityApplied = true;
|
|
1180
1178
|
}
|
|
1181
1179
|
}
|
|
1182
1180
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1181
|
+
}
|
|
1182
|
+
securityService.validateSecureRequest(request)
|
|
1183
|
+
// The following IF code block should not exists. Only for propagating without properly configuring it the suite.
|
|
1184
|
+
let propagateAuthToken = process.env.blz_propagateAuthToken;
|
|
1185
|
+
if(propagateAuthToken) {
|
|
1186
|
+
// check if the system is to be ignored for the redirection of the Security token
|
|
1187
|
+
let propagateAuthTokenIgnoreSystems = process.env.blz_propagateAuthTokenIgnoreSystems;
|
|
1188
|
+
const ignoredSystems = propagateAuthTokenIgnoreSystems ? propagateAuthTokenIgnoreSystems.split(",") : [];
|
|
1189
|
+
const ignorePropagation = ignoredSystems.includes(connection.name);
|
|
1190
|
+
// If system is included in the list, ignore propagation. If not, propagate
|
|
1191
|
+
if(!ignorePropagation) {
|
|
1192
|
+
let value = null;
|
|
1193
|
+
const SESSION_STATE = securityService.getCookieName('session_state')
|
|
1194
|
+
// request object comes null when called in a microservice. if it exists it is inside the frontend.
|
|
1195
|
+
if (request){
|
|
1196
|
+
let sessionState = request.state[SESSION_STATE];
|
|
1197
|
+
// For backward compatibility with previous versions, the session_state is searched if the name of the configured cookie was not found.
|
|
1198
|
+
if (!sessionState) {
|
|
1199
|
+
sessionState = request.state['session_state'];
|
|
1200
|
+
}
|
|
1201
|
+
// If sessionState still does not exists, then it is on the header
|
|
1202
|
+
if(!sessionState) {
|
|
1203
|
+
value = await securityService.extractTokenhNoDecode(request);
|
|
1204
|
+
} else {
|
|
1205
|
+
// added request on getUseToken in case we use hapi modules full stack
|
|
1206
|
+
const token = await securityService.getUseToken(sessionState, request);
|
|
1207
|
+
if (token) {
|
|
1208
|
+
value = token;
|
|
1205
1209
|
} else {
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
if (token) {
|
|
1209
|
-
value = token;
|
|
1210
|
-
} else {
|
|
1211
|
-
const ACCESS_TOKEN = securityService.getCookieName('access_token')
|
|
1212
|
-
value = request.state[ACCESS_TOKEN];
|
|
1213
|
-
}
|
|
1210
|
+
const ACCESS_TOKEN = securityService.getCookieName('access_token')
|
|
1211
|
+
value = request.state[ACCESS_TOKEN];
|
|
1214
1212
|
}
|
|
1215
|
-
} else if (callContext && callContext.callVariables && callContext.callVariables['CallVariable-BearerToken']) {
|
|
1216
|
-
// if i am working from inside a microservice. where should i get the token from?
|
|
1217
|
-
// artificial call variable used to store token
|
|
1218
|
-
value = callContext.callVariables['CallVariable-BearerToken'];
|
|
1219
|
-
} else {
|
|
1220
|
-
value = null;
|
|
1221
1213
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1214
|
+
} else if (callContext && callContext.callVariables && callContext.callVariables['CallVariable-BearerToken']) {
|
|
1215
|
+
// if i am working from inside a microservice. where should i get the token from?
|
|
1216
|
+
// artificial call variable used to store token
|
|
1217
|
+
value = callContext.callVariables['CallVariable-BearerToken'];
|
|
1218
|
+
} else {
|
|
1219
|
+
value = null;
|
|
1220
|
+
}
|
|
1221
|
+
switch (propagateAuthToken){
|
|
1222
|
+
case 'BearerToken': {
|
|
1223
|
+
if (/^Bearer /.test(value)) {
|
|
1224
|
+
requestOptions.headers['Authorization'] = value;
|
|
1225
|
+
} else {
|
|
1226
|
+
requestOptions.headers['Authorization'] = 'Bearer ' + value;
|
|
1230
1227
|
}
|
|
1231
|
-
|
|
1232
|
-
break;
|
|
1228
|
+
break;
|
|
1233
1229
|
}
|
|
1230
|
+
default:
|
|
1231
|
+
break;
|
|
1234
1232
|
}
|
|
1235
1233
|
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1234
|
+
}
|
|
1235
|
+
if (requestUrl.match(/https.*/)) {
|
|
1236
|
+
requestOptions = {
|
|
1237
|
+
...requestOptions,
|
|
1238
|
+
https: {
|
|
1239
|
+
requestCert: true, // Request a certificate from clients that connect and attempt to verify that certificate.
|
|
1240
|
+
rejectUnauthorized: false, // The server will reject any connection which is not authorized with the list of supplied CAs.
|
|
1241
|
+
agent: false // Is responsible for managing connection persistence and reuse for https clients.
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
let traceStartTime = Date.now();
|
|
1246
|
+
const dateISOString = new Date().toISOString();
|
|
1247
|
+
if (typeof _externalRestCallId === 'undefined')
|
|
1248
|
+
_externalRestCallId = 1;
|
|
1249
|
+
else
|
|
1250
|
+
_externalRestCallId++;
|
|
1251
|
+
const traceId = _externalRestCallId;
|
|
1252
|
+
if (process.env.blz_traceAll === 'true' || process.env.blz_traceExternalRestCalls === 'true') {
|
|
1253
|
+
console.log((callContext.devTime ? '' : dateISOString + ' | ') + 'EXTERNAL REST CALL (' + traceId + ') | ' + connection.name + ' | ' + requestOptions.method + ' ' + requestUrl + ' | HEADERS: ' + JSON.stringify(requestOptions.headers) + (requestOptions.body ? ' | BODY: ' + requestOptions.body : ''));
|
|
1254
|
+
}
|
|
1255
|
+
try {
|
|
1256
|
+
|
|
1257
|
+
const response = await Got(requestUrl, requestOptions);
|
|
1258
|
+
const responseTime = Date.now() - traceStartTime;
|
|
1253
1259
|
if (process.env.blz_traceAll === 'true' || process.env.blz_traceExternalRestCalls === 'true') {
|
|
1254
|
-
console.log((callContext.devTime ? '' : dateISOString + ' | ') + 'EXTERNAL REST CALL (' + traceId + ') | ' + connection.name + ' | ' +
|
|
1260
|
+
console.log((callContext.devTime ? '' : dateISOString + ' | ') + 'EXTERNAL REST CALL (' + traceId + ') | ' + connection.name + ' | STATUS: ' + response.statusCode + ' | BODY: ' + response.body + ' | TIME: ' + responseTime + ' milliseconds');
|
|
1255
1261
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
status: response.statusCode,
|
|
1299
|
-
body: response.body,
|
|
1300
|
-
time: responseTime
|
|
1301
|
-
}
|
|
1302
|
-
});
|
|
1303
|
-
} catch (error) {
|
|
1304
|
-
console.error('Error saving navigation in security service', error);
|
|
1305
|
-
}
|
|
1262
|
+
// These 2 are added for the PostProcessRequest event
|
|
1263
|
+
if (request) {
|
|
1264
|
+
request.httpRequestLog = {url: request.path, method: requestOptions.method, headers: Object.entries(requestOptions.headers), body: requestOptions.body, clientInfo: request.clientInfo }
|
|
1265
|
+
request.httpResponseLog = { status: response.statusCode, headers: Object.entries(response.headers), body: response.body}
|
|
1266
|
+
}
|
|
1267
|
+
let httpErrorCode = this.httpErrors[response.statusCode];
|
|
1268
|
+
// If the request has the header x-navigation-info, it means that the request is a navigation request and the response should be saved in the security service.
|
|
1269
|
+
if (request && request.headers['x-navigation-info']) {
|
|
1270
|
+
try{
|
|
1271
|
+
const clientNavigation = request.headers['x-navigation-info'];
|
|
1272
|
+
const userInfo = await securityService.getUserInfo(request)
|
|
1273
|
+
const config = configService.getConfig()
|
|
1274
|
+
securityService.pushNavigation({
|
|
1275
|
+
app: config.buildSystem.name,
|
|
1276
|
+
username: userInfo.user_name,
|
|
1277
|
+
date: dateISOString,
|
|
1278
|
+
client: {
|
|
1279
|
+
nav: JSON.parse(Buffer.from(clientNavigation, 'base64').toString('utf-8')),
|
|
1280
|
+
ip: request.headers['x-forwarded-for'] || request.info.remoteAddress,
|
|
1281
|
+
userAgent: request.headers['user-agent'],
|
|
1282
|
+
lang: request.headers['accept-language'],
|
|
1283
|
+
host: request.info.host,
|
|
1284
|
+
protocol: request.headers['x-forwarded-proto'] || request.server.info.protocol,
|
|
1285
|
+
id: request.info.id
|
|
1286
|
+
},
|
|
1287
|
+
request: {
|
|
1288
|
+
traceId: traceId,
|
|
1289
|
+
traceStartTime: traceStartTime,
|
|
1290
|
+
connection: connection.name,
|
|
1291
|
+
method: request.method,
|
|
1292
|
+
path: request.path,
|
|
1293
|
+
url: requestUrl,
|
|
1294
|
+
body: requestOptions.body
|
|
1295
|
+
},
|
|
1296
|
+
response: {
|
|
1297
|
+
status: response.statusCode,
|
|
1298
|
+
body: response.body,
|
|
1299
|
+
time: responseTime
|
|
1300
|
+
}
|
|
1301
|
+
});
|
|
1302
|
+
} catch(error) {
|
|
1303
|
+
console.error('Error saving navigation in security service', error);
|
|
1306
1304
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
console.log(`Handle error ${err.code}: ${data}`)
|
|
1319
|
-
} else {
|
|
1320
|
-
err.data = {
|
|
1321
|
-
requestUrl: requestUrl,
|
|
1322
|
-
responseStatus: response.statusCode,
|
|
1323
|
-
responseBody: tryParse(response.body, response.body)
|
|
1324
|
-
};
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
if (httpErrorCode) {
|
|
1308
|
+
let err = new Error();
|
|
1309
|
+
err.code = httpErrorCode;
|
|
1310
|
+
try {
|
|
1311
|
+
if (process.env.NODE_ENV === 'production') {
|
|
1312
|
+
const data = {
|
|
1313
|
+
requestUrl: requestUrl,
|
|
1314
|
+
responseStatus: response.statusCode,
|
|
1315
|
+
responseBody: tryParse(response.body, response.body)
|
|
1325
1316
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1317
|
+
console.log(`Handle error ${err.code}: ${data}`)
|
|
1318
|
+
} else {
|
|
1319
|
+
err.data = {
|
|
1320
|
+
requestUrl: requestUrl,
|
|
1321
|
+
responseStatus: response.statusCode,
|
|
1322
|
+
responseBody: tryParse(response.body, response.body)
|
|
1323
|
+
};
|
|
1328
1324
|
}
|
|
1329
|
-
|
|
1325
|
+
} catch (ex) {
|
|
1326
|
+
console.log(`Handle error ${err.code}: ${ex}`)
|
|
1330
1327
|
}
|
|
1331
|
-
|
|
1332
|
-
|
|
1328
|
+
throw err;
|
|
1329
|
+
}
|
|
1330
|
+
else {
|
|
1331
|
+
return tryParse(response.body, response.body)
|
|
1332
|
+
}
|
|
1333
|
+
} catch (error) {
|
|
1334
|
+
if (error.code == 'ETIMEDOUT') {
|
|
1335
|
+
// Here we check for the timeout originated from the request options timeout added for the Got request.
|
|
1336
|
+
// All other errors should be handled in finally.
|
|
1337
|
+
// response is destroyed if it timed out
|
|
1338
|
+
let err = new Error();
|
|
1339
|
+
err.code = 'GatewayTimeout';
|
|
1340
|
+
err.data = {
|
|
1341
|
+
requestUrl: requestUrl,
|
|
1342
|
+
responseStatus: this.httpStatuses.GatewayTimeout,
|
|
1343
|
+
responseBody: ""
|
|
1344
|
+
};
|
|
1345
|
+
console.error(err);
|
|
1346
|
+
throw err;
|
|
1347
|
+
} else {
|
|
1348
|
+
console.error(error);
|
|
1349
|
+
throw error;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
},
|
|
1353
|
+
callSoap: async function (connection, soapMapping, functionName, values, request, configParameters, callContext) {
|
|
1354
|
+
let soapClient = await Soap.createClientAsync(soapMapping.wsdlFileName, { endpoint: connection.url });
|
|
1355
|
+
if (process.env.blz_traceAll === 'true' || process.env.blz_traceExternalSoapCalls === 'true') {
|
|
1356
|
+
let traceId = null;
|
|
1357
|
+
let traceStartTime = null;
|
|
1358
|
+
soapClient.on('request', function (xml) {
|
|
1359
|
+
if (typeof _externalSoapCallId === 'undefined')
|
|
1360
|
+
_externalSoapCallId = 1;
|
|
1361
|
+
else
|
|
1362
|
+
_externalSoapCallId++;
|
|
1363
|
+
traceId = _externalSoapCallId;
|
|
1364
|
+
traceStartTime = Date.now();
|
|
1365
|
+
console.log((callContext.devTime ? '' : new Date().toISOString() + ' | ') + 'EXTERNAL SOAP CALL (' + traceId + ') | ' + connection.name + ' | POST ' + connection.url + ' | HEADERS: {} | BODY: ' + xml);
|
|
1366
|
+
}.bind(this));
|
|
1367
|
+
soapClient.on('response', function (body, response) {
|
|
1368
|
+
console.log((callContext.devTime ? '' : new Date().toISOString() + ' | ') + 'EXTERNAL SOAP CALL (' + traceId + ') | ' + connection.name + ' | STATUS: ' + response.statusCode + ' | BODY: ' + response.body + ' | TIME: ' + (Date.now() - traceStartTime) + ' milliseconds');
|
|
1369
|
+
}.bind(this));
|
|
1370
|
+
}
|
|
1371
|
+
if (soapMapping.security) {
|
|
1372
|
+
let value = null;
|
|
1373
|
+
switch (soapMapping.security.source) {
|
|
1374
|
+
case 'ConfigParameter': {
|
|
1375
|
+
value = configParameters[soapMapping.security.configParameterName];
|
|
1376
|
+
break;
|
|
1333
1377
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
};
|
|
1346
|
-
console.error(err);
|
|
1347
|
-
throw err;
|
|
1348
|
-
} else {
|
|
1349
|
-
console.error(error);
|
|
1350
|
-
throw error;
|
|
1378
|
+
case 'AccessToken': {
|
|
1379
|
+
value = request.state['access_token'];
|
|
1380
|
+
break;
|
|
1381
|
+
}
|
|
1382
|
+
case 'Cookie': {
|
|
1383
|
+
value = request.state[soapMapping.security.cookieName];
|
|
1384
|
+
break;
|
|
1385
|
+
}
|
|
1386
|
+
case 'CallVariable': {
|
|
1387
|
+
value = callContext.callVariables[soapMapping.security.callVariableName];
|
|
1388
|
+
break;
|
|
1351
1389
|
}
|
|
1352
1390
|
}
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
let traceId = null;
|
|
1358
|
-
let traceStartTime = null;
|
|
1359
|
-
soapClient.on('request', function (xml) {
|
|
1360
|
-
if (typeof _externalSoapCallId === 'undefined')
|
|
1361
|
-
_externalSoapCallId = 1;
|
|
1362
|
-
else
|
|
1363
|
-
_externalSoapCallId++;
|
|
1364
|
-
traceId = _externalSoapCallId;
|
|
1365
|
-
traceStartTime = Date.now();
|
|
1366
|
-
console.log((callContext.devTime ? '' : new Date().toISOString() + ' | ') + 'EXTERNAL SOAP CALL (' + traceId + ') | ' + connection.name + ' | POST ' + connection.url + ' | HEADERS: {} | BODY: ' + xml);
|
|
1367
|
-
}.bind(this));
|
|
1368
|
-
soapClient.on('response', function (body, response) {
|
|
1369
|
-
console.log((callContext.devTime ? '' : new Date().toISOString() + ' | ') + 'EXTERNAL SOAP CALL (' + traceId + ') | ' + connection.name + ' | STATUS: ' + response.statusCode + ' | BODY: ' + response.body + ' | TIME: ' + (Date.now() - traceStartTime) + ' milliseconds');
|
|
1370
|
-
}.bind(this));
|
|
1371
|
-
}
|
|
1372
|
-
if (soapMapping.security) {
|
|
1373
|
-
let value = null;
|
|
1374
|
-
switch (soapMapping.security.source) {
|
|
1375
|
-
case 'ConfigParameter': {
|
|
1376
|
-
value = configParameters[soapMapping.security.configParameterName];
|
|
1377
|
-
break;
|
|
1378
|
-
}
|
|
1379
|
-
case 'AccessToken': {
|
|
1380
|
-
value = request.state['access_token'];
|
|
1381
|
-
break;
|
|
1382
|
-
}
|
|
1383
|
-
case 'Cookie': {
|
|
1384
|
-
value = request.state[soapMapping.security.cookieName];
|
|
1385
|
-
break;
|
|
1386
|
-
}
|
|
1387
|
-
case 'CallVariable': {
|
|
1388
|
-
value = callContext.callVariables[soapMapping.security.callVariableName];
|
|
1389
|
-
break;
|
|
1390
|
-
}
|
|
1391
|
+
switch (soapMapping.security.securityType) {
|
|
1392
|
+
case 'BasicAuth': {
|
|
1393
|
+
soapClient.setSecurity(new Soap.BasicAuthSecurity(value.user, value.password));
|
|
1394
|
+
break;
|
|
1391
1395
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
break;
|
|
1396
|
-
}
|
|
1397
|
-
case 'BearerToken': {
|
|
1398
|
-
soapClient.setSecurity(new Soap.BearerSecurity(value));
|
|
1399
|
-
break;
|
|
1400
|
-
}
|
|
1396
|
+
case 'BearerToken': {
|
|
1397
|
+
soapClient.setSecurity(new Soap.BearerSecurity(value));
|
|
1398
|
+
break;
|
|
1401
1399
|
}
|
|
1402
1400
|
}
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1401
|
+
}
|
|
1402
|
+
let soapFunctionName = functionName + 'Async';
|
|
1403
|
+
if (soapClient[soapFunctionName]) {
|
|
1404
|
+
let result = (await soapClient[soapFunctionName](values.request))[0];
|
|
1405
|
+
if (isSoapNull(result))
|
|
1406
|
+
return null;
|
|
1407
|
+
fixSoapValue(result);
|
|
1408
|
+
return result;
|
|
1409
|
+
}
|
|
1410
|
+
let soapFunctionNameSimplified = simplifyName(soapFunctionName);
|
|
1411
|
+
for (let key in soapClient) {
|
|
1412
|
+
if (soapFunctionNameSimplified === simplifyName(key)) {
|
|
1413
|
+
let result = (await soapClient[key](values.request))[0];
|
|
1406
1414
|
if (isSoapNull(result))
|
|
1407
1415
|
return null;
|
|
1408
1416
|
fixSoapValue(result);
|
|
1409
1417
|
return result;
|
|
1410
1418
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
+
}
|
|
1420
|
+
throw new Error('Soap Function "' + soapFunctionName + '" not recognized.');
|
|
1421
|
+
},
|
|
1422
|
+
getFullUrl(request) {
|
|
1423
|
+
let { protocol, host, pathname } = request.url;
|
|
1424
|
+
protocol = ((request.headers['x-forwarded-proto'] || protocol).match(/[a-z]+/gim) || ['https'])[0];
|
|
1425
|
+
return `${protocol}://${request.headers['x-forwarded-host'] || host}${pathname}`;
|
|
1426
|
+
},
|
|
1427
|
+
setCache(key, value, maxAge) {
|
|
1428
|
+
cache.set(key, value, maxAge);
|
|
1429
|
+
},
|
|
1430
|
+
getCache(key) {
|
|
1431
|
+
return cache.get(key);
|
|
1432
|
+
},
|
|
1433
|
+
existsPath: async function (sourcePath) {
|
|
1434
|
+
const fullPath = this.resolvePath(sourcePath)
|
|
1435
|
+
return new Promise((resolve) => {
|
|
1436
|
+
Fs.access(fullPath, (err) => {
|
|
1437
|
+
if (err) {
|
|
1438
|
+
resolve(false)
|
|
1439
|
+
} else {
|
|
1440
|
+
resolve(true)
|
|
1419
1441
|
}
|
|
1420
|
-
}
|
|
1421
|
-
throw new Error('Soap Function "' + soapFunctionName + '" not recognized.');
|
|
1422
|
-
},
|
|
1423
|
-
getFullUrl(request) {
|
|
1424
|
-
let { protocol, host, pathname } = request.url;
|
|
1425
|
-
protocol = ((request.headers['x-forwarded-proto'] || protocol).match(/[a-z]+/gim) || ['https'])[0];
|
|
1426
|
-
return `${protocol}://${request.headers['x-forwarded-host'] || host}${pathname}`;
|
|
1427
|
-
},
|
|
1428
|
-
setCache(key, value, maxAge) {
|
|
1429
|
-
cache.set(key, value, maxAge);
|
|
1430
|
-
},
|
|
1431
|
-
getCache(key) {
|
|
1432
|
-
return cache.get(key);
|
|
1433
|
-
},
|
|
1434
|
-
existsPath: async function (sourcePath) {
|
|
1435
|
-
const fullPath = this.resolvePath(sourcePath)
|
|
1436
|
-
return new Promise((resolve) => {
|
|
1437
|
-
Fs.access(fullPath, (err) => {
|
|
1438
|
-
if (err) {
|
|
1439
|
-
resolve(false)
|
|
1440
|
-
} else {
|
|
1441
|
-
resolve(true)
|
|
1442
|
-
}
|
|
1443
|
-
})
|
|
1444
1442
|
})
|
|
1445
|
-
}
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1443
|
+
})
|
|
1444
|
+
},
|
|
1445
|
+
resolvePath: function (source) {
|
|
1446
|
+
const _source = source.trim()
|
|
1447
|
+
if (_source.startsWith('.')) {
|
|
1448
|
+
return Path.join(process.cwd(), source)
|
|
1449
|
+
}
|
|
1450
|
+
if (_source.startsWith('~')) {
|
|
1451
|
+
return _source.replace('~', process.env.HOME)
|
|
1452
|
+
}
|
|
1453
|
+
return source
|
|
1454
|
+
},
|
|
1455
|
+
readFile: async function(filePath) {
|
|
1456
|
+
const fullPath = this.resolvePath(filePath)
|
|
1457
|
+
if (!await this.existsPath(fullPath)) {
|
|
1458
|
+
return null
|
|
1459
|
+
}
|
|
1460
|
+
return new Promise((resolve, reject) => {
|
|
1461
|
+
Fs.readFile(fullPath, (err, data) => err ? reject(err) : resolve(data.toString('utf8')))
|
|
1462
|
+
})
|
|
1463
|
+
},
|
|
1464
|
+
safeRequire,
|
|
1465
|
+
getHealthStatus
|
|
1468
1466
|
};
|