@weave-js/core 0.10.0 → 0.12.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.
Files changed (132) hide show
  1. package/.eslintrc.js +1 -1
  2. package/jest.config.js +1 -1
  3. package/lib/ExtendableError.js +33 -0
  4. package/lib/broker/context.js +58 -46
  5. package/lib/broker/{default-options.js → defaultOptions.js} +31 -13
  6. package/lib/broker/index.js +273 -251
  7. package/lib/buildRuntime.js +70 -0
  8. package/lib/cache/adapters/base.js +119 -0
  9. package/lib/cache/adapters/inMemory.js +154 -0
  10. package/lib/cache/adapters/inMemoryLru.js +140 -0
  11. package/lib/cache/adapters/index.js +10 -0
  12. package/lib/cache/getCacheKeyByObject.js +31 -0
  13. package/lib/cache/getPropertyFromDataOrMetadata.js +20 -0
  14. package/lib/cache/lock.js +34 -11
  15. package/lib/constants.js +11 -8
  16. package/lib/{error-handler.js → errorHandler.js} +8 -8
  17. package/lib/errors.js +46 -39
  18. package/lib/helper/{define-action.js → defineAction.js} +5 -3
  19. package/lib/helper/{define-broker-options.js → defineBrokerOptions.js} +4 -2
  20. package/lib/helper/{define-service.js → defineService.js} +6 -3
  21. package/lib/index.js +25 -22
  22. package/lib/logger/base.js +38 -29
  23. package/lib/logger/format/asHumanReadable.js +15 -14
  24. package/lib/logger/format/asJson.js +10 -10
  25. package/lib/logger/format/index.js +3 -3
  26. package/lib/logger/index.js +28 -25
  27. package/lib/logger/levels.js +23 -22
  28. package/lib/logger/tools.js +17 -13
  29. package/lib/logger/utils/colorize.js +23 -23
  30. package/lib/logger/utils/format.js +89 -65
  31. package/lib/metrics/common.js +47 -47
  32. package/lib/metrics/constants.js +44 -44
  33. package/lib/metrics/exporter/base.js +8 -8
  34. package/lib/metrics/exporter/event.js +20 -20
  35. package/lib/metrics/exporter/index.js +15 -15
  36. package/lib/metrics/index.js +2 -2
  37. package/lib/metrics/types/base.js +20 -20
  38. package/lib/metrics/types/counter.js +6 -6
  39. package/lib/metrics/types/gauge.js +24 -24
  40. package/lib/metrics/types/histogram.js +26 -26
  41. package/lib/metrics/types/index.js +6 -6
  42. package/lib/metrics/types/info.js +17 -17
  43. package/lib/middlewares/action-hooks/index.js +82 -34
  44. package/lib/middlewares/bulkhead/index.js +34 -33
  45. package/lib/middlewares/cache/index.js +106 -0
  46. package/lib/middlewares/circuit-breaker/index.js +85 -60
  47. package/lib/middlewares/context-tracker/index.js +39 -39
  48. package/lib/middlewares/error-handler/index.js +14 -14
  49. package/lib/middlewares/index.js +3 -2
  50. package/lib/middlewares/metrics/getMiddlewareWrapper.js +17 -17
  51. package/lib/middlewares/metrics/index.js +29 -29
  52. package/lib/middlewares/retry/index.js +15 -15
  53. package/lib/middlewares/timeout/index.js +18 -18
  54. package/lib/middlewares/tracing/index.js +50 -37
  55. package/lib/middlewares/tracing/tags.js +43 -0
  56. package/lib/middlewares/validator/index.js +32 -32
  57. package/lib/registry/{action-endpoint.js → actionEndpoint.js} +8 -8
  58. package/lib/registry/collections/{action-collection.js → actionCollection.js} +39 -35
  59. package/lib/registry/collections/{endpoint-collection.js → endpointCollection.js} +64 -65
  60. package/lib/registry/collections/{event-collection.js → eventCollection.js} +65 -69
  61. package/lib/registry/collections/{node-collection.js → nodeCollection.js} +45 -45
  62. package/lib/registry/collections/{service-collection.js → serviceCollection.js} +61 -55
  63. package/lib/registry/eventEndpoint.js +26 -0
  64. package/lib/registry/load-balancer/base.js +3 -3
  65. package/lib/registry/load-balancer/index.js +7 -7
  66. package/lib/registry/node.js +27 -27
  67. package/lib/registry/registry.js +147 -163
  68. package/lib/registry/service/parseAction.js +16 -16
  69. package/lib/registry/service/parseEvent.js +18 -18
  70. package/lib/registry/service/reduceMixins.js +10 -10
  71. package/lib/registry/service/service.js +72 -72
  72. package/lib/registry/{service-item.js → serviceItem.js} +21 -21
  73. package/lib/runtime/{init-action-invoker.js → initActionInvoker.js} +21 -21
  74. package/lib/runtime/initCache.js +19 -0
  75. package/lib/runtime/{init-context-factory.js → initContextFactory.js} +22 -22
  76. package/lib/runtime/{init-eventbus.js → initEventbus.js} +54 -53
  77. package/lib/runtime/{init-logger.js → initLogger.js} +11 -11
  78. package/lib/runtime/{init-metrics.js → initMetrics.js} +55 -54
  79. package/lib/runtime/{init-middleware-manager.js → initMiddlewareManager.js} +21 -21
  80. package/lib/runtime/{init-registry.js → initRegistry.js} +6 -6
  81. package/lib/runtime/initServiceManager.js +145 -0
  82. package/lib/runtime/{init-tracing.js → initTracing.js} +25 -24
  83. package/lib/runtime/{init-transport.js → initTransport.js} +5 -5
  84. package/lib/runtime/{init-uuid-factory.js → initUuidFactory.js} +4 -4
  85. package/lib/runtime/{init-validator.js → initValidator.js} +5 -5
  86. package/lib/tracing/collectors/base.js +29 -37
  87. package/lib/tracing/collectors/event.js +33 -33
  88. package/lib/tracing/collectors/index.js +16 -16
  89. package/lib/tracing/span.js +34 -32
  90. package/lib/tracing/time.js +8 -8
  91. package/lib/transport/InboundTransformStream.js +75 -0
  92. package/lib/transport/adapters/adapteBase.js +107 -0
  93. package/lib/transport/adapters/adapters.js +4 -4
  94. package/lib/transport/adapters/dummy/index.js +19 -19
  95. package/lib/transport/adapters/fromURI.js +13 -13
  96. package/lib/transport/adapters/getAdapterByName.js +5 -5
  97. package/lib/transport/adapters/index.js +12 -12
  98. package/lib/transport/adapters/tcp/discovery/codec.js +4 -4
  99. package/lib/transport/adapters/tcp/discovery/index.js +90 -76
  100. package/lib/transport/adapters/tcp/index.js +180 -175
  101. package/lib/transport/adapters/tcp/tcp-messagetypes.js +7 -7
  102. package/lib/transport/adapters/tcp/tcpReader.js +39 -38
  103. package/lib/transport/adapters/tcp/tcpWriteStream.js +26 -26
  104. package/lib/transport/adapters/tcp/tcpWriter.js +58 -58
  105. package/lib/transport/adapters/tcp/utils.js +12 -12
  106. package/lib/transport/createMessage.js +11 -0
  107. package/lib/transport/createTransport.js +377 -334
  108. package/lib/transport/errorPayloadFactory.js +15 -0
  109. package/lib/transport/messageHandlers.js +517 -0
  110. package/lib/transport/messageTypes.js +23 -0
  111. package/lib/types.js +95 -71
  112. package/lib/utils/index.js +2 -2
  113. package/lib/utils/options.js +47 -45
  114. package/lib/utils/{restore-error.js → restoreError.js} +4 -4
  115. package/package.json +6 -12
  116. package/CHANGELOG.md +0 -1334
  117. package/lib/build-runtime.js +0 -70
  118. package/lib/cache/base.js +0 -142
  119. package/lib/cache/index.js +0 -48
  120. package/lib/cache/memory.js +0 -121
  121. package/lib/middlewares/tracing/buildTags.js +0 -17
  122. package/lib/new-errors.js +0 -25
  123. package/lib/registry/event-endpoint.js +0 -26
  124. package/lib/runtime/init-cache.js +0 -10
  125. package/lib/runtime/init-service-manager.js +0 -128
  126. package/lib/tracing/collectors/console.js +0 -34
  127. package/lib/tracing/index.js +0 -3
  128. package/lib/tracing/tracer.js +0 -64
  129. package/lib/transport/adapters/adapter-base.js +0 -92
  130. package/lib/transport/message-handlers.js +0 -448
  131. package/lib/transport/message-types.js +0 -59
  132. package/lib/transport/message.js +0 -16
