bpmn-elements 15.0.3 → 16.1.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 (39) hide show
  1. package/README.md +1 -1
  2. package/dist/Environment.js +1 -1
  3. package/dist/Scripts.js +2 -2
  4. package/dist/activity/Activity.js +1 -1
  5. package/dist/condition.js +65 -0
  6. package/dist/eventDefinitions/ConditionalEventDefinition.js +101 -106
  7. package/dist/eventDefinitions/ErrorEventDefinition.js +2 -2
  8. package/dist/eventDefinitions/TimerEventDefinition.js +2 -0
  9. package/dist/eventDefinitions/index.js +76 -0
  10. package/dist/events/BoundaryEvent.js +3 -2
  11. package/dist/events/index.js +67 -55
  12. package/dist/flows/SequenceFlow.js +4 -37
  13. package/dist/flows/index.js +27 -0
  14. package/dist/gateways/index.js +54 -44
  15. package/dist/index.js +39 -64
  16. package/dist/process/Process.js +3 -2
  17. package/dist/tasks/index.js +101 -88
  18. package/eventDefinitions.d.ts +1 -0
  19. package/flows.d.ts +1 -0
  20. package/package.json +21 -6
  21. package/src/Environment.js +1 -1
  22. package/src/activity/Activity.js +1 -1
  23. package/src/condition.js +58 -0
  24. package/src/eventDefinitions/ConditionalEventDefinition.js +96 -106
  25. package/src/eventDefinitions/ErrorEventDefinition.js +2 -2
  26. package/src/eventDefinitions/TimerEventDefinition.js +2 -0
  27. package/src/eventDefinitions/index.js +23 -0
  28. package/src/events/BoundaryEvent.js +5 -2
  29. package/src/events/index.js +18 -5
  30. package/src/flows/SequenceFlow.js +3 -38
  31. package/src/flows/index.js +5 -0
  32. package/src/gateways/index.js +15 -4
  33. package/src/index.js +16 -30
  34. package/src/process/Process.js +3 -2
  35. package/src/tasks/index.js +26 -8
  36. package/types/index.d.ts +31 -25
  37. package/types/types.d.ts +52 -1
  38. package/dist/ExtensionsMapper.js +0 -41
  39. package/dist/iso-duration.js +0 -88
