@shapediver/viewer.session-engine.session-engine 2.12.8 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/implementation/OutputDelayException.js +1 -1
  2. package/dist/implementation/OutputDelayException.js.map +1 -1
  3. package/dist/implementation/OutputLoader.d.ts +9 -7
  4. package/dist/implementation/OutputLoader.d.ts.map +1 -1
  5. package/dist/implementation/OutputLoader.js +56 -41
  6. package/dist/implementation/OutputLoader.js.map +1 -1
  7. package/dist/implementation/SessionData.d.ts +1 -1
  8. package/dist/implementation/SessionData.d.ts.map +1 -1
  9. package/dist/implementation/SessionData.js +2 -2
  10. package/dist/implementation/SessionData.js.map +1 -1
  11. package/dist/implementation/SessionEngine.d.ts +30 -3
  12. package/dist/implementation/SessionEngine.d.ts.map +1 -1
  13. package/dist/implementation/SessionEngine.js +115 -48
  14. package/dist/implementation/SessionEngine.js.map +1 -1
  15. package/dist/implementation/SessionOutputData.d.ts +1 -1
  16. package/dist/implementation/SessionOutputData.d.ts.map +1 -1
  17. package/dist/implementation/SessionOutputData.js +2 -2
  18. package/dist/implementation/SessionOutputData.js.map +1 -1
  19. package/dist/implementation/SessionTreeNode.d.ts +1 -1
  20. package/dist/implementation/SessionTreeNode.d.ts.map +1 -1
  21. package/dist/implementation/SessionTreeNode.js +1 -1
  22. package/dist/implementation/SessionTreeNode.js.map +1 -1
  23. package/dist/implementation/dto/Export.d.ts +4 -4
  24. package/dist/implementation/dto/Export.d.ts.map +1 -1
  25. package/dist/implementation/dto/Export.js +2 -2
  26. package/dist/implementation/dto/Export.js.map +1 -1
  27. package/dist/implementation/dto/FileParameter.d.ts +2 -2
  28. package/dist/implementation/dto/FileParameter.d.ts.map +1 -1
  29. package/dist/implementation/dto/FileParameter.js +69 -31
  30. package/dist/implementation/dto/FileParameter.js.map +1 -1
  31. package/dist/implementation/dto/Output.js +2 -2
  32. package/dist/implementation/dto/Output.js.map +1 -1
  33. package/dist/implementation/dto/Parameter.d.ts +6 -6
  34. package/dist/implementation/dto/Parameter.d.ts.map +1 -1
  35. package/dist/implementation/dto/Parameter.js +106 -87
  36. package/dist/implementation/dto/Parameter.js.map +1 -1
  37. package/dist/index.d.ts +9 -10
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +7 -10
  40. package/dist/index.js.map +1 -1
  41. package/dist/interfaces/ISessionData.d.ts +2 -2
  42. package/dist/interfaces/ISessionData.d.ts.map +1 -1
  43. package/dist/interfaces/ISessionEngine.d.ts +11 -46
  44. package/dist/interfaces/ISessionEngine.d.ts.map +1 -1
  45. package/dist/interfaces/ISessionEngine.js +0 -4
  46. package/dist/interfaces/ISessionEngine.js.map +1 -1
  47. package/dist/interfaces/ISessionOutputData.d.ts +2 -2
  48. package/dist/interfaces/ISessionOutputData.d.ts.map +1 -1
  49. package/dist/interfaces/ISessionTreeNode.d.ts +1 -1
  50. package/dist/interfaces/dto/IExport.d.ts +2 -2
  51. package/dist/interfaces/dto/IExport.d.ts.map +1 -1
  52. package/dist/interfaces/dto/IFileParameter.d.ts +1 -1
  53. package/dist/interfaces/dto/IFileParameter.d.ts.map +1 -1
  54. package/dist/interfaces/dto/IOutput.d.ts +13 -13
  55. package/dist/interfaces/dto/IOutput.d.ts.map +1 -1
  56. package/dist/interfaces/dto/IOutput.js +1 -0
  57. package/dist/interfaces/dto/IOutput.js.map +1 -1
  58. package/dist/interfaces/dto/IParameter.d.ts +3 -3
  59. package/dist/interfaces/dto/IParameter.d.ts.map +1 -1
  60. package/package.json +9 -10
  61. package/src/implementation/OutputDelayException.ts +3 -3
  62. package/src/implementation/OutputLoader.ts +139 -104
  63. package/src/implementation/SessionData.ts +9 -9
  64. package/src/implementation/SessionEngine.ts +133 -53
  65. package/src/implementation/SessionOutputData.ts +8 -8
  66. package/src/implementation/SessionTreeNode.ts +8 -5
  67. package/src/implementation/dto/Export.ts +24 -11
  68. package/src/implementation/dto/FileParameter.ts +72 -37
  69. package/src/implementation/dto/Output.ts +2 -2
  70. package/src/implementation/dto/Parameter.ts +115 -85
  71. package/src/index.ts +17 -21
  72. package/src/interfaces/ISessionData.ts +2 -2
  73. package/src/interfaces/ISessionEngine.ts +19 -60
  74. package/src/interfaces/ISessionOutputData.ts +2 -2
  75. package/src/interfaces/ISessionTreeNode.ts +1 -1
  76. package/src/interfaces/dto/IExport.ts +4 -4
  77. package/src/interfaces/dto/IFileParameter.ts +2 -2
  78. package/src/interfaces/dto/IOutput.ts +38 -26
  79. package/src/interfaces/dto/IParameter.ts +3 -3