@@ -1,41 +1,41 @@
1
- const { createBaseMetricAdapter } = require('./base')
1
+ const { createBaseMetricAdapter } = require('./base');
2
2
 
3
3
  module.exports = (options) => {
4
- const lastChanges = new Set()
4
+ const lastChanges = new Set();
5
5
 
6
- const adapter = createBaseMetricAdapter(options)
6
+ const adapter = createBaseMetricAdapter(options);
7
7
 
8
8
  const sendEvent = (registry, options) => {
9
- const broker = registry.broker
10
- const list = this.registry.list()
9
+ const broker = registry.broker;
10
+ const list = this.registry.list();
11
11
 
12
- broker.emit(this.options.eventName, list)
12
+ broker.emit(this.options.eventName, list);
13
13
 
14
- lastChanges.clear()
15
- }
14
+ lastChanges.clear();
15
+ };
16
16
 
17
17
  adapter.init = (registry) => {
18
18
  this.options = Object.assign(options, {
19
19
  eventName: '$metrics.changed',
20
20
  interval: 5000
21
- })
21
+ });
22
22
 
23
- this.registry = registry
23
+ this.registry = registry;
24
24
 
25
25
  if (this.options.interval > 0) {
26
- this.timer = setInterval(() => sendEvent(), this.options.interval)
27
- this.timer.unref()
26
+ this.timer = setInterval(() => sendEvent(), this.options.interval);
27
+ this.timer.unref();
28
28
  }