@@ -0,0 +1,23 @@
1
+ import CancelEventDefinition from './CancelEventDefinition.js';
2
+ import CompensateEventDefinition from './CompensateEventDefinition.js';
3
+ import ConditionalEventDefinition from './ConditionalEventDefinition.js';
4
+ import ErrorEventDefinition from './ErrorEventDefinition.js';
5
+ import EscalationEventDefinition from './EscalationEventDefinition.js';
6
+ import LinkEventDefinition from './LinkEventDefinition.js';
7
+ import MessageEventDefinition from './MessageEventDefinition.js';
8
+ import SignalEventDefinition from './SignalEventDefinition.js';
9
+ import TerminateEventDefinition from './TerminateEventDefinition.js';
10
+ import TimerEventDefinition from './TimerEventDefinition.js';
11
+
12
+ export {
13
+ CancelEventDefinition,
14
+ CompensateEventDefinition,
15
+ ConditionalEventDefinition,
16
+ ErrorEventDefinition,
17
+ EscalationEventDefinition,
18
+ LinkEventDefinition,
19
+ MessageEventDefinition,
20
+ SignalEventDefinition,
21
+ TerminateEventDefinition,
22
+ TimerEventDefinition,
23
+ };
@@ -69,7 +69,11 @@ BoundaryEventBehaviour.prototype.execute = function execute(executeMessage) {
69
69
  const execQ = broker.assertQueue(`_bound-execution-${executionId}`, { durable: false, autoDelete: true });
70
70
  broker.bindQueue(execQ.name, 'execution', 'execute.detach');
71
71
  broker.bindQueue(execQ.name, 'execution', 'execute.bound.completed');
72
- broker.bindQueue(execQ.name, 'execution', 'execute.repeat');
72
+
73
+ if (!this.cancelActivity) {
74
+ broker.bindQueue(execQ.name, 'execution', 'execute.repeat');
75
+ }
76
+
73
77
  if (eventDefinitionExecution && !this.environment.settings.strict) {
74
78
  broker.bindQueue(execQ.name, 'execution', 'execute.expect');
75
79
  }
@@ -226,7 +230,6 @@ BoundaryEventBehaviour.prototype._onApiMessage = function onApiMessage(_, messag
226
230
  };
227
231
 
228
232
  BoundaryEventBehaviour.prototype._onRepeatMessage = function onRepeatMessage(_, message) {
229
- if (this.cancelActivity) return;
230
233
  const executeMessage = this[kExecuteMessage];
231
234
  const repeat = message.content.repeat;
232
235
  this.broker
@@ -1,5 +1,18 @@
1
- export * from './BoundaryEvent.js';
2
- export * from './EndEvent.js';
3
- export * from './IntermediateCatchEvent.js';
4
- export * from './IntermediateThrowEvent.js';
5
- export * from './StartEvent.js';
1
+ import BoundaryEvent, { BoundaryEventBehaviour } from './BoundaryEvent.js';
2
+ import EndEvent, { EndEventBehaviour } from './EndEvent.js';
3
+ import IntermediateCatchEvent, { IntermediateCatchEventBehaviour } from './IntermediateCatchEvent.js';
4
+ import IntermediateThrowEvent, { IntermediateThrowEventBehaviour } from './IntermediateThrowEvent.js';
5
+ import StartEvent, { StartEventBehaviour } from './StartEvent.js';
6
+
7
+ export {
8
+ BoundaryEvent,
9
+ BoundaryEventBehaviour,
10
+ EndEvent,
11
+ EndEventBehaviour,
12
+ IntermediateCatchEvent,
13
+ IntermediateCatchEventBehaviour,
14
+ IntermediateThrowEvent,
15
+ IntermediateThrowEventBehaviour,
16
+ StartEvent,
17
+ StartEventBehaviour,
18
+ };
@@ -1,8 +1,8 @@
1
- import ExecutionScope from '../activity/ExecutionScope.js';
2
1
  import { cloneParent, cloneContent } from '../messageHelper.js';
3
2
  import { getUniqueId } from '../shared.js';
4
3
  import { EventBroker } from '../EventBroker.js';
5
4
  import { FlowApi } from '../Api.js';
5
+ import { ScriptCondition, ExpressionCondition } from '../condition.js';
6
6
 
7
7
  const kCounters = Symbol.for('counters');
8
8
 
@@ -29,7 +29,6 @@ function SequenceFlow(flowDef, { environment }) {
29
29
  discard: 0,
30
30
  };
31
31
 
32
- environment.registerScript(this);
33
32
  const { broker, on, once, waitFor, emitFatal } = new EventBroker(this, { prefix: 'flow', durable: true, autoDelete: false });
34
33
  this.broker = broker;
35
34
  this.on = on;
@@ -37,6 +36,8 @@ function SequenceFlow(flowDef, { environment }) {
37
36
  this.waitFor = waitFor;
38
37
  this.emitFatal = emitFatal;
39
38
 
39
+ environment.registerScript(this);
40
+
40
41
  logger.debug(`<${id}> init, <${sourceId}> -> <${targetId}>`);
41
42
  }
42
43
 
@@ -167,39 +168,3 @@ SequenceFlow.prototype._publishEvent = function publishEvent(action, content) {
167
168
 
168
169
  this.broker.publish('event', `flow.${action}`, eventContent, { type: action });
169
170
  };
170
-
171
- function ScriptCondition(owner, script, language) {
172
- this.type = 'script';
173
- this.language = language;
174
- this._owner = owner;
175
- this._script = script;
176
- }
177
-
178
- ScriptCondition.prototype.execute = function execute(message, callback) {
179
- const owner = this._owner;
180
- try {
181
- return this._script.execute(ExecutionScope(owner, message), callback);
182
- } catch (err) {
183
- if (!callback) throw err;
184
- owner.logger.error(`<${owner.id}>`, err);
185
- callback(err);
186
- }
187
- };
188
-
189
- function ExpressionCondition(owner, expression) {
190
- this.type = 'expression';
191
- this.expression = expression;
192
- this._owner = owner;
193
- }
194
-
195
- ExpressionCondition.prototype.execute = function execute(message, callback) {
196
- const owner = this._owner;
197
- try {
198
- const result = owner.environment.resolveExpression(this.expression, owner.createMessage(message));
199
- if (callback) return callback(null, result);
200
- return result;
201
- } catch (err) {
202
- if (callback) return callback(err);
203
- throw err;
204
- }
205
- };
@@ -0,0 +1,5 @@
1
+ import Association from './Association.js';
2
+ import MessageFlow from './MessageFlow.js';
3
+ import SequenceFlow from './SequenceFlow.js';
4
+
5
+ export { Association, MessageFlow, SequenceFlow };
@@ -1,4 +1,15 @@
1
- export * from './EventBasedGateway.js';
2
- export * from './ExclusiveGateway.js';
3
- export * from './InclusiveGateway.js';
4
- export * from './ParallelGateway.js';
1
+ import EventBasedGateway, { EventBasedGatewayBehaviour } from './EventBasedGateway.js';
2
+ import ExclusiveGateway, { ExclusiveGatewayBehaviour } from './ExclusiveGateway.js';
3
+ import InclusiveGateway, { InclusiveGatewayBehaviour } from './InclusiveGateway.js';
4
+ import ParallelGateway, { ParallelGatewayBehaviour } from './ParallelGateway.js';
5
+
6
+ export {
7
+ EventBasedGateway,
8
+ EventBasedGatewayBehaviour,
9
+ ExclusiveGateway,
10
+ ExclusiveGatewayBehaviour,
11
+ InclusiveGateway,
12
+ InclusiveGatewayBehaviour,
13
+ ParallelGateway,
14
+ ParallelGatewayBehaviour,
15
+ };
package/src/index.js CHANGED
@@ -1,52 +1,38 @@
1
1
  import Activity from './activity/Activity.js';
2
- import Association from './flows/Association.js';
3
- import BoundaryEvent from './events/BoundaryEvent.js';
4
2
  import BpmnError from './error/BpmnError.js';
5
- import CallActivity from './tasks/CallActivity.js';
6
- import CancelEventDefinition from './eventDefinitions/CancelEventDefinition.js';
7
- import CompensateEventDefinition from './eventDefinitions/CompensateEventDefinition.js';
8
- import ConditionalEventDefinition from './eventDefinitions/ConditionalEventDefinition.js';
9
3
  import Context from './Context.js';
10
4
  import DataObject from './io/EnvironmentDataObject.js';
11
5
  import DataStore from './io/EnvironmentDataStore.js';
12
6
  import DataStoreReference from './io/EnvironmentDataStoreReference.js';
13
7
  import Definition from './definition/Definition.js';
14
8
  import Dummy from './activity/Dummy.js';
15
- import EndEvent from './events/EndEvent.js';
16
9
  import Environment from './Environment.js';
17
- import ErrorEventDefinition from './eventDefinitions/ErrorEventDefinition.js';
18
10
  import Escalation from './activity/Escalation.js';
19
- import EscalationEventDefinition from './eventDefinitions/EscalationEventDefinition.js';
20
- import EventBasedGateway from './gateways/EventBasedGateway.js';
21
- import ExclusiveGateway from './gateways/ExclusiveGateway.js';
22
- import InclusiveGateway from './gateways/InclusiveGateway.js';
23
11
  import InputOutputSpecification from './io/InputOutputSpecification.js';
24
- import IntermediateCatchEvent from './events/IntermediateCatchEvent.js';
25
- import IntermediateThrowEvent from './events/IntermediateThrowEvent.js';
26
12
  import Lane from './process/Lane.js';
27
- import LinkEventDefinition from './eventDefinitions/LinkEventDefinition.js';
28
13
  import LoopCharacteristics from './tasks/LoopCharacteristics.js';
29
14
  import Message from './activity/Message.js';
30
- import MessageEventDefinition from './eventDefinitions/MessageEventDefinition.js';
31
- import MessageFlow from './flows/MessageFlow.js';
32
- import ParallelGateway from './gateways/ParallelGateway.js';
33
15
  import Process from './process/Process.js';
34
16
  import Properties from './io/Properties.js';
35
- import ReceiveTask from './tasks/ReceiveTask.js';
36
- import ScriptTask from './tasks/ScriptTask.js';
37
- import SequenceFlow from './flows/SequenceFlow.js';
38
17
  import ServiceImplementation from './tasks/ServiceImplementation.js';
39
- import ServiceTask from './tasks/ServiceTask.js';
40
18
  import Signal from './activity/Signal.js';
41
- import SignalEventDefinition from './eventDefinitions/SignalEventDefinition.js';
42
- import SignalTask from './tasks/SignalTask.js';
43
19
  import StandardLoopCharacteristics from './tasks/StandardLoopCharacteristics.js';
44
- import StartEvent from './events/StartEvent.js';
45
- import SubProcess from './tasks/SubProcess.js';
46
- import Task from './tasks/Task.js';
47
- import TerminateEventDefinition from './eventDefinitions/TerminateEventDefinition.js';
48
- import TimerEventDefinition from './eventDefinitions/TimerEventDefinition.js';
49
- import Transaction from './tasks/Transaction.js';
20
+ import { Association, MessageFlow, SequenceFlow } from './flows/index.js';
21
+ import { BoundaryEvent, EndEvent, IntermediateCatchEvent, IntermediateThrowEvent, StartEvent } from './events/index.js';
22
+ import { EventBasedGateway, ExclusiveGateway, InclusiveGateway, ParallelGateway } from './gateways/index.js';
23
+ import { CallActivity, ReceiveTask, ServiceTask, ScriptTask, SubProcess, SignalTask, Task, Transaction } from './tasks/index.js';
24
+ import {
25
+ CancelEventDefinition,
26
+ CompensateEventDefinition,
27
+ ConditionalEventDefinition,
28
+ EscalationEventDefinition,
29
+ ErrorEventDefinition,
30
+ LinkEventDefinition,
31
+ MessageEventDefinition,
32
+ SignalEventDefinition,
33
+ TerminateEventDefinition,
34
+ TimerEventDefinition,
35
+ } from './eventDefinitions/index.js';
50
36
  import { Timers } from './Timers.js';
51
37
 
52
38
  export { ActivityError, RunError } from './error/Errors.js';
@@ -306,10 +306,11 @@ Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
306
306
  }
307
307
  case 'run.leave': {
308
308
  this[kStatus] = undefined;
309
- this.broker.cancel('_process-api');
309
+ message.ack();
310
+ this._deactivateRunConsumers();
310
311
  const { output, ...rest } = content; // eslint-disable-line no-unused-vars
311
312
  this._publishEvent('leave', rest);
312
- break;
313
+ return;
313
314
  }
314
315
  }