@@ -1,18 +1,18 @@
1
- import { ShapeDiverResponseParameter } from '@shapediver/sdk.geometry-api-sdk-v2';
2
- import { Logger, ShapeDiverViewerSessionError, UuidGenerator } from '@shapediver/viewer.shared.services';
1
+ import * as MimeTypeUtils from '@shapediver/viewer.utils.mime-type';
3
2
  import { IFileParameter } from '../../interfaces/dto/IFileParameter';
3
+ import { Logger, ShapeDiverViewerSessionError, UuidGenerator } from '@shapediver/viewer.shared.services';
4
4
  import { Parameter } from './Parameter';
5
- import * as MimeTypeUtils from '@shapediver/viewer.utils.mime-type';
6
5
  import { SessionEngine } from '../SessionEngine';
6
+ import { ShapeDiverResponseParameter } from '@shapediver/sdk.geometry-api-sdk-v2';
7
7
 
8
8
  export class FileParameter extends Parameter<File | Blob | string> implements IFileParameter {
9
- // #region Properties (5)
9
+ // #region Properties (3)
10
10
 
11
11
  readonly #logger: Logger = Logger.instance;
12
12
  readonly #sessionEngine: SessionEngine;
13
13
  readonly #uuidGenerator: UuidGenerator = UuidGenerator.instance;
14
14
 
15
- // #endregion Properties (5)
15
+ // #endregion Properties (3)
16
16
 
17
17
  // #region Constructors (1)
18
18
 
@@ -23,29 +23,66 @@ export class FileParameter extends Parameter<File | Blob | string> implements IF
23
23
 
24
24
  // #endregion Constructors (1)
25
25
 
26
- // #region Public Methods (1)
26
+ // #region Public Methods (2)
27
27
 
28
- public async upload() {
29
- if (this.value === undefined) return this.defval;
30
- if (typeof this.value === 'string' && ((this.value.length === 36 && this.#uuidGenerator.validate(this.value)) || this.value === '')) return this.value;
28
+ public async getFilename(fileId?: string): Promise<string | undefined> {
29
+ // if fileId is undefined and value is undefined, return undefined
30
+ if (fileId === undefined && this.value === undefined) return;
31
31
 
32
- const data = new File(
33
- [
34
- typeof this.value === 'string' ?
35
- new Blob([this.value], { type: 'text/plain' }) :
36
- this.value
37
- ],
38
- this.value instanceof File ? this.value.name : '',
39
- { type: (<Blob | File>this.value).type }
40
- );
32
+ // if fileId is undefined and value is a string and is a valid uuid, use the value as fileId
33
+ if (fileId === undefined && typeof this.value === 'string' && ((this.value.length === 36 && this.#uuidGenerator.validate(this.value)) || this.value === ''))
34
+ return (await this.#sessionEngine.getFileInfo(this.id, this.value)).filename;
41
35
 
42
- let types = [data.type];
36
+ // if fileId is undefined, return undefined
37
+ if (fileId === undefined) return;
38
+
39
+ return (await this.#sessionEngine.getFileInfo(this.id, fileId)).filename;
40
+ }
41
+
42
+ public async upload(v?: File | Blob | string): Promise<string> {
43
+ const value = v !== undefined ? v : this.value;
44
+
45
+ if (value === undefined) return this.defval;
46
+ if (typeof value === 'string' && ((value.length === 36 && this.#uuidGenerator.validate(value)) || value === '')) return value;
47
+
48
+ // get the type of the file
49
+ let fileType: string | string[];
50
+ if (value instanceof File) {
51
+ if (value.type === '') {
52
+ // try to get type from file name
53
+ const types = MimeTypeUtils.guessMimeTypeFromFilename(value.name);
54
+ if (types.length === 0) {
55
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.id}).upload: Error uploading FileParameter, provided File has no type and could not be guessed from filename. Has to be ${this.format}.`);
56
+ } else {
57
+ fileType = types;
58
+ }
59
+ } else {
60
+ fileType = value.type;
61
+ }
62
+ } else if (value instanceof Blob) {
63
+ if (value.type === '') {
64
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.id}).upload: Error uploading FileParameter, provided File has no type and could not be guessed from filename. Has to be ${this.format}.`);
65
+ } else {
66
+ fileType = value.type;
67
+ }
68
+ } else {
69
+ fileType = 'text/plain';
70
+ }
71
+
72
+ /**
73
+ * Get all possible mime types for the provided fileType.
74
+ */
75
+ let types = typeof fileType === 'string' ? [fileType] : fileType;
43
76
  // get all endings that are possible for this type
44
77
  const endings = MimeTypeUtils.mapMimeTypeToFileEndings(types);
45
78
  // get all mimeTypes that are possible for these endings
46
79
  endings.forEach((e: string) => types = types.concat(MimeTypeUtils.guessMimeTypeFromFilename(e)));
47
80
 
48
- let type: string;
81
+ /**
82
+ * Check if the provided fileType is allowed for this parameter.
83
+ * If not, throw an error.
84
+ */
85
+ let type: string | undefined = undefined;
49
86
  // check if one of the mime types is allowed
50
87
  let allowedType = false;
51
88
  for (let i = 0; i < types.length; i++) {
@@ -56,27 +93,25 @@ export class FileParameter extends Parameter<File | Blob | string> implements IF
56
93
  }
57
94
  }
58
95
 
59
- if (!allowedType)
60
- throw new ShapeDiverViewerSessionError(`Parameter(${this.id}).upload: Error uploading FileParameter, type of data (${data.type}) is not a valid type. Has to be ${this.format}.`);
96
+ // if the type is not allowed, throw an error
97
+ if (allowedType === false || type === undefined)
98
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.id}).upload: Error uploading FileParameter, type of data (${fileType}) is not a valid type. Has to be ${this.format}.`);
99
+
100
+ // create a File object
101
+ const data = new File(
102
+ [
103
+ typeof value === 'string' ?
104
+ new Blob([value], { type: 'text/plain' }) :
105
+ value
106
+ ],
107
+ value instanceof File && value.name !== undefined ? value.name : '',
108
+ { type }
109
+ );
61
110
 
62
111
  this.#logger.debug(`Parameter(${this.id}).upload: Uploading FileParameter.`);
63
112
 
64
113
  return await this.#sessionEngine.uploadFile(this.id, data, type!);
65
114
  }
66
115
 
67
- public async getFilename(fileId?: string): Promise<string | undefined> {
68
- // if fileId is undefined and value is undefined, return undefined
69
- if (fileId === undefined && this.value === undefined) return;
70
-
71
- // if fileId is undefined and value is a string and is a valid uuid, use the value as fileId
72
- if (fileId === undefined && typeof this.value === 'string' && ((this.value.length === 36 && this.#uuidGenerator.validate(this.value)) || this.value === ''))
73
- return (await this.#sessionEngine.getFileInfo(this.id, this.value)).filename;
74
-
75
- // if fileId is undefined, return undefined
76
- if (fileId === undefined) return;
77
-
78
- return (await this.#sessionEngine.getFileInfo(this.id, fileId)).filename;
79
- }
80
-
81
- // #endregion Public Methods (1)
116
+ // #endregion Public Methods (2)
82
117
  }
@@ -47,7 +47,7 @@ export class Output implements IOutput {
47
47
 
48
48
  // #endregion Constructors (1)
49
49
 
50
- // #region Public Accessors (30)
50
+ // #region Public Getters And Setters (30)
51
51
 
52
52
  public get bbmax(): number[] | undefined {
53
53
  return this.#bbmax;
@@ -169,7 +169,7 @@ export class Output implements IOutput {
169
169
  this.#version = value;
170
170
  }
171
171
 
172
- // #endregion Public Accessors (30)
172
+ // #endregion Public Getters And Setters (30)
173
173
 
174
174
  // #region Public Methods (4)
175
175
 
@@ -1,18 +1,27 @@
1
- import { ShapeDiverResponseParameterStructure, ShapeDiverResponseParameterGroup, ShapeDiverResponseParameter } from "@shapediver/sdk.geometry-api-sdk-v2";
2
- import { Converter, InputValidator, Logger, ShapeDiverViewerSessionError } from "@shapediver/viewer.shared.services";
3
- import { IParameter } from "../../interfaces/dto/IParameter";
4
- import { ISessionEngine, PARAMETER_TYPE, PARAMETER_VISUALIZATION } from "../../interfaces/ISessionEngine";
5
- import * as MimeTypeUtils from "@shapediver/viewer.utils.mime-type"
6
- import { SessionEngine } from "../SessionEngine";
1
+ import * as MimeTypeUtils from '@shapediver/viewer.utils.mime-type';
2
+ import {
3
+ Converter,
4
+ EVENTTYPE_PARAMETER,
5
+ EVENTTYPE_SESSION,
6
+ EventEngine,
7
+ InputValidator,
8
+ Logger,
9
+ ShapeDiverViewerSessionError
10
+ } from '@shapediver/viewer.shared.services';
11
+ import { IParameter } from '../../interfaces/dto/IParameter';
12
+ import { ISessionEvent, PARAMETER_TYPE, PARAMETER_VISUALIZATION } from '@shapediver/viewer.shared.types';
13
+ import { SessionEngine } from '../SessionEngine';
14
+ import { ShapeDiverResponseParameter, ShapeDiverResponseParameterGroup, ShapeDiverResponseParameterStructure } from '@shapediver/sdk.geometry-api-sdk-v2';
7
15
 
8
16
  export class Parameter<T> implements IParameter<T> {
9
- // #region Properties (24)
17
+ // #region Properties (25)
10
18
 
11
19
  readonly #choices?: string[];
12
20
  readonly #converter: Converter = Converter.instance;
13
21
  readonly #decimalplaces?: number;
14
22
  readonly #defaultValue: T | string;
15
23
  readonly #defval: string;
24
+ readonly #eventEngine = EventEngine.instance;
16
25
  readonly #expression?: string;
17
26
  readonly #format?: string[];
18
27
  readonly #group?: ShapeDiverResponseParameterGroup;
@@ -35,7 +44,7 @@ export class Parameter<T> implements IParameter<T> {
35
44
  #tooltip?: string;
36
45
  #value: T | string;
37
46
 
38
- // #endregion Properties (24)
47
+ // #endregion Properties (25)
39
48
 
40
49
  // #region Constructors (1)
41
50
 
@@ -73,9 +82,9 @@ export class Parameter<T> implements IParameter<T> {
73
82
  }
74
83
 
75
84
  if (this.#type === PARAMETER_TYPE.COLOR) {
76
- (<any>this).convertColor = (color: any): string => {
85
+ (this as unknown as { convertColor: (color: unknown) => string }).convertColor = (color: unknown): string => {
77
86
  return this.#converter.toHexColor(color);
78
- }
87
+ };
79
88
  }
80
89
 
81
90
  this.#value = this.#defaultValue;
@@ -85,7 +94,7 @@ export class Parameter<T> implements IParameter<T> {
85
94
 
86
95
  // #endregion Constructors (1)
87
96
 
88
- // #region Public Accessors (26)
97
+ // #region Public Getters And Setters (26)
89
98
 
90
99
  public get choices(): string[] | undefined {
91
100
  return this.#choices;
@@ -161,6 +170,13 @@ export class Parameter<T> implements IParameter<T> {
161
170
 
162
171
  public set sessionValue(value: T | string) {
163
172
  this.#sessionValue = value;
173
+
174
+ // emit event
175
+ this.#eventEngine.emitEvent(EVENTTYPE_PARAMETER.PARAMETER_SESSION_VALUE_CHANGED, <ISessionEvent>{
176
+ sessionId: this.#sessionEngine.id,
177
+ parameterId: this.#id,
178
+ value: value
179
+ });
164
180
  }
165
181
 
166
182
  public get structure(): ShapeDiverResponseParameterStructure | undefined {
@@ -185,22 +201,31 @@ export class Parameter<T> implements IParameter<T> {
185
201
 
186
202
  public set value(value: T | string) {
187
203
  this.#value = value;
188
- if(this.#sessionEngine.customizeOnParameterChange) this.#sessionEngine.customize();
204
+
205
+ // emit event
206
+ this.#eventEngine.emitEvent(EVENTTYPE_PARAMETER.PARAMETER_VALUE_CHANGED, <ISessionEvent>{
207
+ sessionId: this.#sessionEngine.id,
208
+ parameterId: this.#id,
209
+ value: value
210
+ });
211
+
212
+ // if customizeOnParameterChange is true, customize the session
213
+ if (this.#sessionEngine.customizeOnParameterChange) this.#sessionEngine.customize();
189
214
  }
190
215
 
191
216
  public get visualization(): PARAMETER_VISUALIZATION | undefined {
192
217
  return this.#visualization;
193
218
  }
194
219
 
195
- // #endregion Public Accessors (26)
220
+ // #endregion Public Getters And Setters (26)
196
221
 
197
222
  // #region Public Methods (4)
198
223
 
199
- public isValid(value: any): boolean {
224
+ public isValid(value: unknown): boolean {
200
225
  switch (true) {
201
226
  case this.type === PARAMETER_TYPE.BOOL:
202
227
  if (typeof value === 'string') {
203
- if (!(value === 'true' || value === 'false'))
228
+ if (!(value === 'true' || value === 'false'))
204
229
  throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is a string that is neither true or false.`);
205
230
  } else {
206
231
  this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, value, 'boolean');
@@ -213,76 +238,79 @@ export class Parameter<T> implements IParameter<T> {
213
238
  this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, value, 'file');
214
239
  break;
215
240
  case this.type === PARAMETER_TYPE.EVEN || this.type === PARAMETER_TYPE.FLOAT || this.type === PARAMETER_TYPE.INT || this.type === PARAMETER_TYPE.ODD:
216
- let temp: number = value;
217
- if (typeof value === 'string')
218
- temp = +value;
219
- this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, temp, 'number');
220
- if (this.type === PARAMETER_TYPE.EVEN) {
221
- if (temp % 2 !== 0)
222
- throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is not even.`);
223
- } else if (this.type === PARAMETER_TYPE.ODD) {
224
- if (temp % 2 === 0)
225
- throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is not odd.`);
226
- } else if (this.type === PARAMETER_TYPE.INT) {
227
- if (!Number.isInteger(temp))
228
- throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is not an integer.`);
229
- }
230
- if (this.min || this.min === 0)
231
- if (temp < this.min)
232
- throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is smaller than the minimum ${this.min}.`);
233
-
234
- if (this.max || this.max === 0)
235
- if (temp > this.max)
236
- throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is larger than the maximum ${this.max}.`);
237
-
238
- if (this.decimalplaces || this.decimalplaces === 0) {
239
- const numStr = temp + '';
240
- let decimalplaces = 0;
241
- if (numStr.includes('.'))
242
- decimalplaces = numStr.split('.')[1].length;
243
- if (this.decimalplaces < decimalplaces)
244
- throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} has not the correct number of decimalplaces (${this.decimalplaces}).`);
245
- }
241
+ {
242
+ let temp = value as number;
243
+ if (typeof value === 'string')
244
+ temp = +value;
245
+ this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, temp, 'number');
246
+ if (this.type === PARAMETER_TYPE.EVEN) {
247
+ if (temp % 2 !== 0)
248
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is not even.`);
249
+ } else if (this.type === PARAMETER_TYPE.ODD) {
250
+ if (temp % 2 === 0)
251
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is not odd.`);
252
+ } else if (this.type === PARAMETER_TYPE.INT) {
253
+ if (!Number.isInteger(temp))
254
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is not an integer.`);
255
+ }
256
+ if (this.min || this.min === 0)
257
+ if (temp < this.min)
258
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is smaller than the minimum ${this.min}.`);
259
+
260
+ if (this.max || this.max === 0)
261
+ if (temp > this.max)
262
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} is larger than the maximum ${this.max}.`);
246
263
 
264
+ if (this.decimalplaces || this.decimalplaces === 0) {
265
+ const numStr = temp + '';
266
+ let decimalplaces = 0;
267
+ if (numStr.includes('.'))
268
+ decimalplaces = numStr.split('.')[1].length;
269
+ if (this.decimalplaces < decimalplaces)
270
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${value} has not the correct number of decimalplaces (${this.decimalplaces}).`);
271
+ }
272
+ }
247
273
  break;