29
- }
29
+ };
30
30
 
31
31
  adapter.stop = () => {
32
- clearInterval(this.timer)
33
- return Promise.resolve()
34
- }
32
+ clearInterval(this.timer);
33
+ return Promise.resolve();
34
+ };
35
35
 
36
36
  adapter.metricChanged = (metric) => {
37
- lastChanges.add(metric)
38
- }
37
+ lastChanges.add(metric);
38
+ };
39
39
 
40
- return adapter
41
- }
40
+ return adapter;
41
+ };
@@ -1,44 +1,44 @@
1
- const { isString, isFunction } = require('@weave-js/utils')
2
- const { WeaveBrokerOptionsError } = require('../../errors')
1
+ const { isString, isFunction } = require('@weave-js/utils');
2
+ const { WeaveBrokerOptionsError } = require('../../errors');
3
3
 
4
4
  const adapters = {
5
5
  Base: require('./base'),
6
6
  Event: require('./event')
7
- }
7
+ };
8
8
 
9
9
  const getByName = name => {
10
10
  if (!name) {
11
- return null
11
+ return null;
12
12
  }
13
13
 
14
- const n = Object.keys(adapters).find(n => n.toLowerCase() === name.toLowerCase())
14
+ const n = Object.keys(adapters).find(n => n.toLowerCase() === name.toLowerCase());
15
15
 
16
16
  if (n) {
17
- return adapters[n]
17
+ return adapters[n];
18
18
  }
19
- }
19
+ };
20
20
 
