@dnv-plant/typescriptpws 1.0.27 → 1.0.38-alpha.1846913

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.
@@ -0,0 +1,1817 @@
1
+ /***********************************************************************
2
+ * This file has been auto-generated by a code generation tool.
3
+ * Version: 1.0.38
4
+ * Date/time: 24 Mar 2025 16:46:20
5
+ * Template: templates/typescriptpws/calculations.razor.
6
+ ***********************************************************************/
7
+
8
+
9
+
10
+ import * as Enums from "../enums";
11
+ import * as Entities from "../entities";
12
+ import * as EntitySchemas from "../entity-schemas";
13
+ import { getAnalyticsApiTarget, getClientAliasId, postRequest } from "../utilities";
14
+
15
+ import Joi from "joi";
16
+ import { AxiosResponse } from "axios";
17
+
18
+
19
+ class CalculationRequestBase {
20
+ /**
21
+ * Calculation request base class.
22
+ */
23
+ constructor() {
24
+ // Base class initialization code
25
+ }
26
+ }
27
+
28
+ class CalculationBase {
29
+ resultCode?: Enums.ResultCode = Enums.ResultCode.SUCCESS;
30
+ messages: string[] = [];
31
+ calculationElapsedTime?: number = 0.0;
32
+ operationId?: string = "";
33
+
34
+ /**
35
+ * Post JSON to URL and time the call
36
+ */
37
+ async postRequest(url: string, data: string): Promise<AxiosResponse> {
38
+ return postRequest(url, data);
39
+ }
40
+
41
+ /**
42
+ * Utility method to print the messages returned by the calculation.
43
+ */
44
+ printMessages(): void {
45
+ if (this.messages && this.messages.length > 0) {
46
+ this.messages.forEach((message) => console.log(message));
47
+ } else {
48
+ console.log("No messages");
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Utility method to handle a failed response.
54
+ */
55
+ handleFailedResponse(response: AxiosResponse): void {
56
+ try {
57
+ const validatedFailedResponse = new CalculationFailedResponseSchema().validate(response.data);
58
+
59
+ this.resultCode = validatedFailedResponse.resultCode;
60
+ this.messages.push(...(validatedFailedResponse.messages ?? []));
61
+ this.calculationElapsedTime = validatedFailedResponse.calculationElapsedTime;
62
+ this.operationId = validatedFailedResponse.operationId;
63
+ } catch (error) {
64
+ if (error instanceof Error) {
65
+ this.messages.push(`Failed to parse response: ${error.message}`);
66
+ } else {
67
+ this.messages.push("An unknown error occurred during response parsing.");
68
+ }
69
+ console.error("Failed to parse response:", error);
70
+ } finally {
71
+ this.messages.push(`${response.statusText} (Status code: ${response.status})`);
72
+ }
73
+ }
74
+ }
75
+
76
+ class CalculationResponseBase {
77
+ resultCode?: Enums.ResultCode;
78
+ messages?: string[];
79
+ calculationElapsedTime?: number;
80
+ operationId?: string;
81
+
82
+ /**
83
+ * Calculation response base class.
84
+ */
85
+ constructor(
86
+ resultCode?: Enums.ResultCode,
87
+ messages?: string[],
88
+ calculationElapsedTime?: number,
89
+ operationId?: string
90
+ ) {
91
+ this.resultCode = resultCode;
92
+ this.messages = messages;
93
+ this.calculationElapsedTime = calculationElapsedTime;
94
+ this.operationId = operationId;
95
+ }
96
+ }
97
+
98
+ class CalculationFailedResponse extends CalculationResponseBase {
99
+ /**
100
+ * Calculation failed response class.
101
+ */
102
+ constructor(
103
+ resultCode?: Enums.ResultCode,
104
+ messages: string[] = [],
105
+ calculationElapsedTime: number = 0,
106
+ operationId: string = ""
107
+ ) {
108
+ super(resultCode, messages, calculationElapsedTime, operationId);
109
+ }
110
+ }
111
+
112
+ class CalculationFailedResponseSchema {
113
+ schema: Joi.ObjectSchema;
114
+
115
+ /**
116
+ * Calculation failed response schema.
117
+ */
118
+ constructor() {
119
+ this.schema = Joi.object({
120
+ resultCode: Joi.string()
121
+ .valid(...Object.values(Enums.ResultCode))
122
+ .required(),
123
+ messages: Joi.array().items(Joi.string()).required(),
124
+ calculationElapsedTime: Joi.number().required(),
125
+ operationId: Joi.string().required(),
126
+ }).unknown(true);
127
+ }
128
+
129
+ validate(data: {
130
+ resultCode: Enums.ResultCode;
131
+ messages: string[];
132
+ calculationElapsedTime: number;
133
+ operationId: string;
134
+ }) {
135
+ const { error, value } = this.schema.validate(data);
136
+ if (error) throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
137
+ return this.makeCalculationFailedResponse(value);
138
+ }
139
+
140
+ makeCalculationFailedResponse(data: {
141
+ resultCode: Enums.ResultCode;
142
+ messages: string[];
143
+ calculationElapsedTime: number;
144
+ operationId: string;
145
+ }) {
146
+ return new CalculationFailedResponse(data.resultCode, data.messages, data.calculationElapsedTime, data.operationId);
147
+ }
148
+ }
149
+
150
+ export interface LongPipeBreachCalculationRequestSchemaData {
151
+ pipe: Entities.Pipe;
152
+ pipeBreach: Entities.PipeBreach;
153
+ dischargeParameters: Entities.DischargeParameters;
154
+ }
155
+
156
+ class LongPipeBreachCalculationRequest extends CalculationRequestBase {
157
+ pipe: Entities.Pipe;
158
+ pipeBreach: Entities.PipeBreach;
159
+ dischargeParameters: Entities.DischargeParameters;
160
+
161
+ /**
162
+ * LongPipeBreach calculation request class.
163
+ *
164
+ * @param {Entities.Pipe} pipe - A Pipe entity.
165
+ * @param {Entities.PipeBreach} pipeBreach - A Pipe Breach entity.
166
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
167
+ */
168
+ constructor(
169
+ pipe: Entities.Pipe,
170
+ pipeBreach: Entities.PipeBreach,
171
+ dischargeParameters: Entities.DischargeParameters
172
+ ) {
173
+ super();
174
+ this.pipe = pipe;
175
+ this.pipeBreach = pipeBreach;
176
+ this.dischargeParameters = dischargeParameters;
177
+ }
178
+ }
179
+
180
+ export class LongPipeBreachCalculationRequestSchema {
181
+ schema: Joi.ObjectSchema;
182
+ propertyTypes: Record<string, string>;
183
+
184
+ /**
185
+ * Schema for the LongPipeBreach calculation request.
186
+ */
187
+ constructor() {
188
+ this.schema = Joi.object({
189
+ pipe: new EntitySchemas.PipeSchema().schema,
190
+ pipeBreach: new EntitySchemas.PipeBreachSchema().schema,
191
+ dischargeParameters: new EntitySchemas.DischargeParametersSchema().schema,
192
+ }).unknown(true);
193
+
194
+ this.propertyTypes = {
195
+ pipe: "Entities.Pipe",
196
+ pipeBreach: "Entities.PipeBreach",
197
+ dischargeParameters: "Entities.DischargeParameters",
198
+ };
199
+ }
200
+
201
+ validate(data: LongPipeBreachCalculationRequestSchemaData): LongPipeBreachCalculationRequest {
202
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
203
+ if (error) {
204
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
205
+ }
206
+ return this.makeCalculationRequest(value);
207
+ }
208
+
209
+ makeCalculationRequest(data: LongPipeBreachCalculationRequestSchemaData): LongPipeBreachCalculationRequest {
210
+ return new LongPipeBreachCalculationRequest(
211
+ data.pipe,
212
+ data.pipeBreach,
213
+ data.dischargeParameters
214
+ );
215
+ }
216
+ }
217
+
218
+ export class LongPipeBreachCalculation extends CalculationBase {
219
+ pipe: Entities.Pipe;
220
+ pipeBreach: Entities.PipeBreach;
221
+ dischargeParameters: Entities.DischargeParameters;
222
+ exitMaterial?: Entities.Material;
223
+ dischargeResult?: Entities.DischargeResult;
224
+ dischargeRecords?: Entities.DischargeRecord[];
225
+
226
+ /**
227
+ * Calculates the time-varying release from a breach (full bore or partial) in a long pipeline. Currently restricted to gas pipelines only. The release combines the outflow from the branches upstream and downstream of the breach. Valves can be specified along the pipe length. The release stops once the pipe has depressurised. The discharge mass, temperature, and other outputs are reported back as discharge records.
228
+ \remark Pressure as part of the state defined in pipe entity is in absolute units, this is to align with other uses of the
229
+ state entity for which pressure gauge is not the right definition, i.e. the final state discharge, state specification for
230
+ flash calculation, etc.
231
+ *
232
+ * @param {Entities.Pipe} pipe - A Pipe entity.
233
+ * @param {Entities.PipeBreach} pipeBreach - A Pipe Breach entity.
234
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
235
+ */
236
+ constructor(
237
+ pipe: Entities.Pipe,
238
+ pipeBreach: Entities.PipeBreach,
239
+ dischargeParameters: Entities.DischargeParameters
240
+ ) {
241
+ super();
242
+ this.pipe = pipe;
243
+ this.pipeBreach = pipeBreach;
244
+ this.dischargeParameters = dischargeParameters;
245
+ }
246
+
247
+ async run() {
248
+ try {
249
+ const request = new LongPipeBreachCalculationRequest(
250
+ this.pipe,
251
+ this.pipeBreach,
252
+ this.dischargeParameters
253
+ );
254
+
255
+ const schema = new LongPipeBreachCalculationRequestSchema();
256
+ const validatedRequest = schema.validate(request);
257
+
258
+ const requestJson = JSON.stringify(validatedRequest);
259
+ const url = `${getAnalyticsApiTarget()}calculatelongpipebreach?clientId=${getClientAliasId()}`;
260
+
261
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
262
+
263
+ const response = await this.postRequest(url, requestJson);
264
+
265
+ if (response.status >= 200 && response.status < 300) {
266
+ const schema = new LongPipeBreachCalculationResponseSchema();
267
+ const validatedResponse = schema.validate(response.data);
268
+
269
+ this.resultCode = validatedResponse.resultCode;
270
+ if (this.resultCode === Enums.ResultCode.SUCCESS) {
271
+ this.exitMaterial = validatedResponse.exitMaterial;
272
+ this.dischargeResult = validatedResponse.dischargeResult;
273
+ this.dischargeRecords = validatedResponse.dischargeRecords;
274
+ this.resultCode = validatedResponse.resultCode;
275
+ this.messages = validatedResponse.messages ?? [];
276
+ this.calculationElapsedTime = validatedResponse.calculationElapsedTime;
277
+ this.operationId = validatedResponse.operationId;
278
+ } else {
279
+ this.messages.push(...(validatedResponse.messages ?? []));
280
+ }
281
+ } else {
282
+ this.handleFailedResponse(response);
283
+ }
284
+ } catch (error) {
285
+ if (error instanceof Error) {
286
+ this.messages.push(`Error: ${error.message}`);
287
+ } else {
288
+ this.messages.push(`Unexpected error: ${JSON.stringify(error)}`);
289
+ }
290
+ console.error(error);
291
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
292
+ }
293
+
294
+ return this.resultCode;
295
+ }
296
+
297
+ toString() {
298
+ const parts = ["* LongPipeBreach"];
299
+
300
+ parts.push(`exitMaterial: ${String(this.exitMaterial)}`);
301
+ parts.push(`dischargeResult: ${String(this.dischargeResult)}`);
302
+ parts.push("*** dischargeRecords:");
303
+ parts.push(
304
+ this.dischargeRecords && this.dischargeRecords.length > 0
305
+ ? this.dischargeRecords.map((point) => `dischargeRecordsElement: ${point}`).join("\n")
306
+ : "dischargeRecords does not contain any elements"
307
+ );
308
+ parts.push(`resultCode: ${String(this.resultCode)}`);
309
+ parts.push("*** messages:");
310
+ parts.push(`messages: ${this.messages !== undefined ? this.messages : "(None)"}`);
311
+ parts.push(`calculationElapsedTime: ${this.calculationElapsedTime !== undefined ? this.calculationElapsedTime : "(None)"}`);
312
+ parts.push(`operationId: ${this.operationId !== undefined ? this.operationId : "(None)"}`);
313
+
314
+ return parts.join("\n");
315
+ }
316
+ }
317
+
318
+ export class LongPipeBreachCalculationResponse extends CalculationResponseBase {
319
+ exitMaterial: Entities.Material;
320
+ dischargeResult: Entities.DischargeResult;
321
+ dischargeRecords: Entities.DischargeRecord[];
322
+
323
+ /**
324
+ * LongPipeBreach calculation response class.
325
+ *
326
+ * @param {Entities.Material} exitMaterial - A Material entity, representing composition of the released material.
327
+ * @param {Entities.DischargeResult} dischargeResult - Scalar discharge results.
328
+ * @param {Entities.DischargeRecord[]} dischargeRecords - An array of discharge records.
329
+ */
330
+ constructor(
331
+ exitMaterial: Entities.Material,
332
+ dischargeResult: Entities.DischargeResult,
333
+ dischargeRecords: Entities.DischargeRecord[],
334
+ resultCode: Enums.ResultCode,
335
+ messages: string[],
336
+ calculationElapsedTime: number,
337
+ operationId: string
338
+ ) {
339
+ super();
340
+ this.exitMaterial = exitMaterial;
341
+ this.dischargeResult = dischargeResult;
342
+ this.dischargeRecords = dischargeRecords;
343
+ this.resultCode = resultCode;
344
+ this.messages = messages;
345
+ this.calculationElapsedTime = calculationElapsedTime;
346
+ this.operationId = operationId;
347
+ }
348
+
349
+ initialiseFromDictionary(data: { [key: string]: unknown }) {
350
+ if (data.exitMaterial) {
351
+ this.exitMaterial = new Entities.Material();
352
+ this.exitMaterial.initialiseFromDictionary(data.exitMaterial as { [key: string]: unknown });
353
+ }
354
+ if (data.dischargeResult) {
355
+ this.dischargeResult = new Entities.DischargeResult();
356
+ this.dischargeResult.initialiseFromDictionary(data.dischargeResult as { [key: string]: unknown });
357
+ }
358
+ if (data.dischargeRecords && Array.isArray(data.dischargeRecords)) {
359
+ this.dischargeRecords = data.dischargeRecords.map(
360
+ (item) => {
361
+ const record = new Entities.DischargeRecord();
362
+ record.initialiseFromDictionary(item);
363
+ return record;
364
+ }
365
+ );
366
+ }
367
+ if (data.resultCode !== undefined && (typeof data.resultCode === "string" || typeof data.resultCode === "number")) {
368
+ this.resultCode = data.resultCode as Enums.ResultCode;
369
+ }
370
+ this.messages = this.messages ?? [];
371
+ if (data.messages && Array.isArray(data.messages)) {
372
+ this.messages.push(...data.messages);
373
+ }
374
+ if (data.calculationElapsedTime !== undefined && typeof data.calculationElapsedTime === "number") {
375
+ this.calculationElapsedTime = data.calculationElapsedTime as number;
376
+ }
377
+ if (data.operationId !== undefined && typeof data.operationId === "string") {
378
+ this.operationId = data.operationId as string;
379
+ }
380
+ }
381
+ }
382
+
383
+ export interface LongPipeBreachCalculationResponseSchemaData {
384
+ exitMaterial: Entities.Material;
385
+ dischargeResult: Entities.DischargeResult;
386
+ dischargeRecords: Entities.DischargeRecord[];
387
+ resultCode: Enums.ResultCode;
388
+ messages: string[];
389
+ calculationElapsedTime: number;
390
+ operationId: string;
391
+ }
392
+
393
+ export class LongPipeBreachCalculationResponseSchema {
394
+ schema: Joi.ObjectSchema;
395
+ propertyTypes: Record<string, string>;
396
+
397
+ /**
398
+ * Schema for the LongPipeBreach calculation response.
399
+ */
400
+ constructor() {
401
+ this.schema = Joi.object({
402
+ exitMaterial: new EntitySchemas.MaterialSchema().schema,
403
+ dischargeResult: new EntitySchemas.DischargeResultSchema().schema,
404
+ dischargeRecords: Joi.array().items(new EntitySchemas.DischargeRecordSchema().schema).allow(null),
405
+ resultCode: Joi.string().valid(...Object.values(Enums.ResultCode)),
406
+ messages: Joi.array().items(Joi.string()),
407
+ calculationElapsedTime: Joi.number().unsafe(),
408
+ operationId: Joi.string().uuid().allow(null),
409
+ }).unknown(true);
410
+
411
+ this.propertyTypes = {
412
+ exitMaterial: "Entities.Material",
413
+ dischargeResult: "Entities.DischargeResult",
414
+ dischargeRecords: "Entities.DischargeRecord[]",
415
+ };
416
+ }
417
+
418
+ validate(data: LongPipeBreachCalculationResponseSchemaData): LongPipeBreachCalculationResponse {
419
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
420
+ if (error) {
421
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
422
+ }
423
+ return this.makeCalculationResponse(value);
424
+ }
425
+
426
+ makeCalculationResponse(data: LongPipeBreachCalculationResponseSchemaData): LongPipeBreachCalculationResponse {
427
+ return new LongPipeBreachCalculationResponse(
428
+ data.exitMaterial,
429
+ data.dischargeResult,
430
+ data.dischargeRecords,
431
+ data.resultCode,
432
+ data.messages,
433
+ data.calculationElapsedTime,
434
+ data.operationId
435
+ );
436
+ }
437
+ }
438
+
439
+ export interface VesselCatastrophicRuptureCalculationRequestSchemaData {
440
+ vessel: Entities.Vessel;
441
+ dischargeParameters: Entities.DischargeParameters;
442
+ }
443
+
444
+ class VesselCatastrophicRuptureCalculationRequest extends CalculationRequestBase {
445
+ vessel: Entities.Vessel;
446
+ dischargeParameters: Entities.DischargeParameters;
447
+
448
+ /**
449
+ * VesselCatastrophicRupture calculation request class.
450
+ *
451
+ * @param {Entities.Vessel} vessel - A Vessel entity.
452
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
453
+ */
454
+ constructor(
455
+ vessel: Entities.Vessel,
456
+ dischargeParameters: Entities.DischargeParameters
457
+ ) {
458
+ super();
459
+ this.vessel = vessel;
460
+ this.dischargeParameters = dischargeParameters;
461
+ }
462
+ }
463
+
464
+ export class VesselCatastrophicRuptureCalculationRequestSchema {
465
+ schema: Joi.ObjectSchema;
466
+ propertyTypes: Record<string, string>;
467
+
468
+ /**
469
+ * Schema for the VesselCatastrophicRupture calculation request.
470
+ */
471
+ constructor() {
472
+ this.schema = Joi.object({
473
+ vessel: new EntitySchemas.VesselSchema().schema,
474
+ dischargeParameters: new EntitySchemas.DischargeParametersSchema().schema,
475
+ }).unknown(true);
476
+
477
+ this.propertyTypes = {
478
+ vessel: "Entities.Vessel",
479
+ dischargeParameters: "Entities.DischargeParameters",
480
+ };
481
+ }
482
+
483
+ validate(data: VesselCatastrophicRuptureCalculationRequestSchemaData): VesselCatastrophicRuptureCalculationRequest {
484
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
485
+ if (error) {
486
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
487
+ }
488
+ return this.makeCalculationRequest(value);
489
+ }
490
+
491
+ makeCalculationRequest(data: VesselCatastrophicRuptureCalculationRequestSchemaData): VesselCatastrophicRuptureCalculationRequest {
492
+ return new VesselCatastrophicRuptureCalculationRequest(
493
+ data.vessel,
494
+ data.dischargeParameters
495
+ );
496
+ }
497
+ }
498
+
499
+ export class VesselCatastrophicRuptureCalculation extends CalculationBase {
500
+ vessel: Entities.Vessel;
501
+ dischargeParameters: Entities.DischargeParameters;
502
+ exitMaterial?: Entities.Material;
503
+ dischargeResult?: Entities.DischargeResult;
504
+ dischargeRecords?: Entities.DischargeRecord[];
505
+
506
+ /**
507
+ * Calculates the instantaneous release from a pressure vessel or storage tank. It includes expansion modelling to atmospheric conditions. The discharge mass, temperature, and other outputs are reported back as discharge records. The height of the release is located at the midpoint of the vessel.
508
+ *
509
+ * @param {Entities.Vessel} vessel - A Vessel entity.
510
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
511
+ */
512
+ constructor(
513
+ vessel: Entities.Vessel,
514
+ dischargeParameters: Entities.DischargeParameters
515
+ ) {
516
+ super();
517
+ this.vessel = vessel;
518
+ this.dischargeParameters = dischargeParameters;
519
+ }
520
+
521
+ async run() {
522
+ try {
523
+ const request = new VesselCatastrophicRuptureCalculationRequest(
524
+ this.vessel,
525
+ this.dischargeParameters
526
+ );
527
+
528
+ const schema = new VesselCatastrophicRuptureCalculationRequestSchema();
529
+ const validatedRequest = schema.validate(request);
530
+
531
+ const requestJson = JSON.stringify(validatedRequest);
532
+ const url = `${getAnalyticsApiTarget()}calculatevesselcatastrophicrupture?clientId=${getClientAliasId()}`;
533
+
534
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
535
+
536
+ const response = await this.postRequest(url, requestJson);
537
+
538
+ if (response.status >= 200 && response.status < 300) {
539
+ const schema = new VesselCatastrophicRuptureCalculationResponseSchema();
540
+ const validatedResponse = schema.validate(response.data);
541
+
542
+ this.resultCode = validatedResponse.resultCode;
543
+ if (this.resultCode === Enums.ResultCode.SUCCESS) {
544
+ this.exitMaterial = validatedResponse.exitMaterial;
545
+ this.dischargeResult = validatedResponse.dischargeResult;
546
+ this.dischargeRecords = validatedResponse.dischargeRecords;
547
+ this.resultCode = validatedResponse.resultCode;
548
+ this.messages = validatedResponse.messages ?? [];
549
+ this.calculationElapsedTime = validatedResponse.calculationElapsedTime;
550
+ this.operationId = validatedResponse.operationId;
551
+ } else {
552
+ this.messages.push(...(validatedResponse.messages ?? []));
553
+ }
554
+ } else {
555
+ this.handleFailedResponse(response);
556
+ }
557
+ } catch (error) {
558
+ if (error instanceof Error) {
559
+ this.messages.push(`Error: ${error.message}`);
560
+ } else {
561
+ this.messages.push(`Unexpected error: ${JSON.stringify(error)}`);
562
+ }
563
+ console.error(error);
564
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
565
+ }
566
+
567
+ return this.resultCode;
568
+ }
569
+
570
+ toString() {
571
+ const parts = ["* VesselCatastrophicRupture"];
572
+
573
+ parts.push(`exitMaterial: ${String(this.exitMaterial)}`);
574
+ parts.push(`dischargeResult: ${String(this.dischargeResult)}`);
575
+ parts.push("*** dischargeRecords:");
576
+ parts.push(
577
+ this.dischargeRecords && this.dischargeRecords.length > 0
578
+ ? this.dischargeRecords.map((point) => `dischargeRecordsElement: ${point}`).join("\n")
579
+ : "dischargeRecords does not contain any elements"
580
+ );
581
+ parts.push(`resultCode: ${String(this.resultCode)}`);
582
+ parts.push("*** messages:");
583
+ parts.push(`messages: ${this.messages !== undefined ? this.messages : "(None)"}`);
584
+ parts.push(`calculationElapsedTime: ${this.calculationElapsedTime !== undefined ? this.calculationElapsedTime : "(None)"}`);
585
+ parts.push(`operationId: ${this.operationId !== undefined ? this.operationId : "(None)"}`);
586
+
587
+ return parts.join("\n");
588
+ }
589
+ }
590
+
591
+ export class VesselCatastrophicRuptureCalculationResponse extends CalculationResponseBase {
592
+ exitMaterial: Entities.Material;
593
+ dischargeResult: Entities.DischargeResult;
594
+ dischargeRecords: Entities.DischargeRecord[];
595
+
596
+ /**
597
+ * VesselCatastrophicRupture calculation response class.
598
+ *
599
+ * @param {Entities.Material} exitMaterial - A Material entity representing the released material (indentical to storage composition).
600
+ * @param {Entities.DischargeResult} dischargeResult - Scalar discharge results.
601
+ * @param {Entities.DischargeRecord[]} dischargeRecords - An array of Discharge Records.
602
+ */
603
+ constructor(
604
+ exitMaterial: Entities.Material,
605
+ dischargeResult: Entities.DischargeResult,
606
+ dischargeRecords: Entities.DischargeRecord[],
607
+ resultCode: Enums.ResultCode,
608
+ messages: string[],
609
+ calculationElapsedTime: number,
610
+ operationId: string
611
+ ) {
612
+ super();
613
+ this.exitMaterial = exitMaterial;
614
+ this.dischargeResult = dischargeResult;
615
+ this.dischargeRecords = dischargeRecords;
616
+ this.resultCode = resultCode;
617
+ this.messages = messages;
618
+ this.calculationElapsedTime = calculationElapsedTime;
619
+ this.operationId = operationId;
620
+ }
621
+
622
+ initialiseFromDictionary(data: { [key: string]: unknown }) {
623
+ if (data.exitMaterial) {
624
+ this.exitMaterial = new Entities.Material();
625
+ this.exitMaterial.initialiseFromDictionary(data.exitMaterial as { [key: string]: unknown });
626
+ }
627
+ if (data.dischargeResult) {
628
+ this.dischargeResult = new Entities.DischargeResult();
629
+ this.dischargeResult.initialiseFromDictionary(data.dischargeResult as { [key: string]: unknown });
630
+ }
631
+ if (data.dischargeRecords && Array.isArray(data.dischargeRecords)) {
632
+ this.dischargeRecords = data.dischargeRecords.map(
633
+ (item) => {
634
+ const record = new Entities.DischargeRecord();
635
+ record.initialiseFromDictionary(item);
636
+ return record;
637
+ }
638
+ );
639
+ }
640
+ if (data.resultCode !== undefined && (typeof data.resultCode === "string" || typeof data.resultCode === "number")) {
641
+ this.resultCode = data.resultCode as Enums.ResultCode;
642
+ }
643
+ this.messages = this.messages ?? [];
644
+ if (data.messages && Array.isArray(data.messages)) {
645
+ this.messages.push(...data.messages);
646
+ }
647
+ if (data.calculationElapsedTime !== undefined && typeof data.calculationElapsedTime === "number") {
648
+ this.calculationElapsedTime = data.calculationElapsedTime as number;
649
+ }
650
+ if (data.operationId !== undefined && typeof data.operationId === "string") {
651
+ this.operationId = data.operationId as string;
652
+ }
653
+ }
654
+ }
655
+
656
+ export interface VesselCatastrophicRuptureCalculationResponseSchemaData {
657
+ exitMaterial: Entities.Material;
658
+ dischargeResult: Entities.DischargeResult;
659
+ dischargeRecords: Entities.DischargeRecord[];
660
+ resultCode: Enums.ResultCode;
661
+ messages: string[];
662
+ calculationElapsedTime: number;
663
+ operationId: string;
664
+ }
665
+
666
+ export class VesselCatastrophicRuptureCalculationResponseSchema {
667
+ schema: Joi.ObjectSchema;
668
+ propertyTypes: Record<string, string>;
669
+
670
+ /**
671
+ * Schema for the VesselCatastrophicRupture calculation response.
672
+ */
673
+ constructor() {
674
+ this.schema = Joi.object({
675
+ exitMaterial: new EntitySchemas.MaterialSchema().schema,
676
+ dischargeResult: new EntitySchemas.DischargeResultSchema().schema,
677
+ dischargeRecords: Joi.array().items(new EntitySchemas.DischargeRecordSchema().schema).allow(null),
678
+ resultCode: Joi.string().valid(...Object.values(Enums.ResultCode)),
679
+ messages: Joi.array().items(Joi.string()),
680
+ calculationElapsedTime: Joi.number().unsafe(),
681
+ operationId: Joi.string().uuid().allow(null),
682
+ }).unknown(true);
683
+
684
+ this.propertyTypes = {
685
+ exitMaterial: "Entities.Material",
686
+ dischargeResult: "Entities.DischargeResult",
687
+ dischargeRecords: "Entities.DischargeRecord[]",
688
+ };
689
+ }
690
+
691
+ validate(data: VesselCatastrophicRuptureCalculationResponseSchemaData): VesselCatastrophicRuptureCalculationResponse {
692
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
693
+ if (error) {
694
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
695
+ }
696
+ return this.makeCalculationResponse(value);
697
+ }
698
+
699
+ makeCalculationResponse(data: VesselCatastrophicRuptureCalculationResponseSchemaData): VesselCatastrophicRuptureCalculationResponse {
700
+ return new VesselCatastrophicRuptureCalculationResponse(
701
+ data.exitMaterial,
702
+ data.dischargeResult,
703
+ data.dischargeRecords,
704
+ data.resultCode,
705
+ data.messages,
706
+ data.calculationElapsedTime,
707
+ data.operationId
708
+ );
709
+ }
710
+ }
711
+
712
+ export interface VesselLeakCalculationRequestSchemaData {
713
+ vessel: Entities.Vessel;
714
+ leak: Entities.Leak;
715
+ dischargeParameters: Entities.DischargeParameters;
716
+ }
717
+
718
+ class VesselLeakCalculationRequest extends CalculationRequestBase {
719
+ vessel: Entities.Vessel;
720
+ leak: Entities.Leak;
721
+ dischargeParameters: Entities.DischargeParameters;
722
+
723
+ /**
724
+ * VesselLeak calculation request class.
725
+ *
726
+ * @param {Entities.Vessel} vessel - A Vessel entity.
727
+ * @param {Entities.Leak} leak - A Leak entity.
728
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
729
+ */
730
+ constructor(
731
+ vessel: Entities.Vessel,
732
+ leak: Entities.Leak,
733
+ dischargeParameters: Entities.DischargeParameters
734
+ ) {
735
+ super();
736
+ this.vessel = vessel;
737
+ this.leak = leak;
738
+ this.dischargeParameters = dischargeParameters;
739
+ }
740
+ }
741
+
742
+ export class VesselLeakCalculationRequestSchema {
743
+ schema: Joi.ObjectSchema;
744
+ propertyTypes: Record<string, string>;
745
+
746
+ /**
747
+ * Schema for the VesselLeak calculation request.
748
+ */
749
+ constructor() {
750
+ this.schema = Joi.object({
751
+ vessel: new EntitySchemas.VesselSchema().schema,
752
+ leak: new EntitySchemas.LeakSchema().schema,
753
+ dischargeParameters: new EntitySchemas.DischargeParametersSchema().schema,
754
+ }).unknown(true);
755
+
756
+ this.propertyTypes = {
757
+ vessel: "Entities.Vessel",
758
+ leak: "Entities.Leak",
759
+ dischargeParameters: "Entities.DischargeParameters",
760
+ };
761
+ }
762
+
763
+ validate(data: VesselLeakCalculationRequestSchemaData): VesselLeakCalculationRequest {
764
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
765
+ if (error) {
766
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
767
+ }
768
+ return this.makeCalculationRequest(value);
769
+ }
770
+
771
+ makeCalculationRequest(data: VesselLeakCalculationRequestSchemaData): VesselLeakCalculationRequest {
772
+ return new VesselLeakCalculationRequest(
773
+ data.vessel,
774
+ data.leak,
775
+ data.dischargeParameters
776
+ );
777
+ }
778
+ }
779
+
780
+ export class VesselLeakCalculation extends CalculationBase {
781
+ vessel: Entities.Vessel;
782
+ leak: Entities.Leak;
783
+ dischargeParameters: Entities.DischargeParameters;
784
+ exitMaterial?: Entities.Material;
785
+ dischargeResult?: Entities.DischargeResult;
786
+ dischargeRecords?: Entities.DischargeRecord[];
787
+
788
+ /**
789
+ * Calculates the steady state or time-varying leak from a pressure vessel or storage tank. It includes expansion modelling (from the vessel orifice to atmospheric conditions). The discharge rate, temperature, and other time-dependent outputs at a particular time are reported back as discharge records. For steady-state there are always two DischargeRecords generated; for time-varying the number can vary.
790
+ *
791
+ * @param {Entities.Vessel} vessel - A Vessel entity.
792
+ * @param {Entities.Leak} leak - A Leak entity.
793
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
794
+ */
795
+ constructor(
796
+ vessel: Entities.Vessel,
797
+ leak: Entities.Leak,
798
+ dischargeParameters: Entities.DischargeParameters
799
+ ) {
800
+ super();
801
+ this.vessel = vessel;
802
+ this.leak = leak;
803
+ this.dischargeParameters = dischargeParameters;
804
+ }
805
+
806
+ async run() {
807
+ try {
808
+ const request = new VesselLeakCalculationRequest(
809
+ this.vessel,
810
+ this.leak,
811
+ this.dischargeParameters
812
+ );
813
+
814
+ const schema = new VesselLeakCalculationRequestSchema();
815
+ const validatedRequest = schema.validate(request);
816
+
817
+ const requestJson = JSON.stringify(validatedRequest);
818
+ const url = `${getAnalyticsApiTarget()}calculatevesselleak?clientId=${getClientAliasId()}`;
819
+
820
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
821
+
822
+ const response = await this.postRequest(url, requestJson);
823
+
824
+ if (response.status >= 200 && response.status < 300) {
825
+ const schema = new VesselLeakCalculationResponseSchema();
826
+ const validatedResponse = schema.validate(response.data);
827
+
828
+ this.resultCode = validatedResponse.resultCode;
829
+ if (this.resultCode === Enums.ResultCode.SUCCESS) {
830
+ this.exitMaterial = validatedResponse.exitMaterial;
831
+ this.dischargeResult = validatedResponse.dischargeResult;
832
+ this.dischargeRecords = validatedResponse.dischargeRecords;
833
+ this.resultCode = validatedResponse.resultCode;
834
+ this.messages = validatedResponse.messages ?? [];
835
+ this.calculationElapsedTime = validatedResponse.calculationElapsedTime;
836
+ this.operationId = validatedResponse.operationId;
837
+ } else {
838
+ this.messages.push(...(validatedResponse.messages ?? []));
839
+ }
840
+ } else {
841
+ this.handleFailedResponse(response);
842
+ }
843
+ } catch (error) {
844
+ if (error instanceof Error) {
845
+ this.messages.push(`Error: ${error.message}`);
846
+ } else {
847
+ this.messages.push(`Unexpected error: ${JSON.stringify(error)}`);
848
+ }
849
+ console.error(error);
850
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
851
+ }
852
+
853
+ return this.resultCode;
854
+ }
855
+
856
+ toString() {
857
+ const parts = ["* VesselLeak"];
858
+
859
+ parts.push(`exitMaterial: ${String(this.exitMaterial)}`);
860
+ parts.push(`dischargeResult: ${String(this.dischargeResult)}`);
861
+ parts.push("*** dischargeRecords:");
862
+ parts.push(
863
+ this.dischargeRecords && this.dischargeRecords.length > 0
864
+ ? this.dischargeRecords.map((point) => `dischargeRecordsElement: ${point}`).join("\n")
865
+ : "dischargeRecords does not contain any elements"
866
+ );
867
+ parts.push(`resultCode: ${String(this.resultCode)}`);
868
+ parts.push("*** messages:");
869
+ parts.push(`messages: ${this.messages !== undefined ? this.messages : "(None)"}`);
870
+ parts.push(`calculationElapsedTime: ${this.calculationElapsedTime !== undefined ? this.calculationElapsedTime : "(None)"}`);
871
+ parts.push(`operationId: ${this.operationId !== undefined ? this.operationId : "(None)"}`);
872
+
873
+ return parts.join("\n");
874
+ }
875
+ }
876
+
877
+ export class VesselLeakCalculationResponse extends CalculationResponseBase {
878
+ exitMaterial: Entities.Material;
879
+ dischargeResult: Entities.DischargeResult;
880
+ dischargeRecords: Entities.DischargeRecord[];
881
+
882
+ /**
883
+ * VesselLeak calculation response class.
884
+ *
885
+ * @param {Entities.Material} exitMaterial - A Material entity representing the released material (may differ from storage composition).
886
+ * @param {Entities.DischargeResult} dischargeResult - Scalar discharge results.
887
+ * @param {Entities.DischargeRecord[]} dischargeRecords - An array of Discharge Records.
888
+ */
889
+ constructor(
890
+ exitMaterial: Entities.Material,
891
+ dischargeResult: Entities.DischargeResult,
892
+ dischargeRecords: Entities.DischargeRecord[],
893
+ resultCode: Enums.ResultCode,
894
+ messages: string[],
895
+ calculationElapsedTime: number,
896
+ operationId: string
897
+ ) {
898
+ super();
899
+ this.exitMaterial = exitMaterial;
900
+ this.dischargeResult = dischargeResult;
901
+ this.dischargeRecords = dischargeRecords;
902
+ this.resultCode = resultCode;
903
+ this.messages = messages;
904
+ this.calculationElapsedTime = calculationElapsedTime;
905
+ this.operationId = operationId;
906
+ }
907
+
908
+ initialiseFromDictionary(data: { [key: string]: unknown }) {
909
+ if (data.exitMaterial) {
910
+ this.exitMaterial = new Entities.Material();
911
+ this.exitMaterial.initialiseFromDictionary(data.exitMaterial as { [key: string]: unknown });
912
+ }
913
+ if (data.dischargeResult) {
914
+ this.dischargeResult = new Entities.DischargeResult();
915
+ this.dischargeResult.initialiseFromDictionary(data.dischargeResult as { [key: string]: unknown });
916
+ }
917
+ if (data.dischargeRecords && Array.isArray(data.dischargeRecords)) {
918
+ this.dischargeRecords = data.dischargeRecords.map(
919
+ (item) => {
920
+ const record = new Entities.DischargeRecord();
921
+ record.initialiseFromDictionary(item);
922
+ return record;
923
+ }
924
+ );
925
+ }
926
+ if (data.resultCode !== undefined && (typeof data.resultCode === "string" || typeof data.resultCode === "number")) {
927
+ this.resultCode = data.resultCode as Enums.ResultCode;
928
+ }
929
+ this.messages = this.messages ?? [];
930
+ if (data.messages && Array.isArray(data.messages)) {
931
+ this.messages.push(...data.messages);
932
+ }
933
+ if (data.calculationElapsedTime !== undefined && typeof data.calculationElapsedTime === "number") {
934
+ this.calculationElapsedTime = data.calculationElapsedTime as number;
935
+ }
936
+ if (data.operationId !== undefined && typeof data.operationId === "string") {
937
+ this.operationId = data.operationId as string;
938
+ }
939
+ }
940
+ }
941
+
942
+ export interface VesselLeakCalculationResponseSchemaData {
943
+ exitMaterial: Entities.Material;
944
+ dischargeResult: Entities.DischargeResult;
945
+ dischargeRecords: Entities.DischargeRecord[];
946
+ resultCode: Enums.ResultCode;
947
+ messages: string[];
948
+ calculationElapsedTime: number;
949
+ operationId: string;
950
+ }
951
+
952
+ export class VesselLeakCalculationResponseSchema {
953
+ schema: Joi.ObjectSchema;
954
+ propertyTypes: Record<string, string>;
955
+
956
+ /**
957
+ * Schema for the VesselLeak calculation response.
958
+ */
959
+ constructor() {
960
+ this.schema = Joi.object({
961
+ exitMaterial: new EntitySchemas.MaterialSchema().schema,
962
+ dischargeResult: new EntitySchemas.DischargeResultSchema().schema,
963
+ dischargeRecords: Joi.array().items(new EntitySchemas.DischargeRecordSchema().schema).allow(null),
964
+ resultCode: Joi.string().valid(...Object.values(Enums.ResultCode)),
965
+ messages: Joi.array().items(Joi.string()),
966
+ calculationElapsedTime: Joi.number().unsafe(),
967
+ operationId: Joi.string().uuid().allow(null),
968
+ }).unknown(true);
969
+
970
+ this.propertyTypes = {
971
+ exitMaterial: "Entities.Material",
972
+ dischargeResult: "Entities.DischargeResult",
973
+ dischargeRecords: "Entities.DischargeRecord[]",
974
+ };
975
+ }
976
+
977
+ validate(data: VesselLeakCalculationResponseSchemaData): VesselLeakCalculationResponse {
978
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
979
+ if (error) {
980
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
981
+ }
982
+ return this.makeCalculationResponse(value);
983
+ }
984
+
985
+ makeCalculationResponse(data: VesselLeakCalculationResponseSchemaData): VesselLeakCalculationResponse {
986
+ return new VesselLeakCalculationResponse(
987
+ data.exitMaterial,
988
+ data.dischargeResult,
989
+ data.dischargeRecords,
990
+ data.resultCode,
991
+ data.messages,
992
+ data.calculationElapsedTime,
993
+ data.operationId
994
+ );
995
+ }
996
+ }
997
+
998
+ export interface VesselLineRuptureCalculationRequestSchemaData {
999
+ vessel: Entities.Vessel;
1000
+ lineRupture: Entities.LineRupture;
1001
+ dischargeParameters: Entities.DischargeParameters;
1002
+ }
1003
+
1004
+ class VesselLineRuptureCalculationRequest extends CalculationRequestBase {
1005
+ vessel: Entities.Vessel;
1006
+ lineRupture: Entities.LineRupture;
1007
+ dischargeParameters: Entities.DischargeParameters;
1008
+
1009
+ /**
1010
+ * VesselLineRupture calculation request class.
1011
+ *
1012
+ * @param {Entities.Vessel} vessel - A Vessel entity.
1013
+ * @param {Entities.LineRupture} lineRupture - A Line Rupture entity.
1014
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
1015
+ */
1016
+ constructor(
1017
+ vessel: Entities.Vessel,
1018
+ lineRupture: Entities.LineRupture,
1019
+ dischargeParameters: Entities.DischargeParameters
1020
+ ) {
1021
+ super();
1022
+ this.vessel = vessel;
1023
+ this.lineRupture = lineRupture;
1024
+ this.dischargeParameters = dischargeParameters;
1025
+ }
1026
+ }
1027
+
1028
+ export class VesselLineRuptureCalculationRequestSchema {
1029
+ schema: Joi.ObjectSchema;
1030
+ propertyTypes: Record<string, string>;
1031
+
1032
+ /**
1033
+ * Schema for the VesselLineRupture calculation request.
1034
+ */
1035
+ constructor() {
1036
+ this.schema = Joi.object({
1037
+ vessel: new EntitySchemas.VesselSchema().schema,
1038
+ lineRupture: new EntitySchemas.LineRuptureSchema().schema,
1039
+ dischargeParameters: new EntitySchemas.DischargeParametersSchema().schema,
1040
+ }).unknown(true);
1041
+
1042
+ this.propertyTypes = {
1043
+ vessel: "Entities.Vessel",
1044
+ lineRupture: "Entities.LineRupture",
1045
+ dischargeParameters: "Entities.DischargeParameters",
1046
+ };
1047
+ }
1048
+
1049
+ validate(data: VesselLineRuptureCalculationRequestSchemaData): VesselLineRuptureCalculationRequest {
1050
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
1051
+ if (error) {
1052
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
1053
+ }
1054
+ return this.makeCalculationRequest(value);
1055
+ }
1056
+
1057
+ makeCalculationRequest(data: VesselLineRuptureCalculationRequestSchemaData): VesselLineRuptureCalculationRequest {
1058
+ return new VesselLineRuptureCalculationRequest(
1059
+ data.vessel,
1060
+ data.lineRupture,
1061
+ data.dischargeParameters
1062
+ );
1063
+ }
1064
+ }
1065
+
1066
+ export class VesselLineRuptureCalculation extends CalculationBase {
1067
+ vessel: Entities.Vessel;
1068
+ lineRupture: Entities.LineRupture;
1069
+ dischargeParameters: Entities.DischargeParameters;
1070
+ exitMaterial?: Entities.Material;
1071
+ dischargeResult?: Entities.DischargeResult;
1072
+ dischargeRecords?: Entities.DischargeRecord[];
1073
+
1074
+ /**
1075
+ * Calculations of discharge from a short pipe attached to a vessel.
1076
+ *
1077
+ * @param {Entities.Vessel} vessel - A Vessel entity.
1078
+ * @param {Entities.LineRupture} lineRupture - A Line Rupture entity.
1079
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
1080
+ */
1081
+ constructor(
1082
+ vessel: Entities.Vessel,
1083
+ lineRupture: Entities.LineRupture,
1084
+ dischargeParameters: Entities.DischargeParameters
1085
+ ) {
1086
+ super();
1087
+ this.vessel = vessel;
1088
+ this.lineRupture = lineRupture;
1089
+ this.dischargeParameters = dischargeParameters;
1090
+ }
1091
+
1092
+ async run() {
1093
+ try {
1094
+ const request = new VesselLineRuptureCalculationRequest(
1095
+ this.vessel,
1096
+ this.lineRupture,
1097
+ this.dischargeParameters
1098
+ );
1099
+
1100
+ const schema = new VesselLineRuptureCalculationRequestSchema();
1101
+ const validatedRequest = schema.validate(request);
1102
+
1103
+ const requestJson = JSON.stringify(validatedRequest);
1104
+ const url = `${getAnalyticsApiTarget()}calculatevessellinerupture?clientId=${getClientAliasId()}`;
1105
+
1106
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
1107
+
1108
+ const response = await this.postRequest(url, requestJson);
1109
+
1110
+ if (response.status >= 200 && response.status < 300) {
1111
+ const schema = new VesselLineRuptureCalculationResponseSchema();
1112
+ const validatedResponse = schema.validate(response.data);
1113
+
1114
+ this.resultCode = validatedResponse.resultCode;
1115
+ if (this.resultCode === Enums.ResultCode.SUCCESS) {
1116
+ this.exitMaterial = validatedResponse.exitMaterial;
1117
+ this.dischargeResult = validatedResponse.dischargeResult;
1118
+ this.dischargeRecords = validatedResponse.dischargeRecords;
1119
+ this.resultCode = validatedResponse.resultCode;
1120
+ this.messages = validatedResponse.messages ?? [];
1121
+ this.calculationElapsedTime = validatedResponse.calculationElapsedTime;
1122
+ this.operationId = validatedResponse.operationId;
1123
+ } else {
1124
+ this.messages.push(...(validatedResponse.messages ?? []));
1125
+ }
1126
+ } else {
1127
+ this.handleFailedResponse(response);
1128
+ }
1129
+ } catch (error) {
1130
+ if (error instanceof Error) {
1131
+ this.messages.push(`Error: ${error.message}`);
1132
+ } else {
1133
+ this.messages.push(`Unexpected error: ${JSON.stringify(error)}`);
1134
+ }
1135
+ console.error(error);
1136
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
1137
+ }
1138
+
1139
+ return this.resultCode;
1140
+ }
1141
+
1142
+ toString() {
1143
+ const parts = ["* VesselLineRupture"];
1144
+
1145
+ parts.push(`exitMaterial: ${String(this.exitMaterial)}`);
1146
+ parts.push(`dischargeResult: ${String(this.dischargeResult)}`);
1147
+ parts.push("*** dischargeRecords:");
1148
+ parts.push(
1149
+ this.dischargeRecords && this.dischargeRecords.length > 0
1150
+ ? this.dischargeRecords.map((point) => `dischargeRecordsElement: ${point}`).join("\n")
1151
+ : "dischargeRecords does not contain any elements"
1152
+ );
1153
+ parts.push(`resultCode: ${String(this.resultCode)}`);
1154
+ parts.push("*** messages:");
1155
+ parts.push(`messages: ${this.messages !== undefined ? this.messages : "(None)"}`);
1156
+ parts.push(`calculationElapsedTime: ${this.calculationElapsedTime !== undefined ? this.calculationElapsedTime : "(None)"}`);
1157
+ parts.push(`operationId: ${this.operationId !== undefined ? this.operationId : "(None)"}`);
1158
+
1159
+ return parts.join("\n");
1160
+ }
1161
+ }
1162
+
1163
+ export class VesselLineRuptureCalculationResponse extends CalculationResponseBase {
1164
+ exitMaterial: Entities.Material;
1165
+ dischargeResult: Entities.DischargeResult;
1166
+ dischargeRecords: Entities.DischargeRecord[];
1167
+
1168
+ /**
1169
+ * VesselLineRupture calculation response class.
1170
+ *
1171
+ * @param {Entities.Material} exitMaterial - A Material entity representing the released material (which may differ from storage composition).
1172
+ * @param {Entities.DischargeResult} dischargeResult - Scalar discharge results.
1173
+ * @param {Entities.DischargeRecord[]} dischargeRecords - An array of Discharge Records.
1174
+ */
1175
+ constructor(
1176
+ exitMaterial: Entities.Material,
1177
+ dischargeResult: Entities.DischargeResult,
1178
+ dischargeRecords: Entities.DischargeRecord[],
1179
+ resultCode: Enums.ResultCode,
1180
+ messages: string[],
1181
+ calculationElapsedTime: number,
1182
+ operationId: string
1183
+ ) {
1184
+ super();
1185
+ this.exitMaterial = exitMaterial;
1186
+ this.dischargeResult = dischargeResult;
1187
+ this.dischargeRecords = dischargeRecords;
1188
+ this.resultCode = resultCode;
1189
+ this.messages = messages;
1190
+ this.calculationElapsedTime = calculationElapsedTime;
1191
+ this.operationId = operationId;
1192
+ }
1193
+
1194
+ initialiseFromDictionary(data: { [key: string]: unknown }) {
1195
+ if (data.exitMaterial) {
1196
+ this.exitMaterial = new Entities.Material();
1197
+ this.exitMaterial.initialiseFromDictionary(data.exitMaterial as { [key: string]: unknown });
1198
+ }
1199
+ if (data.dischargeResult) {
1200
+ this.dischargeResult = new Entities.DischargeResult();
1201
+ this.dischargeResult.initialiseFromDictionary(data.dischargeResult as { [key: string]: unknown });
1202
+ }
1203
+ if (data.dischargeRecords && Array.isArray(data.dischargeRecords)) {
1204
+ this.dischargeRecords = data.dischargeRecords.map(
1205
+ (item) => {
1206
+ const record = new Entities.DischargeRecord();
1207
+ record.initialiseFromDictionary(item);
1208
+ return record;
1209
+ }
1210
+ );
1211
+ }
1212
+ if (data.resultCode !== undefined && (typeof data.resultCode === "string" || typeof data.resultCode === "number")) {
1213
+ this.resultCode = data.resultCode as Enums.ResultCode;
1214
+ }
1215
+ this.messages = this.messages ?? [];
1216
+ if (data.messages && Array.isArray(data.messages)) {
1217
+ this.messages.push(...data.messages);
1218
+ }
1219
+ if (data.calculationElapsedTime !== undefined && typeof data.calculationElapsedTime === "number") {
1220
+ this.calculationElapsedTime = data.calculationElapsedTime as number;
1221
+ }
1222
+ if (data.operationId !== undefined && typeof data.operationId === "string") {
1223
+ this.operationId = data.operationId as string;
1224
+ }
1225
+ }
1226
+ }
1227
+
1228
+ export interface VesselLineRuptureCalculationResponseSchemaData {
1229
+ exitMaterial: Entities.Material;
1230
+ dischargeResult: Entities.DischargeResult;
1231
+ dischargeRecords: Entities.DischargeRecord[];
1232
+ resultCode: Enums.ResultCode;
1233
+ messages: string[];
1234
+ calculationElapsedTime: number;
1235
+ operationId: string;
1236
+ }
1237
+
1238
+ export class VesselLineRuptureCalculationResponseSchema {
1239
+ schema: Joi.ObjectSchema;
1240
+ propertyTypes: Record<string, string>;
1241
+
1242
+ /**
1243
+ * Schema for the VesselLineRupture calculation response.
1244
+ */
1245
+ constructor() {
1246
+ this.schema = Joi.object({
1247
+ exitMaterial: new EntitySchemas.MaterialSchema().schema,
1248
+ dischargeResult: new EntitySchemas.DischargeResultSchema().schema,
1249
+ dischargeRecords: Joi.array().items(new EntitySchemas.DischargeRecordSchema().schema).allow(null),
1250
+ resultCode: Joi.string().valid(...Object.values(Enums.ResultCode)),
1251
+ messages: Joi.array().items(Joi.string()),
1252
+ calculationElapsedTime: Joi.number().unsafe(),
1253
+ operationId: Joi.string().uuid().allow(null),
1254
+ }).unknown(true);
1255
+
1256
+ this.propertyTypes = {
1257
+ exitMaterial: "Entities.Material",
1258
+ dischargeResult: "Entities.DischargeResult",
1259
+ dischargeRecords: "Entities.DischargeRecord[]",
1260
+ };
1261
+ }
1262
+
1263
+ validate(data: VesselLineRuptureCalculationResponseSchemaData): VesselLineRuptureCalculationResponse {
1264
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
1265
+ if (error) {
1266
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
1267
+ }
1268
+ return this.makeCalculationResponse(value);
1269
+ }
1270
+
1271
+ makeCalculationResponse(data: VesselLineRuptureCalculationResponseSchemaData): VesselLineRuptureCalculationResponse {
1272
+ return new VesselLineRuptureCalculationResponse(
1273
+ data.exitMaterial,
1274
+ data.dischargeResult,
1275
+ data.dischargeRecords,
1276
+ data.resultCode,
1277
+ data.messages,
1278
+ data.calculationElapsedTime,
1279
+ data.operationId
1280
+ );
1281
+ }
1282
+ }
1283
+
1284
+ export interface VesselReliefValveCalculationRequestSchemaData {
1285
+ vessel: Entities.Vessel;
1286
+ reliefValve: Entities.ReliefValve;
1287
+ dischargeParameters: Entities.DischargeParameters;
1288
+ }
1289
+
1290
+ class VesselReliefValveCalculationRequest extends CalculationRequestBase {
1291
+ vessel: Entities.Vessel;
1292
+ reliefValve: Entities.ReliefValve;
1293
+ dischargeParameters: Entities.DischargeParameters;
1294
+
1295
+ /**
1296
+ * VesselReliefValve calculation request class.
1297
+ *
1298
+ * @param {Entities.Vessel} vessel - A Vessel entity.
1299
+ * @param {Entities.ReliefValve} reliefValve - A Relief Valve entity.
1300
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
1301
+ */
1302
+ constructor(
1303
+ vessel: Entities.Vessel,
1304
+ reliefValve: Entities.ReliefValve,
1305
+ dischargeParameters: Entities.DischargeParameters
1306
+ ) {
1307
+ super();
1308
+ this.vessel = vessel;
1309
+ this.reliefValve = reliefValve;
1310
+ this.dischargeParameters = dischargeParameters;
1311
+ }
1312
+ }
1313
+
1314
+ export class VesselReliefValveCalculationRequestSchema {
1315
+ schema: Joi.ObjectSchema;
1316
+ propertyTypes: Record<string, string>;
1317
+
1318
+ /**
1319
+ * Schema for the VesselReliefValve calculation request.
1320
+ */
1321
+ constructor() {
1322
+ this.schema = Joi.object({
1323
+ vessel: new EntitySchemas.VesselSchema().schema,
1324
+ reliefValve: new EntitySchemas.ReliefValveSchema().schema,
1325
+ dischargeParameters: new EntitySchemas.DischargeParametersSchema().schema,
1326
+ }).unknown(true);
1327
+
1328
+ this.propertyTypes = {
1329
+ vessel: "Entities.Vessel",
1330
+ reliefValve: "Entities.ReliefValve",
1331
+ dischargeParameters: "Entities.DischargeParameters",
1332
+ };
1333
+ }
1334
+
1335
+ validate(data: VesselReliefValveCalculationRequestSchemaData): VesselReliefValveCalculationRequest {
1336
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
1337
+ if (error) {
1338
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
1339
+ }
1340
+ return this.makeCalculationRequest(value);
1341
+ }
1342
+
1343
+ makeCalculationRequest(data: VesselReliefValveCalculationRequestSchemaData): VesselReliefValveCalculationRequest {
1344
+ return new VesselReliefValveCalculationRequest(
1345
+ data.vessel,
1346
+ data.reliefValve,
1347
+ data.dischargeParameters
1348
+ );
1349
+ }
1350
+ }
1351
+
1352
+ export class VesselReliefValveCalculation extends CalculationBase {
1353
+ vessel: Entities.Vessel;
1354
+ reliefValve: Entities.ReliefValve;
1355
+ dischargeParameters: Entities.DischargeParameters;
1356
+ exitMaterial?: Entities.Material;
1357
+ dischargeResult?: Entities.DischargeResult;
1358
+ dischargeRecords?: Entities.DischargeRecord[];
1359
+
1360
+ /**
1361
+ * Calculations of venting from a relief valve attached to a vessel.
1362
+ *
1363
+ * @param {Entities.Vessel} vessel - A Vessel entity.
1364
+ * @param {Entities.ReliefValve} reliefValve - A Relief Valve entity.
1365
+ * @param {Entities.DischargeParameters} dischargeParameters - A Discharge Parameters entity.
1366
+ */
1367
+ constructor(
1368
+ vessel: Entities.Vessel,
1369
+ reliefValve: Entities.ReliefValve,
1370
+ dischargeParameters: Entities.DischargeParameters
1371
+ ) {
1372
+ super();
1373
+ this.vessel = vessel;
1374
+ this.reliefValve = reliefValve;
1375
+ this.dischargeParameters = dischargeParameters;
1376
+ }
1377
+
1378
+ async run() {
1379
+ try {
1380
+ const request = new VesselReliefValveCalculationRequest(
1381
+ this.vessel,
1382
+ this.reliefValve,
1383
+ this.dischargeParameters
1384
+ );
1385
+
1386
+ const schema = new VesselReliefValveCalculationRequestSchema();
1387
+ const validatedRequest = schema.validate(request);
1388
+
1389
+ const requestJson = JSON.stringify(validatedRequest);
1390
+ const url = `${getAnalyticsApiTarget()}calculatevesselreliefvalve?clientId=${getClientAliasId()}`;
1391
+
1392
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
1393
+
1394
+ const response = await this.postRequest(url, requestJson);
1395
+
1396
+ if (response.status >= 200 && response.status < 300) {
1397
+ const schema = new VesselReliefValveCalculationResponseSchema();
1398
+ const validatedResponse = schema.validate(response.data);
1399
+
1400
+ this.resultCode = validatedResponse.resultCode;
1401
+ if (this.resultCode === Enums.ResultCode.SUCCESS) {
1402
+ this.exitMaterial = validatedResponse.exitMaterial;
1403
+ this.dischargeResult = validatedResponse.dischargeResult;
1404
+ this.dischargeRecords = validatedResponse.dischargeRecords;
1405
+ this.resultCode = validatedResponse.resultCode;
1406
+ this.messages = validatedResponse.messages ?? [];
1407
+ this.calculationElapsedTime = validatedResponse.calculationElapsedTime;
1408
+ this.operationId = validatedResponse.operationId;
1409
+ } else {
1410
+ this.messages.push(...(validatedResponse.messages ?? []));
1411
+ }
1412
+ } else {
1413
+ this.handleFailedResponse(response);
1414
+ }
1415
+ } catch (error) {
1416
+ if (error instanceof Error) {
1417
+ this.messages.push(`Error: ${error.message}`);
1418
+ } else {
1419
+ this.messages.push(`Unexpected error: ${JSON.stringify(error)}`);
1420
+ }
1421
+ console.error(error);
1422
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
1423
+ }
1424
+
1425
+ return this.resultCode;
1426
+ }
1427
+
1428
+ toString() {
1429
+ const parts = ["* VesselReliefValve"];
1430
+
1431
+ parts.push(`exitMaterial: ${String(this.exitMaterial)}`);
1432
+ parts.push(`dischargeResult: ${String(this.dischargeResult)}`);
1433
+ parts.push("*** dischargeRecords:");
1434
+ parts.push(
1435
+ this.dischargeRecords && this.dischargeRecords.length > 0
1436
+ ? this.dischargeRecords.map((point) => `dischargeRecordsElement: ${point}`).join("\n")
1437
+ : "dischargeRecords does not contain any elements"
1438
+ );
1439
+ parts.push(`resultCode: ${String(this.resultCode)}`);
1440
+ parts.push("*** messages:");
1441
+ parts.push(`messages: ${this.messages !== undefined ? this.messages : "(None)"}`);
1442
+ parts.push(`calculationElapsedTime: ${this.calculationElapsedTime !== undefined ? this.calculationElapsedTime : "(None)"}`);
1443
+ parts.push(`operationId: ${this.operationId !== undefined ? this.operationId : "(None)"}`);
1444
+
1445
+ return parts.join("\n");
1446
+ }
1447
+ }
1448
+
1449
+ export class VesselReliefValveCalculationResponse extends CalculationResponseBase {
1450
+ exitMaterial: Entities.Material;
1451
+ dischargeResult: Entities.DischargeResult;
1452
+ dischargeRecords: Entities.DischargeRecord[];
1453
+
1454
+ /**
1455
+ * VesselReliefValve calculation response class.
1456
+ *
1457
+ * @param {Entities.Material} exitMaterial - A Material entity representing the released material (which may differ from storage composition).
1458
+ * @param {Entities.DischargeResult} dischargeResult - Scalar discharge results.
1459
+ * @param {Entities.DischargeRecord[]} dischargeRecords - An array of Discharge Records.
1460
+ */
1461
+ constructor(
1462
+ exitMaterial: Entities.Material,
1463
+ dischargeResult: Entities.DischargeResult,
1464
+ dischargeRecords: Entities.DischargeRecord[],
1465
+ resultCode: Enums.ResultCode,
1466
+ messages: string[],
1467
+ calculationElapsedTime: number,
1468
+ operationId: string
1469
+ ) {
1470
+ super();
1471
+ this.exitMaterial = exitMaterial;
1472
+ this.dischargeResult = dischargeResult;
1473
+ this.dischargeRecords = dischargeRecords;
1474
+ this.resultCode = resultCode;
1475
+ this.messages = messages;
1476
+ this.calculationElapsedTime = calculationElapsedTime;
1477
+ this.operationId = operationId;
1478
+ }
1479
+
1480
+ initialiseFromDictionary(data: { [key: string]: unknown }) {
1481
+ if (data.exitMaterial) {
1482
+ this.exitMaterial = new Entities.Material();
1483
+ this.exitMaterial.initialiseFromDictionary(data.exitMaterial as { [key: string]: unknown });
1484
+ }
1485
+ if (data.dischargeResult) {
1486
+ this.dischargeResult = new Entities.DischargeResult();
1487
+ this.dischargeResult.initialiseFromDictionary(data.dischargeResult as { [key: string]: unknown });
1488
+ }
1489
+ if (data.dischargeRecords && Array.isArray(data.dischargeRecords)) {
1490
+ this.dischargeRecords = data.dischargeRecords.map(
1491
+ (item) => {
1492
+ const record = new Entities.DischargeRecord();
1493
+ record.initialiseFromDictionary(item);
1494
+ return record;
1495
+ }
1496
+ );
1497
+ }
1498
+ if (data.resultCode !== undefined && (typeof data.resultCode === "string" || typeof data.resultCode === "number")) {
1499
+ this.resultCode = data.resultCode as Enums.ResultCode;
1500
+ }
1501
+ this.messages = this.messages ?? [];
1502
+ if (data.messages && Array.isArray(data.messages)) {
1503
+ this.messages.push(...data.messages);
1504
+ }
1505
+ if (data.calculationElapsedTime !== undefined && typeof data.calculationElapsedTime === "number") {
1506
+ this.calculationElapsedTime = data.calculationElapsedTime as number;
1507
+ }
1508
+ if (data.operationId !== undefined && typeof data.operationId === "string") {
1509
+ this.operationId = data.operationId as string;
1510
+ }
1511
+ }
1512
+ }
1513
+
1514
+ export interface VesselReliefValveCalculationResponseSchemaData {
1515
+ exitMaterial: Entities.Material;
1516
+ dischargeResult: Entities.DischargeResult;
1517
+ dischargeRecords: Entities.DischargeRecord[];
1518
+ resultCode: Enums.ResultCode;
1519
+ messages: string[];
1520
+ calculationElapsedTime: number;
1521
+ operationId: string;
1522
+ }
1523
+
1524
+ export class VesselReliefValveCalculationResponseSchema {
1525
+ schema: Joi.ObjectSchema;
1526
+ propertyTypes: Record<string, string>;
1527
+
1528
+ /**
1529
+ * Schema for the VesselReliefValve calculation response.
1530
+ */
1531
+ constructor() {
1532
+ this.schema = Joi.object({
1533
+ exitMaterial: new EntitySchemas.MaterialSchema().schema,
1534
+ dischargeResult: new EntitySchemas.DischargeResultSchema().schema,
1535
+ dischargeRecords: Joi.array().items(new EntitySchemas.DischargeRecordSchema().schema).allow(null),
1536
+ resultCode: Joi.string().valid(...Object.values(Enums.ResultCode)),
1537
+ messages: Joi.array().items(Joi.string()),
1538
+ calculationElapsedTime: Joi.number().unsafe(),
1539
+ operationId: Joi.string().uuid().allow(null),
1540
+ }).unknown(true);
1541
+
1542
+ this.propertyTypes = {
1543
+ exitMaterial: "Entities.Material",
1544
+ dischargeResult: "Entities.DischargeResult",
1545
+ dischargeRecords: "Entities.DischargeRecord[]",
1546
+ };
1547
+ }
1548
+
1549
+ validate(data: VesselReliefValveCalculationResponseSchemaData): VesselReliefValveCalculationResponse {
1550
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
1551
+ if (error) {
1552
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
1553
+ }
1554
+ return this.makeCalculationResponse(value);
1555
+ }
1556
+
1557
+ makeCalculationResponse(data: VesselReliefValveCalculationResponseSchemaData): VesselReliefValveCalculationResponse {
1558
+ return new VesselReliefValveCalculationResponse(
1559
+ data.exitMaterial,
1560
+ data.dischargeResult,
1561
+ data.dischargeRecords,
1562
+ data.resultCode,
1563
+ data.messages,
1564
+ data.calculationElapsedTime,
1565
+ data.operationId
1566
+ );
1567
+ }
1568
+ }
1569
+
1570
+ export interface VesselStateCalculationRequestSchemaData {
1571
+ material: Entities.Material;
1572
+ materialState: Entities.State;
1573
+ }
1574
+
1575
+ class VesselStateCalculationRequest extends CalculationRequestBase {
1576
+ material: Entities.Material;
1577
+ materialState: Entities.State;
1578
+
1579
+ /**
1580
+ * VesselState calculation request class.
1581
+ *
1582
+ * @param {Entities.Material} material - A Material entity.
1583
+ * @param {Entities.State} materialState - A State entity describing the fluid pressure, temperature, liquid fraction.
1584
+ */
1585
+ constructor(
1586
+ material: Entities.Material,
1587
+ materialState: Entities.State
1588
+ ) {
1589
+ super();
1590
+ this.material = material;
1591
+ this.materialState = materialState;
1592
+ }
1593
+ }
1594
+
1595
+ export class VesselStateCalculationRequestSchema {
1596
+ schema: Joi.ObjectSchema;
1597
+ propertyTypes: Record<string, string>;
1598
+
1599
+ /**
1600
+ * Schema for the VesselState calculation request.
1601
+ */
1602
+ constructor() {
1603
+ this.schema = Joi.object({
1604
+ material: new EntitySchemas.MaterialSchema().schema,
1605
+ materialState: new EntitySchemas.StateSchema().schema,
1606
+ }).unknown(true);
1607
+
1608
+ this.propertyTypes = {
1609
+ material: "Entities.Material",
1610
+ materialState: "Entities.State",
1611
+ };
1612
+ }
1613
+
1614
+ validate(data: VesselStateCalculationRequestSchemaData): VesselStateCalculationRequest {
1615
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
1616
+ if (error) {
1617
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
1618
+ }
1619
+ return this.makeCalculationRequest(value);
1620
+ }
1621
+
1622
+ makeCalculationRequest(data: VesselStateCalculationRequestSchemaData): VesselStateCalculationRequest {
1623
+ return new VesselStateCalculationRequest(
1624
+ data.material,
1625
+ data.materialState
1626
+ );
1627
+ }
1628
+ }
1629
+
1630
+ export class VesselStateCalculation extends CalculationBase {
1631
+ material: Entities.Material;
1632
+ materialState: Entities.State;
1633
+ vesselConditions?: Enums.VesselConditions;
1634
+ outputState?: Entities.State;
1635
+
1636
+ /**
1637
+ * Calculates the fluid phase for a user-defined material where the user has defined the pressure and/or temperature. The model carries out a flash calculation to obtain the fluid properties. And returns
1638
+ the vessel conditions (e.g. Pure gas, Stratified Two-Phase vessel, Pressurised Liquid) that can be input to the
1639
+ source term models: vessel leak and vessel catastrophic rupture.
1640
+ *
1641
+ * @param {Entities.Material} material - A Material entity.
1642
+ * @param {Entities.State} materialState - A State entity describing the fluid pressure, temperature, liquid fraction.
1643
+ */
1644
+ constructor(
1645
+ material: Entities.Material,
1646
+ materialState: Entities.State
1647
+ ) {
1648
+ super();
1649
+ this.material = material;
1650
+ this.materialState = materialState;
1651
+ }
1652
+
1653
+ async run() {
1654
+ try {
1655
+ const request = new VesselStateCalculationRequest(
1656
+ this.material,
1657
+ this.materialState
1658
+ );
1659
+
1660
+ const schema = new VesselStateCalculationRequestSchema();
1661
+ const validatedRequest = schema.validate(request);
1662
+
1663
+ const requestJson = JSON.stringify(validatedRequest);
1664
+ const url = `${getAnalyticsApiTarget()}calculatevesselstate?clientId=${getClientAliasId()}`;
1665
+
1666
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
1667
+
1668
+ const response = await this.postRequest(url, requestJson);
1669
+
1670
+ if (response.status >= 200 && response.status < 300) {
1671
+ const schema = new VesselStateCalculationResponseSchema();
1672
+ const validatedResponse = schema.validate(response.data);
1673
+
1674
+ this.resultCode = validatedResponse.resultCode;
1675
+ if (this.resultCode === Enums.ResultCode.SUCCESS) {
1676
+ this.vesselConditions = validatedResponse.vesselConditions;
1677
+ this.outputState = validatedResponse.outputState;
1678
+ this.resultCode = validatedResponse.resultCode;
1679
+ this.messages = validatedResponse.messages ?? [];
1680
+ this.calculationElapsedTime = validatedResponse.calculationElapsedTime;
1681
+ this.operationId = validatedResponse.operationId;
1682
+ } else {
1683
+ this.messages.push(...(validatedResponse.messages ?? []));
1684
+ }
1685
+ } else {
1686
+ this.handleFailedResponse(response);
1687
+ }
1688
+ } catch (error) {
1689
+ if (error instanceof Error) {
1690
+ this.messages.push(`Error: ${error.message}`);
1691
+ } else {
1692
+ this.messages.push(`Unexpected error: ${JSON.stringify(error)}`);
1693
+ }
1694
+ console.error(error);
1695
+ this.resultCode = Enums.ResultCode.UNEXPECTED_APPLICATION_ERROR;
1696
+ }
1697
+
1698
+ return this.resultCode;
1699
+ }
1700
+
1701
+ toString() {
1702
+ const parts = ["* VesselState"];
1703
+
1704
+ parts.push(`vesselConditions: ${String(this.vesselConditions)}`);
1705
+ parts.push(`outputState: ${String(this.outputState)}`);
1706
+ parts.push(`resultCode: ${String(this.resultCode)}`);
1707
+ parts.push("*** messages:");
1708
+ parts.push(`messages: ${this.messages !== undefined ? this.messages : "(None)"}`);
1709
+ parts.push(`calculationElapsedTime: ${this.calculationElapsedTime !== undefined ? this.calculationElapsedTime : "(None)"}`);
1710
+ parts.push(`operationId: ${this.operationId !== undefined ? this.operationId : "(None)"}`);
1711
+
1712
+ return parts.join("\n");
1713
+ }
1714
+ }
1715
+
1716
+ export class VesselStateCalculationResponse extends CalculationResponseBase {
1717
+ vesselConditions: Enums.VesselConditions;
1718
+ outputState: Entities.State;
1719
+
1720
+ /**
1721
+ * VesselState calculation response class.
1722
+ *
1723
+ * @param {Enums.VesselConditions} vesselConditions - The conditions of the material in the vessel.
1724
+ * @param {Entities.State} outputState - A State entity describing the fluid pressure, temperature and liquid fraction after the flash calculation.
1725
+ */
1726
+ constructor(
1727
+ vesselConditions: Enums.VesselConditions,
1728
+ outputState: Entities.State,
1729
+ resultCode: Enums.ResultCode,
1730
+ messages: string[],
1731
+ calculationElapsedTime: number,
1732
+ operationId: string
1733
+ ) {
1734
+ super();
1735
+ this.vesselConditions = vesselConditions;
1736
+ this.outputState = outputState;
1737
+ this.resultCode = resultCode;
1738
+ this.messages = messages;
1739
+ this.calculationElapsedTime = calculationElapsedTime;
1740
+ this.operationId = operationId;
1741
+ }
1742
+
1743
+ initialiseFromDictionary(data: { [key: string]: unknown }) {
1744
+ if (data.vesselConditions !== undefined && (typeof data.vesselConditions === "string" || typeof data.vesselConditions === "number")) {
1745
+ this.vesselConditions = data.vesselConditions as Enums.VesselConditions;
1746
+ }
1747
+ if (data.outputState) {
1748
+ this.outputState = new Entities.State();
1749
+ this.outputState.initialiseFromDictionary(data.outputState as { [key: string]: unknown });
1750
+ }
1751
+ if (data.resultCode !== undefined && (typeof data.resultCode === "string" || typeof data.resultCode === "number")) {
1752
+ this.resultCode = data.resultCode as Enums.ResultCode;
1753
+ }
1754
+ this.messages = this.messages ?? [];
1755
+ if (data.messages && Array.isArray(data.messages)) {
1756
+ this.messages.push(...data.messages);
1757
+ }
1758
+ if (data.calculationElapsedTime !== undefined && typeof data.calculationElapsedTime === "number") {
1759
+ this.calculationElapsedTime = data.calculationElapsedTime as number;
1760
+ }
1761
+ if (data.operationId !== undefined && typeof data.operationId === "string") {
1762
+ this.operationId = data.operationId as string;
1763
+ }
1764
+ }
1765
+ }
1766
+
1767
+ export interface VesselStateCalculationResponseSchemaData {
1768
+ vesselConditions: Enums.VesselConditions;
1769
+ outputState: Entities.State;
1770
+ resultCode: Enums.ResultCode;
1771
+ messages: string[];
1772
+ calculationElapsedTime: number;
1773
+ operationId: string;
1774
+ }
1775
+
1776
+ export class VesselStateCalculationResponseSchema {
1777
+ schema: Joi.ObjectSchema;
1778
+ propertyTypes: Record<string, string>;
1779
+
1780
+ /**
1781
+ * Schema for the VesselState calculation response.
1782
+ */
1783
+ constructor() {
1784
+ this.schema = Joi.object({
1785
+ vesselConditions: Joi.string().valid(...Object.values(Enums.VesselConditions)),
1786
+ outputState: new EntitySchemas.StateSchema().schema,
1787
+ resultCode: Joi.string().valid(...Object.values(Enums.ResultCode)),
1788
+ messages: Joi.array().items(Joi.string()),
1789
+ calculationElapsedTime: Joi.number().unsafe(),
1790
+ operationId: Joi.string().uuid().allow(null),
1791
+ }).unknown(true);
1792
+
1793
+ this.propertyTypes = {
1794
+ vesselConditions: "Enums.VesselConditions",
1795
+ outputState: "Entities.State",
1796
+ };
1797
+ }
1798
+
1799
+ validate(data: VesselStateCalculationResponseSchemaData): VesselStateCalculationResponse {
1800
+ const { error, value } = this.schema.validate(data, { abortEarly: false });
1801
+ if (error) {
1802
+ throw new Error(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
1803
+ }
1804
+ return this.makeCalculationResponse(value);
1805
+ }
1806
+
1807
+ makeCalculationResponse(data: VesselStateCalculationResponseSchemaData): VesselStateCalculationResponse {
1808
+ return new VesselStateCalculationResponse(
1809
+ data.vesselConditions,
1810
+ data.outputState,
1811
+ data.resultCode,
1812
+ data.messages,
1813
+ data.calculationElapsedTime,
1814
+ data.operationId
1815
+ );
1816
+ }
1817
+ }