raain-model 2.6.7 → 2.6.10
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/.cursorignore +10 -0
- package/.github/workflows/ci.yml +29 -0
- package/CHANGELOG.md +166 -0
- package/LICENSE +21 -0
- package/README.md +90 -9
- package/RELEASE_PROCESS.md +111 -0
- package/package.json +10 -8
- package/specs/REQUIREMENTS.md +42 -0
- package/specs/TECHNICAL.md +57 -0
- package/specs/cartesian/Cartesian.spec.ts +82 -0
- package/specs/cartesian/CartesianTools.spec.ts +121 -0
- package/specs/gauge/Gauge.spec.ts +39 -0
- package/specs/organization/Organization.spec.ts +38 -0
- package/specs/polar/Polar.spec.ts +267 -0
- package/specs/quality/Position.spec.ts +18 -0
- package/specs/quality/QualityPointEdgeCases.spec.ts +215 -0
- package/specs/quality/QualityTools.spec.ts +67 -0
- package/specs/quality/SpeedMatrix.spec.ts +214 -0
- package/specs/radar/Radar.spec.ts +129 -0
- package/specs/rain/Rain.spec.ts +334 -0
- package/specs/tsconfig.json +12 -0
- package/{cartesian/CartesianMeasureValue.js → src/cartesian/CartesianMeasureValue.ts} +73 -41
- package/{cartesian/CartesianTools.js → src/cartesian/CartesianTools.ts} +130 -69
- package/src/cartesian/CartesianValue.ts +26 -0
- package/src/cartesian/EarthMap.ts +5 -0
- package/src/cartesian/ICartesianMeasureValue.ts +22 -0
- package/src/cartesian/LatLng.ts +43 -0
- package/src/cartesian/RadarCartesianMeasureValue.ts +32 -0
- package/src/cartesian/RainCartesianMeasureValue.ts +32 -0
- package/src/gauge/GaugeMeasure.ts +42 -0
- package/src/gauge/GaugeNode.ts +133 -0
- package/src/gauge/GaugeNodeMap.ts +55 -0
- package/src/organization/EventNode.ts +43 -0
- package/{organization/Link.js → src/organization/Link.ts} +17 -14
- package/src/organization/Measure.ts +61 -0
- package/{organization/PeopleNode.js → src/organization/PeopleNode.ts} +20 -10
- package/src/organization/RaainNode.ts +205 -0
- package/src/organization/TeamNode.ts +91 -0
- package/{polar/AbstractPolarMeasureValue.js → src/polar/AbstractPolarMeasureValue.ts} +58 -32
- package/src/polar/IPolarMeasureValue.ts +21 -0
- package/{polar/MeasureValuePolarContainer.js → src/polar/MeasureValuePolarContainer.ts} +29 -13
- package/src/polar/PolarFilter.ts +46 -0
- package/{polar/PolarMeasureValue.js → src/polar/PolarMeasureValue.ts} +125 -62
- package/{polar/PolarMeasureValueMap.js → src/polar/PolarMeasureValueMap.ts} +165 -88
- package/src/polar/PolarValue.ts +16 -0
- package/{polar/RadarPolarMeasureValue.js → src/polar/RadarPolarMeasureValue.ts} +34 -21
- package/src/polar/RainPolarMeasureValue.ts +57 -0
- package/{quality/QualityPoint.js → src/quality/QualityPoint.ts} +62 -34
- package/{quality/SpeedMatrix.js → src/quality/SpeedMatrix.ts} +117 -76
- package/{quality/SpeedMatrixContainer.js → src/quality/SpeedMatrixContainer.ts} +210 -103
- package/src/quality/history/CartesianGaugeHistory.ts +23 -0
- package/src/quality/history/CartesianRainHistory.ts +15 -0
- package/src/quality/history/PositionHistory.ts +31 -0
- package/{quality/index.d.ts → src/quality/index.ts} +3 -0
- package/src/quality/position/Position.ts +59 -0
- package/src/quality/position/PositionValue.ts +15 -0
- package/{quality/tools/QualityTools.js → src/quality/tools/QualityTools.ts} +18 -17
- package/src/radar/RadarMeasure.ts +41 -0
- package/{radar/RadarNode.js → src/radar/RadarNode.ts} +41 -19
- package/src/radar/RadarNodeMap.ts +61 -0
- package/src/rain/MergeStrategy.ts +15 -0
- package/src/rain/RainComputation.ts +96 -0
- package/{rain/RainComputationAbstract.js → src/rain/RainComputationAbstract.ts} +135 -69
- package/src/rain/RainComputationMap.ts +139 -0
- package/{rain/RainComputationQuality.js → src/rain/RainComputationQuality.ts} +82 -44
- package/src/rain/RainMeasure.ts +25 -0
- package/{rain/RainNode.js → src/rain/RainNode.ts} +117 -72
- package/tsconfig.json +17 -0
- package/tslint.json +79 -0
- package/typedoc.json +31 -0
- package/cartesian/CartesianMeasureValue.d.ts +0 -40
- package/cartesian/CartesianMeasureValue.js.map +0 -1
- package/cartesian/CartesianTools.d.ts +0 -32
- package/cartesian/CartesianTools.js.map +0 -1
- package/cartesian/CartesianValue.d.ts +0 -14
- package/cartesian/CartesianValue.js +0 -17
- package/cartesian/CartesianValue.js.map +0 -1
- package/cartesian/EarthMap.d.ts +0 -5
- package/cartesian/EarthMap.js +0 -3
- package/cartesian/EarthMap.js.map +0 -1
- package/cartesian/ICartesianMeasureValue.d.ts +0 -23
- package/cartesian/ICartesianMeasureValue.js +0 -3
- package/cartesian/ICartesianMeasureValue.js.map +0 -1
- package/cartesian/LatLng.d.ts +0 -16
- package/cartesian/LatLng.js +0 -34
- package/cartesian/LatLng.js.map +0 -1
- package/cartesian/RadarCartesianMeasureValue.d.ts +0 -17
- package/cartesian/RadarCartesianMeasureValue.js +0 -22
- package/cartesian/RadarCartesianMeasureValue.js.map +0 -1
- package/cartesian/RainCartesianMeasureValue.d.ts +0 -17
- package/cartesian/RainCartesianMeasureValue.js +0 -23
- package/cartesian/RainCartesianMeasureValue.js.map +0 -1
- package/cartesian/index.js +0 -25
- package/cartesian/index.js.map +0 -1
- package/gauge/GaugeMeasure.d.ts +0 -20
- package/gauge/GaugeMeasure.js +0 -30
- package/gauge/GaugeMeasure.js.map +0 -1
- package/gauge/GaugeNode.d.ts +0 -28
- package/gauge/GaugeNode.js +0 -54
- package/gauge/GaugeNode.js.map +0 -1
- package/gauge/GaugeNodeMap.d.ts +0 -24
- package/gauge/GaugeNodeMap.js +0 -40
- package/gauge/GaugeNodeMap.js.map +0 -1
- package/gauge/index.js +0 -20
- package/gauge/index.js.map +0 -1
- package/index.js +0 -24
- package/index.js.map +0 -1
- package/organization/EventNode.d.ts +0 -22
- package/organization/EventNode.js +0 -30
- package/organization/EventNode.js.map +0 -1
- package/organization/IVersion.js +0 -3
- package/organization/IVersion.js.map +0 -1
- package/organization/Link.d.ts +0 -16
- package/organization/Link.js.map +0 -1
- package/organization/Measure.d.ts +0 -22
- package/organization/Measure.js +0 -45
- package/organization/Measure.js.map +0 -1
- package/organization/PeopleNode.d.ts +0 -18
- package/organization/PeopleNode.js.map +0 -1
- package/organization/RaainNode.d.ts +0 -24
- package/organization/RaainNode.js +0 -109
- package/organization/RaainNode.js.map +0 -1
- package/organization/TeamNode.d.ts +0 -22
- package/organization/TeamNode.js +0 -32
- package/organization/TeamNode.js.map +0 -1
- package/organization/index.js +0 -24
- package/organization/index.js.map +0 -1
- package/polar/AbstractPolarMeasureValue.d.ts +0 -29
- package/polar/AbstractPolarMeasureValue.js.map +0 -1
- package/polar/IPolarMeasureValue.d.ts +0 -19
- package/polar/IPolarMeasureValue.js +0 -3
- package/polar/IPolarMeasureValue.js.map +0 -1
- package/polar/MeasureValuePolarContainer.d.ts +0 -19
- package/polar/MeasureValuePolarContainer.js.map +0 -1
- package/polar/PolarFilter.d.ts +0 -16
- package/polar/PolarFilter.js +0 -45
- package/polar/PolarFilter.js.map +0 -1
- package/polar/PolarMeasureValue.d.ts +0 -51
- package/polar/PolarMeasureValue.js.map +0 -1
- package/polar/PolarMeasureValueMap.d.ts +0 -45
- package/polar/PolarMeasureValueMap.js.map +0 -1
- package/polar/PolarValue.d.ts +0 -10
- package/polar/PolarValue.js +0 -12
- package/polar/PolarValue.js.map +0 -1
- package/polar/RadarPolarMeasureValue.d.ts +0 -27
- package/polar/RadarPolarMeasureValue.js.map +0 -1
- package/polar/RainPolarMeasureValue.d.ts +0 -20
- package/polar/RainPolarMeasureValue.js +0 -42
- package/polar/RainPolarMeasureValue.js.map +0 -1
- package/polar/index.js +0 -25
- package/polar/index.js.map +0 -1
- package/quality/QualityPoint.d.ts +0 -37
- package/quality/QualityPoint.js.map +0 -1
- package/quality/SpeedMatrix.d.ts +0 -83
- package/quality/SpeedMatrix.js.map +0 -1
- package/quality/SpeedMatrixContainer.d.ts +0 -102
- package/quality/SpeedMatrixContainer.js.map +0 -1
- package/quality/history/CartesianGaugeHistory.d.ts +0 -15
- package/quality/history/CartesianGaugeHistory.js +0 -14
- package/quality/history/CartesianGaugeHistory.js.map +0 -1
- package/quality/history/CartesianRainHistory.d.ts +0 -9
- package/quality/history/CartesianRainHistory.js +0 -11
- package/quality/history/CartesianRainHistory.js.map +0 -1
- package/quality/history/PositionHistory.d.ts +0 -20
- package/quality/history/PositionHistory.js +0 -17
- package/quality/history/PositionHistory.js.map +0 -1
- package/quality/index.js +0 -26
- package/quality/index.js.map +0 -1
- package/quality/position/Position.d.ts +0 -22
- package/quality/position/Position.js +0 -50
- package/quality/position/Position.js.map +0 -1
- package/quality/position/PositionValue.d.ts +0 -9
- package/quality/position/PositionValue.js +0 -12
- package/quality/position/PositionValue.js.map +0 -1
- package/quality/tools/QualityTools.d.ts +0 -9
- package/quality/tools/QualityTools.js.map +0 -1
- package/radar/RadarMeasure.d.ts +0 -19
- package/radar/RadarMeasure.js +0 -30
- package/radar/RadarMeasure.js.map +0 -1
- package/radar/RadarNode.d.ts +0 -30
- package/radar/RadarNode.js.map +0 -1
- package/radar/RadarNodeMap.d.ts +0 -26
- package/radar/RadarNodeMap.js +0 -44
- package/radar/RadarNodeMap.js.map +0 -1
- package/radar/index.js +0 -20
- package/radar/index.js.map +0 -1
- package/rain/MergeStrategy.d.ts +0 -13
- package/rain/MergeStrategy.js +0 -11
- package/rain/MergeStrategy.js.map +0 -1
- package/rain/RainComputation.d.ts +0 -42
- package/rain/RainComputation.js +0 -65
- package/rain/RainComputation.js.map +0 -1
- package/rain/RainComputationAbstract.d.ts +0 -73
- package/rain/RainComputationAbstract.js.map +0 -1
- package/rain/RainComputationMap.d.ts +0 -37
- package/rain/RainComputationMap.js +0 -58
- package/rain/RainComputationMap.js.map +0 -1
- package/rain/RainComputationQuality.d.ts +0 -40
- package/rain/RainComputationQuality.js.map +0 -1
- package/rain/RainMeasure.d.ts +0 -17
- package/rain/RainMeasure.js +0 -18
- package/rain/RainMeasure.js.map +0 -1
- package/rain/RainNode.d.ts +0 -46
- package/rain/RainNode.js.map +0 -1
- package/rain/index.js +0 -23
- package/rain/index.js.map +0 -1
- /package/{cartesian/index.d.ts → src/cartesian/index.ts} +0 -0
- /package/{gauge/index.d.ts → src/gauge/index.ts} +0 -0
- /package/{index.d.ts → src/index.ts} +0 -0
- /package/{organization/IVersion.d.ts → src/organization/IVersion.ts} +0 -0
- /package/{organization/index.d.ts → src/organization/index.ts} +0 -0
- /package/{polar/index.d.ts → src/polar/index.ts} +0 -0
- /package/{radar/index.d.ts → src/radar/index.ts} +0 -0
- /package/{rain/index.d.ts → src/rain/index.ts} +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import {Link, RaainNode, TeamNode} from '../organization';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a rain gauge station in the RAAIN system.
|
|
5
|
+
* This class manages gauge data collection and configuration.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Used in the API endpoint: api/gauges/:id
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const gaugeNode = new GaugeNode({
|
|
13
|
+
* id: 'gauge1',
|
|
14
|
+
* latitude: 48.8566,
|
|
15
|
+
* longitude: 2.3522,
|
|
16
|
+
* name: 'Paris Gauge',
|
|
17
|
+
* team: teamNode,
|
|
18
|
+
* description: 'Main rain gauge station'
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class GaugeNode extends RaainNode {
|
|
23
|
+
|
|
24
|
+
/** Type identifier for gauge nodes */
|
|
25
|
+
public static TYPE = 'gauge';
|
|
26
|
+
|
|
27
|
+
/** Name of the gauge station */
|
|
28
|
+
public name: string;
|
|
29
|
+
|
|
30
|
+
/** Description of the gauge station */
|
|
31
|
+
public description: string;
|
|
32
|
+
|
|
33
|
+
/** Latitude of the gauge station */
|
|
34
|
+
public latitude: number;
|
|
35
|
+
|
|
36
|
+
/** Longitude of the gauge station */
|
|
37
|
+
public longitude: number;
|
|
38
|
+
|
|
39
|
+
/** Associated team */
|
|
40
|
+
public team: TeamNode;
|
|
41
|
+
|
|
42
|
+
/** Internal configuration storage */
|
|
43
|
+
private configurationAsJSON: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Creates a new GaugeNode instance.
|
|
47
|
+
*
|
|
48
|
+
* @param json - Configuration object
|
|
49
|
+
* @param json.id - Unique identifier
|
|
50
|
+
* @param json.latitude - Latitude of the gauge station
|
|
51
|
+
* @param json.longitude - Longitude of the gauge station
|
|
52
|
+
* @param json.name - Name of the gauge station
|
|
53
|
+
* @param json.team - Associated team
|
|
54
|
+
* @param json.description - Optional description
|
|
55
|
+
* @param json.links - Optional array of links
|
|
56
|
+
* @param json.version - Optional version string
|
|
57
|
+
* @param json.configurationAsJSON - Optional configuration object
|
|
58
|
+
*/
|
|
59
|
+
constructor(json: {
|
|
60
|
+
id: string,
|
|
61
|
+
latitude: number,
|
|
62
|
+
longitude: number,
|
|
63
|
+
name: string,
|
|
64
|
+
team: TeamNode,
|
|
65
|
+
description?: string,
|
|
66
|
+
links?: Link[] | RaainNode[],
|
|
67
|
+
version?: string,
|
|
68
|
+
configurationAsJSON?: any,
|
|
69
|
+
}) {
|
|
70
|
+
super(json);
|
|
71
|
+
this.latitude = json.latitude;
|
|
72
|
+
this.longitude = json.longitude;
|
|
73
|
+
this.name = json.name;
|
|
74
|
+
this.description = json.description;
|
|
75
|
+
this.team = json.team;
|
|
76
|
+
this.setConfiguration(json.configurationAsJSON);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Sets the configuration for the gauge node.
|
|
81
|
+
*
|
|
82
|
+
* @param configuration - Configuration object or JSON string
|
|
83
|
+
*/
|
|
84
|
+
public setConfiguration(configuration: string | any) {
|
|
85
|
+
let conf = configuration;
|
|
86
|
+
try {
|
|
87
|
+
conf = JSON.parse(configuration);
|
|
88
|
+
} catch (ignored) {
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (conf) {
|
|
92
|
+
this.configurationAsJSON = JSON.stringify(conf);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Gets the configuration of the gauge node.
|
|
98
|
+
*
|
|
99
|
+
* @returns The configuration object or null if not set
|
|
100
|
+
*/
|
|
101
|
+
public getConfiguration(): any {
|
|
102
|
+
try {
|
|
103
|
+
return JSON.parse(this.configurationAsJSON);
|
|
104
|
+
} catch (e) {
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Converts the gauge node to a JSON object.
|
|
111
|
+
*
|
|
112
|
+
* @returns A JSON object containing the gauge node's data
|
|
113
|
+
*/
|
|
114
|
+
public toJSON(): any {
|
|
115
|
+
const json = super.toJSON();
|
|
116
|
+
json['name'] = this.name;
|
|
117
|
+
json['description'] = this.description;
|
|
118
|
+
json['latitude'] = this.latitude;
|
|
119
|
+
json['longitude'] = this.longitude;
|
|
120
|
+
json['team'] = this.team?.id || this.team;
|
|
121
|
+
json['configurationAsJSON'] = this.configurationAsJSON;
|
|
122
|
+
return json;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Returns the link type for gauge nodes.
|
|
127
|
+
*
|
|
128
|
+
* @returns The string 'gauge'
|
|
129
|
+
*/
|
|
130
|
+
protected getLinkType(): string {
|
|
131
|
+
return GaugeNode.TYPE;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {Link, RaainNode, TeamNode} from '../organization';
|
|
2
|
+
import {GaugeNode} from './GaugeNode';
|
|
3
|
+
import {GaugeMeasure} from './GaugeMeasure';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* api/gauges/:id?format=map&begin=...
|
|
7
|
+
*/
|
|
8
|
+
export class GaugeNodeMap extends GaugeNode {
|
|
9
|
+
|
|
10
|
+
private map: string; // GaugeMeasure[]; stringified
|
|
11
|
+
|
|
12
|
+
constructor(json: {
|
|
13
|
+
id: string,
|
|
14
|
+
latitude: number,
|
|
15
|
+
longitude: number,
|
|
16
|
+
name: string,
|
|
17
|
+
description: string,
|
|
18
|
+
team: TeamNode,
|
|
19
|
+
configurationAsJSON?: any,
|
|
20
|
+
map?: string,
|
|
21
|
+
links?: Link[] | RaainNode[],
|
|
22
|
+
version?: string,
|
|
23
|
+
}) {
|
|
24
|
+
super(json);
|
|
25
|
+
this.setMapData(json.map);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public toJSON(): any {
|
|
29
|
+
const json = super.toJSON();
|
|
30
|
+
json.map = this.map;
|
|
31
|
+
return json;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public setMapData(mapData: GaugeMeasure[] | string) {
|
|
35
|
+
if (!mapData) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let map = mapData;
|
|
40
|
+
try {
|
|
41
|
+
if (typeof (mapData) !== 'string') {
|
|
42
|
+
map = JSON.stringify(mapData);
|
|
43
|
+
}
|
|
44
|
+
} catch (e) {
|
|
45
|
+
}
|
|
46
|
+
this.map = map.toString();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public getMapData(): GaugeMeasure[] {
|
|
50
|
+
if (!this.map) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
return JSON.parse(this.map);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* api/notifications/:id
|
|
3
|
+
*/
|
|
4
|
+
export class EventNode {
|
|
5
|
+
public id: string;
|
|
6
|
+
public title: string;
|
|
7
|
+
public status: number;
|
|
8
|
+
public red: boolean;
|
|
9
|
+
public description: string;
|
|
10
|
+
public created: Date;
|
|
11
|
+
public modified: Date;
|
|
12
|
+
|
|
13
|
+
constructor(json: {
|
|
14
|
+
id: string,
|
|
15
|
+
title: string,
|
|
16
|
+
status: number,
|
|
17
|
+
red: boolean,
|
|
18
|
+
description: string,
|
|
19
|
+
created: Date,
|
|
20
|
+
modified: Date
|
|
21
|
+
}
|
|
22
|
+
) {
|
|
23
|
+
this.id = json.id;
|
|
24
|
+
this.title = json.title;
|
|
25
|
+
this.status = json.status;
|
|
26
|
+
this.red = json.red;
|
|
27
|
+
this.description = json.description;
|
|
28
|
+
this.created = json.created;
|
|
29
|
+
this.modified = json.modified;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public toJSON(): any {
|
|
33
|
+
return {
|
|
34
|
+
id: this.id,
|
|
35
|
+
title: this.title,
|
|
36
|
+
status: this.status,
|
|
37
|
+
red: this.red,
|
|
38
|
+
description: this.description,
|
|
39
|
+
created: this.created,
|
|
40
|
+
modified: this.modified,
|
|
41
|
+
} as any;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Link = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Hateoas Links :
|
|
6
3
|
* [ {
|
|
@@ -8,28 +5,34 @@ exports.Link = void 0;
|
|
|
8
5
|
* href: string // like "https://../rains/2"
|
|
9
6
|
* },...]
|
|
10
7
|
*/
|
|
11
|
-
class Link {
|
|
12
|
-
constructor(
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
export class Link {
|
|
9
|
+
constructor(
|
|
10
|
+
public rel: string,
|
|
11
|
+
public href: string
|
|
12
|
+
) {
|
|
15
13
|
}
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
|
|
15
|
+
public static isCloneable(object: any): boolean {
|
|
16
|
+
return object?.rel && object?.href;
|
|
18
17
|
}
|
|
19
|
-
|
|
18
|
+
|
|
19
|
+
public static clone(object: any): Link | null {
|
|
20
|
+
if (!object?.rel || !object?.href) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
20
23
|
return new Link(object.rel, object.href);
|
|
21
24
|
}
|
|
22
|
-
|
|
25
|
+
|
|
26
|
+
public getId(): string {
|
|
23
27
|
const urls = this.href.split('/');
|
|
24
28
|
// can be enforced : verify rel in -2 urls ?...
|
|
25
29
|
return urls[urls.length - 1];
|
|
26
30
|
}
|
|
27
|
-
|
|
31
|
+
|
|
32
|
+
public getLinkType(): string {
|
|
28
33
|
// const urls = this.href.split('/');
|
|
29
34
|
// can be enforced : verify rel in -2 urls ?...
|
|
30
35
|
// return urls[1].substring(0, urls[1].length - 1);
|
|
31
36
|
return this.rel;
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
|
-
exports.Link = Link;
|
|
35
|
-
//# sourceMappingURL=Link.js.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {IPolarMeasureValue} from '../polar';
|
|
2
|
+
import {RaainNode} from './RaainNode';
|
|
3
|
+
import {ICartesianMeasureValue} from '../cartesian';
|
|
4
|
+
|
|
5
|
+
export class Measure extends RaainNode {
|
|
6
|
+
public date: Date;
|
|
7
|
+
// -> why array ? because you have different angle/axis from the Radar
|
|
8
|
+
public values: IPolarMeasureValue[] | ICartesianMeasureValue[] | number[];
|
|
9
|
+
public validity: number;
|
|
10
|
+
|
|
11
|
+
// internal
|
|
12
|
+
private configurationAsJSON: string;
|
|
13
|
+
|
|
14
|
+
constructor(json: {
|
|
15
|
+
id: string,
|
|
16
|
+
values: IPolarMeasureValue[] | ICartesianMeasureValue[] | number[],
|
|
17
|
+
date?: Date,
|
|
18
|
+
validity?: number,
|
|
19
|
+
configurationAsJSON?: string,
|
|
20
|
+
version?: string,
|
|
21
|
+
}
|
|
22
|
+
) {
|
|
23
|
+
super(json);
|
|
24
|
+
this.values = json.values ? json.values : [];
|
|
25
|
+
this.date = json.date ? new Date(json.date) : undefined;
|
|
26
|
+
this.validity = json.validity >= 0 ? json.validity : -1;
|
|
27
|
+
this.setConfiguration(json.configurationAsJSON);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public setConfiguration(configuration: string | any) {
|
|
31
|
+
let conf = configuration;
|
|
32
|
+
try {
|
|
33
|
+
conf = JSON.parse(configuration);
|
|
34
|
+
} catch (ignored) {
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (conf) {
|
|
38
|
+
this.configurationAsJSON = JSON.stringify(conf);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public toJSON(options: { removeValues?: boolean } = {}): any {
|
|
43
|
+
const json = super.toJSON();
|
|
44
|
+
json['date'] = this.date?.toISOString();
|
|
45
|
+
json['validity'] = this.validity;
|
|
46
|
+
json['configurationAsJSON'] = this.configurationAsJSON;
|
|
47
|
+
|
|
48
|
+
if (!options?.removeValues) {
|
|
49
|
+
json['values'] = this.values;
|
|
50
|
+
}
|
|
51
|
+
return json;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public getConfiguration(): any {
|
|
55
|
+
try {
|
|
56
|
+
return JSON.parse(this.configurationAsJSON);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PeopleNode = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* api/teams/:id => contacts
|
|
6
3
|
*/
|
|
7
|
-
class PeopleNode {
|
|
8
|
-
|
|
4
|
+
export class PeopleNode {
|
|
5
|
+
|
|
6
|
+
public id: string;
|
|
7
|
+
public roles: string[];
|
|
8
|
+
public email: string;
|
|
9
|
+
public name: string;
|
|
10
|
+
|
|
11
|
+
constructor(json: {
|
|
12
|
+
id: string,
|
|
13
|
+
roles: string[],
|
|
14
|
+
email: string,
|
|
15
|
+
name: string,
|
|
16
|
+
}
|
|
17
|
+
) {
|
|
9
18
|
this.id = json.id;
|
|
10
19
|
this.roles = json.roles;
|
|
11
20
|
this.email = json.email;
|
|
12
21
|
this.name = json.name;
|
|
13
22
|
}
|
|
14
|
-
|
|
23
|
+
|
|
24
|
+
public toJSON(): any {
|
|
15
25
|
return {
|
|
16
26
|
id: this.id,
|
|
17
27
|
roles: this.roles,
|
|
@@ -19,14 +29,14 @@ class PeopleNode {
|
|
|
19
29
|
name: this.name,
|
|
20
30
|
};
|
|
21
31
|
}
|
|
22
|
-
|
|
32
|
+
|
|
33
|
+
hasRole(role: string): boolean {
|
|
23
34
|
return this.roles.indexOf(role) >= 0;
|
|
24
35
|
}
|
|
25
|
-
|
|
36
|
+
|
|
37
|
+
addRole(role: string) {
|
|
26
38
|
if (!this.hasRole(role)) {
|
|
27
39
|
this.roles.push(role);
|
|
28
40
|
}
|
|
29
41
|
}
|
|
30
42
|
}
|
|
31
|
-
exports.PeopleNode = PeopleNode;
|
|
32
|
-
//# sourceMappingURL=PeopleNode.js.map
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import {Link} from './Link';
|
|
2
|
+
import {IVersion} from './IVersion';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Base class for all RAAIN nodes in the system.
|
|
6
|
+
* Implements versioning and link management functionality.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* This is the foundation class for all API entities in the RAAIN system.
|
|
10
|
+
* It provides common functionality for:
|
|
11
|
+
* - Version management
|
|
12
|
+
* - HATEOAS link handling
|
|
13
|
+
* - JSON serialization
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const node = new RaainNode({
|
|
18
|
+
* id: 'node1',
|
|
19
|
+
* version: '1.0.0',
|
|
20
|
+
* links: [
|
|
21
|
+
* new Link('self', '/api/nodes/node1')
|
|
22
|
+
* ]
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class RaainNode implements IVersion {
|
|
27
|
+
/** Unique identifier for the node */
|
|
28
|
+
public id: string;
|
|
29
|
+
/** Version string of the node */
|
|
30
|
+
public version: string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new RaainNode instance.
|
|
34
|
+
*
|
|
35
|
+
* @param json - Configuration object
|
|
36
|
+
* @param json.id - Unique identifier
|
|
37
|
+
* @param json.links - Array of HATEOAS links
|
|
38
|
+
* @param json.version - Version string
|
|
39
|
+
*/
|
|
40
|
+
constructor(json: {
|
|
41
|
+
id: string,
|
|
42
|
+
links?: Link[] | RaainNode[],
|
|
43
|
+
version?: string,
|
|
44
|
+
}) {
|
|
45
|
+
if (!json?.id) {
|
|
46
|
+
throw new Error('RaainNode needs a valid Object or ID');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.id = json.id;
|
|
50
|
+
this.links = json.links ? json.links : [];
|
|
51
|
+
this.version = json.version ? json.version : undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Array of HATEOAS links associated with the node */
|
|
55
|
+
protected _links: Link[];
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Gets all links associated with the node.
|
|
59
|
+
*
|
|
60
|
+
* @returns Array of HATEOAS links
|
|
61
|
+
*/
|
|
62
|
+
public get links(): Link[] {
|
|
63
|
+
return this._links;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sets the links for the node.
|
|
68
|
+
*
|
|
69
|
+
* @param links - Array of links to set
|
|
70
|
+
*/
|
|
71
|
+
public set links(links: Link[] | RaainNode[]) {
|
|
72
|
+
this._links = RaainNode._getPurifiedLinks(links);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private static _getPurifiedLinks(linksToPurify: any[]): Link[] {
|
|
76
|
+
if (!linksToPurify || linksToPurify.length === 0) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const linksPurified = linksToPurify
|
|
81
|
+
.filter(l => l !== null && l !== undefined)
|
|
82
|
+
.map(l => {
|
|
83
|
+
if (l instanceof Link || Link.isCloneable(l)) {
|
|
84
|
+
return Link.clone(l);
|
|
85
|
+
} else if (l && typeof l.getLinkType === 'function' && l.id) {
|
|
86
|
+
const linkType = l.getLinkType();
|
|
87
|
+
let href = '../' + linkType + 's';
|
|
88
|
+
const l2 = l;
|
|
89
|
+
if (l2.date?.toISOString) {
|
|
90
|
+
href += '/' + l2.date.toISOString();
|
|
91
|
+
if (l2.version) {
|
|
92
|
+
href += '/' + l2.version;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
href += '/' + l2.id;
|
|
96
|
+
return new Link(linkType, href);
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
})
|
|
100
|
+
.filter(l => l !== null);
|
|
101
|
+
|
|
102
|
+
function uniqBy(a: Link[], key: (a: any) => string) {
|
|
103
|
+
const seen = {};
|
|
104
|
+
return a.filter((item) => {
|
|
105
|
+
if (!item) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const k = key(item);
|
|
109
|
+
if (seen.hasOwnProperty(k)) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
seen[k] = true;
|
|
113
|
+
return true;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return uniqBy(linksPurified, JSON.stringify);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Converts the node to a JSON object.
|
|
122
|
+
*
|
|
123
|
+
* @returns A JSON object containing the node's data
|
|
124
|
+
*/
|
|
125
|
+
public toJSON(): any {
|
|
126
|
+
const json: any = {
|
|
127
|
+
id: this.id,
|
|
128
|
+
links: this.links
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
if (this.version) {
|
|
132
|
+
json.version = this.version;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return json;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public getLinks(linkType?: string): Link[] {
|
|
139
|
+
if (!this._links) {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
if (!linkType) {
|
|
143
|
+
return this._links;
|
|
144
|
+
}
|
|
145
|
+
// return this.links.filter(l => l && l.rel && linkType === l.rel);
|
|
146
|
+
return this._links.filter(l => l.getLinkType() === linkType);
|
|
147
|
+
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public getLink(linkType: string, index?: number): Link {
|
|
151
|
+
index = !index ? 0 : index;
|
|
152
|
+
const linksFound = this.getLinks(linkType);
|
|
153
|
+
if (linksFound.length <= index) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
return linksFound[index];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Gets all link IDs associated with the node.
|
|
161
|
+
*
|
|
162
|
+
* @returns Array of link IDs
|
|
163
|
+
*/
|
|
164
|
+
public getLinkIds(): string[] {
|
|
165
|
+
return this._links.map(l => l.getId());
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Gets the count of links, optionally filtered by type.
|
|
170
|
+
*
|
|
171
|
+
* @param linkType - Optional type of links to count
|
|
172
|
+
* @returns The number of links
|
|
173
|
+
*/
|
|
174
|
+
public getLinksCount(linkType?: string): number {
|
|
175
|
+
if (!this._links) {
|
|
176
|
+
return 0;
|
|
177
|
+
}
|
|
178
|
+
if (!linkType) {
|
|
179
|
+
return this._links.length;
|
|
180
|
+
}
|
|
181
|
+
return this._links.filter(l => l.getLinkType() === linkType).length;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Adds new links to the node.
|
|
186
|
+
*
|
|
187
|
+
* @param links - Array of links to add
|
|
188
|
+
*/
|
|
189
|
+
public addLinks(links: Link[] | RaainNode[]) {
|
|
190
|
+
if (!links) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
this._links = RaainNode._getPurifiedLinks([...this._links, ...links]);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Gets the version string of the node.
|
|
199
|
+
*
|
|
200
|
+
* @returns The version string
|
|
201
|
+
*/
|
|
202
|
+
public getVersion(): string | undefined {
|
|
203
|
+
return this.version;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {PeopleNode} from './PeopleNode';
|
|
2
|
+
import {RaainNode} from './RaainNode';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Represents a team in the RAAIN system.
|
|
6
|
+
* This class manages team members and their contracts.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Used in the API endpoint: api/teams?name=customerTeam
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const teamNode = new TeamNode({
|
|
14
|
+
* id: 'team1',
|
|
15
|
+
* name: 'Customer Team',
|
|
16
|
+
* description: 'Main customer support team',
|
|
17
|
+
* contracts: ['basic', 'premium'],
|
|
18
|
+
* contacts: [peopleNode1, peopleNode2]
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class TeamNode extends RaainNode {
|
|
23
|
+
|
|
24
|
+
/** Type identifier for team nodes */
|
|
25
|
+
public static TYPE = 'team';
|
|
26
|
+
|
|
27
|
+
/** Unique identifier for the team */
|
|
28
|
+
public id: any | string;
|
|
29
|
+
|
|
30
|
+
/** Name of the team */
|
|
31
|
+
public name: string;
|
|
32
|
+
|
|
33
|
+
/** Description of the team */
|
|
34
|
+
public description: string;
|
|
35
|
+
|
|
36
|
+
/** Array of contract types associated with the team */
|
|
37
|
+
public contracts: string[];
|
|
38
|
+
|
|
39
|
+
/** Array of team members */
|
|
40
|
+
public contacts: PeopleNode[];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new TeamNode instance.
|
|
44
|
+
*
|
|
45
|
+
* @param json - Configuration object
|
|
46
|
+
* @param json.id - Unique identifier
|
|
47
|
+
* @param json.name - Optional name of the team
|
|
48
|
+
* @param json.description - Optional description
|
|
49
|
+
* @param json.contracts - Optional array of contract types
|
|
50
|
+
* @param json.contacts - Optional array of team members
|
|
51
|
+
*/
|
|
52
|
+
constructor(json: {
|
|
53
|
+
id: any | string,
|
|
54
|
+
name?: string,
|
|
55
|
+
description?: string,
|
|
56
|
+
contracts?: string[],
|
|
57
|
+
contacts?: PeopleNode[]
|
|
58
|
+
}) {
|
|
59
|
+
super(json);
|
|
60
|
+
|
|
61
|
+
this.id = json.id;
|
|
62
|
+
this.name = json.name;
|
|
63
|
+
this.description = json.description;
|
|
64
|
+
this.contracts = json.contracts;
|
|
65
|
+
this.contacts = json.contacts;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Converts the team node to a JSON object.
|
|
70
|
+
*
|
|
71
|
+
* @returns A JSON object containing the team's data
|
|
72
|
+
*/
|
|
73
|
+
public toJSON(): any {
|
|
74
|
+
return {
|
|
75
|
+
id: this.id,
|
|
76
|
+
name: this.name,
|
|
77
|
+
description: this.description,
|
|
78
|
+
contracts: this.contracts,
|
|
79
|
+
contacts: this.contacts,
|
|
80
|
+
} as any;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Returns the link type for team nodes.
|
|
85
|
+
*
|
|
86
|
+
* @returns The string 'team'
|
|
87
|
+
*/
|
|
88
|
+
protected getLinkType(): string {
|
|
89
|
+
return TeamNode.TYPE;
|
|
90
|
+
}
|
|
91
|
+
}
|