21
21
  module.exports = {
22
22
  ...adapters,
23
23
  resolve (options) {
24
- let cacheFactory
24
+ let cacheFactory;
25
25
 
26
26
  if (options === true) {
27
- cacheFactory = this.adapters.Event
27
+ cacheFactory = this.adapters.Event;
28
28
  } else if (isString(options)) {
29
- const cache = getByName(options)
29
+ const cache = getByName(options);
30
30
 
31
31
  if (cache) {
32
- cacheFactory = cache
32
+ cacheFactory = cache;
33
33
  } else {
34
- throw new WeaveBrokerOptionsError(`Unknown metric adapter: "${options}"`)
34
+ throw new WeaveBrokerOptionsError(`Unknown metric adapter: "${options}"`);
35
35
  }
36
36
  } else if (isFunction(options)) {
37
- cacheFactory = options
37
+ cacheFactory = options;
38
38
  }
39
39
 
40
40
  if (cacheFactory) {
41
- return cacheFactory
41
+ return cacheFactory;
42
42
  }
43
43
  }
44
- }
44
+ };
@@ -1,2 +1,2 @@
1
- exports.Constants = require('./constants')
2
- exports.Exporter = require('./exporter')
1
+ exports.Constants = require('./constants');
2
+ exports.Exporter = require('./exporter');
@@ -6,39 +6,39 @@ exports.createBaseMetricType = (metricRegistry, obj) => {
6
6
  labels: obj.labels || [],
7
7
  type: obj.type,
8
8
  unit: obj.unit
9
- })
9
+ });
10
10
 
11
11
  base.stringifyLabels = (labels) => {
12
12
  if (base.labels.length === 0 || labels === null || typeof labels !== 'object') {
13
- return ''
13
+ return '';
14
14
  }
15
15
 
16
- const parts = []
16
+ const parts = [];
17
17
 
18
18
  base.labels.forEach(labelName => {
19
- const value = labels[labelName]
19
+ const value = labels[labelName];
20
20
  if (typeof value === 'number') {
21
- parts.push(value)
21
+ parts.push(value);
22
22
  } else if (typeof value === 'string') {
23
- parts.push(value)
23
+ parts.push(value);
24
24
  } else if (typeof value === 'boolean') {
25
- parts.push('' + value)
25
+ parts.push('' + value);
26
26
  } else {
27
- parts.push('')
27
+ parts.push('');
28
28
  }
29
- })
29
+ });
30
30
 
31
- return parts.join('|')
32
- }
31
+ return parts.join('|');
32
+ };
33
33
 
34
34
  base.get = (labels) => {
35
- const labelString = base.stringifyLabels(labels)
36
- return base.values.get(labelString)
37
- }
35
+ const labelString = base.stringifyLabels(labels);
36
+ return base.values.get(labelString);
37
+ };
38
38
 
39
39
  base.snapshot = () => {
40
- return base.generateSnapshot()
41
- }
40
+ return base.generateSnapshot();
41
+ };
42
42
 
43
43
  base.toObject = () => {
44
44
  return {
@@ -47,8 +47,8 @@ exports.createBaseMetricType = (metricRegistry, obj) => {
47
47
  description: base.description,
48
48
  value: base.snapshot(),
49
49
  unit: base.unit
50
- }
51
- }
50
+ };
51
+ };
52
52
 
53
- return base
54
- }
53
+ return base;
54
+ };
@@ -1,11 +1,11 @@
1
- const { createGauge } = require('./gauge')
1
+ const { createGauge } = require('./gauge');
2
2
 
3
3
  exports.createCounter = (metricRegistry, obj) => {
4
- const base = createGauge(metricRegistry, obj)
4
+ const base = createGauge(metricRegistry, obj);
5
5
 
6
6
  base.decrement = () => {
7
- throw new Error('Not allowed to decrement a counter')
8
- }
7
+ throw new Error('Not allowed to decrement a counter');
8
+ };
9
9
 
