@axinom/mosaic-service-common 0.33.0 → 0.34.0-rc.0

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.
@@ -40,5 +40,13 @@ export declare const MosaicErrors: {
40
40
  readonly message: "This is a wrapper error for the original unhandled error of unsupported type.";
41
41
  readonly code: "ERROR_WRAPPER";
42
42
  };
43
+ readonly ValueIsNotObject: {
44
+ readonly message: "The %s is not an object.";
45
+ readonly code: "VALUE_IS_NOT_OBJECT";
46
+ };
47
+ readonly ObjectIsMissingProperties: {
48
+ readonly message: "The %s is missing required properties: %s.";
49
+ readonly code: "OBJECT_IS_MISSING_PROPERTIES";
50
+ };
43
51
  };
44
52
  //# sourceMappingURL=mosaic-errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mosaic-errors.d.ts","sourceRoot":"","sources":["../../../src/common/errors/mosaic-errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Cf,CAAC"}
1
+ {"version":3,"file":"mosaic-errors.d.ts","sourceRoot":"","sources":["../../../src/common/errors/mosaic-errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDf,CAAC"}
@@ -45,5 +45,13 @@ exports.MosaicErrors = {
45
45
  message: 'This is a wrapper error for the original unhandled error of unsupported type.',
46
46
  code: 'ERROR_WRAPPER',
47
47
  },
48
+ ValueIsNotObject: {
49
+ message: 'The %s is not an object.',
50
+ code: 'VALUE_IS_NOT_OBJECT',
51
+ },
52
+ ObjectIsMissingProperties: {
53
+ message: 'The %s is missing required properties: %s.',
54
+ code: 'OBJECT_IS_MISSING_PROPERTIES',
55
+ },
48
56
  };
49
57
  //# sourceMappingURL=mosaic-errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mosaic-errors.js","sourceRoot":"","sources":["../../../src/common/errors/mosaic-errors.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACU,QAAA,YAAY,GAAG;IAC1B,mBAAmB,EAAE;QACnB,OAAO,EACL,qFAAqF;QACvF,IAAI,EAAE,uBAAuB;KAC9B;IACD,sBAAsB,EAAE;QACtB,OAAO,EACL,uFAAuF;QACzF,IAAI,EAAE,0BAA0B;KACjC;IACD,cAAc,EAAE;QACd,OAAO,EACL,sEAAsE;QACxE,IAAI,EAAE,iBAAiB;KACxB;IACD,2GAA2G;IAC3G,wBAAwB,EAAE;QACxB,OAAO,EACL,gHAAgH;QAClH,IAAI,EAAE,4BAA4B;KACnC;IACD,sFAAsF;IACtF,8BAA8B,EAAE;QAC9B,OAAO,EACL,2FAA2F;QAC7F,IAAI,EAAE,mCAAmC;KAC1C;IACD,uBAAuB,EAAE;QACvB,OAAO,EACL,+HAA+H;QACjI,IAAI,EAAE,2BAA2B;KAClC;IACD,YAAY,EAAE;QACZ,OAAO,EACL,2FAA2F;QAC7F,IAAI,EAAE,eAAe;KACtB;IACD,eAAe,EAAE;QACf,OAAO,EAAE,mDAAmD;QAC5D,IAAI,EAAE,kBAAkB;KACzB;IACD,YAAY,EAAE;QACZ,OAAO,EACL,+EAA+E;QACjF,IAAI,EAAE,eAAe;KACtB;CACO,CAAC"}