248
274
  case this.type === PARAMETER_TYPE.STRINGLIST:
249
- this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, value, 'string');
250
- const choicesChecker = (v: string) => {
251
- // has to be a single value that is
252
- // 1. convertible to number
253
- // 2. between 0 and choices.length -1
254
- const temp = +v;
255
- this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, temp, 'number');
256
- if (temp < 0 || temp > this.choices!.length - 1)
257
- throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${v} is not within the range of the defined number choices.`);
258
- }
259
-
260
- if (this.visualization === PARAMETER_VISUALIZATION.CHECKLIST) {
261
- // comma separated numbers
262
- if (value.includes(',')) {
263
- const values: string[] = value.split(',');
264
- for (let i = 0; i < values.length; i++) {
265
- if (values.filter(item => item === values[i]).length !== 1)
266
- throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${values[i]} exists multiple times, but should only exist once.`);
267
- choicesChecker(values[i]);
275
+ {
276
+ this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, value, 'string');
277
+ const choicesChecker = (v: string) => {
278
+ // has to be a single value that is
279
+ // 1. convertible to number
280
+ // 2. between 0 and choices.length -1
281
+ const temp = +v;
282
+ this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, temp, 'number');
283
+ if (temp < 0 || temp > this.choices!.length - 1)
284
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${v} is not within the range of the defined number choices.`);
285
+ };
286
+
287
+ if (this.visualization === PARAMETER_VISUALIZATION.CHECKLIST) {
288
+ // comma separated numbers
289
+ if ((value as string).includes(',')) {
290
+ const values: string[] = (value as string).split(',');
291
+ for (let i = 0; i < values.length; i++) {
292
+ if (values.filter(item => item === values[i]).length !== 1)
293
+ throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).isValid: The value ${values[i]} exists multiple times, but should only exist once.`);
294
+ choicesChecker(values[i]);
295
+ }
296
+ } else {
297
+ // to number
298
+ let temp = value as number;
299
+ if (typeof value === 'string')
300
+ temp = +value;
301
+ this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, temp, 'number');
302
+ choicesChecker(value as string);
268
303
  }