10
- return base
11
- }
10
+ return base;
11
+ };
@@ -1,19 +1,19 @@
1
- const { createBaseMetricType } = require('./base')
1
+ const { createBaseMetricType } = require('./base');
2
2
 
3
3
  exports.createGauge = (registry, obj) => {
4
- const base = createBaseMetricType(registry, obj)
4
+ const base = createBaseMetricType(registry, obj);
5
5
 
6
- base.value = 0
6
+ base.value = 0;
7
7
 
8
8
  base.increment = (labels, value, timestamp) => {
9
- const item = base.values.get(labels)
10
- base.set((item ? item.value : 0) + value, labels, timestamp)
11
- }
9
+ const item = base.get(labels);
10
+ base.set((item ? item.value : 0) + value, labels, timestamp);
11
+ };
12
12
 
13
13
  base.decrement = (labels, value, timestamp) => {
14
- const item = base.get(labels)
15
- base.set((item ? item.value : 0) - value, labels, timestamp)
16
- }
14
+ const item = base.get(labels);
15
+ base.set((item ? item.value : 0) - value, labels, timestamp);
16
+ };
17
17
 
18
18
  base.generateSnapshot = () => {
19
19
  return Array.from(base.values)
@@ -21,33 +21,33 @@ exports.createGauge = (registry, obj) => {
21
21
  return {
22
22
  value: item.value,
23
23
  labels: item.labels
24
- }
25
- })
26
- }
24
+ };
25
+ });
26
+ };
27
27
 
28
28
  base.set = (value, labels, timestamp = Date.now()) => {
29
- const labelString = base.stringifyLabels(labels)
30
- let item = base.values.get(labelString)
29
+ const labelString = base.stringifyLabels(labels);
30
+ let item = base.values.get(labelString);
31
31
 
32
- base.value = value
32
+ base.value = value;
33
33
 
34
34
  if (item) {
35
35
  if (item.value !== value) {
36
- item.labels = labels
37
- item.value = value
38
- item.timestamp = timestamp
36
+ item.labels = labels;
37
+ item.value = value;
38
+ item.timestamp = timestamp;
39
39
  }
40
40
  } else {
41
41
  item = {
42
42
  labels,
43
43
  value,
44
44
  timestamp
45
- }
45
+ };
46
46
 
47
- base.values.set(labelString, item)
47
+ base.values.set(labelString, item);
48
48
  }
49
- return item
50
- }
49
+ return item;
50
+ };
51
51
 
52
- return base
53
- }
52
+ return base;
53
+ };
@@ -1,34 +1,34 @@
1
- const { createBaseMetricType } = require('./base')
1
+ const { createBaseMetricType } = require('./base');
2
2
 
3
3
  exports.createHistogram = (registry, obj) => {
4
- const base = createBaseMetricType(registry, obj)
4
+ const base = createBaseMetricType(registry, obj);
5
5
 
6
- base.value = 0
6
+ base.value = 0;
7
7
 
8
8
  // create default buckets
9
9
  if (obj.buckets) {
10
- base.buckets = registry.options.defaultBuckets
10
+ base.buckets = registry.options.defaultBuckets;
11
11
  }
12
12
 
13
- base.buckets = base.buckets.sort((a, b) => a - b)
13
+ base.buckets = base.buckets.sort((a, b) => a - b);
14
14
 
15
15
  base.observe = (value, labels, timestamp) => {
16
- const labelString = base.stringifyLabels(labels)
16
+ const labelString = base.stringifyLabels(labels);
17
17
 
18
- const item = base.values.get(labelString)
18
+ const item = base.values.get(labelString);
19
19
 
20
20
  if (!value) {
21
21
 
22
22
  }
23
23
 
24
- base.set(labels, (item ? item.value : 0) + value)
25
- }
24
+ base.set(labels, (item ? item.value : 0) + value);
25
+ };
26
26
 
