@fincity/kirun-js 2.3.2 → 2.4.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fincity/kirun-js",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "description": "Javascript Runtime for Kinetic Instructions",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/index.js",
@@ -35,12 +35,12 @@
35
35
  "@parcel/transformer-typescript-types": "^2.7.0",
36
36
  "@tsconfig/recommended": "^1.0.1",
37
37
  "@types/jest": "^28.1.8",
38
+ "jest": "^29.5.0",
38
39
  "parcel": "^2.7.0",
39
40
  "prettier": "2.7.1",
40
- "typescript": "^5.1.3",
41
+ "ts-jest": "^29.1.0",
41
42
  "ts-loader": "^9.3.1",
42
- "jest": "^29.5.0",
43
- "ts-jest": "^29.1.0"
43
+ "typescript": "^5.1.3"
44
44
  },
45
45
  "jest": {
46
46
  "transform": {
@@ -22,6 +22,10 @@ export abstract class AbstractDateFunction extends AbstractFunction {
22
22
  public static readonly PARAMETER_DATE_NAME: string = 'isoDate';
23
23
 
24
24
  public static readonly PARAMETER_FIELD_NAME: string = 'value';
25
+
26
+ public static readonly PARAMETER_INT_NAME: string = "intValue";
27
+
28
+ public static readonly PARAMETER_UNIT_NAME: string = "unit";
25
29
 
26
30
  protected static readonly PARAMETER_DATE: Parameter = new Parameter(
27
31
  AbstractDateFunction.PARAMETER_DATE_NAME,
@@ -33,6 +37,17 @@ export abstract class AbstractDateFunction extends AbstractFunction {
33
37
  Schema.ofInteger(this.PARAMETER_FIELD_NAME)
34
38
  );
35
39
 
40
+ protected static readonly PARAMETER_INT : Parameter = new Parameter(
41
+ AbstractDateFunction.PARAMETER_INT_NAME,
42
+ Schema.ofInteger(this.PARAMETER_INT_NAME)
43
+ );
44
+
45
+ protected static readonly PARAMETER_UNIT : Parameter = new Parameter(
46
+ AbstractDateFunction.PARAMETER_UNIT_NAME,
47
+ Schema.ofString(this.PARAMETER_UNIT_NAME)
48
+ .setEnums(["YEAR" , "MONTH" , "DAY" , "HOUR" , "MINUTE" , "SECOND" , "MILLISECOND"])
49
+ );
50
+
36
51
  protected static readonly EVENT_INT: Event = new Event(
37
52
  Event.OUTPUT,
38
53
  MapUtil.of(
@@ -41,6 +56,22 @@ export abstract class AbstractDateFunction extends AbstractFunction {
41
56
  ),
42
57
  );
43
58
 
59
+ protected static readonly EVENT_BOOLEAN: Event = new Event(
60
+ Event.OUTPUT,
61
+ MapUtil.of(
62
+ AbstractDateFunction.EVENT_RESULT_NAME,
63
+ Schema.ofBoolean(AbstractDateFunction.EVENT_RESULT_NAME)
64
+ )
65
+ );
66
+
67
+ protected static readonly EVENT_DATE : Event = new Event(
68
+ Event.OUTPUT,
69
+ MapUtil.of(
70
+ AbstractDateFunction.EVENT_RESULT_NAME,
71
+ Schema.ofString(AbstractDateFunction.EVENT_RESULT_NAME).setRef(Namespaces.DATE + ".timeStamp")
72
+ )
73
+ );
74
+
44
75
  public getSignature(): FunctionSignature {
45
76
  return this.signature;
46
77
  }
@@ -79,7 +110,7 @@ export abstract class AbstractDateFunction extends AbstractFunction {
79
110
  }
80
111
 
81
112
 
82
- })(Namespaces.DATE, name, AbstractDateFunction.EVENT_INT, AbstractDateFunction.PARAMETER_DATE)];
113
+ })(Namespaces.DATE, name, AbstractDateFunction.EVENT_BOOLEAN, AbstractDateFunction.PARAMETER_DATE)];
83
114
  }
84
115
 
85
116
  public static ofEntryDateAndIntegerOutput(name: string, fun: (date: string) => number) : [string, Function] {
@@ -101,4 +132,31 @@ export abstract class AbstractDateFunction extends AbstractFunction {
101
132
  })(Namespaces.DATE, name, AbstractDateFunction.EVENT_INT, AbstractDateFunction.PARAMETER_DATE)];