1
+ {"version":3,"file":"mosaic-errors.js","sourceRoot":"","sources":["../../../src/common/errors/mosaic-errors.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACU,QAAA,YAAY,GAAG;IAC1B,mBAAmB,EAAE;QACnB,OAAO,EACL,qFAAqF;QACvF,IAAI,EAAE,uBAAuB;KAC9B;IACD,sBAAsB,EAAE;QACtB,OAAO,EACL,uFAAuF;QACzF,IAAI,EAAE,0BAA0B;KACjC;IACD,cAAc,EAAE;QACd,OAAO,EACL,sEAAsE;QACxE,IAAI,EAAE,iBAAiB;KACxB;IACD,2GAA2G;IAC3G,wBAAwB,EAAE;QACxB,OAAO,EACL,gHAAgH;QAClH,IAAI,EAAE,4BAA4B;KACnC;IACD,sFAAsF;IACtF,8BAA8B,EAAE;QAC9B,OAAO,EACL,2FAA2F;QAC7F,IAAI,EAAE,mCAAmC;KAC1C;IACD,uBAAuB,EAAE;QACvB,OAAO,EACL,+HAA+H;QACjI,IAAI,EAAE,2BAA2B;KAClC;IACD,YAAY,EAAE;QACZ,OAAO,EACL,2FAA2F;QAC7F,IAAI,EAAE,eAAe;KACtB;IACD,eAAe,EAAE;QACf,OAAO,EAAE,mDAAmD;QAC5D,IAAI,EAAE,kBAAkB;KACzB;IACD,YAAY,EAAE;QACZ,OAAO,EACL,+EAA+E;QACjF,IAAI,EAAE,eAAe;KACtB;IACD,gBAAgB,EAAE;QAChB,OAAO,EAAE,0BAA0B;QACnC,IAAI,EAAE,qBAAqB;KAC5B;IACD,yBAAyB,EAAE;QACzB,OAAO,EAAE,4CAA4C;QACrD,IAAI,EAAE,8BAA8B;KACrC;CACO,CAAC"}
@@ -43,4 +43,12 @@ export declare const pick: <T extends Record<string, unknown>, U extends keyof T
43
43
  * @param map mapping function that will return a partial object for the property
44
44
  */
45
45
  export declare const conditional: (condition: boolean, map: () => Dict<unknown>) => false | Dict<unknown>;
46
+ /**
47
+ * Asserts that object has specific properties. Resulting object is assumed to
48
+ * have all properties, even optional, resulting in Required<T> type.
49
+ * @param value object to be asserted.
50
+ * @param properties properties to be checked.
51
+ * @param identifier object identifier to be used in error messages.
52
+ */
53
+ export declare function assertObjectHasProperties<T>(object: unknown, properties: (keyof T)[], objectDescription?: string): asserts object is Required<T>;
46
54
  //# sourceMappingURL=object-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"object-helpers.d.ts","sourceRoot":"","sources":["../../../src/common/helpers/object-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC;;GAEG;AACH,eAAO,MAAM,oBAAoB,oCAQhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,oCAQjC,CAAC;AAEF;;;GAGG;AAEH,eAAO,MAAM,aAAa,6BAA4B,OAErD,CAAC;AAEF;;;GAGG;AAEH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,GAEb,OAAO,CAAC,KAAK,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAIzC;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,qGAShB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,WAAW,cACX,OAAO,OACb,MAAM,KAAK,OAAO,CAAC,KACvB,KAAK,GAAG,KAAK,OAAO,CAEtB,CAAC"}
1
+ {"version":3,"file":"object-helpers.d.ts","sourceRoot":"","sources":["../../../src/common/helpers/object-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC;;GAEG;AACH,eAAO,MAAM,oBAAoB,oCAQhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,oCAQjC,CAAC;AAEF;;;GAGG;AAEH,eAAO,MAAM,aAAa,6BAA4B,OAErD,CAAC;AAEF;;;GAGG;AAEH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,GAEb,OAAO,CAAC,KAAK,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAIzC;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,qGAShB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,WAAW,cACX,OAAO,OACb,MAAM,KAAK,OAAO,CAAC,KACvB,KAAK,GAAG,KAAK,OAAO,CAEtB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EACzC,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EACvB,iBAAiB,SAAiB,GACjC,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,CAmB/B"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.conditional = exports.pick = exports.assertDictionary = exports.isEmptyObject = exports.removeEmptyProperties = exports.removeNullProperties = void 0;
3
+ exports.assertObjectHasProperties = exports.conditional = exports.pick = exports.assertDictionary = exports.isEmptyObject = exports.removeEmptyProperties = exports.removeNullProperties = void 0;
4
+ const errors_1 = require("../errors");
4
5
  const string_helpers_1 = require("./string-helpers");
5
6
  /**
6
7
  * Removes all properties with null value from object and returns a new object
@@ -82,4 +83,21 @@ const conditional = (condition, map) => {
82
83
  return condition && map();
83
84
  };
84
85
  exports.conditional = conditional;
86
+ /**
87
+ * Asserts that object has specific properties. Resulting object is assumed to
88
+ * have all properties, even optional, resulting in Required<T> type.
89
+ * @param value object to be asserted.
90
+ * @param properties properties to be checked.
91
+ * @param identifier object identifier to be used in error messages.
92
+ */
93
+ function assertObjectHasProperties(object, properties, objectDescription = 'passed value') {
94
+ if (object === null || typeof object !== 'object' || Array.isArray(object)) {
95
+ throw new errors_1.MosaicError(Object.assign(Object.assign({}, errors_1.MosaicErrors.ValueIsNotObject), { messageParams: [objectDescription] }));
96
+ }
97
+ const missingProperties = properties.filter((property) => !(property in object) || !object[property]);
98
+ if (missingProperties.length > 0) {
99
+ throw new errors_1.MosaicError(Object.assign(Object.assign({}, errors_1.MosaicErrors.ObjectIsMissingProperties), { messageParams: [objectDescription, missingProperties.join(', ')] }));
100
+ }
101
+ }
102
+ exports.assertObjectHasProperties = assertObjectHasProperties;
85
103
  //# sourceMappingURL=object-helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"object-helpers.js","sourceRoot":"","sources":["../../../src/common/helpers/object-helpers.ts"],"names":[],"mappings":";;;AACA,qDAAsD;AAEtD;;GAEG;AACI,MAAM,oBAAoB,GAAG,CAAU,GAAY,EAAW,EAAE;IACrE,MAAM,MAAM,qBAAQ,GAAG,CAAE,CAAC;IAC1B,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE;QAC7B,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE;YAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;SACzB;KACF;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AARW,QAAA,oBAAoB,wBAQ/B;AAEF;;GAEG;AACI,MAAM,qBAAqB,GAAG,CAAU,GAAY,EAAW,EAAE;IACtE,MAAM,MAAM,qBAAQ,GAAG,CAAE,CAAC;IAC1B,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE;QAC7B,IAAI,IAAA,mCAAkB,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE;YACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;SACzB;KACF;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AARW,QAAA,qBAAqB,yBAQhC;AAEF;;;GAGG;AACH,6EAA6E;AACtE,MAAM,aAAa,GAAG,CAAU,GAAY,EAAW,EAAE;IAC9D,OAAO,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1E,CAAC,CAAC;AAFW,QAAA,aAAa,iBAExB;AAEF;;;GAGG;AACH,gFAAgF;AAChF,SAAgB,gBAAgB,CAC9B,KAAc;IAGd,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;QAC/C,MAAM,KAAK,CAAC,wCAAwC,CAAC,CAAC;KACvD;AACH,CAAC;AAPD,4CAOC;AAED;;;;GAIG;AACI,MAAM,IAAI,GAAG,CAClB,GAAM,EACN,GAAG,aAAkB,EACT,EAAE;IACd,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE;QAC7B,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;KACjB;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AATW,QAAA,IAAI,QASf;AAEF;;;;;;;;;;;;;;;;GAgBG;AACI,MAAM,WAAW,GAAG,CACzB,SAAkB,EAClB,GAAwB,EACD,EAAE;IACzB,OAAO,SAAS,IAAI,GAAG,EAAE,CAAC;AAC5B,CAAC,CAAC;AALW,QAAA,WAAW,eAKtB"}
1
+ {"version":3,"file":"object-helpers.js","sourceRoot":"","sources":["../../../src/common/helpers/object-helpers.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"generate-log.d.ts","sourceRoot":"","sources":["../../../src/common/logging/generate-log.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAW5D;;GAEG;AACH,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,YAAY,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,CAAC;CAC7B;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,WACd,iBAAiB,YACf,kBAAkB,kBACZ,aAAa,EAAE,KAC9B,GAAG,GAAG,SAqER,CAAC"}
1
+ {"version":3,"file":"generate-log.d.ts","sourceRoot":"","sources":["../../../src/common/logging/generate-log.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAc,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAW5D;;GAEG;AACH,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,YAAY,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,CAAC;CAC7B;AA4CD;;GAEG;AACH,eAAO,MAAM,WAAW,WACd,iBAAiB,YACf,kBAAkB,kBACZ,aAAa,EAAE,KAC9B,GAAG,GAAG,SAyER,CAAC"}
@@ -8,6 +8,7 @@ const moment_1 = __importDefault(require("moment"));
8
8
  const serialize_error_1 = require("serialize-error");
9
9
  const helpers_1 = require("../helpers");
10
10
  const log_level_1 = require("./log-level");
11
+ const log_retention_1 = require("./log-retention");
11
12
  const mask_middleware_1 = require("./mask-middleware");
12
13
  const parseTimestamp = (timestamp) => {
13
14
  var _a;
@@ -19,6 +20,40 @@ const parseTimestamp = (timestamp) => {
19
20
  return now;
20
21
  }
21
22
  };
23
+ /**
24
+ * If value.message exists, object type and is it a empty object return true
25
+ * If value.message exists, object type and object has any of LogMessage properties(message,logtime,retention,context,details) with correct type then return true
26
+ * otherwise return false
27
+ */
28
+ const isLikeLogMessage = (value) => {
29
+ return (!!value &&
30
+ typeof value === 'object' &&
31
+ ((0, helpers_1.isEmptyObject)(value) ||
32
+ ('message' in value && typeof value.message === 'string') ||
33
+ ('logtime' in value &&
34
+ (typeof value.logtime === 'string' || value.logtime instanceof Date)) ||
35
+ ('retention' in value &&
36
+ typeof value.retention === 'string' &&
37
+ Object.values(log_retention_1.LogRetention).includes(value.retention)) ||
38
+ ('context' in value && typeof value.context === 'string') ||
39
+ ('details' in value && typeof value.details === 'object')));
40
+ };
41
+ /**
42
+ * Generates a LogMessage property called details object with correct values
43
+ */
44
+ const generateLogMessageDetailsProp = (inputMessage) => {
45
+ const invalidMessage = JSON.stringify(inputMessage);
46
+ const longMessageClarification = invalidMessage.length <= 1000
47
+ ? ''
48
+ : `because the message is too long (${invalidMessage.length} characters), first 1000 characters are `;
49
+ const hint = `The message passed into the logger is of the invalid format. It is stringified and ${longMessageClarification}logged as details.invalidMessage.`;
50
+ return {
51
+ details: {
52
+ invalidMessage: invalidMessage.slice(0, 1000),
53
+ hint: hint,
54
+ },
55
+ };
56
+ };
22
57
  /**
23
58
  * Generates a default log object without relying on config values.
24
59
  */
@@ -26,7 +61,9 @@ const generateLog = (values, masking, logMiddleware) => {
26
61
  var _a;
27
62
  const { message: msg, logtime, context, details, } = typeof values.message === 'string'
28
63
  ? { message: values.message }
29
- : values.message;
64
+ : isLikeLogMessage(values.message)
65
+ ? values.message
66
+ : generateLogMessageDetailsProp(values.message);
30
67
  let logMessage = {
31
68
  logtime: parseTimestamp(logtime),
32
69
  loglevel: log_level_1.LogLevel[values.level],
@@ -36,7 +73,9 @@ const generateLog = (values, masking, logMiddleware) => {
36
73
  // sensitive properties
37
74
  message: !(0, helpers_1.isNullOrWhitespace)(msg)
38
75
  ? msg
39
- : values.error
76
+ : values.error &&
77
+ values.error.message &&
78
+ typeof values.error.message === 'string'
40
79
  ? values.error.message
41
80
  : 'no message',
42
81
  details: (0, helpers_1.isEmptyObject)(details) ? undefined : details,
@@ -1 +1 @@
1
- {"version":3,"file":"generate-log.js","sourceRoot":"","sources":["../../../src/common/logging/generate-log.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generate-log.js","sourceRoot":"","sources":["../../../src/common/logging/generate-log.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,qDAAiD;AACjD,wCAA+D;AAE/D,2CAAuC;AAEvC,mDAA+C;AAC/C,uDAA4E;AAG5E,MAAM,cAAc,GAAG,CAAC,SAAoC,EAAU,EAAE;;IACtE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,IAAI;QACF,OAAO,SAAS,CAAC,CAAC,CAAC,MAAA,gBAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,mCAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;KACrE;IAAC,WAAM;QACN,OAAO,GAAG,CAAC;KACZ;AACH,CAAC,CAAC;AA8BF;;;;GAIG;AAEH,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAW,EAAE;IACnD,OAAO,CACL,CAAC,CAAC,KAAK;QACP,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,IAAA,uBAAa,EAAC,KAAK,CAAC;YACnB,CAAC,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC;YACzD,CAAC,SAAS,IAAI,KAAK;gBACjB,CAAC,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,YAAY,IAAI,CAAC,CAAC;YACvE,CAAC,WAAW,IAAI,KAAK;gBACnB,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;gBACnC,MAAM,CAAC,MAAM,CAAC,4BAAY,CAAC,CAAC,QAAQ,CAClC,KAAK,CAAC,SAAyB,CAChC,CAAC;YACJ,CAAC,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC;YACzD,CAAC,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAC7D,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,6BAA6B,GAAG,CAAC,YAAqB,EAAU,EAAE;IACtE,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,wBAAwB,GAC5B,cAAc,CAAC,MAAM,IAAI,IAAI;QAC3B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,oCAAoC,cAAc,CAAC,MAAM,0CAA0C,CAAC;IAC1G,MAAM,IAAI,GAAG,sFAAsF,wBAAwB,mCAAmC,CAAC;IAC/J,OAAO;QACL,OAAO,EAAE;YACP,cAAc,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;YAC7C,IAAI,EAAE,IAAI;SACX;KACF,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACI,MAAM,WAAW,GAAG,CACzB,MAAyB,EACzB,OAA4B,EAC5B,aAA+B,EACd,EAAE;;IACnB,MAAM,EACJ,OAAO,EAAE,GAAG,EACZ,OAAO,EACP,OAAO,EACP,OAAO,GACR,GAAe,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;QAChD,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE;QAC7B,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC;YAClC,CAAC,CAAC,MAAM,CAAC,OAAO;YAChB,CAAC,CAAC,6BAA6B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElD,IAAI,UAAU,GAAQ;QACpB,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC;QAChC,QAAQ,EAAE,oBAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;QAChC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,aAAa;QACxC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,uBAAuB;QACvB,OAAO,EAAE,CAAC,IAAA,4BAAkB,EAAC,GAAG,CAAC;YAC/B,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,MAAM,CAAC,KAAK;gBACZ,MAAM,CAAC,KAAK,CAAC,OAAO;gBACpB,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,KAAK,QAAQ;gBAC1C,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO;gBACtB,CAAC,CAAC,YAAY;QAChB,OAAO,EAAE,IAAA,uBAAa,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;QACrD,KAAK,EAAE,IAAA,gCAAc,EAAC,MAAM,CAAC,KAAK,CAAC;KACpC,CAAC;IAEF,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;QAC7C,KAAK,MAAM,qBAAqB,IAAI,aAAa,EAAE;YACjD,MAAM,MAAM,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;YACjD,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,OAAO,SAAS,CAAC;aAClB;YACD,UAAU,GAAG,MAAM,CAAC;SACrB;KACF;IAED,mEAAmE;IACnE,MAAM,MAAM,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,kBAAkB,wDACxC,UAAU,EACV,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,cAAc,EACvB,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,CACrB,CAAC;IAEF,IAAI,mBAAmB,GAAiB;QACtC,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,KAAK,EAAE,UAAU,CAAC,KAAK;KACxB,CAAC;IAEF,IAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,EAAE;QACvB,iCAAiC;QACjC,mBAAmB,GAAG;YACpB,OAAO,EAAE,CAAC,IAAA,4BAAkB,EAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;gBACtD,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO;gBAC5B,CAAC,CAAC,qFAAqF;YACzF,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO;YACnC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK;SAChC,CAAC;KACH;IAED,IAAI,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,CAAA,IAAI,OAAO,IAAI,OAAO,CAAC,cAAc,EAAE;QAC7D,mBAAmB,GAAG,IAAA,4BAAU,EAC9B,mBAAmB,EACnB,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,WAAW,CACpB,CAAC;KACH;IAED,uCAAY,UAAU,GAAK,mBAAmB,EAAG;AACnD,CAAC,CAAC;AA7EW,QAAA,WAAW,eA6EtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-service-common",
3
- "version": "0.33.0",
3
+ "version": "0.34.0-rc.0",
4
4
  "description": "Common helpers and PostgreSQL-related functionality",
5
5
  "author": "Axinom",
6
6
  "license": "PROPRIETARY",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "b0c12ef914e4ead795480b4fc90b13bc1088bd3f"
73
+ "gitHead": "32853a01e5b6de8cb3712ea5e1bd75780df8d59d"
74
74
  }
@@ -50,4 +50,12 @@ export const MosaicErrors = {
50
50
  'This is a wrapper error for the original unhandled error of unsupported type.',
51
51
  code: 'ERROR_WRAPPER',
52
52
  },
53
+ ValueIsNotObject: {
54
+ message: 'The %s is not an object.',
55
+ code: 'VALUE_IS_NOT_OBJECT',
56
+ },
57
+ ObjectIsMissingProperties: {
58
+ message: 'The %s is missing required properties: %s.',
59
+ code: 'OBJECT_IS_MISSING_PROPERTIES',
60
+ },
53
61
  } as const;
@@ -1,11 +1,13 @@
1
1
  import 'jest-extended';
2
+ import { MosaicErrors } from '../errors';
2
3
  import {
4
+ assertObjectHasProperties,
3
5
  conditional,
4
6
  isEmptyObject,
5
7
  removeEmptyProperties,
6
8
  removeNullProperties,
7
9
  } from './object-helpers';
8
- import { toSerializeEqual } from './test-helpers';
10
+ import { expectFailure, toSerializeEqual } from './test-helpers';
9
11
 
10
12
  class TestClass {
11
13
  public test?: string;
@@ -135,4 +137,121 @@ describe('Object Helpers', () => {
135
137
  });
136
138
  });
137
139
  });
140
+
141
+ describe('assertObjectHasProperties', () => {
142
+ interface Test {
143
+ propA: string;
144
+ propB?: { test: string };
145
+ }
146
+
147
+ it('assert interface object as interface -> no type error', () => {
148
+ // Arrange
149
+ const obj: Test = { propA: 'test A', propB: { test: 'test B' } };
150
+
151
+ // Act
152
+ assertObjectHasProperties<Test>(obj, ['propA', 'propB'], 'test object');
153
+
154
+ // Assert
155
+ // Without type assertion this would have been underlined with error `obj.propB' is possibly 'undefined'.`
156
+ expect(obj.propB.test).toBeTruthy();
157
+ });
158
+
159
+ it('assert index signature object as interface -> no type error', () => {
160
+ // Arrange
161
+ const obj: {
162
+ [str: string]: unknown;
163
+ } = { propA: 'test A', propB: { test: 'test B' } };
164
+
165
+ // Act
166
+ assertObjectHasProperties<Test>(obj, ['propA', 'propB'], 'test object');
167
+
168
+ // Assert
169
+ // Without type assertion this would have been underlined with error `obj.propB' is possibly 'undefined'.`
170
+ expect(obj.propB.test).toBeTruthy();
171
+ });
172
+
173
+ it('assert unknown object as interface -> no type error', () => {
174
+ // Arrange
175
+ const obj: unknown = { propA: 'test A', propB: { test: 'test B' } };
176
+
177
+ // Act
178
+ assertObjectHasProperties<Test>(obj, ['propA', 'propB'], 'test object');
179
+
180
+ // Assert
181
+ // Without type assertion this would have been underlined with error `obj.propB' is possibly 'undefined'.`
182
+ expect(obj.propB.test).toBeTruthy();
183
+ });
184
+
185
+ it('assert empty object as interface -> missing properties error', () => {
186
+ // Act
187
+ const error = expectFailure(() =>
188
+ assertObjectHasProperties<Test>({}, ['propA', 'propB'], 'test object'),
189
+ );
190
+
191
+ // Assert
192
+ expect(error).toMatchObject({
193
+ message:
194
+ 'The test object is missing required properties: propA, propB.',
195
+ code: MosaicErrors.ObjectIsMissingProperties.code,
196
+ });
197
+ });
198
+
199
+ it('assert half-empty object as interface -> missing properties error', () => {
200
+ // Act
201
+ const error = expectFailure(() =>
202
+ assertObjectHasProperties<Test>({ propA: 'test A' }, [
203
+ 'propA',
204
+ 'propB',
205
+ ]),
206
+ );
207
+
208
+ // Assert
209
+ expect(error).toMatchObject({
210
+ // Also testing default object description
211
+ message: 'The passed value is missing required properties: propB.',
212
+ code: MosaicErrors.ObjectIsMissingProperties.code,
213
+ });
214
+ });
215
+
216
+ it.each([null, undefined])(
217
+ 'assert object with %p value as interface -> missing properties error',
218
+ (emptyValue) => {
219
+ // Act
220
+ const error = expectFailure(() =>
221
+ assertObjectHasProperties<Test>(
222
+ { propA: 'test A', propB: emptyValue },
223
+ ['propA', 'propB'],
224
+ 'test object',
225
+ ),
226
+ );
227
+
228
+ // Assert
229
+ expect(error).toMatchObject({
230
+ message: 'The test object is missing required properties: propB.',
231
+ code: MosaicErrors.ObjectIsMissingProperties.code,
232
+ });
233
+ },
234
+ );
235
+
236
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
237
+ it.each([null, undefined, '', ' ', 123, true, [], () => {}])(
238
+ 'assert non-object %p -> not object error',
239
+ (value) => {
240
+ // Act
241
+ const error = expectFailure(() =>
242
+ assertObjectHasProperties<Test>(
243
+ value,
244
+ ['propA', 'propB'],
245
+ 'test object',
246
+ ),
247
+ );
248
+
249
+ // Assert
250
+ expect(error).toMatchObject({
251
+ message: 'The test object is not an object.',
252
+ code: MosaicErrors.ValueIsNotObject.code,
253
+ });
254
+ },
255
+ );
256
+ });
138
257
  });
@@ -1,3 +1,4 @@
1
+ import { MosaicError, MosaicErrors } from '../errors';
1
2
  import { Dict } from '../types';
2
3
  import { isNullOrWhitespace } from './string-helpers';
3
4
 
@@ -89,3 +90,35 @@ export const conditional = (
89
90
  ): false | Dict<unknown> => {
90
91
  return condition && map();
91
92
  };
93
+
94
+ /**
95
+ * Asserts that object has specific properties. Resulting object is assumed to
96
+ * have all properties, even optional, resulting in Required<T> type.
97
+ * @param value object to be asserted.
98
+ * @param properties properties to be checked.
99
+ * @param identifier object identifier to be used in error messages.
100
+ */
101
+ export function assertObjectHasProperties<T>(
102
+ object: unknown,
103
+ properties: (keyof T)[],
104
+ objectDescription = 'passed value',
105
+ ): asserts object is Required<T> {
106
+ if (object === null || typeof object !== 'object' || Array.isArray(object)) {
107
+ throw new MosaicError({
108
+ ...MosaicErrors.ValueIsNotObject,
109
+ messageParams: [objectDescription],
110
+ });
111
+ }
112
+
113
+ const missingProperties = properties.filter(
114
+ (property) =>
115
+ !(property in object) || !(object as Record<keyof T, unknown>)[property],
116
+ );
117
+
118
+ if (missingProperties.length > 0) {
119
+ throw new MosaicError({
120
+ ...MosaicErrors.ObjectIsMissingProperties,
121
+ messageParams: [objectDescription, missingProperties.join(', ')],
122
+ });
123
+ }
124
+ }
@@ -5,7 +5,7 @@ import { Log } from './log';
5
5
  import { LogLevel } from './log-level';
6
6
  import { LogMessage } from './log-message';
7
7
  import { LogRetention } from './log-retention';
8
- import { MaskMiddleware, maskObject, MaskOptions } from './mask-middleware';
8
+ import { MaskMiddleware, MaskOptions, maskObject } from './mask-middleware';
9
9
  import { SkipMaskMiddleware } from './skip-mask-middleware';
10
10
 
11
11
  const parseTimestamp = (timestamp: string | Date | undefined): string => {
@@ -45,6 +45,48 @@ export interface LogMiddleware {
45
45
  (log: Log): Log | undefined;
46
46
  }
47
47
 
48
+ /**
49
+ * If value.message exists, object type and is it a empty object return true
50
+ * If value.message exists, object type and object has any of LogMessage properties(message,logtime,retention,context,details) with correct type then return true
51
+ * otherwise return false
52
+ */
53
+
54
+ const isLikeLogMessage = (value: unknown): boolean => {
55
+ return (
56
+ !!value &&
57
+ typeof value === 'object' &&
58
+ (isEmptyObject(value) ||
59
+ ('message' in value && typeof value.message === 'string') ||
60
+ ('logtime' in value &&
61
+ (typeof value.logtime === 'string' || value.logtime instanceof Date)) ||
62
+ ('retention' in value &&
63
+ typeof value.retention === 'string' &&
64
+ Object.values(LogRetention).includes(
65
+ value.retention as LogRetention,
66
+ )) ||
67
+ ('context' in value && typeof value.context === 'string') ||
68
+ ('details' in value && typeof value.details === 'object'))
69
+ );
70
+ };
71
+
72
+ /**
73
+ * Generates a LogMessage property called details object with correct values
74
+ */
75
+ const generateLogMessageDetailsProp = (inputMessage: unknown): object => {
76
+ const invalidMessage = JSON.stringify(inputMessage);
77
+ const longMessageClarification =
78
+ invalidMessage.length <= 1000
79
+ ? ''
80
+ : `because the message is too long (${invalidMessage.length} characters), first 1000 characters are `;
81
+ const hint = `The message passed into the logger is of the invalid format. It is stringified and ${longMessageClarification}logged as details.invalidMessage.`;
82
+ return {
83
+ details: {
84
+ invalidMessage: invalidMessage.slice(0, 1000),
85
+ hint: hint,
86
+ },
87
+ };
88
+ };
89
+
48
90
  /**
49
91
  * Generates a default log object without relying on config values.
50
92
  */
@@ -60,7 +102,9 @@ export const generateLog = (
60
102
  details,
61
103
  }: LogMessage = typeof values.message === 'string'
62
104
  ? { message: values.message }
63
- : values.message;
105
+ : isLikeLogMessage(values.message)
106
+ ? values.message
107
+ : generateLogMessageDetailsProp(values.message);
64
108
 
65
109
  let logMessage: Log = {
66
110
  logtime: parseTimestamp(logtime),
@@ -71,7 +115,9 @@ export const generateLog = (
71
115
  // sensitive properties
72
116
  message: !isNullOrWhitespace(msg)
73
117
  ? msg
74
- : values.error
118
+ : values.error &&
119
+ values.error.message &&
120
+ typeof values.error.message === 'string'
75
121
  ? values.error.message
76
122
  : 'no message',
77
123
  details: isEmptyObject(details) ? undefined : details,
@@ -1364,4 +1364,237 @@ describe('Logger', () => {
1364
1364
  });
1365
1365
  });
1366
1366
  });
1367
+
1368
+ describe(`error log when the type of 'message' is unknown`, () => {
1369
+ it('error log message with string message value -> set string value for message', () => {
1370
+ // Act
1371
+ logger.error('Hello World');
1372
+
1373
+ // Assert
1374
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1375
+
1376
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1377
+
1378
+ const referenceObject = {
1379
+ logtime: loggedObject.logtime,
1380
+ loglevel: LogLevel[LogLevel.ERROR],
1381
+ retention: LogRetention.Medium,
1382
+ message: 'Hello World',
1383
+ context: 'LoggerTests',
1384
+ component: 'navy-asset-service_test',
1385
+ };
1386
+ expect(loggedObject).toEqual(referenceObject);
1387
+ });
1388
+
1389
+ it('error log message with boolean message value -> convert boolean value to string value for message', () => {
1390
+ // Act
1391
+ logger.error(true as any);
1392
+
1393
+ // Assert
1394
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1395
+
1396
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1397
+
1398
+ const referenceObject = {
1399
+ logtime: loggedObject.logtime,
1400
+ loglevel: LogLevel[LogLevel.ERROR],
1401
+ retention: LogRetention.Medium,
1402
+ message: 'no message',
1403
+ details: {
1404
+ invalidMessage: 'true',
1405
+ hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
1406
+ },
1407
+ context: 'LoggerTests',
1408
+ component: 'navy-asset-service_test',
1409
+ };
1410
+ expect(loggedObject).toEqual(referenceObject);
1411
+ });
1412
+
1413
+ it('error log message with number message value -> convert number value to string value for message', () => {
1414
+ // Act
1415
+ logger.error(100 as any);
1416
+
1417
+ // Assert
1418
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1419
+
1420
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1421
+
1422
+ const referenceObject = {
1423
+ logtime: loggedObject.logtime,
1424
+ loglevel: LogLevel[LogLevel.ERROR],
1425
+ retention: LogRetention.Medium,
1426
+ message: 'no message',
1427
+ details: {
1428
+ invalidMessage: '100',
1429
+ hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
1430
+ },
1431
+ context: 'LoggerTests',
1432
+ component: 'navy-asset-service_test',
1433
+ };
1434
+ expect(loggedObject).toEqual(referenceObject);
1435
+ });
1436
+
1437
+ it('error log message with empty object message value -> convert object value to string value for message', () => {
1438
+ // Act
1439
+ logger.error({} as any);
1440
+
1441
+ // Assert
1442
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1443
+
1444
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1445
+
1446
+ const referenceObject = {
1447
+ logtime: loggedObject.logtime,
1448
+ loglevel: LogLevel[LogLevel.ERROR],
1449
+ retention: LogRetention.Medium,
1450
+ message: 'no message',
1451
+ context: 'LoggerTests',
1452
+ component: 'navy-asset-service_test',
1453
+ };
1454
+ expect(loggedObject).toEqual(referenceObject);
1455
+ });
1456
+
1457
+ it('error log message with object message having string value -> set string value for message', () => {
1458
+ // Act
1459
+ logger.error({ message: 'Hello World' } as any);
1460
+
1461
+ // Assert
1462
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1463
+
1464
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1465
+
1466
+ const referenceObject = {
1467
+ logtime: loggedObject.logtime,
1468
+ loglevel: LogLevel[LogLevel.ERROR],
1469
+ retention: LogRetention.Medium,
1470
+ message: 'Hello World',
1471
+ context: 'LoggerTests',
1472
+ component: 'navy-asset-service_test',
1473
+ };
1474
+ expect(loggedObject).toEqual(referenceObject);
1475
+ });
1476
+
1477
+ it('error log message with object message having number value -> set stringified object value for message', () => {
1478
+ // Act
1479
+ logger.error({ message: 100 } as any);
1480
+
1481
+ // Assert
1482
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1483
+
1484
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1485
+
1486
+ const referenceObject = {
1487
+ logtime: loggedObject.logtime,
1488
+ loglevel: LogLevel[LogLevel.ERROR],
1489
+ retention: LogRetention.Medium,
1490
+ message: 'no message',
1491
+ details: {
1492
+ invalidMessage: '{"message":100}',
1493
+ hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
1494
+ },
1495
+ context: 'LoggerTests',
1496
+ component: 'navy-asset-service_test',
1497
+ };
1498
+ expect(loggedObject).toEqual(referenceObject);
1499
+ });
1500
+
1501
+ it('error log message with object message having boolean value -> set stringified object value for message', () => {
1502
+ // Act
1503
+ logger.error({ message: true } as any);
1504
+
1505
+ // Assert
1506
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1507
+
1508
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1509
+
1510
+ const referenceObject = {
1511
+ logtime: loggedObject.logtime,
1512
+ loglevel: LogLevel[LogLevel.ERROR],
1513
+ retention: LogRetention.Medium,
1514
+ message: 'no message',
1515
+ details: {
1516
+ invalidMessage: '{"message":true}',
1517
+ hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
1518
+ },
1519
+ context: 'LoggerTests',
1520
+ component: 'navy-asset-service_test',
1521
+ };
1522
+ expect(loggedObject).toEqual(referenceObject);
1523
+ });
1524
+
1525
+ it('error log message with object message having different format of values -> set stringified object value for message', () => {
1526
+ // Act
1527
+ logger.error({ message: {}, test: 'test prop' } as any);
1528
+
1529
+ // Assert
1530
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1531
+
1532
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1533
+
1534
+ const referenceObject = {
1535
+ logtime: loggedObject.logtime,
1536
+ loglevel: LogLevel[LogLevel.ERROR],
1537
+ retention: LogRetention.Medium,
1538
+ message: 'no message',
1539
+ details: {
1540
+ invalidMessage: '{"message":{},"test":"test prop"}',
1541
+ hint: 'The message passed into the logger is of the invalid format. It is stringified and logged as details.invalidMessage.',
1542
+ },
1543
+ context: 'LoggerTests',
1544
+ component: 'navy-asset-service_test',
1545
+ };
1546
+ expect(loggedObject).toEqual(referenceObject);
1547
+ });
1548
+
1549
+ it('error log message with non string format and more than 1000 characters -> set stringified and first 1000 characters are set for message', () => {
1550
+ const randomString =
1551
+ 'TNwCBNAVmXXzZOaPiKGJTQyueACishwwLnZMPUaniVtTgOlqMwlqcGvBNABRyJFOVTTgBfEeZuCPHaNMuwTgQpduvKtPykFSuiLTQkRyeEnPwrGThTdlmiObxmpFkZygfXAwezfsbKxioablETznFcRXtOJmKFWFtiacqcdEkDooycxaiOkyVPhTUCsCTelggTzPrTTBSazsTpnyKQmoLikEueSNyXxuhEAAuwQGdStXdIxVRIxTpFkgePWLheWSxJkZUkJrbvpsJyEulQWRclmRbDrcVEKlMDFQsADwnJCkNPhLdOyagsruMwcJdJaSlisNmNEmNHGfNTTzTScomxFbDKTyaPXuxXrvtCooLqbXWfQnhnwcyRuSLpoRfMXeDRFCdTeVkbNuXKdMsNqESXrrSlEtvmAkHdXGmHmHiyBsSwaFhCCmgwgniBQQKemOFvZckaOIRADroRUGWLAJNyhTpVaFvJbuCNEIJNToWuiniTZUpMJOOTNMRhABJnpQHfLGsAWJTtWtBdBxZCXxBhaClzORcgpstBggDUwCtpagvzCIGbKDfDJhWWxcLKNbgBxzzNoaGlrTipoxbKKlJGESGxlJOxwquTRaEvIckdUOBebKczCEifeZiREUalMSnrPLVuunyZzIXFPDsePJIMXyvOzvlXgkqhBtgVbfAqmsbvkPVKUXKXtiDlQCfAnfKzETgfHhxsdXOevPXCnxqFEpmWvxaQnXcyUCcLgEvLSioLbfLWutRAfJJPfCTRhrVwwTDFMgnJAGrreTOXRDtouHysurRUdspnwsKuqNeozvfkaWkfyyZpAdBsUgaVqpTJzlXipLdrxtqiiATveTnbuAzPTatNTCwyJTTNSklHTVVndNqknyQIbULeWgNWHedthZeQFKvdXtQVVuHJfvhSJfuXOVxEfKpzezSkfqHZgWPRfUtbLFbNlJSfOgUJdcvxnliUZOCQilOPmzGxOeyaWiZFOmumwcbHmWulcS';
1552
+ // Act
1553
+ logger.error({ message: {}, testMsg: randomString } as any);
1554
+
1555
+ // Assert
1556
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1557
+
1558
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1559
+
1560
+ const referenceObject = {
1561
+ logtime: loggedObject.logtime,
1562
+ loglevel: LogLevel[LogLevel.ERROR],
1563
+ retention: LogRetention.Medium,
1564
+ message: 'no message',
1565
+ details: {
1566
+ invalidMessage:
1567
+ '{"message":{},"testMsg":"TNwCBNAVmXXzZOaPiKGJTQyueACishwwLnZMPUaniVtTgOlqMwlqcGvBNABRyJFOVTTgBfEeZuCPHaNMuwTgQpduvKtPykFSuiLTQkRyeEnPwrGThTdlmiObxmpFkZygfXAwezfsbKxioablETznFcRXtOJmKFWFtiacqcdEkDooycxaiOkyVPhTUCsCTelggTzPrTTBSazsTpnyKQmoLikEueSNyXxuhEAAuwQGdStXdIxVRIxTpFkgePWLheWSxJkZUkJrbvpsJyEulQWRclmRbDrcVEKlMDFQsADwnJCkNPhLdOyagsruMwcJdJaSlisNmNEmNHGfNTTzTScomxFbDKTyaPXuxXrvtCooLqbXWfQnhnwcyRuSLpoRfMXeDRFCdTeVkbNuXKdMsNqESXrrSlEtvmAkHdXGmHmHiyBsSwaFhCCmgwgniBQQKemOFvZckaOIRADroRUGWLAJNyhTpVaFvJbuCNEIJNToWuiniTZUpMJOOTNMRhABJnpQHfLGsAWJTtWtBdBxZCXxBhaClzORcgpstBggDUwCtpagvzCIGbKDfDJhWWxcLKNbgBxzzNoaGlrTipoxbKKlJGESGxlJOxwquTRaEvIckdUOBebKczCEifeZiREUalMSnrPLVuunyZzIXFPDsePJIMXyvOzvlXgkqhBtgVbfAqmsbvkPVKUXKXtiDlQCfAnfKzETgfHhxsdXOevPXCnxqFEpmWvxaQnXcyUCcLgEvLSioLbfLWutRAfJJPfCTRhrVwwTDFMgnJAGrreTOXRDtouHysurRUdspnwsKuqNeozvfkaWkfyyZpAdBsUgaVqpTJzlXipLdrxtqiiATveTnbuAzPTatNTCwyJTTNSklHTVVndNqknyQIbULeWgNWHedthZeQFKvdXtQVVuHJfvhSJfuXOVxEfKpzezSkfqHZgWPRfUtbLFbNlJSfOgUJdcvxnliUZOCQilOPm',
1568
+ hint: 'The message passed into the logger is of the invalid format. It is stringified and because the message is too long (1027 characters), first 1000 characters are logged as details.invalidMessage.',
1569
+ },
1570
+ context: 'LoggerTests',
1571
+ component: 'navy-asset-service_test',
1572
+ };
1573
+ expect(loggedObject).toEqual(referenceObject);
1574
+ expect(referenceObject.details.invalidMessage).toHaveLength(1000);
1575
+ });
1576
+
1577
+ it('error log message with non-string value and error object message also dont have string message property -> set no message as for message', () => {
1578
+ // Act
1579
+ const error = new Error();
1580
+ logger.error({ message: 600 } as any, error);
1581
+
1582
+ // Assert
1583
+ expect(consoleOverride).toHaveBeenCalledTimes(1);
1584
+ const loggedObject = getFirstMockResult<any>(consoleOverride);
1585
+
1586
+ const referenceObject = {
1587
+ logtime: loggedObject.logtime,
1588
+ loglevel: LogLevel[LogLevel.ERROR],
1589
+ retention: LogRetention.Medium,
1590
+ message: 'no message',
1591
+ context: 'LoggerTests',
1592
+ error: {
1593
+ message: 600,
1594
+ },
1595
+ component: 'navy-asset-service_test',
1596
+ };
1597
+ expect(loggedObject).toEqual(referenceObject);
1598
+ });
1599
+ });
1367
1600
  });