27
27
  base.decrement = (labels, value, timestamp) => {
28
- const item = base.get(labels)
28
+ const item = base.get(labels);
29
29
 
30
- base.set(labels, (item ? item.value : 0) - value)
31
- }
30
+ base.set(labels, (item ? item.value : 0) - value);
31
+ };
32
32
 
33
33
  base.generateSnapshot = () => {
34
34
  return Array.from(base.values)
@@ -36,32 +36,32 @@ exports.createHistogram = (registry, obj) => {
36
36
  return {
37
37
  value: item.value,
38
38
  labels: item.labels
39
- }
40
- })
41
- }
39
+ };
40
+ });
41
+ };
42
42
 
43
43
  base.set = (labels, value, timestamp) => {
44
- const labelString = base.stringifyLabels(labels)
45
- const item = base.values.get(labelString)
44
+ const labelString = base.stringifyLabels(labels);
45
+ const item = base.values.get(labelString);
46
46
 
47
- base.value = value
47
+ base.value = value;
48
48
 
49
49
  if (item) {
50
50
  if (item.value !== value) {
51
- item.labels = labels
52
- item.value = value
51
+ item.labels = labels;
52
+ item.value = value;
53
53
  }
54
54
  } else {
55
55
  const item = {
56
56
  labels: labels,
57
57
  value: value
58
- }
58
+ };
59
59
 
60
- base.values.set(labelString, item)
60
+ base.values.set(labelString, item);
61
61
  }
62
- return item
63
- }
62
+ return item;
63
+ };
64
64
 
65
- return base
66
- }
65
+ return base;
66
+ };
67
67
 
@@ -2,18 +2,18 @@ const types = {
2
2
  Counter: require('./counter').createCounter,
3
3
  Gauge: require('./gauge').createGauge,
4
4
  Info: require('./info').createInfo
5
- }
5
+ };
6
6
 
7
7
  const getByName = name => {
8
- const n = Object.keys(types).find(i => i.toLocaleLowerCase() === name.toLocaleLowerCase())
8
+ const n = Object.keys(types).find(i => i.toLocaleLowerCase() === name.toLocaleLowerCase());
9
9
 
10
10
  if (n) {
11
- return types[n]
11
+ return types[n];
12
12
  }
13
- }
13
+ };
14
14
 
15
15
  module.exports = {
16
16
  resolve (type) {
17
- return getByName(type)
17
+ return getByName(type);
18
18
  }
19
- }
19
+ };
@@ -1,7 +1,7 @@
1
- const { createBaseMetricType } = require('./base')
1
+ const { createBaseMetricType } = require('./base');
2
2
 
3
3
  exports.createInfo = (metricRegistry, obj) => {
4
- const base = createBaseMetricType(metricRegistry, obj)
4
+ const base = createBaseMetricType(metricRegistry, obj);
5
5
 
6
6
  base.generateSnapshot = () => {
7
7
  return Array.from(base.values)
@@ -9,33 +9,33 @@ exports.createInfo = (metricRegistry, obj) => {
9
9
  return {
10
10
  value: item.value,
11
11
  labels: item.labels
12
- }
13
- })
14
- }
12
+ };
13
+ });
14
+ };
15
15
 
16
16
  base.set = (value, labels, timestamp) => {
17
- const labelString = base.stringifyLabels(labels)
18
- const item = base.values.get(labelString)
17
+ const labelString = base.stringifyLabels(labels);
18
+ const item = base.values.get(labelString);
19
19
 
20
- base.value = value
20
+ base.value = value;
21
21
 
22
22
  if (item) {
23
23
  if (item.value !== value) {
24
- item.labels = labels
25
- item.value = value
26
- item.timestamp = timestamp || Date.now()
24
+ item.labels = labels;
25
+ item.value = value;
26
+ item.timestamp = timestamp || Date.now();
27
27
  }
28
28
  } else {
29
29
  const item = {
30
30
  labels: labels,
31
31
  value: value,
32
32
  timestamp: timestamp || Date.now()
33
- }
33
+ };
34
34
 
35
- base.values.set(labelString, item)
35
+ base.values.set(labelString, item);
36
36
  }