102
133
  }
103
134
 
104
- }
135
+ public static ofEntryDateWithIntegerUnitWithOutputName( functionName: string,
136
+ func: (date: string, amount: number, unit: string) => string): [string, Function] {
137
+ return [functionName, new (class extends AbstractDateFunction {
138
+ constructor(namespace: string, functionName: string, event: Event, ...parameter: Parameter[]) {
139
+ super(namespace, functionName, event, ...parameter);
140
+ }
141
+
142
+ protected async internalExecute(context: FunctionExecutionParameters): Promise<FunctionOutput> {
143
+
144
+ const date = context.getArguments()?.get(AbstractDateFunction.PARAMETER_DATE_NAME);
145
+
146
+ if(isNullValue(date) || !ValidDateTimeUtil.validate(date))
147
+ throw new KIRuntimeException("Please provide a valid date object");
148
+
149
+ const value = context.getArguments()?.get(AbstractDateFunction.PARAMETER_INT_NAME);
150
+
151
+ const unit = context.getArguments()?.get(AbstractDateFunction.PARAMETER_UNIT_NAME);
152
+
153
+ return new FunctionOutput([EventResult.outputOf(MapUtil.of( AbstractDateFunction.EVENT_RESULT_NAME, func(date, value , unit)))]);
154
+
155
+ }
156
+ })(Namespaces.DATE, functionName, AbstractDateFunction.EVENT_DATE,
157
+ AbstractDateFunction.PARAMETER_DATE, AbstractDateFunction.PARAMETER_INT, AbstractDateFunction.PARAMETER_UNIT)];
158
+
159
+
160
+ }
161
+
162
+ }
@@ -3,12 +3,33 @@ import { Repository } from "../../../Repository";
3
3
  import { MapUtil } from "../../../util/MapUtil";
4
4
  import { AbstractDateFunction } from "./AbstractDateFunction";
5
5
  import { Function } from '../../Function';
6
+ import { KIRuntimeException } from "../../../exception/KIRuntimeException";
7
+ import mapEntry from '../../../util/mapEntry';
8
+ import { DateToEpoch } from "./DateToEpoch";
9
+ import { DifferenceOfTimestamps } from "./DifferenceOfTimestamps";
10
+ import { EpochToDate } from "./EpochToDate";
11
+ import { GetCurrentTimeStamp } from "./GetCurrentTimeStamp";
12
+ import { GetTimeAsArray } from "./GetTimeAsArray";
13
+ import { GetTimeAsObject } from "./GetTimeAsObject";
14
+ import { IsValidISODate } from "./IsValidISODate";
15
+ import { MaximumTimestamp } from "./MaximumTimestamp";
16
+ import { MinimumTimestamp } from "./MinimumTimestamp";
6
17
 
7
18
 