315
316
 
@@ -1,8 +1,26 @@
1
- export * from './CallActivity.js';
2
- export * from './ReceiveTask.js';
3
- export * from './ScriptTask.js';
4
- export * from './ServiceTask.js';
5
- export * from './SignalTask.js';
6
- export * from './SubProcess.js';
7
- export * from './Task.js';
8
- export * from './Transaction.js';
1
+ import CallActivity, { CallActivityBehaviour } from './CallActivity.js';
2
+ import ReceiveTask, { ReceiveTaskBehaviour } from './ReceiveTask.js';
3
+ import ScriptTask, { ScriptTaskBehaviour } from './ScriptTask.js';
4
+ import ServiceTask, { ServiceTaskBehaviour } from './ServiceTask.js';
5
+ import SignalTask, { SignalTaskBehaviour } from './SignalTask.js';
6
+ import SubProcess, { SubProcessBehaviour } from './SubProcess.js';
7
+ import Task, { TaskBehaviour } from './Task.js';
8
+ import Transaction from './Transaction.js';
9
+
10
+ export {
11
+ CallActivity,
12
+ CallActivityBehaviour,
13
+ ReceiveTask,
14
+ ReceiveTaskBehaviour,
15
+ ScriptTask,
16
+ ScriptTaskBehaviour,
17
+ ServiceTask,
18
+ ServiceTaskBehaviour,
19
+ SignalTask,
20
+ SignalTaskBehaviour,
21
+ SubProcess,
22
+ SubProcessBehaviour,
23
+ Task,
24
+ TaskBehaviour,
25
+ Transaction,
26
+ };
package/types/index.d.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  export * from './types.js';
2
- import { IActivityBehaviour, ActivityBehaviour, EventDefinition, MessageElement } from './types.js';
2
+ import {
3
+ Association,
4
+ MessageFlow,
5
+ SequenceFlow,
6
+ IActivityBehaviour,
7
+ ActivityBehaviour,
8
+ EventDefinition,
9
+ MessageElement,
10
+ ConditionalEventDefinition,
11
+ TimerEventDefinition,
12
+ } from './types.js';
3
13
 