37
- return item
38
- }
37
+ return item;
38
+ };
39
39
 
40
- return base
41
- }
40
+ return base;
41
+ };
@@ -1,90 +1,138 @@
1
1
  /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
2
+ * Author: Kevin Ries (kevin.ries@fachwerk.io)
3
3
  * -----
4
4
  * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
7
  function callHook (hook, service, context, result) {
8
8
  if (typeof hook === 'function') {
9
- return hook.call(service, context, result)
9
+ return hook.call(service, context, result);
10
10
  } else if (Array.isArray(hook)) {
11
- return hook.reduce((promise, fn) => promise.then(res => fn.call(service, context, res)), Promise.resolve(result))
11
+ return hook.reduce(
12
+ (promise, fn) => promise.then(res => fn.call(service, context, res)),
13
+ Promise.resolve(result));
14
+ }
15
+ }
16
+
17
+ function callErrorHook (hook, service, context, error) {
18
+ if (typeof hook === 'function') {
19
+ return hook.call(service, context, error);
20
+ } else if (Array.isArray(hook)) {
21
+ return hook.reduce(
22
+ (promise, fn) => promise.catch(err => fn.call(service, context, err)),
23
+ Promise.reject(error));
12
24
  }
13
25
  }
14
26
 
15
27
  function sanitizeHooks (hooks, service) {
16
28
  if (typeof hooks === 'string') {
17
- hooks = hooks.split(' ')
29
+ hooks = hooks.split(' ');
18
30
  }
19
31
 
20
32
  if (Array.isArray(hooks)) {
21
33
  return hooks.map((hook) => {
34
+ // resolve the method name
22
35
  if (typeof hook === 'string') {
23
- return (service && typeof service[hook] === 'function') ? service[hook] : null
36
+ return (service && typeof service[hook] === 'function') ? service[hook] : null;
24
37
  }
25
- return hook
26
- })
38
+ return hook;
39
+ });
27
40
  }
28
- return hooks
41
+ return hooks;
29
42
  }
30
43
 