8
19
  export class DateFunctionRepository implements Repository<Function> {
9
20
 
10
21
  private static readonly repoMap: Map<string, Function> = MapUtil.ofArrayEntries(
11
22
 
23
+ mapEntry(new DateToEpoch()),
24
+ mapEntry(new EpochToDate()),
25
+ mapEntry(new GetCurrentTimeStamp()),
26
+ mapEntry(new DifferenceOfTimestamps()),
27
+ mapEntry(new IsValidISODate()),
28
+ mapEntry(new GetTimeAsArray()),
29
+ mapEntry(new GetTimeAsObject()),
30
+ mapEntry(new MaximumTimestamp()),
31
+ mapEntry(new MinimumTimestamp()),
32
+
12
33
  AbstractDateFunction.ofEntryDateAndBooleanOutput("IsLeapYear", date => {
13
34
  const year = new Date(date).getUTCFullYear();
14
35
  return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
@@ -20,7 +41,7 @@ export class DateFunctionRepository implements Repository<Function> {
20
41
 
21
42
  AbstractDateFunction.ofEntryDateAndIntegerOutput("GetFullYear", date => new Date(date).getUTCFullYear()),
22
43
 
23
- AbstractDateFunction.ofEntryDateAndIntegerOutput("GetMonth", date => new Date(date).getUTCMonth() + 1),
44
+ AbstractDateFunction.ofEntryDateAndIntegerOutput("GetMonth", date => new Date(date).getUTCMonth()),
24
45
 
25
46
  AbstractDateFunction.ofEntryDateAndIntegerOutput("GetHours", date => new Date(date).getUTCHours()),
26
47
 
@@ -31,13 +52,95 @@ export class DateFunctionRepository implements Repository<Function> {
31
52
  AbstractDateFunction.ofEntryDateAndIntegerOutput("GetMilliSeconds", date => new Date(date).getUTCMilliseconds()),
32
53
 
33
54
  AbstractDateFunction.ofEntryDateAndIntegerOutput("GetTime" , date => new Date(date).getTime()),
34
-
55
+
56
+ AbstractDateFunction.ofEntryDateWithIntegerUnitWithOutputName("AddTime",
57
+ (date , value , unit) => this.changeAmountToUnit(date, unit, value, true)
58
+ ),
59
+
60
+ AbstractDateFunction.ofEntryDateWithIntegerUnitWithOutputName("SubtractTime",
61
+ (date , value , unit) => this.changeAmountToUnit(date, unit, value, false)
62
+ )
35
63
  );
36
64
 
37
65
  private static readonly filterableNames = Array.from(
38
66
  DateFunctionRepository.repoMap.values(),
39
67
  ).map((e) => e.getSignature().getFullName());
68
+
69
+ private static changeAmountToUnit(inputDate: string , unit: string, value: number, isAdd: boolean): string{
70
+
71
+ const amount = isAdd ? value : -1 * value;
72
+
73
+ const date = this.getFullUTCDate(inputDate);
74
+ const originalOffset = this.getTimezoneOffset(inputDate);
75
+
76
+ switch(unit){
77
+
78
+ case "MILLISECOND" : date.setMilliseconds(date.getMilliseconds() + amount);
79
+ break;
80
+ case "SECOND" : date.setSeconds(date.getSeconds() + amount);
81
+ break;
82
+ case "MINUTE" : date.setMinutes(date.getMinutes() + amount);
83
+ break;
84
+ case "HOUR" : date.setHours(date.getHours() + amount);
85
+ break;
86
+ case "DAY" : date.setDate(date.getDate() + amount);
87
+ break;
88
+ case "MONTH" : date.setMonth(date.getMonth() + amount);
89
+ break;
90
+ case "YEAR" : date.setFullYear(date.getFullYear() + amount);
91
+ break;
92
+ default :
93
+ throw new KIRuntimeException("No such unit: " + unit)
94
+
95
+ }
96
+
97
+ return this.formatDate(date, originalOffset);
98
+ }
40
99
 
100
+ private static getTimezoneOffset(dateString: string): string {
101
+ const lastChar = dateString.charAt(dateString.length - 1);
102
+ if (lastChar === 'Z') return '+00:00';
103
+
104
+ const offsetStart = dateString.indexOf('+') !== -1 ? dateString.lastIndexOf('+') : dateString.lastIndexOf('-');
105
+ if (offsetStart === -1) return '+00:00';
106
+
107
+ let offset = dateString.substring(offsetStart);
108
+ if (offset.length === 3) {
109
+ offset = offset.substring(0, 1) + '0' + offset.substring(1) + ':00';
110
+ } else if (offset.length === 5) {
111
+ offset = offset.substring(0, 3) + ':' + offset.substring(3);
112
+ }
113
+
114
+ return offset;
115
+ }
116
+
117
+ private static getFullUTCDate(inputDate:string): Date {
118
+
119
+ if(inputDate.lastIndexOf('+') !== -1)
120
+ inputDate = inputDate.substring(0, inputDate.lastIndexOf('+')) + 'Z';
121
+ else if(inputDate.lastIndexOf('-') !== -1)
122
+ inputDate = inputDate.substring(0, inputDate.lastIndexOf('-')) + 'Z';
123
+
124
+ const date: Date = new Date(inputDate);
125
+
126
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1,
127
+ date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(),
128
+ date.getUTCSeconds(), date.getUTCMilliseconds()));
129
+ }
130
+
131
+ private static formatDate(date: Date, offset: string): string {
132
+ const pad = (num: number) => num.toString().padStart(2, '0');
133
+
134
+ const year = date.getUTCMonth() === 0 ? date.getUTCFullYear() - 1 : date.getUTCFullYear();
135
+ const month = pad(date.getUTCMonth() === 0 ? 12 : date.getUTCMonth());
136
+ const day = pad(date.getUTCDate());
137
+ const hours = pad(date.getUTCHours());
138
+ const minutes = pad(date.getUTCMinutes());
139
+ const seconds = pad(date.getUTCSeconds());
140
+ const milliseconds = pad(date.getUTCMilliseconds());
141
+
142
+ return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}${offset}`;
143
+ }
41
144
 
42
145
  find(namespace: string, name: string): Promise<Function | undefined> {
43
146
  if (namespace != Namespaces.DATE) {
@@ -22,17 +22,17 @@ const functionObjectsIndex: { [key: string]: AbstractFunction } = {
22
22
  SchemaType.FLOAT,
23
23
  SchemaType.DOUBLE,
24
24
  ),
25
- ACosine: new GenericMathFunction('ArcCosine', (v) => Math.acos(v)),
26
- ASine: new GenericMathFunction('ArcSine', (v) => Math.asin(v)),
27
- ATangent: new GenericMathFunction('ArcTangent', (v) => Math.atan(v)),
25
+ ArcCosine: new GenericMathFunction('ArcCosine', (v) => Math.acos(v)),
26
+ ArcSine: new GenericMathFunction('ArcSine', (v) => Math.asin(v)),
27
+ ArcTangent: new GenericMathFunction('ArcTangent', (v) => Math.atan(v)),
28
28
  Ceiling: new GenericMathFunction('Ceiling', (v) => Math.ceil(v)),
29
29
  Cosine: new GenericMathFunction('Cosine', (v) => Math.cos(v)),
30
- CosineH: new GenericMathFunction('HyperbolicCosine', (v) => Math.cosh(v)),
30
+ HyperbolicCosine: new GenericMathFunction('HyperbolicCosine', (v) => Math.cosh(v)),
31
31
  CubeRoot: new GenericMathFunction('CubeRoot', (v) => Math.cbrt(v)),
32
32
  Exponential: new GenericMathFunction('Exponential', (v) => Math.exp(v)),
33
- Expm1: new GenericMathFunction('ExponentialMinus1', (v) => Math.expm1(v)),
33
+ ExponentialMinus1: new GenericMathFunction('ExponentialMinus1', (v) => Math.expm1(v)),
34
34
  Floor: new GenericMathFunction('Floor', (v) => Math.floor(v)),
35
- Log: new GenericMathFunction('LogNatural', (v) => Math.log(v)),
35
+ LogNatural: new GenericMathFunction('LogNatural', (v) => Math.log(v)),
36
36
  Log10: new GenericMathFunction('Log10', (v) => Math.log10(v)),
37
37
  Round: new GenericMathFunction(
38
38
  'Round',
@@ -42,13 +42,13 @@ const functionObjectsIndex: { [key: string]: AbstractFunction } = {
42
42
  SchemaType.LONG,
43
43
  ),
44
44
  Sine: new GenericMathFunction('Sine', (v) => Math.sin(v)),
45
- SineH: new GenericMathFunction('HyperbolicSine', (v) => Math.sinh(v)),
45
+ HyperbolicSine: new GenericMathFunction('HyperbolicSine', (v) => Math.sinh(v)),
46
46
  Tangent: new GenericMathFunction('Tangent', (v) => Math.tan(v)),
47
- TangentH: new GenericMathFunction('HyperbolicTangent', (v) => Math.tanh(v)),
47
+ HyperbolicTangent: new GenericMathFunction('HyperbolicTangent', (v) => Math.tanh(v)),
48
48
  ToDegrees: new GenericMathFunction('ToDegrees', (v) => v * (Math.PI / 180)),
49
49
  ToRadians: new GenericMathFunction('ToRadians', (v) => v * (180 / Math.PI)),
50
50
  SquareRoot: new GenericMathFunction('SquareRoot', (v) => Math.sqrt(v)),
51
- ArcTangent: new GenericMathFunction('ArcTangent2', (v1, v2) => Math.atan2(v1, v2!), 2),
51
+ ArcTangent2: new GenericMathFunction('ArcTangent2', (v1, v2) => Math.atan2(v1, v2!), 2),
52
52
  Power: new GenericMathFunction('Power', (v1, v2) => Math.pow(v1, v2!), 2),
53
53
  Add: new Add(),
54
54
  Hypotenuse: new Hypotenuse(),