269
304
  } else {
270
305
  // to number
271
- let temp: number = value;
306
+ let temp = value as number;
272
307
  if (typeof value === 'string')
273
308
  temp = +value;
274
309
  this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, temp, 'number');
275
- choicesChecker(value);
310
+ choicesChecker(value as string);
276
311
  }
277
- } else {
278
- // to number
279
- let temp: number = value;
280
- if (typeof value === 'string')
281
- temp = +value;
282
- this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, temp, 'number');
283
- choicesChecker(value);
312
+ break;
284
313
  }
285
- break;
286
314
  default:
287
315
  this.#inputValidator.validateAndError(`Parameter(${this.#id}).isValid`, value, 'string');
288
316
  break;
@@ -298,35 +326,37 @@ export class Parameter<T> implements IParameter<T> {
298
326
  this.#value = this.sessionValue;
299
327
  }
300
328
 
301
- public stringify(): string {
329
+ public stringify(val?: unknown): string {
330
+ const value = val !== undefined ? val : this.value;
331
+
302
332
  switch (true) {
303
333
  case this.type === PARAMETER_TYPE.BOOL:
304
- return typeof this.value === 'string' ? this.value : (<boolean><unknown>this.value) + '';
334
+ return typeof value === 'string' ? value : (<boolean><unknown>value) + '';
305
335
  case this.type === PARAMETER_TYPE.COLOR:
306
- return this.#converter.toHex8Color(this.value);
336
+ return this.#converter.toHex8Color(value);
307
337
  case this.type === PARAMETER_TYPE.FILE:
308
- if (typeof this.value !== 'string')
338
+ if (typeof value !== 'string')
309
339
  throw new ShapeDiverViewerSessionError(`Parameter(${this.#id}).stringify: Error in stringify. Cannot stringify FileParameter that has not been uploaded yet.`);
310
- return <string>this.value;
340
+ return <string>value;
311
341
  case this.type === PARAMETER_TYPE.EVEN || this.type === PARAMETER_TYPE.FLOAT || this.type === PARAMETER_TYPE.INT || this.type === PARAMETER_TYPE.ODD:
312
- if(typeof this.value === 'string') {
342
+ if (typeof value === 'string') {
313
343
  // cast to number and round to decimalplaces if they exist
314
344
  if (this.decimalplaces || this.decimalplaces === 0) {
315
- const number = +this.value;
345
+ const number = +value;
316
346
  return number.toFixed(this.#decimalplaces);
317
347
  } else {
318
- return this.value;
348
+ return value;
319
349
  }
320
350
  } else {
321
351
  // round to decimalplaces if they exist
322
352
  if (this.decimalplaces || this.decimalplaces === 0) {
323
- return (<number><unknown>this.value).toFixed(this.#decimalplaces);
353
+ return (<number><unknown>value).toFixed(this.#decimalplaces);
324
354
  } else {
325
- return (<number><unknown>this.value) + '';
355
+ return (<number><unknown>value) + '';
326
356
  }
327
357
  }
328
358
  default:
329
- return <string>this.value;
359
+ return <string>value;
330
360
  }
331
361
  }
332
362
 
package/src/index.ts CHANGED
@@ -1,26 +1,22 @@
1
- import { SessionEngine } from './implementation/SessionEngine'
2
- import { ISessionEngine, ISettingsSections, PARAMETER_TYPE, PARAMETER_VISUALIZATION } from './interfaces/ISessionEngine'
3
- import { SessionOutputData } from './implementation/SessionOutputData'
4
- import { SessionData } from './implementation/SessionData'
5
- import { ISessionData } from './interfaces/ISessionData'
6
- import { ISessionOutputData } from './interfaces/ISessionOutputData'
7
- import { Export } from './implementation/dto/Export'
8
- import { FileParameter } from './implementation/dto/FileParameter'
9
- import { Output } from './implementation/dto/Output'
10
- import { Parameter } from './implementation/dto/Parameter'
11
- import { IExport } from './interfaces/dto/IExport'
12
- import { IFileParameter } from './interfaces/dto/IFileParameter'
13
- import { IOutput, ShapeDiverResponseOutputChunk, ShapeDiverResponseOutputContent } from './interfaces/dto/IOutput'
14
- import { IParameter } from './interfaces/dto/IParameter'
1
+ import { Export } from './implementation/dto/Export';
2
+ import { FileParameter } from './implementation/dto/FileParameter';
3
+ import { IExport } from './interfaces/dto/IExport';
4
+ import { IFileParameter } from './interfaces/dto/IFileParameter';
5
+ import { IOutput, ShapeDiverResponseOutputChunk, ShapeDiverResponseOutputContent } from './interfaces/dto/IOutput';
6
+ import { IParameter } from './interfaces/dto/IParameter';
7
+ import { ISessionData } from './interfaces/ISessionData';
8
+ import { ISessionEngine } from './interfaces/ISessionEngine';
9
+ import { ISessionOutputData } from './interfaces/ISessionOutputData';
10
+ import { Output } from './implementation/dto/Output';
11
+ import { Parameter } from './implementation/dto/Parameter';
12
+ import { SessionData } from './implementation/SessionData';
13
+ import { SessionEngine } from './implementation/SessionEngine';
14
+ import { SessionOutputData } from './implementation/SessionOutputData';
15
15
 
16
16
  export {
17
- ISessionData, SessionData, ISessionOutputData, SessionOutputData, ISettingsSections
18
- }
17
+ ISessionData, SessionData, ISessionOutputData, SessionOutputData
18
+ };
19
19
 
20
20
  export {
21
21
  ISessionEngine, SessionEngine, IOutput, Output, IParameter, Parameter, IFileParameter, FileParameter, IExport, Export, ShapeDiverResponseOutputContent, ShapeDiverResponseOutputChunk
22
- }
23
-
24
- export {
25
- PARAMETER_TYPE, PARAMETER_VISUALIZATION
26
- }
22
+ };
@@ -1,5 +1,5 @@
1
- import { ShapeDiverResponseDto } from "@shapediver/sdk.geometry-api-sdk-v2";
2
- import { ITreeNodeData } from "@shapediver/viewer.shared.node-tree";
1
+ import { ITreeNodeData } from '@shapediver/viewer.shared.node-tree';
2
+ import { ShapeDiverResponseDto } from '@shapediver/sdk.geometry-api-sdk-v2';
3
3
 
4
4
  export interface ISessionData extends ITreeNodeData {
5
5
  // #region Properties (1)
@@ -1,64 +1,21 @@
1
- import { ShapeDiverRequestCustomization, ShapeDiverRequestExport, ShapeDiverRequestGltfUploadQueryConversion, ShapeDiverResponseDto, ShapeDiverResponseExport, ShapeDiverResponseFileInfo, ShapeDiverResponseParameterType, ShapeDiverResponseParameterVisualization } from '@shapediver/sdk.geometry-api-sdk-v2';
2
- import { ITreeNode } from '@shapediver/viewer.shared.node-tree';
3
- import { SettingsEngine } from '@shapediver/viewer.shared.services';
4
- import { OutputLoaderTaskEventInfo } from '../implementation/OutputLoader';
5
1
  import { IExport } from './dto/IExport';
6
2
  import { IOutput } from './dto/IOutput';
7
3
  import { IParameter } from './dto/IParameter';
8
-
9
- /**
10
- * The type of the parameter.
11
- */
12
- export {
13
- ShapeDiverResponseParameterType as PARAMETER_TYPE,
14
- ShapeDiverResponseParameterVisualization as PARAMETER_VISUALIZATION
15
- };
16
-
17
- export interface ISettingsSections {
18
- // #region Properties (2)
19
-
20
- session?: {
21
- parameter?: {
22
- /** Option to update the displayname of the parameters (default: false) */
23
- displayname?: boolean,
24
- /** Option to update the order of the parameters (default: false) */
25
- order?: boolean,
26
- /** Option to update the hidden state of the parameters (default: false) */
27
- hidden?: boolean,
28
- /** Option to update the value of the parameters (default: false) */
29
- value?: boolean
30
- },
31
- export?: {
32
- /** Option to update the displayname of the exports (default: false) */
33
- displayname?: boolean,
34
- /** Option to update the order of the exports (default: false) */
35
- order?: boolean,
36
- /** Option to update the hidden state of the exports (default: false) */
37
- hidden?: boolean
38
- }
39
- },
40
- viewport?: {
41
- /** Option to update the ar settings (default: false) */
42
- ar?: boolean,
43
- /** Option to update the scene settings (default: false) */
44
- scene?: boolean,
45
- /** Option to update the camera settings (default: false) */
46
- camera?: boolean,
47
- /** Option to update the light settings (default: false) */
48
- light?: boolean,
49
- /** Option to update the environment settings (default: false) */
50
- environment?: boolean
51
- /** Option to update the general settings (default: false) */
52
- general?: boolean
53
- /** Option to update the postprocessing settings (default: false) */
54
- postprocessing?: boolean
55
- }
56
-
57
- // #endregion Properties (2)
58
- }
4
+ import { ISettingsSections } from '@shapediver/viewer.shared.types';
5
+ import { ITreeNode } from '@shapediver/viewer.shared.node-tree';
6
+ import { OutputLoaderTaskEventInfo } from '../implementation/OutputLoader';
7
+ import { SettingsEngine } from '@shapediver/viewer.shared.services';
8
+ import {
9
+ ShapeDiverRequestCustomization,
10
+ ShapeDiverRequestExport,
11
+ ShapeDiverRequestGltfUploadQueryConversion,
12
+ ShapeDiverResponseDto,
13
+ ShapeDiverResponseExport,
14
+ ShapeDiverResponseFileInfo
15
+ } from '@shapediver/sdk.geometry-api-sdk-v2';
59
16
 
60
17
  export interface ISessionEngine {
61
- // #region Properties (13)
18
+ // #region Properties (14)
62
19
 
63
20
  readonly jwtToken?: string;
64
21
 
@@ -67,6 +24,7 @@ export interface ISessionEngine {
67
24
  guid?: string;
68
25
  id: string;
69
26
  initialized: boolean;
27
+ loadSdtf: boolean;
70
28
  modelViewUrl: string;
71
29
  outputs: { [key: string]: IOutput };
72
30
  parameters: { [key: string]: IParameter<unknown> };
@@ -75,15 +33,15 @@ export interface ISessionEngine {
75
33
  ticket?: string;
76
34
  updateCallback: ((newNode: ITreeNode, oldNode: ITreeNode) => void) | null;
77
35
 
78
- // #endregion Properties (13)
36
+ // #endregion Properties (14)
79
37
 
80
- // #region Public Methods (21)
38
+ // #region Public Methods (24)
81
39
 
82
40
  applySettings(response: ShapeDiverResponseDto, sections?: ISettingsSections): void;
83
41
  canGoBack(): boolean;
84
42
  canGoForward(): boolean;
85
43
  close(): Promise<void>;
86
- customize(force: boolean, waitForViewportUpdate?: boolean):Promise<ITreeNode | ShapeDiverResponseDto>;
44
+ customize(force: boolean, waitForViewportUpdate?: boolean): Promise<ITreeNode | ShapeDiverResponseDto>;
87
45
  customizeParallel(parameterValues: { [key: string]: string }, loadOutputs: boolean): Promise<ITreeNode | ShapeDiverResponseDto>;
88
46
  getFileInfo(parameterId: string, fileId: string): Promise<ShapeDiverResponseFileInfo>
89
47
  goBack(): Promise<ITreeNode>;
@@ -101,7 +59,8 @@ export interface ISessionEngine {
101
59
  setJwtToken(token: string): Promise<void>;
102
60
  updateOutputs(taskEventInfo?: OutputLoaderTaskEventInfo, waitForViewportUpdate?: boolean): Promise<ITreeNode>;
103
61
  uploadFile(parameterId: string, data: File, type: string): Promise<string>;
62
+ uploadFileParameters(parameterValues?: { [key: string]: string | File | Blob }): Promise<{ [key: string]: string }>
104
63
  uploadGLTF(blob: Blob, conversion?: ShapeDiverRequestGltfUploadQueryConversion): Promise<ShapeDiverResponseDto>;
105
64
 
106
- // #endregion Public Methods (21)
65
+ // #endregion Public Methods (24)
107
66
  }