31
44
  const makeActionHookMiddleware = function (handler, action) {
32
- const name = action.shortName
33
- const hooks = (action.service && action.service.schema) ? action.service.schema.hooks : null
34
-
35
- if (hooks) {
36
- const beforeWildcardHook = hooks.before ? sanitizeHooks(hooks.before['*'], action.service) : null
37
- const afterWildcardHook = hooks.after ? sanitizeHooks(hooks.after['*'], action.service) : null
38
- const errorWildcardHook = hooks.error ? sanitizeHooks(hooks.error['*'], action.service) : null
39
- const beforeHook = hooks.before ? sanitizeHooks(hooks.before[name], action.service) : null
40
- const afterHook = hooks.after ? sanitizeHooks(hooks.after[name], action.service) : null
41
- const errorHook = hooks.error ? sanitizeHooks(hooks.error[name], action.service) : null
42
-
43
- if (beforeWildcardHook || afterWildcardHook || errorWildcardHook || beforeHook || afterHook || errorHook) {
45
+ const name = action.shortName;
46
+ const hooks = (action.service && action.service.schema) ? action.service.schema.hooks : null;
47
+
48
+ if (hooks || action.hooks) {
49
+ // Wildcard hooks
50
+ const beforeWildcardHook = hooks && hooks.before ? sanitizeHooks(hooks.before['*'], action.service) : null;
51
+ const afterWildcardHook = hooks && hooks.after ? sanitizeHooks(hooks.after['*'], action.service) : null;
52
+ const errorWildcardHook = hooks && hooks.error ? sanitizeHooks(hooks.error['*'], action.service) : null;
53
+
54
+ // Action name-related hooks
55
+ const beforeHook = hooks && hooks.before ? sanitizeHooks(hooks.before[name], action.service) : null;
56
+ const afterHook = hooks && hooks.after ? sanitizeHooks(hooks.after[name], action.service) : null;
57
+ const errorHook = hooks && hooks.error ? sanitizeHooks(hooks.error[name], action.service) : null;
58
+
59
+ // Hooks in action definition
60
+ const actionBeforeHook = action.hooks && action.hooks.before ? sanitizeHooks(action.hooks.before, action.service) : null;
61
+ const actionAfterHook = action.hooks && action.hooks.after ? sanitizeHooks(action.hooks.after, action.service) : null;
62
+ const actionErrorHook = action.hooks && action.hooks.error ? sanitizeHooks(action.hooks.error, action.service) : null;
63
+
64
+ if (
65
+ beforeWildcardHook ||
66
+ afterWildcardHook ||
67
+ errorWildcardHook ||
68
+ beforeHook ||
69
+ afterHook ||
70
+ errorHook ||
71
+ actionBeforeHook ||
72
+ actionAfterHook ||
73
+ actionErrorHook
74
+ ) {
44
75
  return function actionHookMiddleware (context, serviceInjections) {
45
- let promise = Promise.resolve()
76
+ let promise = Promise.resolve();
46
77
 
47
78
  // before all hook
48
79
  if (beforeWildcardHook) {
49
- promise = promise.then(() => callHook(beforeWildcardHook, action.service, context))
80
+ promise = promise.then(() => callHook(beforeWildcardHook, action.service, context));
50
81
  }
51
82
 
52
83
  // Before hook
53
84
  if (beforeHook) {
54
- promise = promise.then(() => callHook(beforeHook, action.service, context))
85
+ promise = promise.then(() => callHook(beforeHook, action.service, context));
86
+ }
87
+
88
+ // Before hook
89
+ if (actionBeforeHook) {
90
+ promise = promise.then(() => callHook(actionBeforeHook, action.service, context));
55
91
  }
56
92
 
57
93
  // Call action handler
58
- promise = promise.then(() => handler(context, serviceInjections))
94
+ promise = promise.then(() => handler(context, serviceInjections));
95
+
96
+ // After hook in action definition
97
+ if (actionAfterHook) {
98
+ promise = promise.then(result => callHook(actionAfterHook, action.service, context, result));
99
+ }
59
100
 
60
101
  // After hook
61
102
  if (afterHook) {
62
- promise = promise.then(result => callHook(afterHook, action.service, context, result))
103
+ promise = promise.then(result => callHook(afterHook, action.service, context, result));
63
104
  }
64
105
 
65
106
  // After wildcard hook
66
107
  if (afterWildcardHook) {
67
- promise = promise.then(result => callHook(afterWildcardHook, action.service, context, result))
108
+ promise = promise.then(result => callHook(afterWildcardHook, action.service, context, result));
109
+ }
110
+
111
+ // Error hooks
112
+ // Error hook in action definition
113
+ if (actionErrorHook) {
114
+ promise = promise.catch(error => callErrorHook(actionErrorHook, action.service, context, error));
68
115
  }
69
116
 
70
117
  // Error hook
71
118
  if (errorHook) {
72
- promise = promise.catch(error => callHook(errorHook, action.service, context, error))
119
+ promise = promise.catch(error => callErrorHook(errorHook, action.service, context, error));
73
120
  }
121
+
74
122
  // Error wildcard hook
75
123
  if (errorWildcardHook) {
76
- promise = promise.catch(error => callHook(errorWildcardHook, action.service, context, error))
124
+ promise = promise.catch(error => callErrorHook(errorWildcardHook, action.service, context, error));
77
125
  }
78
126
 
79
- return promise
80
- }
127
+ return promise;
128
+ };
81
129
  }
82
130
  }
83
- return handler
84
- }
131
+ return handler;
132
+ };
85
133
 
86
134
  module.exports = () => {
87
135
  return {
88
136
  localAction: makeActionHookMiddleware
89
- }
90
- }
137
+ };
138
+ };