4
14
  declare module 'bpmn-elements' {
5
15
  export var BoundaryEvent: typeof ActivityBehaviour;
@@ -37,30 +47,7 @@ declare module 'bpmn-elements' {
37
47
  export var MessageEventDefinition: EventDefinition;
38
48
  export var SignalEventDefinition: EventDefinition;
39
49
  export var TerminateEventDefinition: EventDefinition;
40
-
41
- export const enum TimerType {
42
- TimeCycle = 'timeCycle',
43
- TimeDuration = 'timeDuration',
44
- TimeDate = 'timeDate',
45
- }
46
-
47
- type parsedTimer = {
48
- /** Expires at date time */
49
- expireAt?: Date;
50
- /** Repeat number of times */
51
- repeat?: number;
52
- /** Delay in milliseconds */
53
- delay?: number;
54
- };
55
-
56
- export class TimerEventDefinition extends EventDefinition {
57
- /**
58
- * Parse timer type
59
- * @param timerType type of timer
60
- * @param timerValue resolved expression timer string
61
- */
62
- parse(timerType: TimerType, timerValue: string): parsedTimer;
63
- }
50
+ export var TimerEventDefinition: TimerEventDefinition;
64
51
 
65
52
  export class Message extends MessageElement {}
66
53
  export class Signal extends MessageElement {}
@@ -75,6 +62,25 @@ declare module 'bpmn-elements/events' {
75
62
  export var StartEventBehaviour: IActivityBehaviour;
76
63
  }
77
64
 
65
+ declare module 'bpmn-elements/eventDefinitions' {
66
+ export var CancelEventDefinition: EventDefinition;
67
+ export var CompensateEventDefinition: EventDefinition;
68
+ export var ConditionalEventDefinition: ConditionalEventDefinition;
69
+ export var ErrorEventDefinition: EventDefinition;
70
+ export var EscalationEventDefinition: EventDefinition;
71
+ export var LinkEventDefinition: EventDefinition;
72
+ export var MessageEventDefinition: EventDefinition;
73
+ export var SignalEventDefinition: EventDefinition;
74
+ export var TerminateEventDefinition: EventDefinition;
75
+ export var TimerEventDefinition: TimerEventDefinition;
76
+ }
77
+
78
+ declare module 'bpmn-elements/flows' {
79
+ export var Association: Association;
80
+ export var SequenceFlow: SequenceFlow;
81
+ export var MessageFlow: MessageFlow;
82
+ }
83
+
78
84
  declare module 'bpmn-elements/gateways' {
79
85
  export var EventBasedGatewayBehaviour: IActivityBehaviour;
80
86
  export var ExclusiveGatewayBehaviour: IActivityBehaviour;
package/types/types.d.ts CHANGED
@@ -37,7 +37,7 @@ declare interface ElementBrokerMessage extends MessageMessage {
37
37
  }
38
38
 
39
39
  declare class EventDefinition {
40
- constructor(activity: Activity, eventDefinitionElement: SerializableElement);
40
+ constructor(activity: Activity, eventDefinitionElement: SerializableElement, context?: ContextInstance, index?: number);
41
41
  get id(): string;
42
42
  get type(): string;
43
43
  get executionId(): string;
@@ -54,6 +54,57 @@ declare class EventDefinition {
54
54
  execute(executeMessage: ElementBrokerMessage): void;
55
55
  }
56
56
 
57
+ declare const enum TimerType {
58
+ TimeCycle = 'timeCycle',
59
+ TimeDuration = 'timeDuration',
60
+ TimeDate = 'timeDate',
61
+ }
62
+
63
+ type parsedTimer = {
64
+ /** Expires at date time */
65
+ expireAt?: Date;
66
+ /** Repeat number of times */
67
+ repeat?: number;
68
+ /** Delay in milliseconds */
69
+ delay?: number;
70
+ };
71
+
72
+ declare class TimerEventDefinition extends EventDefinition {
73
+ /**
74
+ * Parse timer type
75
+ * @param timerType type of timer
76
+ * @param timerValue resolved expression timer string
77
+ */
78
+ parse(timerType: TimerType, timerValue: string): parsedTimer;
79
+ }
80
+
81
+ declare interface ICondition {
82
+ /** Condition type */
83
+ get type(): string;
84
+ [x: string]: any;
85
+ execute(message: ElementBrokerMessage, callback: CallableFunction): void;
86
+ }
87
+
88
+ declare class ConditionalEventDefinition extends EventDefinition {
89
+ /**
90
+ * Evaluate condition
91
+ * @param message
92
+ * @param callback
93
+ */
94
+ evaluate(message: ElementBrokerMessage, callback: CallableFunction): void;
95
+ /**
96
+ * Handle evaluate result or error
97
+ * @param err Condition evaluation error
98
+ * @param result Result from evaluated condition, completes execution if truthy
99
+ */
100
+ evaluateCallback(err: Error | null, result?: any): void;
101
+ /**
102
+ * Get condition from behaviour
103
+ * @param index Event definition sequence number, used to name registered script
104
+ */
105
+ getCondition(index: number): ICondition | null;
106
+ }
107
+
57
108
  declare abstract class ElementBase {
58
109
  get id(): string;
59
110
  get type(): string;
@@ -1,41 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = ExtensionsMapper;
7
- const kActivated = Symbol.for('activated');
8
- function ExtensionsMapper(context) {
9
- this.context = context;
10
- }
11
- ExtensionsMapper.prototype.get = function get(activity) {
12
- return new Extensions(activity, this.context, this._getExtensions());
13
- };
14
- ExtensionsMapper.prototype._getExtensions = function getExtensions() {
15
- let extensions;
16
- if (!(extensions = this.context.environment.extensions)) return [];
17
- return Object.values(extensions);
18
- };
19
- function Extensions(activity, context, extensions) {
20
- const result = this.extensions = [];
21
- for (const Extension of extensions) {
22
- const extension = Extension(activity, context);
23
- if (extension) result.push(extension);
24
- }
25
- this[kActivated] = false;
26
- }
27
- Object.defineProperty(Extensions.prototype, 'count', {
28
- get() {
29
- return this.extensions.length;
30
- }
31
- });
32
- Extensions.prototype.activate = function activate(message) {
33
- if (this[kActivated]) return;
34
- this[kActivated] = true;
35
- for (const extension of this.extensions) extension.activate(message);
36
- };
37
- Extensions.prototype.deactivate = function deactivate(message) {
38
- if (!this[kActivated]) return;
39
- this[kActivated] = false;
40
- for (const extension of this.extensions) extension.deactivate(message);
41
- };
@@ -1,88 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.end = end;
7
- exports.parse = parse;
8
- exports.toSeconds = toSeconds;
9
- // License MIT @ https://tolu.mit-license.org/
10
-
11
- const numbers = '\\d+';
12
- const fractionalNumbers = ''.concat(numbers, '(?:[\\.,]').concat(numbers, ')?');
13
- const datePattern = '('.concat(numbers, 'Y)?(').concat(numbers, 'M)?(').concat(numbers, 'W)?(').concat(fractionalNumbers, 'D)?');
14
- const timePattern = 'T('.concat(fractionalNumbers, 'H)?(').concat(fractionalNumbers, 'M)?(').concat(fractionalNumbers, 'S)?');
15
- const rPattern = '(?:R('.concat(numbers).concat(')/)?');
16
- const iso8601 = rPattern.concat('P(?:').concat(datePattern, '(?:').concat(timePattern, ')?)');
17
- const objMap = ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'];
18
- const defaultDuration = Object.freeze({
19
- years: 0,
20
- months: 0,
21
- weeks: 0,
22
- days: 0,
23
- hours: 0,
24
- minutes: 0,
25
- seconds: 0
26
- });
27
-
28
- /**
29
- * The ISO8601 regex for matching / testing durations
30
- */
31
- const pattern = new RegExp(iso8601);
32
-
33
- /** Parse PnYnMnDTnHnMnS format to object */
34
- function parse(durationString) {
35
- const matches = durationString.replace(/,/g, '.').match(pattern);
36
- if (!matches) {
37
- throw new RangeError('invalid duration: ' + durationString);
38
- }
39
-
40
- // Slice away repeat and first entry in match-array (the input string)
41
- const slicedMatches = matches.slice(2);
42
- if (slicedMatches.filter(Boolean).length === 0) {
43
- throw new RangeError('invalid duration: ' + durationString);
44
- }
45
- // Check only one fraction is used
46
- if (slicedMatches.filter(v => {
47
- return /\./.test(v || '');
48
- }).length > 1) {
49
- throw new RangeError('Fractions are allowed on the smallest unit in the string, e.g. P0.5D or PT1.0001S but not PT0.5M0.1S: ' + durationString);
50
- }
51
- const result = {};
52
- if (matches[1]) result.repeat = Number(matches[1]);
53
- return slicedMatches.reduce((prev, next, idx) => {
54
- prev[objMap[idx]] = parseFloat(next || '0') || 0;
55
- return prev;
56
- }, result);
57
- }
58
-
59
- /** Convert ISO8601 duration object to an end Date. */
60
- function end(durationInput, startDate) {
61
- const duration = Object.assign({}, defaultDuration, durationInput);
62
- // Create two equal timestamps, add duration to 'then' and return time difference
63
- const timestamp = startDate.getTime();
64
- const then = new Date(timestamp);
65
- then.setFullYear(then.getFullYear() + duration.years);
66
- then.setMonth(then.getMonth() + duration.months);
67
- then.setDate(then.getDate() + duration.days);
68
- // set time as milliseconds to get fractions working for minutes/hours
69
- const hoursInMs = duration.hours * 3600 * 1000;
70
- const minutesInMs = duration.minutes * 60 * 1000;
71
- then.setMilliseconds(then.getMilliseconds() + duration.seconds * 1000 + hoursInMs + minutesInMs);
72
- // Special case weeks
73
- then.setDate(then.getDate() + duration.weeks * 7);
74
- return then;
75
- }
76
-
77
- /** Convert ISO8601 duration object to seconds */
78
- function toSeconds(durationInput, startDate) {
79
- if (startDate === void 0) {
80
- startDate = new Date();
81
- }
82
- const duration = Object.assign({}, defaultDuration, durationInput);
83
- const timestamp = startDate.getTime();
84
- const now = new Date(timestamp);
85
- const then = end(duration, now);
86
- const seconds = (then.getTime() - now.getTime()) / 1000;
87
- return seconds;
88
- }