@blazedpath/commons 0.0.8 → 0.0.9
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 +895 -893
- package/blz-cache/index.js +14 -25
- package/blz-core/index.js +349 -347
- package/blz-cryptography/index.js +49 -47
- package/blz-datetimes/index.js +350 -348
- package/blz-file/index.js +88 -83
- package/blz-hazelcast/index.js +103 -100
- package/blz-iterable/index.js +406 -404
- package/blz-json-schema/index.js +8 -6
- package/blz-jwt/index.js +92 -89
- package/blz-kafka/index.js +107 -105
- package/blz-math/index.js +129 -127
- package/blz-mongodb/index.js +35 -33
- package/blz-rds/index.js +46 -44
- package/blz-rds-mysql/index.js +23 -21
- package/blz-rds-mysqlx/index.js +22 -20
- package/blz-rds-oracle/index.js +204 -199
- package/blz-rds-postgres/index.js +22 -20
- package/blz-redis/index.js +125 -123
- package/blz-regex/index.js +24 -22
- package/blz-strings/index.js +167 -165
- package/blz-uuid/index.js +4 -2
- package/blz-yaml/index.js +19 -16
- 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(stack) {
|
|
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(stack) {
|
|
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(stack) {
|
|
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(path) {
|
|
481
|
+
const safeRequire = function (path) {
|
|
482
482
|
try {
|
|
483
483
|
require.resolve(path);
|
|
484
484
|
return require(path);
|
|
@@ -495,972 +495,974 @@ 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
|
-
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('../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)); });
|
|
544
|
-
}
|
|
545
|
-
else {
|
|
546
|
-
return await reader.read(callContext, transformation.sourceCodePaths, async function (sourceItem) { return await transformationExecutor(callContext, sourceItem); });
|
|
547
|
-
}
|
|
498
|
+
Dual: {
|
|
499
|
+
deepClone,
|
|
500
|
+
beginTransaction,
|
|
501
|
+
commitTransaction,
|
|
502
|
+
rollbackTransaction,
|
|
503
|
+
closeTransaction,
|
|
504
|
+
compare,
|
|
505
|
+
stringifyObject,
|
|
506
|
+
checkDuplicateKeysInEnv,
|
|
507
|
+
normalizeConfig,
|
|
508
|
+
setMetadata: function (metadata) {
|
|
509
|
+
_metadata = metadata;
|
|
510
|
+
},
|
|
511
|
+
getMetadataItem: function (metadataItemName) {
|
|
512
|
+
if (_metadata[metadataItemName] === undefined)
|
|
513
|
+
return null;
|
|
514
|
+
return _metadata[metadataItemName];
|
|
515
|
+
},
|
|
516
|
+
getConnection: function (connectionName) {
|
|
517
|
+
if (!_connections[connectionName]) {
|
|
518
|
+
console.log(`The connectionName: "${connectionName}" does not seem to be defined. Please review the .env or yaml build configuration.`);
|
|
519
|
+
} return _connections[connectionName];
|
|
520
|
+
},
|
|
521
|
+
setConnections: function (connections) {
|
|
522
|
+
_connections = connections;
|
|
523
|
+
},
|
|
524
|
+
getConfigParameterValue: function (configParameterName) {
|
|
525
|
+
if (_configParameters[configParameterName] === undefined) {
|
|
526
|
+
console.log(`The configParameter: "${configParameterName}" does not seem to be defined. Please review the .env or yaml build configuration.`);
|
|
527
|
+
return null;
|
|
548
528
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
529
|
+
return _configParameters[configParameterName];
|
|
530
|
+
},
|
|
531
|
+
setConfigParameters: function (configParameters) {
|
|
532
|
+
_configParameters = configParameters;
|
|
533
|
+
},
|
|
534
|
+
setTransformations: function (transformations) {
|
|
535
|
+
_transformations = transformations;
|
|
536
|
+
},
|
|
537
|
+
transform: async function (callContext, transformationName, source, writer) {
|
|
538
|
+
let transformation = _metadata[transformationName];
|
|
539
|
+
let transformationExecutor = require('../sources/' + transformation.sourceFileName);
|
|
540
|
+
if (source) {
|
|
541
|
+
if (source._blz_reader) { // reader
|
|
542
|
+
let reader = source;
|
|
543
|
+
if (writer) {
|
|
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); });
|
|
555
548
|
}
|
|
556
|
-
return target;
|
|
557
549
|
}
|
|
558
|
-
else {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
let
|
|
562
|
-
|
|
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;
|
|
563
566
|
}
|
|
564
|
-
return target;
|
|
565
567
|
}
|
|
568
|
+
else { // obj
|
|
569
|
+
if (writer) {
|
|
570
|
+
return await writer.write(callContext, transformationExecutor(callContext, source));
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
return await transformationExecutor(callContext, source);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return null;
|
|
578
|
+
},
|
|
579
|
+
writer: function (callContext, functionName, extraArgs) {
|
|
580
|
+
let fn
|
|
581
|
+
try {
|
|
582
|
+
fn = require('../sources/' + module.exports.ensureDashedFormat(functionName) + '.js')
|
|
566
583
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
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);
|
|
597
|
+
}
|
|
570
598
|
}
|
|
571
|
-
|
|
572
|
-
|
|
599
|
+
};
|
|
600
|
+
},
|
|
601
|
+
getValue: function (root, bind) {
|
|
602
|
+
if (root === null)
|
|
603
|
+
return null;
|
|
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];
|
|
614
|
+
}
|
|
615
|
+
return current;
|
|
573
616
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
return null;
|
|
577
|
-
},
|
|
578
|
-
writer: function (callContext, functionName, extraArgs) {
|
|
579
|
-
let fn
|
|
580
|
-
try {
|
|
581
|
-
fn = require('../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);
|
|
617
|
+
else if (rootType === '[object Array]') {
|
|
618
|
+
return root[bind];
|
|
593
619
|
}
|
|
594
620
|
else {
|
|
595
|
-
return
|
|
621
|
+
return null;
|
|
596
622
|
}
|
|
597
623
|
}
|
|
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];
|
|
613
|
-
}
|
|
614
|
-
return current;
|
|
624
|
+
else {
|
|
625
|
+
return root;
|
|
615
626
|
}
|
|
616
|
-
|
|
617
|
-
|
|
627
|
+
},
|
|
628
|
+
setValue: function (root, bind, value) {
|
|
629
|
+
let bindParts = bind.split('.');
|
|
630
|
+
let current = root;
|
|
631
|
+
for (let i = 0; i < (bindParts.length - 1); i++) {
|
|
632
|
+
let bindPart = bindParts[i];
|
|
633
|
+
if (current[bindPart] === null || current[bindPart] === undefined)
|
|
634
|
+
current[bindPart] = {};
|
|
635
|
+
current = current[bindPart];
|
|
636
|
+
}
|
|
637
|
+
current[bindParts[bindParts.length - 1]] = value;
|
|
638
|
+
},
|
|
639
|
+
divide: function (dividend, divisor) {
|
|
640
|
+
if (divisor === null || divisor === 0) {
|
|
641
|
+
let err = new Error();
|
|
642
|
+
err.code = 'DivisionByZero';
|
|
643
|
+
err.data = { dividend: dividend, divisor: divisor };
|
|
644
|
+
throw err;
|
|
618
645
|
}
|
|
619
646
|
else {
|
|
620
|
-
return
|
|
647
|
+
return dividend / divisor;
|
|
621
648
|
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
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;
|
|
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;
|
|
718
656
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
657
|
+
else {
|
|
658
|
+
return dividend % divisor;
|
|
659
|
+
}
|
|
660
|
+
},
|
|
661
|
+
httpErrors: {
|
|
662
|
+
400: 'BadRequest',
|
|
663
|
+
401: 'Unauthorized',
|
|
664
|
+
402: 'PaymentRequired',
|
|
665
|
+
403: 'Forbidden',
|
|
666
|
+
404: 'NotFound',
|
|
667
|
+
405: 'MethodNotAllowed',
|
|
668
|
+
406: 'NotAcceptable',
|
|
669
|
+
407: 'ProxyAuthenticationRequired',
|
|
670
|
+
408: 'RequestTimeout',
|
|
671
|
+
409: 'Conflict',
|
|
672
|
+
410: 'Gone',
|
|
673
|
+
411: 'LengthRequired',
|
|
674
|
+
412: 'PreconditionFailed',
|
|
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
|
|
727
712
|
};
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
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;
|
|
719
|
+
}
|
|
720
|
+
if (requestUrl.match(/https.*/)) {
|
|
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
|
+
};
|
|
729
|
+
}
|
|
730
|
+
let response = await Got(requestUrl, requestOptions);
|
|
731
|
+
let httpErrorCode = this.httpErrors[response.statusCode];
|
|
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;
|
|
737
|
+
}
|
|
738
|
+
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('../sources/' + module.exports.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.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.callSoap(connection, soapMappings[connection.name], functionName, values, null, _configParameters, callContext);
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
error: function (code, data, innerError) {
|
|
732
766
|
let err = new Error();
|
|
733
|
-
err.code =
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
return
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
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;
|
|
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
|
+
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;
|
|
892
825
|
}
|
|
893
|
-
|
|
894
|
-
|
|
826
|
+
if (valueType === '[object Number]') {
|
|
827
|
+
if (value === 1)
|
|
828
|
+
return true;
|
|
829
|
+
if (value === 0)
|
|
830
|
+
return false;
|
|
895
831
|
}
|
|
896
|
-
|
|
897
|
-
|
|
832
|
+
if (valueType === '[object Boolean]')
|
|
833
|
+
return value;
|
|
834
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'boolean' });
|
|
835
|
+
},
|
|
836
|
+
convertToDatetime: function (value) {
|
|
837
|
+
if (value === null)
|
|
838
|
+
return null;
|
|
839
|
+
let valueType = toString.call(value);
|
|
840
|
+
if (valueType === '[object String]') {
|
|
841
|
+
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);
|
|
842
|
+
if (matchDatetime)
|
|
843
|
+
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])));
|
|
898
844
|
}
|
|
899
|
-
|
|
900
|
-
|
|
845
|
+
if (valueType === '[object Date]') {
|
|
846
|
+
return value;
|
|
901
847
|
}
|
|
902
|
-
|
|
903
|
-
|
|
848
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'datetime' });
|
|
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));
|
|
904
861
|
}
|
|
905
|
-
|
|
906
|
-
|
|
862
|
+
if (valueType === '[object Date]') {
|
|
863
|
+
return new Date(Date.UTC(value.getUTCFullYear(), value.getUTCMonth(), value.getUTCDate(), 0, 0, 0, 0));
|
|
907
864
|
}
|
|
908
|
-
|
|
909
|
-
|
|
865
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'date' });
|
|
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])));
|
|
910
878
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
879
|
+
if (valueType === '[object Date]') {
|
|
880
|
+
return new Date(Date.UTC(1970, 0, 1, value.getUTCHours(), value.getUTCMinutes(), value.getUTCSeconds(), value.getUTCMilliseconds()));
|
|
881
|
+
}
|
|
882
|
+
throw this.error('InvalidConversion', { value: value, targetType: 'time' });
|
|
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;
|
|
913
|
+
}
|
|
914
|
+
return result;
|
|
915
|
+
},
|
|
916
|
+
mapRoutingParameters: function (request, routingParameters) {
|
|
917
|
+
let result = {};
|
|
918
|
+
if (routingParameters) {
|
|
919
|
+
const lowerCaseHeadersKeysEntries = Object.keys(request.headers || {}).map(headerKey => [headerKey.toLowerCase(), headerKey])
|
|
920
|
+
const lowerCaseHeadersKeysMap = Object.fromEntries(lowerCaseHeadersKeysEntries)
|
|
921
|
+
for (let i = 0; i < routingParameters.length; i++) {
|
|
922
|
+
let routingParameter = routingParameters[i];
|
|
923
|
+
if (routingParameter.name && routingParameter.type) {
|
|
924
|
+
if (routingParameter.in === 'Path' || routingParameter.in === 'Query' || routingParameter.in === 'Header') {
|
|
925
|
+
let value = null;
|
|
926
|
+
if (routingParameter.in === 'Path') {
|
|
927
|
+
if (request.params && request.params[routingParameter.name])
|
|
928
|
+
value = request.params[routingParameter.name];
|
|
929
|
+
}
|
|
930
|
+
else if (routingParameter.in === 'Query') {
|
|
931
|
+
if (request.query && request.query[routingParameter.name])
|
|
932
|
+
value = request.query[routingParameter.name];
|
|
933
|
+
}
|
|
934
|
+
else if (routingParameter.in === 'Header') {
|
|
935
|
+
const headerKey = lowerCaseHeadersKeysMap[routingParameter.name.toLowerCase()]
|
|
936
|
+
const headerValue = headerKey && request.headers && request.headers[headerKey]
|
|
937
|
+
if (headerValue) {
|
|
938
|
+
value = headerValue
|
|
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));
|
|
938
970
|
}
|
|
939
971
|
}
|
|
940
|
-
if (
|
|
941
|
-
|
|
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));
|
|
972
|
+
else if (routingParameter.in === 'Body') {
|
|
973
|
+
this.setValue(result, routingParameter.bind, request.payload);
|
|
969
974
|
}
|
|
970
975
|
}
|
|
971
|
-
else if (routingParameter.in === 'Body') {
|
|
972
|
-
this.setValue(result, routingParameter.bind, request.payload);
|
|
973
|
-
}
|
|
974
976
|
}
|
|
975
977
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
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
|
+
}
|
|
986
988
|
}
|
|
989
|
+
break;
|
|
990
|
+
}
|
|
991
|
+
case 'Query': {
|
|
992
|
+
if (request.query) {
|
|
993
|
+
let queryValue = request.query[apiKeyName];
|
|
994
|
+
if (queryValue) {
|
|
995
|
+
return { key: queryValue };
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
break;
|
|
987
999
|
}
|
|
988
|
-
break;
|
|
989
1000
|
}
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1001
|
+
return null;
|
|
1002
|
+
},
|
|
1003
|
+
decodeBasicAuth: function (request) {
|
|
1004
|
+
if (request.headers) {
|
|
1005
|
+
let headerValue = request.headers['authorization'];
|
|
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] };
|
|
995
1012
|
}
|
|
1013
|
+
catch (err2) { }
|
|
996
1014
|
}
|
|
997
|
-
break;
|
|
998
1015
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
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] };
|
|
1016
|
+
return null;
|
|
1017
|
+
},
|
|
1018
|
+
decodeBearerToken: function (request) {
|
|
1019
|
+
if (request.headers) {
|
|
1020
|
+
let headerValue = request.headers['authorization'];
|
|
1021
|
+
if (headerValue && headerValue.startsWith('Bearer')) {
|
|
1022
|
+
return { token: headerValue.split(' ')[1] };
|
|
1011
1023
|
}
|
|
1012
|
-
catch (err2) { }
|
|
1013
1024
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
return
|
|
1025
|
+
return null;
|
|
1026
|
+
},
|
|
1027
|
+
loadResource: async function (path) {
|
|
1028
|
+
try {
|
|
1029
|
+
let resourceContent = await Fs.readFile(Path.join(_metadata.appPath, '../resources', path), 'utf8');
|
|
1030
|
+
if (path.endsWith('.json')) return JSON.parse(resourceContent)
|
|
1031
|
+
else if (path.endsWith('.yaml') || path.endsWith('.yml')) return jsyaml.load(resourceContent)
|
|
1032
|
+
else return resourceContent;
|
|
1022
1033
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
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)));
|
|
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;
|
|
1058
|
+
}
|
|
1059
|
+
var isFirstQueryParameter = true;
|
|
1060
|
+
if (restMappingFunction.parameters) {
|
|
1061
|
+
for (let i = 0; i < restMappingFunction.parameters.length; i++) {
|
|
1062
|
+
let routingParameter = restMappingFunction.parameters[i];
|
|
1063
|
+
let bindParts = routingParameter.bind.split('.');
|
|
1064
|
+
let value = values;
|
|
1065
|
+
for (let j = 0; j < bindParts.length; j++) {
|
|
1066
|
+
let bindPart = bindParts[j];
|
|
1067
|
+
if (value)
|
|
1068
|
+
value = value[bindPart];
|
|
1074
1069
|
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1070
|
+
if (value === null && routingParameter.in === 'Path')
|
|
1071
|
+
throw new Error('Error trying to call [' + connection.url + restMappingFunction.path + ']. The parameter [' + routingParameter.name + '] is mandatory.');
|
|
1072
|
+
if (value !== null && value !== undefined) {
|
|
1073
|
+
if (routingParameter.in === 'Path') {
|
|
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));
|
|
1079
1085
|
isFirstQueryParameter = false;
|
|
1080
1086
|
}
|
|
1081
1087
|
}
|
|
1082
|
-
else {
|
|
1083
|
-
|
|
1084
|
-
|
|
1088
|
+
else if (routingParameter.in === 'Header') {
|
|
1089
|
+
requestOptions.headers[routingParameter.name] = this.convertToString(value);
|
|
1090
|
+
}
|
|
1091
|
+
else if (routingParameter.in === 'Body') {
|
|
1092
|
+
requestOptions.body = JSON.stringify(value);
|
|
1085
1093
|
}
|
|
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
1094
|
}
|
|
1093
1095
|
}
|
|
1094
1096
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
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) {
|
|
1097
|
+
if (restMappingFunction.security) {
|
|
1098
|
+
let securityApplied = false;
|
|
1099
|
+
for (let i = 0; i < restMappingFunction.security.length; i++) {
|
|
1100
|
+
if (!securityApplied) {
|
|
1101
|
+
let securityItem = restMappingFunction.security[i];
|
|
1102
|
+
let securityItemOk = true;
|
|
1103
|
+
let securityItemValues = [];
|
|
1149
1104
|
for (let j = 0; j < securityItem.length; j++) {
|
|
1150
1105
|
let securityConditionItem = securityItem[j];
|
|
1151
|
-
let value =
|
|
1152
|
-
switch (securityConditionItem.
|
|
1153
|
-
case '
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1106
|
+
let value = null;
|
|
1107
|
+
switch (securityConditionItem.source) {
|
|
1108
|
+
case 'ConfigParameter': {
|
|
1109
|
+
value = configParameters[securityConditionItem.configParameterName];
|
|
1110
|
+
break;
|
|
1111
|
+
}
|
|
1112
|
+
case 'AccessToken': {
|
|
1113
|
+
const SESSION_STATE = securityService.getCookieName('session_state')
|
|
1114
|
+
let sessionState = request.state[SESSION_STATE];
|
|
1115
|
+
// For backward compatibility with previous versions, the session_state is searched if the name of the configured cookie was not found.
|
|
1116
|
+
if (!sessionState) {
|
|
1117
|
+
sessionState = request.state['session_state'];
|
|
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];
|
|
1164
1132
|
}
|
|
1165
1133
|
break;
|
|
1166
1134
|
}
|
|
1167
|
-
case '
|
|
1168
|
-
|
|
1135
|
+
case 'Cookie': {
|
|
1136
|
+
value = request.state[securityConditionItem.cookieName];
|
|
1169
1137
|
break;
|
|
1170
1138
|
}
|
|
1171
|
-
case '
|
|
1172
|
-
|
|
1139
|
+
case 'CallVariable': {
|
|
1140
|
+
value = callContext.callVariables[securityConditionItem.callVariableName];
|
|
1173
1141
|
break;
|
|
1174
1142
|
}
|
|
1175
1143
|
}
|
|
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;
|
|
1176
1179
|
}
|
|
1177
|
-
securityApplied = true;
|
|
1178
1180
|
}
|
|
1179
1181
|
}
|
|
1180
1182
|
}
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
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;
|
|
1183
|
+
securityService.validateSecureRequest(request)
|
|
1184
|
+
// The following IF code block should not exists. Only for propagating without properly configuring it the suite.
|
|
1185
|
+
let propagateAuthToken = process.env.blz_propagateAuthToken;
|
|
1186
|
+
if (propagateAuthToken) {
|
|
1187
|
+
// check if the system is to be ignored for the redirection of the Security token
|
|
1188
|
+
let propagateAuthTokenIgnoreSystems = process.env.blz_propagateAuthTokenIgnoreSystems;
|
|
1189
|
+
const ignoredSystems = propagateAuthTokenIgnoreSystems ? propagateAuthTokenIgnoreSystems.split(",") : [];
|
|
1190
|
+
const ignorePropagation = ignoredSystems.includes(connection.name);
|
|
1191
|
+
// If system is included in the list, ignore propagation. If not, propagate
|
|
1192
|
+
if (!ignorePropagation) {
|
|
1193
|
+
let value = null;
|
|
1194
|
+
const SESSION_STATE = securityService.getCookieName('session_state')
|
|
1195
|
+
// request object comes null when called in a microservice. if it exists it is inside the frontend.
|
|
1196
|
+
if (request) {
|
|
1197
|
+
let sessionState = request.state[SESSION_STATE];
|
|
1198
|
+
// For backward compatibility with previous versions, the session_state is searched if the name of the configured cookie was not found.
|
|
1199
|
+
if (!sessionState) {
|
|
1200
|
+
sessionState = request.state['session_state'];
|
|
1201
|
+
}
|
|
1202
|
+
// If sessionState still does not exists, then it is on the header
|
|
1203
|
+
if (!sessionState) {
|
|
1204
|
+
value = await securityService.extractTokenhNoDecode(request);
|
|
1209
1205
|
} else {
|
|
1210
|
-
|
|
1211
|
-
|
|
1206
|
+
// added request on getUseToken in case we use hapi modules full stack
|
|
1207
|
+
const token = await securityService.getUseToken(sessionState, request);
|
|
1208
|
+
if (token) {
|
|
1209
|
+
value = token;
|
|
1210
|
+
} else {
|
|
1211
|
+
const ACCESS_TOKEN = securityService.getCookieName('access_token')
|
|
1212
|
+
value = request.state[ACCESS_TOKEN];
|
|
1213
|
+
}
|
|
1212
1214
|
}
|
|
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;
|
|
1213
1221
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
case 'BearerToken': {
|
|
1223
|
-
if (/^Bearer /.test(value)) {
|
|
1224
|
-
requestOptions.headers['Authorization'] = value;
|
|
1225
|
-
} else {
|
|
1226
|
-
requestOptions.headers['Authorization'] = 'Bearer ' + value;
|
|
1222
|
+
switch (propagateAuthToken) {
|
|
1223
|
+
case 'BearerToken': {
|
|
1224
|
+
if (/^Bearer /.test(value)) {
|
|
1225
|
+
requestOptions.headers['Authorization'] = value;
|
|
1226
|
+
} else {
|
|
1227
|
+
requestOptions.headers['Authorization'] = 'Bearer ' + value;
|
|
1228
|
+
}
|
|
1229
|
+
break;
|
|
1227
1230
|
}
|
|
1228
|
-
|
|
1231
|
+
default:
|
|
1232
|
+
break;
|
|
1229
1233
|
}
|
|
1230
|
-
default:
|
|
1231
|
-
break;
|
|
1232
1234
|
}
|
|
1233
1235
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
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;
|
|
1259
|
-
if (process.env.blz_traceAll === 'true' || process.env.blz_traceExternalRestCalls === 'true') {
|
|
1260
|
-
console.log((callContext.devTime ? '' : dateISOString + ' | ') + 'EXTERNAL REST CALL (' + traceId + ') | ' + connection.name + ' | STATUS: ' + response.statusCode + ' | BODY: ' + response.body + ' | TIME: ' + responseTime + ' milliseconds');
|
|
1236
|
+
if (requestUrl.match(/https.*/)) {
|
|
1237
|
+
requestOptions = {
|
|
1238
|
+
...requestOptions,
|
|
1239
|
+
https: {
|
|
1240
|
+
requestCert: true, // Request a certificate from clients that connect and attempt to verify that certificate.
|
|
1241
|
+
rejectUnauthorized: false, // The server will reject any connection which is not authorized with the list of supplied CAs.
|
|
1242
|
+
agent: false // Is responsible for managing connection persistence and reuse for https clients.
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1261
1245
|
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1246
|
+
let traceStartTime = Date.now();
|
|
1247
|
+
const dateISOString = new Date().toISOString();
|
|
1248
|
+
if (typeof _externalRestCallId === 'undefined')
|
|
1249
|
+
_externalRestCallId = 1;
|
|
1250
|
+
else
|
|
1251
|
+
_externalRestCallId++;
|
|
1252
|
+
const traceId = _externalRestCallId;
|
|
1253
|
+
if (process.env.blz_traceAll === 'true' || process.env.blz_traceExternalRestCalls === 'true') {
|
|
1254
|
+
console.log((callContext.devTime ? '' : dateISOString + ' | ') + 'EXTERNAL REST CALL (' + traceId + ') | ' + connection.name + ' | ' + requestOptions.method + ' ' + requestUrl + ' | HEADERS: ' + JSON.stringify(requestOptions.headers) + (requestOptions.body ? ' | BODY: ' + requestOptions.body : ''));
|
|
1266
1255
|
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
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);
|
|
1256
|
+
try {
|
|
1257
|
+
|
|
1258
|
+
const response = await Got(requestUrl, requestOptions);
|
|
1259
|
+
const responseTime = Date.now() - traceStartTime;
|
|
1260
|
+
if (process.env.blz_traceAll === 'true' || process.env.blz_traceExternalRestCalls === 'true') {
|
|
1261
|
+
console.log((callContext.devTime ? '' : dateISOString + ' | ') + 'EXTERNAL REST CALL (' + traceId + ') | ' + connection.name + ' | STATUS: ' + response.statusCode + ' | BODY: ' + response.body + ' | TIME: ' + responseTime + ' milliseconds');
|
|
1304
1262
|
}
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
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)
|
|
1316
|
-
}
|
|
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
|
-
};
|
|
1324
|
-
}
|
|
1325
|
-
} catch (ex) {
|
|
1326
|
-
console.log(`Handle error ${err.code}: ${ex}`)
|
|
1263
|
+
// These 2 are added for the PostProcessRequest event
|
|
1264
|
+
if (request) {
|
|
1265
|
+
request.httpRequestLog = { url: request.path, method: requestOptions.method, headers: Object.entries(requestOptions.headers), body: requestOptions.body, clientInfo: request.clientInfo }
|
|
1266
|
+
request.httpResponseLog = { status: response.statusCode, headers: Object.entries(response.headers), body: response.body }
|
|
1327
1267
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
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;
|
|
1268
|
+
let httpErrorCode = this.httpErrors[response.statusCode];
|
|
1269
|
+
// 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.
|
|
1270
|
+
if (request && request.headers['x-navigation-info']) {
|
|
1271
|
+
try {
|
|
1272
|
+
const clientNavigation = request.headers['x-navigation-info'];
|
|
1273
|
+
const userInfo = await securityService.getUserInfo(request)
|
|
1274
|
+
const config = configService.getConfig()
|
|
1275
|
+
securityService.pushNavigation({
|
|
1276
|
+
app: config.buildSystem.name,
|
|
1277
|
+
username: userInfo.user_name,
|
|
1278
|
+
date: dateISOString,
|
|
1279
|
+
client: {
|
|
1280
|
+
nav: JSON.parse(Buffer.from(clientNavigation, 'base64').toString('utf-8')),
|
|
1281
|
+
ip: request.headers['x-forwarded-for'] || request.info.remoteAddress,
|
|
1282
|
+
userAgent: request.headers['user-agent'],
|
|
1283
|
+
lang: request.headers['accept-language'],
|
|
1284
|
+
host: request.info.host,
|
|
1285
|
+
protocol: request.headers['x-forwarded-proto'] || request.server.info.protocol,
|
|
1286
|
+
id: request.info.id
|
|
1287
|
+
},
|
|
1288
|
+
request: {
|
|
1289
|
+
traceId: traceId,
|
|
1290
|
+
traceStartTime: traceStartTime,
|
|
1291
|
+
connection: connection.name,
|
|
1292
|
+
method: request.method,
|
|
1293
|
+
path: request.path,
|
|
1294
|
+
url: requestUrl,
|
|
1295
|
+
body: requestOptions.body
|
|
1296
|
+
},
|
|
1297
|
+
response: {
|
|
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
|
+
}
|
|
1377
1306
|
}
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1307
|
+
|
|
1308
|
+
if (httpErrorCode) {
|
|
1309
|
+
let err = new Error();
|
|
1310
|
+
err.code = httpErrorCode;
|
|
1311
|
+
try {
|
|
1312
|
+
if (process.env.NODE_ENV === 'production') {
|
|
1313
|
+
const data = {
|
|
1314
|
+
requestUrl: requestUrl,
|
|
1315
|
+
responseStatus: response.statusCode,
|
|
1316
|
+
responseBody: tryParse(response.body, response.body)
|
|
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
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
} catch (ex) {
|
|
1327
|
+
console.log(`Handle error ${err.code}: ${ex}`)
|
|
1328
|
+
}
|
|
1329
|
+
throw err;
|
|
1381
1330
|
}
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
break;
|
|
1331
|
+
else {
|
|
1332
|
+
return tryParse(response.body, response.body)
|
|
1385
1333
|
}
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1334
|
+
} catch (error) {
|
|
1335
|
+
if (error.code == 'ETIMEDOUT') {
|
|
1336
|
+
// Here we check for the timeout originated from the request options timeout added for the Got request.
|
|
1337
|
+
// All other errors should be handled in finally.
|
|
1338
|
+
// response is destroyed if it timed out
|
|
1339
|
+
let err = new Error();
|
|
1340
|
+
err.code = 'GatewayTimeout';
|
|
1341
|
+
err.data = {
|
|
1342
|
+
requestUrl: requestUrl,
|
|
1343
|
+
responseStatus: this.httpStatuses.GatewayTimeout,
|
|
1344
|
+
responseBody: ""
|
|
1345
|
+
};
|
|
1346
|
+
console.error(err);
|
|
1347
|
+
throw err;
|
|
1348
|
+
} else {
|
|
1349
|
+
console.error(error);
|
|
1350
|
+
throw error;
|
|
1389
1351
|
}
|
|
1390
1352
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1353
|
+
},
|
|
1354
|
+
callSoap: async function (connection, soapMapping, functionName, values, request, configParameters, callContext) {
|
|
1355
|
+
let soapClient = await Soap.createClientAsync(soapMapping.wsdlFileName, { endpoint: connection.url });
|
|
1356
|
+
if (process.env.blz_traceAll === 'true' || process.env.blz_traceExternalSoapCalls === 'true') {
|
|
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
|
+
}
|
|
1395
1391
|
}
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1392
|
+
switch (soapMapping.security.securityType) {
|
|
1393
|
+
case 'BasicAuth': {
|
|
1394
|
+
soapClient.setSecurity(new Soap.BasicAuthSecurity(value.user, value.password));
|
|
1395
|
+
break;
|
|
1396
|
+
}
|
|
1397
|
+
case 'BearerToken': {
|
|
1398
|
+
soapClient.setSecurity(new Soap.BearerSecurity(value));
|
|
1399
|
+
break;
|
|
1400
|
+
}
|
|
1399
1401
|
}
|
|
1400
1402
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
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];
|
|
1403
|
+
let soapFunctionName = functionName + 'Async';
|
|
1404
|
+
if (soapClient[soapFunctionName]) {
|
|
1405
|
+
let result = (await soapClient[soapFunctionName](values.request))[0];
|
|
1414
1406
|
if (isSoapNull(result))
|
|
1415
1407
|
return null;
|
|
1416
1408
|
fixSoapValue(result);
|
|
1417
1409
|
return result;
|
|
1418
1410
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
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)
|
|
1411
|
+
let soapFunctionNameSimplified = simplifyName(soapFunctionName);
|
|
1412
|
+
for (let key in soapClient) {
|
|
1413
|
+
if (soapFunctionNameSimplified === simplifyName(key)) {
|
|
1414
|
+
let result = (await soapClient[key](values.request))[0];
|
|
1415
|
+
if (isSoapNull(result))
|
|
1416
|
+
return null;
|
|
1417
|
+
fixSoapValue(result);
|
|
1418
|
+
return result;
|
|
1441
1419
|
}
|
|
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
|
+
})
|
|
1442
1444
|
})
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1445
|
+
},
|
|
1446
|
+
resolvePath: function (source) {
|
|
1447
|
+
const _source = source.trim()
|
|
1448
|
+
if (_source.startsWith('.')) {
|
|
1449
|
+
return Path.join(process.cwd(), source)
|
|
1450
|
+
}
|
|
1451
|
+
if (_source.startsWith('~')) {
|
|
1452
|
+
return _source.replace('~', process.env.HOME)
|
|
1453
|
+
}
|
|
1454
|
+
return source
|
|
1455
|
+
},
|
|
1456
|
+
readFile: async function (filePath) {
|
|
1457
|
+
const fullPath = this.resolvePath(filePath)
|
|
1458
|
+
if (!await this.existsPath(fullPath)) {
|
|
1459
|
+
return null
|
|
1460
|
+
}
|
|
1461
|
+
return new Promise((resolve, reject) => {
|
|
1462
|
+
Fs.readFile(fullPath, (err, data) => err ? reject(err) : resolve(data.toString('utf8')))
|
|
1463
|
+
})
|
|
1464
|
+
},
|
|
1465
|
+
safeRequire,
|
|
1466
|
+
getHealthStatus
|
|
1467
|
+
}
|
|
1466
1468
|
};
|