@adobe/acc-js-sdk 1.1.61 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/.cursor/commands/opsx-apply.md +152 -0
  2. package/.cursor/commands/opsx-archive.md +157 -0
  3. package/.cursor/commands/opsx-explore.md +173 -0
  4. package/.cursor/commands/opsx-propose.md +106 -0
  5. package/.cursor/skills/openspec-apply-change/SKILL.md +156 -0
  6. package/.cursor/skills/openspec-archive-change/SKILL.md +114 -0
  7. package/.cursor/skills/openspec-explore/SKILL.md +288 -0
  8. package/.cursor/skills/openspec-propose/SKILL.md +110 -0
  9. package/.eslintrc.js +2 -2
  10. package/.github/prompts/opsx-apply.prompt.md +149 -0
  11. package/.github/prompts/opsx-archive.prompt.md +154 -0
  12. package/.github/prompts/opsx-explore.prompt.md +170 -0
  13. package/.github/prompts/opsx-propose.prompt.md +103 -0
  14. package/.github/skills/openspec-apply-change/SKILL.md +156 -0
  15. package/.github/skills/openspec-archive-change/SKILL.md +114 -0
  16. package/.github/skills/openspec-explore/SKILL.md +288 -0
  17. package/.github/skills/openspec-propose/SKILL.md +110 -0
  18. package/.github/workflows/codeql-analysis.yml +5 -4
  19. package/.github/workflows/npm-publish.yml +3 -3
  20. package/AGENTS.md +117 -0
  21. package/CLAUDE.md +2 -0
  22. package/MIGRATION.md +10 -0
  23. package/README.md +6 -2
  24. package/ai-docs/coding-rules.md +95 -0
  25. package/ai-docs/tech-stack.md +43 -0
  26. package/babel.config.js +5 -0
  27. package/docs/changeLog.html +34 -0
  28. package/docs/checkList.html +2 -2
  29. package/docs/connectionParameters.html +5 -0
  30. package/docs/quickstart.html +2 -1
  31. package/docs/release.html +1 -1
  32. package/openspec/config.yaml +20 -0
  33. package/package-lock.json +7437 -3924
  34. package/package.json +9 -7
  35. package/src/AGENTS.md +98 -0
  36. package/src/CLAUDE.md +2 -0
  37. package/src/application.js +637 -637
  38. package/src/cache.js +133 -133
  39. package/src/cacheRefresher.js +190 -190
  40. package/src/campaign.js +532 -532
  41. package/src/client.js +1539 -1532
  42. package/src/crypto.js +52 -52
  43. package/src/domUtil.js +346 -346
  44. package/src/entityAccessor.js +61 -61
  45. package/src/index.js +83 -83
  46. package/src/methodCache.js +69 -69
  47. package/src/optionCache.js +26 -26
  48. package/src/soap.js +321 -322
  49. package/src/testUtil.js +13 -13
  50. package/src/transport.js +70 -70
  51. package/src/util.js +147 -147
  52. package/src/web/bundler.js +5 -5
  53. package/src/xtkCaster.js +258 -258
  54. package/src/xtkEntityCache.js +34 -34
  55. package/src/xtkJob.js +185 -185
  56. package/test/AGENTS.md +37 -0
  57. package/test/CLAUDE.md +2 -0
  58. package/test/cacheRefresher.test.js +7 -0
  59. package/test/client.test.js +123 -81
  60. package/test/jest.config.js +6 -0
  61. package/test/observability.test.js +6 -1
  62. package/test/xtkJob.test.js +2 -2
@@ -10,31 +10,31 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
  (function() {
13
- "use strict";
13
+ "use strict";
14
14
 
15
15
 
16
- /**********************************************************************************
16
+ /**********************************************************************************
17
17
  *
18
18
  * SDK "application" object
19
19
  * https://docs.adobe.com/content/help/en/campaign-classic/technicalresources/api/c-Application.html
20
20
  *
21
21
  *********************************************************************************/
22
- const { DomException, DomUtil, XPath } = require('./domUtil.js');
23
- const XtkCaster = require('./xtkCaster.js').XtkCaster;
24
- const EntityAccessor = require('./entityAccessor.js').EntityAccessor;
25
- const { ArrayMap } = require('./util.js');
22
+ const { DomException, DomUtil, XPath } = require('./domUtil.js');
23
+ const XtkCaster = require('./xtkCaster.js').XtkCaster;
24
+ const EntityAccessor = require('./entityAccessor.js').EntityAccessor;
25
+ const { ArrayMap } = require('./util.js');
26
26
 
27
- const PACKAGE_STATUS = { "never": 0, "always": 1, "default": 2, "preCreate": 3 };
27
+ const PACKAGE_STATUS = { "never": 0, "always": 1, "default": 2, "preCreate": 3 };
28
28
 
29
- /**
29
+ /**
30
30
  * @namespace Campaign
31
31
  */
32
32
 
33
- // ========================================================================================
34
- // Helper functions
35
- // ========================================================================================
33
+ // ========================================================================================
34
+ // Helper functions
35
+ // ========================================================================================
36
36
 
37
- /**
37
+ /**
38
38
  * Creates a schema object from an XML representation.
39
39
  * The returned XtkSchema object will not be added to the application schema cache.
40
40
  * If you do not pass an application object, it will not be possible to follow
@@ -47,32 +47,32 @@ const PACKAGE_STATUS = { "never": 0, "always": 1, "default": 2, "preCreate": 3 }
47
47
  * @see {@link XtkSchema}
48
48
  * @memberof Campaign
49
49
  */
50
- function newSchema(xml, application) {
50
+ function newSchema(xml, application) {
51
51
  if (xml.nodeType == 9) xml = xml.documentElement; // Document -> element
52
52
  var schema = new XtkSchema(application, xml);
53
53
  return schema;
54
- }
54
+ }
55
55
 
56
- // Propagate implicit values
57
- // Name -> Label -> Desc -> HelpText
58
- function propagateImplicitValues(xtkDesc, labelOnly) {
56
+ // Propagate implicit values
57
+ // Name -> Label -> Desc -> HelpText
58
+ function propagateImplicitValues(xtkDesc, labelOnly) {
59
59
  if (!xtkDesc.label) {
60
- if (xtkDesc.isAttribute) xtkDesc.label = xtkDesc.name.substring(1); // without @
61
- else xtkDesc.label = xtkDesc.name;
62
- // Force first letter as uppercase
63
- xtkDesc.label = xtkDesc.label.substring(0, 1).toUpperCase() + xtkDesc.label.substring(1);
60
+ if (xtkDesc.isAttribute) xtkDesc.label = xtkDesc.name.substring(1); // without @
61
+ else xtkDesc.label = xtkDesc.name;
62
+ // Force first letter as uppercase
63
+ xtkDesc.label = xtkDesc.label.substring(0, 1).toUpperCase() + xtkDesc.label.substring(1);
64
64
  }
65
65
  if (!labelOnly && !xtkDesc.description) {
66
- xtkDesc.description = xtkDesc.label;
67
- xtkDesc.descriptionLocalizationId = xtkDesc.labelLocalizationId;
66
+ xtkDesc.description = xtkDesc.label;
67
+ xtkDesc.descriptionLocalizationId = xtkDesc.labelLocalizationId;
68
68
  }
69
- }
69
+ }
70
70
 
71
- // ========================================================================================
72
- // Schema Cache
73
- // ========================================================================================
71
+ // ========================================================================================
72
+ // Schema Cache
73
+ // ========================================================================================
74
74
 
75
- /**
75
+ /**
76
76
  * A cache of schemas of type `XtkSchema` instead of plain XML or JSON objects
77
77
  *
78
78
  * @private
@@ -81,10 +81,10 @@ function propagateImplicitValues(xtkDesc, labelOnly) {
81
81
  * @memberof Campaign
82
82
  */
83
83
 
84
- class SchemaCache {
84
+ class SchemaCache {
85
85
  constructor(client) {
86
- this._client = client;
87
- this._schemas = {};
86
+ this._client = client;
87
+ this._schemas = {};
88
88
  }
89
89
 
90
90
  /**
@@ -94,14 +94,14 @@ class SchemaCache {
94
94
  * @returns {Campaign.XtkSchema} the schema, or null if the schema was not found
95
95
  */
96
96
  async getSchema(schemaId) {
97
- let schema = this._schemas[schemaId];
98
- if (schema === undefined) {
99
- schema = await this._client.application._getSchema(schemaId);
100
- if (!schema) schema = null; // null = not found
101
- if (!schemaId.startsWith("temp:group:"))
102
- this._schemas[schemaId] = schema;
103
- }
104
- return schema;
97
+ let schema = this._schemas[schemaId];
98
+ if (schema === undefined) {
99
+ schema = await this._client.application._getSchema(schemaId);
100
+ if (!schema) schema = null; // null = not found
101
+ if (!schemaId.startsWith("temp:group:"))
102
+ this._schemas[schemaId] = schema;
103
+ }
104
+ return schema;
105
105
  }
106
106
 
107
107
  /**
@@ -110,15 +110,15 @@ class SchemaCache {
110
110
  * @param {string} schemaId
111
111
  */
112
112
  invalidateCacheItem(schemaId) {
113
- this._schemas[schemaId] = undefined;
113
+ this._schemas[schemaId] = undefined;
114
114
  }
115
- }
115
+ }
116
116
 
117
- // ========================================================================================
118
- // Keys
119
- // ========================================================================================
117
+ // ========================================================================================
118
+ // Keys
119
+ // ========================================================================================
120
120
 
121
- /**
121
+ /**
122
122
  * A key in a schema
123
123
  *
124
124
  * @private
@@ -129,69 +129,69 @@ class SchemaCache {
129
129
  * @param {Campaign.XtkSchemaNode} schemaNode
130
130
  * @memberof Campaign
131
131
  */
132
- class XtkSchemaKey {
132
+ class XtkSchemaKey {
133
133
 
134
134
  constructor(schema, xml, schemaNode) {
135
135
 
136
- /**
136
+ /**
137
137
  * The schema this key belongs to
138
138
  * @type {Campaign.XtkSchema}
139
139
  */
140
- this.schema = schema;
140
+ this.schema = schema;
141
141
 
142
- /**
142
+ /**
143
143
  * The name of the key
144
144
  * @type {string}
145
145
  */
146
- this.name = EntityAccessor.getAttributeAsString(xml, "name");
146
+ this.name = EntityAccessor.getAttributeAsString(xml, "name");
147
147
 
148
- /**
148
+ /**
149
149
  * A human friendly name for they key
150
150
  * @type {string}
151
151
  */
152
- this.label = EntityAccessor.getAttributeAsString(xml, "label");
152
+ this.label = EntityAccessor.getAttributeAsString(xml, "label");
153
153
 
154
- /**
154
+ /**
155
155
  * A longer, human friendly description for they key
156
156
  * @type {string}
157
157
  */
158
- this.description = EntityAccessor.getAttributeAsString(xml, "desc");
158
+ this.description = EntityAccessor.getAttributeAsString(xml, "desc");
159
159
 
160
- /**
160
+ /**
161
161
  * Indicates if the key is internal or not
162
162
  * @type {boolean}
163
163
  */
164
- this.isInternal = EntityAccessor.getAttributeAsBoolean(xml, "internal");
164
+ this.isInternal = EntityAccessor.getAttributeAsBoolean(xml, "internal");
165
165
 
166
- /**
166
+ /**
167
167
  * Indicates if the fields (parts) of a composite key may be empty (null). At least one part must always be populated
168
168
  * @type {boolean}
169
169
  */
170
- this.allowEmptyPart = EntityAccessor.getAttributeAsString(xml, "allowEmptyPart");
170
+ this.allowEmptyPart = EntityAccessor.getAttributeAsString(xml, "allowEmptyPart");
171
171
 
172
- /**
172
+ /**
173
173
  * The fields making up the key
174
174
  * @type {Utils.ArrayMap<Campaign.XtkSchemaNode>}
175
175
  */
176
- this.fields = new ArrayMap();
176
+ this.fields = new ArrayMap();
177
177
 
178
- for (var child of EntityAccessor.getChildElements(xml, "keyfield")) {
179
- const xpathString = EntityAccessor.getAttributeAsString(child, "xpath");
180
- if (xpathString == "") throw new DomException(`Cannot create XtkSchemaKey for key '${this.name}': keyfield does not have an xpath attribute`);
178
+ for (var child of EntityAccessor.getChildElements(xml, "keyfield")) {
179
+ const xpathString = EntityAccessor.getAttributeAsString(child, "xpath");
180
+ if (xpathString == "") throw new DomException(`Cannot create XtkSchemaKey for key '${this.name}': keyfield does not have an xpath attribute`);
181
181
 
182
- // find key field
183
- const xpath = new XPath(xpathString);
184
- const elements = xpath.getElements();
185
- let keyNode = schemaNode;
186
- while (keyNode && elements.length > 0)
187
- keyNode = keyNode.children[elements.shift()];
188
- if (keyNode)
189
- this.fields._push(xpathString, keyNode);
190
- }
182
+ // find key field
183
+ const xpath = new XPath(xpathString);
184
+ const elements = xpath.getElements();
185
+ let keyNode = schemaNode;
186
+ while (keyNode && elements.length > 0)
187
+ keyNode = keyNode.children[elements.shift()];
188
+ if (keyNode)
189
+ this.fields._push(xpathString, keyNode);
190
+ }
191
191
  }
192
- }
192
+ }
193
193
 
194
- /**
194
+ /**
195
195
  * A join in a XtkSchemaNode link type
196
196
  *
197
197
  * @private
@@ -200,29 +200,29 @@ class XtkSchemaKey {
200
200
  * @param {} xml
201
201
  * @memberof Campaign
202
202
  */
203
- class XtkJoin {
203
+ class XtkJoin {
204
204
 
205
205
  constructor(xml) {
206
206
 
207
- /**
207
+ /**
208
208
  * The xpath of the join condition on the source table
209
209
  * @type {string}
210
210
  */
211
- this.src = EntityAccessor.getAttributeAsString(xml, "xpath-src");
211
+ this.src = EntityAccessor.getAttributeAsString(xml, "xpath-src");
212
212
 
213
- /**
213
+ /**
214
214
  * The xpath of the join condition on the destination table
215
215
  * @type {string}
216
216
  */
217
- this.dst = EntityAccessor.getAttributeAsString(xml, "xpath-dst");
217
+ this.dst = EntityAccessor.getAttributeAsString(xml, "xpath-dst");
218
218
  }
219
- }
219
+ }
220
220
 
221
- // ========================================================================================
222
- // Schema nodes
223
- // ========================================================================================
221
+ // ========================================================================================
222
+ // Schema nodes
223
+ // ========================================================================================
224
224
 
225
- /**
225
+ /**
226
226
  * A Schema Node (CXtkNodeDef). Schemas are a hierarchy of nodes. The top-level node (i.e. the
227
227
  * schema itself is also a node). The "root" node is the first child node having the same name
228
228
  * as the schema itself
@@ -232,7 +232,7 @@ class XtkSchemaKey {
232
232
  * @constructor
233
233
  * @memberof Campaign
234
234
  */
235
- class XtkSchemaNode {
235
+ class XtkSchemaNode {
236
236
 
237
237
  constructor() {
238
238
  }
@@ -246,460 +246,460 @@ class XtkSchemaNode {
246
246
  */
247
247
  init(schema, xml, parentNode, isAttribute) {
248
248
 
249
- /**
249
+ /**
250
250
  * The schema the node belongs to
251
251
  * @type {XtkSchema}
252
252
  */
253
- this.schema = schema;
253
+ this.schema = schema;
254
254
 
255
- /**
255
+ /**
256
256
  * Returns a string of characters which provides the data policy of the current node.
257
257
  * @type {string}
258
258
  */
259
- this.dataPolicy = EntityAccessor.getAttributeAsString(xml, "dataPolicy");
259
+ this.dataPolicy = EntityAccessor.getAttributeAsString(xml, "dataPolicy");
260
260
 
261
- /**
261
+ /**
262
262
  * Returns a string of characters which provides the db enum of the current node.
263
263
  * @type {string}
264
264
  */
265
- this.dbEnum = EntityAccessor.getAttributeAsString(xml, "dbEnum");
265
+ this.dbEnum = EntityAccessor.getAttributeAsString(xml, "dbEnum");
266
266
 
267
- /**
267
+ /**
268
268
  * Returns a string of characters which specifies the editing type of the current node.
269
269
  * @type {string}
270
270
  */
271
- this.editType = EntityAccessor.getAttributeAsString(xml, "edit");
271
+ this.editType = EntityAccessor.getAttributeAsString(xml, "edit");
272
272
 
273
- /**
273
+ /**
274
274
  * Only on the root node, returns a string which contains the folder template(s). On the other nodes, it returns undefined.
275
275
  * @type {string}
276
276
  */
277
- this.folderModel = EntityAccessor.getAttributeAsString(xml, "folderModel");
277
+ this.folderModel = EntityAccessor.getAttributeAsString(xml, "folderModel");
278
278
 
279
- /**
279
+ /**
280
280
  * The parent node
281
281
  * @type {XtkSchemaNode}
282
282
  */
283
- this.parent = parentNode;
283
+ this.parent = parentNode;
284
284
 
285
- /**
285
+ /**
286
286
  * Indicates if the node is an attribute or not (element or schema itself)
287
287
  * @type {boolean}
288
288
  */
289
- this.isAttribute = isAttribute;
289
+ this.isAttribute = isAttribute;
290
290
 
291
- /**
291
+ /**
292
292
  * The attribute or the node name (with the "@" sign for attributes)
293
293
  * @type {string}
294
294
  */
295
- this.name = (this.isAttribute ? "@" : "") + EntityAccessor.getAttributeAsString(xml, "name");
295
+ this.name = (this.isAttribute ? "@" : "") + EntityAccessor.getAttributeAsString(xml, "name");
296
296
 
297
- /**
297
+ /**
298
298
  * A human friendly name for the node. If the node is the schema node, the label will be in the plural form and "labelSingular"
299
299
  * should be used for the singular form
300
300
  * @type {string}
301
301
  */
302
- this.label = EntityAccessor.getAttributeAsString(xml, "label");
302
+ this.label = EntityAccessor.getAttributeAsString(xml, "label");
303
303
 
304
- /**
304
+ /**
305
305
  * A long description of the node
306
306
  * @type {string}
307
307
  */
308
- this.description = EntityAccessor.getAttributeAsString(xml, "desc");
308
+ this.description = EntityAccessor.getAttributeAsString(xml, "desc");
309
309
 
310
- /**
310
+ /**
311
311
  * An optional image for the node
312
312
  * @type {string}
313
313
  */
314
- this.img = EntityAccessor.getAttributeAsString(xml, "img");
314
+ this.img = EntityAccessor.getAttributeAsString(xml, "img");
315
315
 
316
- /**
316
+ /**
317
317
  * An optional image for the node (alias to the img property)
318
318
  * @type {string}
319
319
  */
320
- this.image = this.img;
320
+ this.image = this.img;
321
321
 
322
- /**
322
+ /**
323
323
  * Returns the name of the image of the current node in the form of a string of characters.
324
324
  * @type {string}
325
325
  */
326
- this.enumerationImage = EntityAccessor.getAttributeAsString(xml, "enumImage");
326
+ this.enumerationImage = EntityAccessor.getAttributeAsString(xml, "enumImage");
327
327
 
328
- /**
328
+ /**
329
329
  * The node type. Attribute nodes without an explicitedly defined type will be reported as "string"
330
330
  * @type {string}
331
331
  */
332
- this.type = EntityAccessor.getAttributeAsString(xml, "type");
333
- if (!this.type && isAttribute) this.type = "string";
332
+ this.type = EntityAccessor.getAttributeAsString(xml, "type");
333
+ if (!this.type && isAttribute) this.type = "string";
334
334
 
335
- /**
335
+ /**
336
336
  * For link type nodes, the target of the link
337
337
  * @type {string}
338
338
  */
339
- this.target = EntityAccessor.getAttributeAsString(xml, "target");
339
+ this.target = EntityAccessor.getAttributeAsString(xml, "target");
340
340
 
341
- /**
341
+ /**
342
342
  * The node integrity
343
343
  * @type {string}
344
344
  */
345
- this.integrity = EntityAccessor.getAttributeAsString(xml, "integrity");
345
+ this.integrity = EntityAccessor.getAttributeAsString(xml, "integrity");
346
346
 
347
- /**
347
+ /**
348
348
  * The node data length (applicable for string-types only)
349
349
  * @type {number}
350
350
  */
351
- this.length = EntityAccessor.getAttributeAsLong(xml, "length");
351
+ this.length = EntityAccessor.getAttributeAsLong(xml, "length");
352
352
 
353
- /**
353
+ /**
354
354
  * The node data length (applicable for string-types only)
355
355
  * @type {number}
356
356
  */
357
- this.size = this.length;
357
+ this.size = this.length;
358
358
 
359
- /**
359
+ /**
360
360
  * The enum of the node
361
361
  * @type {string}
362
362
  */
363
- this.enum = EntityAccessor.getAttributeAsString(xml, "enum");
363
+ this.enum = EntityAccessor.getAttributeAsString(xml, "enum");
364
364
 
365
- /**
365
+ /**
366
366
  * Returns a string of characters which is the name of the user enumeration used by the current node.
367
367
  * @type {string}
368
368
  */
369
- this.userEnumeration = EntityAccessor.getAttributeAsString(xml, "userEnum");
369
+ this.userEnumeration = EntityAccessor.getAttributeAsString(xml, "userEnum");
370
370
 
371
- /**
371
+ /**
372
372
  * Returns a boolean which indicates whether the value of the current node is linked to a user enumeration.
373
373
  * @type {boolean}
374
374
  */
375
- this.hasUserEnumeration = !!this.userEnumeration;
375
+ this.hasUserEnumeration = !!this.userEnumeration;
376
376
 
377
- /**
377
+ /**
378
378
  * "ref" attribute of the node, which references another node
379
379
  * @type {string}
380
380
  */
381
- this.ref = EntityAccessor.getAttributeAsString(xml, "ref");
381
+ this.ref = EntityAccessor.getAttributeAsString(xml, "ref");
382
382
 
383
- /**
383
+ /**
384
384
  * Has an unlimited number of children of the same type
385
385
  * @type {boolean}
386
386
  */
387
- this.unbound = EntityAccessor.getAttributeAsBoolean(xml, "unbound");
387
+ this.unbound = EntityAccessor.getAttributeAsBoolean(xml, "unbound");
388
388
 
389
- /**
389
+ /**
390
390
  * If children are ordered
391
391
  * @type {boolean}
392
392
  */
393
- this.ordered = EntityAccessor.getAttributeAsBoolean(xml, "ordered");
393
+ this.ordered = EntityAccessor.getAttributeAsBoolean(xml, "ordered");
394
394
 
395
- /**
395
+ /**
396
396
  * The expression controlling the visibility of the current node
397
397
  * @type {string}
398
398
  */
399
- this.visibleIf = EntityAccessor.getAttributeAsString(xml, "visibleIf");
399
+ this.visibleIf = EntityAccessor.getAttributeAsString(xml, "visibleIf");
400
400
 
401
- /**
401
+ /**
402
402
  * Has an unlimited number of children of the same type
403
403
  * @type {boolean}
404
404
  */
405
- this.isCollection = this.unbound;
405
+ this.isCollection = this.unbound;
406
406
 
407
- /**
407
+ /**
408
408
  * is mapped as a xml
409
409
  * @type {boolean}
410
410
  */
411
- this.isMappedAsXML = EntityAccessor.getAttributeAsBoolean(xml, "xml");
411
+ this.isMappedAsXML = EntityAccessor.getAttributeAsBoolean(xml, "xml");
412
412
 
413
- /**
413
+ /**
414
414
  * is an advanced node
415
415
  * @type {boolean}
416
416
  */
417
- this.isAdvanced = EntityAccessor.getAttributeAsBoolean(xml, "advanced");
417
+ this.isAdvanced = EntityAccessor.getAttributeAsBoolean(xml, "advanced");
418
418
 
419
- /**
419
+ /**
420
420
  * if returning the whole node when camparing difference
421
421
  * @type {boolean}
422
422
  */
423
- this.doesNotSupportDiff = EntityAccessor.getAttributeAsBoolean(xml, "doesNotSupportDiff");
423
+ this.doesNotSupportDiff = EntityAccessor.getAttributeAsBoolean(xml, "doesNotSupportDiff");
424
424
 
425
- /**
425
+ /**
426
426
  * Children of the node. This is a object whose key are the names of the children nodes (without the "@"
427
427
  * character for attributes)
428
428
  * @type {Utils.ArrayMap.<Campaign.XtkSchemaNode>}
429
429
  */
430
- this.children = new ArrayMap();
430
+ this.children = new ArrayMap();
431
431
 
432
- /**
432
+ /**
433
433
  * Count the children of a node
434
434
  * @type {number}
435
435
  */
436
- this.childrenCount = 0;
436
+ this.childrenCount = 0;
437
437
 
438
- /**
438
+ /**
439
439
  * Get the default value of a node
440
440
  * @type {string}
441
441
  */
442
- this.default = EntityAccessor.getAttributeAsString(xml, "default");
442
+ this.default = EntityAccessor.getAttributeAsString(xml, "default");
443
443
 
444
- /**
444
+ /**
445
445
  * Get the default translation for the default value of a node
446
446
  * @type {string}
447
447
  */
448
- this.translatedDefault = EntityAccessor.getAttributeAsString(xml, "translatedDefault");
448
+ this.translatedDefault = EntityAccessor.getAttributeAsString(xml, "translatedDefault");
449
449
 
450
- /**
450
+ /**
451
451
  * Indicates if the node is the root node, i.e. the first child node of the schema, whose name is the same as the schema name
452
452
  * @type {boolean}
453
453
  */
454
- this.isRoot = this.parent && !this.parent.parent && this.parent.name == this.name;
454
+ this.isRoot = this.parent && !this.parent.parent && this.parent.name == this.name;
455
455
 
456
- /**
456
+ /**
457
457
  * Schema root elements may have a list of keys. This is a dictionary whose names are the key names and values the keys
458
458
  * @type {ArrayNode<Campaign.XtkSchemaKey>}
459
459
  */
460
- this.keys = new ArrayMap();
460
+ this.keys = new ArrayMap();
461
461
 
462
- /**
462
+ /**
463
463
  * The full path of the node
464
464
  * @type {string}
465
465
  */
466
- this.nodePath = this._getNodePath(true)._path;
466
+ this.nodePath = this._getNodePath(true)._path;
467
467
 
468
- this._buildLocalizationIds();
468
+ this._buildLocalizationIds();
469
469
 
470
- /**
470
+ /**
471
471
  * Element of type "link" has an array of XtkJoin
472
472
  * @type {XtkJoin[]}
473
473
  */
474
- this.joins = [];
475
- for (var child of EntityAccessor.getChildElements(xml, "join")) {
476
- this.joins.push(new XtkJoin(child));
477
- }
474
+ this.joins = [];
475
+ for (var child of EntityAccessor.getChildElements(xml, "join")) {
476
+ this.joins.push(new XtkJoin(child));
477
+ }
478
478
 
479
- /**
479
+ /**
480
480
  * Returns a boolean which indicates whether the current node is ordinary.
481
481
  * @type {boolean}
482
482
  */
483
- this.isAnyType = this.type === "ANY";
483
+ this.isAnyType = this.type === "ANY";
484
484
 
485
- /**
485
+ /**
486
486
  * Returns a boolean which indicates whether the node is a link.
487
487
  * @type {boolean}
488
488
  */
489
- this.isLink = this.type === "link";
489
+ this.isLink = this.type === "link";
490
490
 
491
- /**
491
+ /**
492
492
  * Returns a boolean which indicates whether the value of the current node is linked to an enumeration.
493
493
  * @type {boolean}
494
494
  */
495
- this.hasEnumeration = this.enum !== "";
495
+ this.hasEnumeration = this.enum !== "";
496
496
 
497
- /**
497
+ /**
498
498
  * Returns a boolean which indicates whether the current node is linked to an SQL table.
499
499
  * @type {boolean}
500
500
  */
501
- this.hasSQLTable = this.sqlTable !== '';
501
+ this.hasSQLTable = this.sqlTable !== '';
502
502
 
503
- /**
503
+ /**
504
504
  * The SQL name of the field. The property is an empty string if the object isn't an SQL type field.
505
505
  * @type {string}
506
506
  */
507
- this.SQLName = EntityAccessor.getAttributeAsString(xml, "sqlname");
507
+ this.SQLName = EntityAccessor.getAttributeAsString(xml, "sqlname");
508
508
 
509
- /**
509
+ /**
510
510
  * The SQL name of the table. The property is an empty string if the object isn't the main element or if schema mapping isn't of SQL type.
511
511
  * @type {string}
512
512
  */
513
- this.SQLTable = EntityAccessor.getAttributeAsString(xml, "sqltable");
513
+ this.SQLTable = EntityAccessor.getAttributeAsString(xml, "sqltable");
514
514
 
515
- /**
515
+ /**
516
516
  * Returns a boolean indicating whether the table is a temporary table. The table will not be created during database creation.
517
517
  * @type {boolean}
518
518
  */
519
- this.isTemporaryTable = EntityAccessor.getAttributeAsBoolean(xml, "temporaryTable");
519
+ this.isTemporaryTable = EntityAccessor.getAttributeAsBoolean(xml, "temporaryTable");
520
520
 
521
- /**
521
+ /**
522
522
  * Returns a boolean which indicates whether the current node is a logical sub-division of the schema.
523
523
  * @type {boolean}
524
524
  */
525
- // An element has no real value if its type is empty
526
- this.isElementOnly = this.type === "";
525
+ // An element has no real value if its type is empty
526
+ this.isElementOnly = this.type === "";
527
527
 
528
- /**
528
+ /**
529
529
  * Returns a boolean. If the value added is vrai, during record deduplication, the default value (defined in defaultValue) is automatically reapplied during recording.
530
530
  * @type {boolean}
531
531
  */
532
- this.isDefaultOnDuplicate = EntityAccessor.getAttributeAsBoolean(xml, "defOnDuplicate");
532
+ this.isDefaultOnDuplicate = EntityAccessor.getAttributeAsBoolean(xml, "defOnDuplicate");
533
533
 
534
- /**
534
+ /**
535
535
  * True if the node is a link and if the join is external.
536
536
  * @type {boolean}
537
537
  */
538
- this.isExternalJoin = EntityAccessor.getAttributeAsBoolean(xml, "externalJoin");
538
+ this.isExternalJoin = EntityAccessor.getAttributeAsBoolean(xml, "externalJoin");
539
539
 
540
- /**
540
+ /**
541
541
  * Returns a boolean which indicates whether the current node is mapped by a Memo.
542
542
  * @type {boolean}
543
543
  */
544
- this.isMemo = this.type === "memo" || this.type === "CDATA";
544
+ this.isMemo = this.type === "memo" || this.type === "CDATA";
545
545
 
546
- /**
546
+ /**
547
547
  * Returns a boolean which indicates whether the current node is mapped by a MemoData.
548
548
  * @type {boolean}
549
549
  */
550
- this.isMemoData = this.isMemo && this.name === 'data';
550
+ this.isMemoData = this.isMemo && this.name === 'data';
551
551
 
552
- /**
552
+ /**
553
553
  * Returns a boolean which indicates whether the current node is a BLOB.
554
554
  * @type {boolean}
555
555
  */
556
- this.isBlob = this.type === "blob";
556
+ this.isBlob = this.type === "blob";
557
557
 
558
- /**
558
+ /**
559
559
  * Returns a boolean which indicates whether the current node is mapped from CDATA type XML.
560
560
  * @type {boolean}
561
561
  */
562
- this.isCDATA = this.type === "CDATA";
562
+ this.isCDATA = this.type === "CDATA";
563
563
 
564
- const notNull = EntityAccessor.getAttributeAsString(xml, "notNull");
565
- const sqlDefault = EntityAccessor.getAttributeAsString(xml, "sqlDefault");
566
- const notNullOverriden = notNull || sqlDefault === "NULL";
567
- /**
564
+ const notNull = EntityAccessor.getAttributeAsString(xml, "notNull");
565
+ const sqlDefault = EntityAccessor.getAttributeAsString(xml, "sqlDefault");
566
+ const notNullOverriden = notNull || sqlDefault === "NULL";
567
+ /**
568
568
  * Returns a boolean which indicates whether or not the current node can take the null value into account.
569
569
  * @type {boolean}
570
570
  */
571
- this.isNotNull = notNullOverriden ? XtkCaster.asBoolean(notNull) : this.type === "int64" || this.type === "short" ||
571
+ this.isNotNull = notNullOverriden ? XtkCaster.asBoolean(notNull) : this.type === "int64" || this.type === "short" ||
572
572
  this.type === "long" || this.type === "byte" || this.type === "float" || this.type === "double" ||
573
573
  this.type === "money" || this.type === "percent" || this.type === "time" || this.type === "boolean";
574
574
 
575
- /**
575
+ /**
576
576
  * Returns a boolean which indicates whether or not the value of the current node is mandatory.
577
577
  * @type {boolean}
578
578
  */
579
- this.isRequired = EntityAccessor.getAttributeAsBoolean(xml, "required");
579
+ this.isRequired = EntityAccessor.getAttributeAsBoolean(xml, "required");
580
580
 
581
- /**
581
+ /**
582
582
  * Returns a boolean which indicates whether the current node is mapped in SQL.
583
583
  * @type {boolean}
584
584
  */
585
- this.isSQL = !!this.SQLName || !!this.SQLTable || (this.isLink && this.schema.mappingType === 'sql' && !this.isMappedAsXML);
585
+ this.isSQL = !!this.SQLName || !!this.SQLTable || (this.isLink && this.schema.mappingType === 'sql' && !this.isMappedAsXML);
586
586
 
587
- /**
587
+ /**
588
588
  * The SQL name of the field. The property is an empty string if the object isn't an SQL type field.
589
589
  * @type {string}
590
590
  */
591
- this.PKSequence = EntityAccessor.getAttributeAsString(xml, "pkSequence");
591
+ this.PKSequence = EntityAccessor.getAttributeAsString(xml, "pkSequence");
592
592
 
593
- /**
593
+ /**
594
594
  * Name of the reverse link in the target schema
595
595
  * @type {string}
596
596
  */
597
- this.revLink = EntityAccessor.getAttributeAsString(xml, "revLink");
597
+ this.revLink = EntityAccessor.getAttributeAsString(xml, "revLink");
598
598
 
599
- /**
599
+ /**
600
600
  * Returns a boolean which indicates whether the value of the current node is the result of a calculation.
601
601
  * @type {boolean}
602
602
  */
603
- this.isCalculated = false;
603
+ this.isCalculated = false;
604
604
 
605
- /**
605
+ /**
606
606
  * Expression associated with the node
607
607
  * @type {string}
608
608
  */
609
- this.expr = EntityAccessor.getAttributeAsString(xml, "expr");
610
- if (this.expr) this.isCalculated = true;
609
+ this.expr = EntityAccessor.getAttributeAsString(xml, "expr");
610
+ if (this.expr) this.isCalculated = true;
611
611
 
612
- /**
612
+ /**
613
613
  * Returns a boolean which indicates whether the value of the current node is incremented automatically.
614
614
  * @type {boolean}
615
615
  */
616
- this.isAutoIncrement = EntityAccessor.getAttributeAsBoolean(xml, "autoIncrement");
616
+ this.isAutoIncrement = EntityAccessor.getAttributeAsBoolean(xml, "autoIncrement");
617
617
 
618
- /**
618
+ /**
619
619
  * Returns a boolean which indicates whether the current node is a primary key.
620
620
  * @type {boolean}
621
621
  */
622
- this.isAutoPK = EntityAccessor.getAttributeAsBoolean(xml, "autopk");
622
+ this.isAutoPK = EntityAccessor.getAttributeAsBoolean(xml, "autopk");
623
623
 
624
- /**
624
+ /**
625
625
  * Returns a boolean which indicates whether the current node is an automatic UUID
626
626
  * @type {boolean}
627
627
  */
628
- this.isAutoUUID = EntityAccessor.getAttributeAsBoolean(xml, "autouuid");
628
+ this.isAutoUUID = EntityAccessor.getAttributeAsBoolean(xml, "autouuid");
629
629
 
630
- /**
630
+ /**
631
631
  * Returns a boolean which indicates whether the schema is a staging schema
632
632
  * @type {boolean}
633
633
  */
634
- this.isAutoStg = EntityAccessor.getAttributeAsBoolean(xml, "autoStg");
634
+ this.isAutoStg = EntityAccessor.getAttributeAsBoolean(xml, "autoStg");
635
635
 
636
- /**
636
+ /**
637
637
  * Returns a string that gives the package status.
638
638
  * @type {"never" | "always" | "default" | "preCreate"}
639
639
  */
640
- this.packageStatusString = EntityAccessor.getAttributeAsString(xml, "pkgStatus");
640
+ this.packageStatusString = EntityAccessor.getAttributeAsString(xml, "pkgStatus");
641
641
 
642
- /**
642
+ /**
643
643
  * Returns a number that gives the package status.
644
644
  * @type {0 | 1 | 2 | 3}
645
645
  */
646
- this.packageStatus = PACKAGE_STATUS[this.packageStatusString];
646
+ this.packageStatus = PACKAGE_STATUS[this.packageStatusString];
647
647
 
648
- /**
648
+ /**
649
649
  * Returns a string (a schema id) which indicates the custom/extended entity, attribute belongs to.
650
650
  */
651
- this.belongsTo = EntityAccessor.getAttributeAsString(xml, "belongsTo");
651
+ this.belongsTo = EntityAccessor.getAttributeAsString(xml, "belongsTo");
652
652
 
653
- // Children (elements and attributes)
654
- const childNodes = [];
655
- for (const child of EntityAccessor.getChildElements(xml)) {
656
- if (child.tagName === "attribute") {
657
- const node = new XtkSchemaNode();
658
- node.init(schema, child, this, true);
659
- childNodes.push(node);
660
- }
661
- if (child.tagName === "element") {
662
- const node = new XtkSchemaNode();
663
- node.init(schema, child, this, false);
664
- childNodes.push(node);
665
- }
666
- if (child.tagName === "compute-string") {
667
- this.expr = EntityAccessor.getAttributeAsString(child, "expr");
668
- this.isCalculated = false;
669
- }
670
- if (child.tagName === "default" || child.tagName === "translatedDefault") {
671
- if(this.unbound) {
672
- // Default value for a collection of elements
673
- const xml = DomUtil.parse(`<xml>${child.textContent}</xml>`);
674
- const json = DomUtil.toJSON(xml);
675
- if(child.tagName === "translatedDefault") {
676
- this.translatedDefault = XtkCaster.asArray(json[this.name]);
677
- } else {
678
- this.default = XtkCaster.asArray(json[this.name]);
679
- }
680
- } else {
681
- if(child.tagName === "translatedDefault") {
682
- this.translatedDefault = child.textContent;
683
- } else {
684
- this.default = child.textContent;
685
- }
686
- }
687
- }
653
+ // Children (elements and attributes)
654
+ const childNodes = [];
655
+ for (const child of EntityAccessor.getChildElements(xml)) {
656
+ if (child.tagName === "attribute") {
657
+ const node = new XtkSchemaNode();
658
+ node.init(schema, child, this, true);
659
+ childNodes.push(node);
688
660
  }
689
- for (const childNode of childNodes) {
690
- this.children._push(childNode.name, childNode);
691
- this.childrenCount = this.childrenCount + 1;
661
+ if (child.tagName === "element") {
662
+ const node = new XtkSchemaNode();
663
+ node.init(schema, child, this, false);
664
+ childNodes.push(node);
692
665
  }
693
-
694
- // Keys (after elements and attributes have been found)
695
- for (const child of EntityAccessor.getChildElements(xml, "key")) {
696
- const key = new XtkSchemaKey(schema, child, this);
697
- this.keys._push(key.name, key);
666
+ if (child.tagName === "compute-string") {
667
+ this.expr = EntityAccessor.getAttributeAsString(child, "expr");
668
+ this.isCalculated = false;
698
669
  }
699
-
700
- // Propagate implicit values
701
- // Name -> Label -> Desc -> HelpText
702
- propagateImplicitValues(this);
670
+ if (child.tagName === "default" || child.tagName === "translatedDefault") {
671
+ if(this.unbound) {
672
+ // Default value for a collection of elements
673
+ const xml = DomUtil.parse(`<xml>${child.textContent}</xml>`);
674
+ const json = DomUtil.toJSON(xml);
675
+ if(child.tagName === "translatedDefault") {
676
+ this.translatedDefault = XtkCaster.asArray(json[this.name]);
677
+ } else {
678
+ this.default = XtkCaster.asArray(json[this.name]);
679
+ }
680
+ } else {
681
+ if(child.tagName === "translatedDefault") {
682
+ this.translatedDefault = child.textContent;
683
+ } else {
684
+ this.default = child.textContent;
685
+ }
686
+ }
687
+ }
688
+ }
689
+ for (const childNode of childNodes) {
690
+ this.children._push(childNode.name, childNode);
691
+ this.childrenCount = this.childrenCount + 1;
692
+ }
693
+
694
+ // Keys (after elements and attributes have been found)
695
+ for (const child of EntityAccessor.getChildElements(xml, "key")) {
696
+ const key = new XtkSchemaKey(schema, child, this);
697
+ this.keys._push(key.name, key);
698
+ }
699
+
700
+ // Propagate implicit values
701
+ // Name -> Label -> Desc -> HelpText
702
+ propagateImplicitValues(this);
703
703
  }
704
704
 
705
705
  /* create two ids that are identifying in an unique way the node label and
@@ -709,30 +709,30 @@ class XtkSchemaNode {
709
709
  * nms__recipient__e____recipient__mobilePhone__@label
710
710
  * */
711
711
  _buildLocalizationIds() {
712
- if (!this.parent) {
713
- this._localizationId = this.schema.id.replace(":", "__");
712
+ if (!this.parent) {
713
+ this._localizationId = this.schema.id.replace(":", "__");
714
+ } else {
715
+ this._localizationId = this.parent._localizationId;
716
+ }
717
+
718
+ if (this.parent) {
719
+ // Separate each element of the path with a double _
720
+ if (this.isAttribute) {
721
+ this._localizationId = this._localizationId + "__" + this.name.replace('@', '');
714
722
  } else {
715
- this._localizationId = this.parent._localizationId;
716
- }
717
-
718
- if (this.parent) {
719
- // Separate each element of the path with a double _
720
- if (this.isAttribute) {
721
- this._localizationId = this._localizationId + "__" + this.name.replace('@', '');
722
- } else {
723
- // node is not an attribute so it is an element add "e____"
724
- this._localizationId = this._localizationId + "__e____" + this.name;
725
- }
726
- }
727
- if (this.label) {
728
- this.labelLocalizationId = this._localizationId + "__@label";
729
- }
730
- if (this.description) {
731
- this.descriptionLocalizationId = this._localizationId + "__@desc";
732
- }
733
- if (!this.parent && this.labelSingular) {
734
- this.labelSingularLocalizationId = this._localizationId + "__@labelSingular";
723
+ // node is not an attribute so it is an element add "e____"
724
+ this._localizationId = this._localizationId + "__e____" + this.name;
735
725
  }
726
+ }
727
+ if (this.label) {
728
+ this.labelLocalizationId = this._localizationId + "__@label";
729
+ }
730
+ if (this.description) {
731
+ this.descriptionLocalizationId = this._localizationId + "__@desc";
732
+ }
733
+ if (!this.parent && this.labelSingular) {
734
+ this.labelSingularLocalizationId = this._localizationId + "__@labelSingular";
735
+ }
736
736
  }
737
737
 
738
738
  /**
@@ -741,7 +741,7 @@ class XtkSchemaNode {
741
741
  * @returns {boolean} a boolean indicating whether the node contains a child with the given name
742
742
  */
743
743
  isUnbound() {
744
- return this.unbound;
744
+ return this.unbound;
745
745
  }
746
746
 
747
747
  /**
@@ -752,24 +752,24 @@ class XtkSchemaNode {
752
752
  * @returns {string} the node path
753
753
  */
754
754
  _getNodePath(absolute) {
755
- if (absolute === undefined) absolute = true;
756
- var path = !this.parent ? this.name : "";
757
- var schemaName = this.schema.name;
758
- var node = this;
759
- while (node && node.parent) {
760
- if (path != "") path = `/${path}`;
761
- if (node.parent.parent || node.name != schemaName)
762
- path = `${node.name}${path}`;
763
- node = node.parent;
764
- }
765
- if (absolute) {
766
- if (path == "") path = "/";
767
- else if (!path.startsWith("/")) path = `/${path}`;
768
- }
769
- else {
770
- if (path.startsWith("/")) path = path.substring(1);
771
- }
772
- return new XPath(path);
755
+ if (absolute === undefined) absolute = true;
756
+ var path = !this.parent ? this.name : "";
757
+ var schemaName = this.schema.name;
758
+ var node = this;
759
+ while (node && node.parent) {
760
+ if (path != "") path = `/${path}`;
761
+ if (node.parent.parent || node.name != schemaName)
762
+ path = `${node.name}${path}`;
763
+ node = node.parent;
764
+ }
765
+ if (absolute) {
766
+ if (path == "") path = "/";
767
+ else if (!path.startsWith("/")) path = `/${path}`;
768
+ }
769
+ else {
770
+ if (path.startsWith("/")) path = path.substring(1);
771
+ }
772
+ return new XPath(path);
773
773
  }
774
774
 
775
775
  /**
@@ -777,51 +777,51 @@ class XtkSchemaNode {
777
777
  * @returns {Promise<Campaign.XtkNode>} the target node, or undefined if not found
778
778
  */
779
779
  async refTarget() {
780
- if (!this.ref) return;
781
- const index = this.ref.lastIndexOf(':');
782
- if (index !== -1) {
783
- // find the associated schame
784
- const refSchemaId = this.ref.substring(0, index);
785
- if (refSchemaId.indexOf(':') === -1)
786
- throw Error(`Cannot find ref target '${this.ref}' from node '${this.nodePath}' of schema '${this.schema.id}': ref value is not correct (expeted <schemaId>:<path>)`);
787
- const refPath = this.ref.substring(index + 1);
788
- // inside current schema ?
789
- if (refSchemaId === this.schema.id)
790
- return this.schema.findNode(refPath);
791
- const refSchema = await this.schema._application.getSchema(refSchemaId);
792
- if (!refSchema) return;
793
- return refSchema.findNode(refPath);
794
- }
795
- else {
796
- // ref is in the current schema
797
- return this.schema.findNode(this.ref);
798
- }
780
+ if (!this.ref) return;
781
+ const index = this.ref.lastIndexOf(':');
782
+ if (index !== -1) {
783
+ // find the associated schame
784
+ const refSchemaId = this.ref.substring(0, index);
785
+ if (refSchemaId.indexOf(':') === -1)
786
+ throw Error(`Cannot find ref target '${this.ref}' from node '${this.nodePath}' of schema '${this.schema.id}': ref value is not correct (expeted <schemaId>:<path>)`);
787
+ const refPath = this.ref.substring(index + 1);
788
+ // inside current schema ?
789
+ if (refSchemaId === this.schema.id)
790
+ return this.schema.findNode(refPath);
791
+ const refSchema = await this.schema._application.getSchema(refSchemaId);
792
+ if (!refSchema) return;
793
+ return refSchema.findNode(refPath);
794
+ }
795
+ else {
796
+ // ref is in the current schema
797
+ return this.schema.findNode(this.ref);
798
+ }
799
799
  }
800
800
 
801
801
  /**
802
802
  * Find the target of a link node.
803
803
  * @returns {Promise<Campaign.XtkNode>} the target node, or undefined if not found
804
804
  */
805
- async linkTarget() {
806
- if (this.type !== "link") return this.schema.root;
807
- let schemaId = this.target;
808
- let xpath = "";
809
- if (this.target.indexOf(',') !== -1)
810
- throw new Error(`Cannot find target of link '${this.target}': target has multiple schemas`);
811
- const index = this.target.indexOf('/');
812
- if (index !== -1) {
813
- xpath = this.target.substring(index + 1);
814
- schemaId = this.target.substring(0, index);
815
- xpath = this.target.substring(index + 1);
816
- }
817
- if (schemaId.indexOf(':') === -1)
818
- throw new Error(`Cannot find target of link '${this.target}': target is not a valid link target (missing schema id)`);
819
- const schema = await this.schema._application.getSchema(schemaId);
820
- if (!schema) return;
821
- const root = schema.root;
822
- if (!root) return;
823
- if (!xpath) return root;
824
- return await root.findNode(xpath);
805
+ async linkTarget() {
806
+ if (this.type !== "link") return this.schema.root;
807
+ let schemaId = this.target;
808
+ let xpath = "";
809
+ if (this.target.indexOf(',') !== -1)
810
+ throw new Error(`Cannot find target of link '${this.target}': target has multiple schemas`);
811
+ const index = this.target.indexOf('/');
812
+ if (index !== -1) {
813
+ xpath = this.target.substring(index + 1);
814
+ schemaId = this.target.substring(0, index);
815
+ xpath = this.target.substring(index + 1);
816
+ }
817
+ if (schemaId.indexOf(':') === -1)
818
+ throw new Error(`Cannot find target of link '${this.target}': target is not a valid link target (missing schema id)`);
819
+ const schema = await this.schema._application.getSchema(schemaId);
820
+ if (!schema) return;
821
+ const root = schema.root;
822
+ if (!root) return;
823
+ if (!xpath) return root;
824
+ return await root.findNode(xpath);
825
825
  }
826
826
 
827
827
  /**
@@ -831,45 +831,45 @@ class XtkSchemaNode {
831
831
  * @param {XML.XPath|string} path XPath represents the name of the node to be searched
832
832
  * @returns {Promise<XtkSchemaNode>} Returns a XtkSchemaNode instance if the node can be found
833
833
  */
834
- async findNode(path) {
835
- if (typeof path == "string") path = new XPath(path);
836
-
837
- // Find the starting node
838
- var node = this;
839
- if (path.isEmpty() || path.isAbsolute()) {
840
- node = this.schema.root;
841
- if (!node) return;
842
- path = path.getRelativePath();
843
- }
844
-
845
- // Special case for current path "."
846
- if (path.isSelf()) return this;
847
-
848
- const elements = path.getElements();
849
- while (node && elements.length > 0) {
850
- const element = elements.shift();
851
- var name = element.asString();
852
-
853
- // TODO: if the path is a collection path, ignore the collection index
854
-
855
- // handle ref elements (consider the ref target instead)
856
- if (node.ref) node = await node.refTarget();
857
- if (!node) break;
858
-
859
- if (node.type === "link") node = await node.linkTarget();
860
- if (!node) break;
861
-
862
- // Don't continue for any type
863
- // kludge to accept immediate child of an ANY type node (cas in packages)
864
- if (node.type === 'ANY') return this.children[name];
865
-
866
- var childNode = null;
867
- if (element.isSelf()) childNode = node;
868
- else if (element.isParent()) childNode = node.parent;
869
- else childNode = await node.children[name];
870
- node = childNode;
871
- }
872
- return node;
834
+ async findNode(path) {
835
+ if (typeof path == "string") path = new XPath(path);
836
+
837
+ // Find the starting node
838
+ var node = this;
839
+ if (path.isEmpty() || path.isAbsolute()) {
840
+ node = this.schema.root;
841
+ if (!node) return;
842
+ path = path.getRelativePath();
843
+ }
844
+
845
+ // Special case for current path "."
846
+ if (path.isSelf()) return this;
847
+
848
+ const elements = path.getElements();
849
+ while (node && elements.length > 0) {
850
+ const element = elements.shift();
851
+ var name = element.asString();
852
+
853
+ // TODO: if the path is a collection path, ignore the collection index
854
+
855
+ // handle ref elements (consider the ref target instead)
856
+ if (node.ref) node = await node.refTarget();
857
+ if (!node) break;
858
+
859
+ if (node.type === "link") node = await node.linkTarget();
860
+ if (!node) break;
861
+
862
+ // Don't continue for any type
863
+ // kludge to accept immediate child of an ANY type node (cas in packages)
864
+ if (node.type === 'ANY') return this.children[name];
865
+
866
+ var childNode = null;
867
+ if (element.isSelf()) childNode = node;
868
+ else if (element.isParent()) childNode = node.parent;
869
+ else childNode = await node.children[name];
870
+ node = childNode;
871
+ }
872
+ return node;
873
873
  }
874
874
 
875
875
  /**
@@ -880,12 +880,12 @@ class XtkSchemaNode {
880
880
  * @returns {string} a multi-line string representing the schema definition in a human readable form for troubleshooting purposes
881
881
  */
882
882
  toString(indent) {
883
- indent = indent || "";
884
- var s = `${indent}${this.label} (${this.name})\n`;
885
- for (var child of this.children) {
886
- s = s + child.toString(` ${indent}`);
887
- }
888
- return s;
883
+ indent = indent || "";
884
+ var s = `${indent}${this.label} (${this.name})\n`;
885
+ for (var child of this.children) {
886
+ s = s + child.toString(` ${indent}`);
887
+ }
888
+ return s;
889
889
  }
890
890
 
891
891
  /**
@@ -893,20 +893,20 @@ class XtkSchemaNode {
893
893
  * @returns {Promise<Array>} returns an array of joins. Each join is an element having a source and destination attributes, whose value is the corresponding XtkSchemaNode
894
894
  */
895
895
  async joinNodes() {
896
- if (!this.isLink) return;
897
- const joinParts = [];
898
- for (const join of this.joins) {
899
- const source = await this.parent.findNode(join.src);
900
- let destination = await this.linkTarget();
901
- if (destination)
902
- destination = await destination.findNode(join.dst);
903
- if (source && destination)
904
- joinParts.push({
905
- source: source,
906
- destination: destination
907
- });
908
- }
909
- return joinParts;
896
+ if (!this.isLink) return;
897
+ const joinParts = [];
898
+ for (const join of this.joins) {
899
+ const source = await this.parent.findNode(join.src);
900
+ let destination = await this.linkTarget();
901
+ if (destination)
902
+ destination = await destination.findNode(join.dst);
903
+ if (source && destination)
904
+ joinParts.push({
905
+ source: source,
906
+ destination: destination
907
+ });
908
+ }
909
+ return joinParts;
910
910
  }
911
911
 
912
912
  /**
@@ -914,32 +914,32 @@ class XtkSchemaNode {
914
914
  * @returns {Promise<Campaign.XtkSchemaNode>}
915
915
  */
916
916
  async reverseLink() {
917
- if (!this.isLink) return;
918
- const target = await this.linkTarget();
919
- if (!target) return;
920
- const revLink = await target.findNode(this.revLink);
921
- return revLink;
917
+ if (!this.isLink) return;
918
+ const target = await this.linkTarget();
919
+ if (!target) return;
920
+ const revLink = await target.findNode(this.revLink);
921
+ return revLink;
922
922
  }
923
923
 
924
924
  /**
925
925
  * Returns the compute string of a node. As the node can be a link or a reference, this function is asynchronous
926
926
  * @returns {Promise<string>}
927
927
  */
928
- async computeString() {
929
- if (this.expr) return this.expr;
930
- // if we are a ref: ask the target of the ref
931
- if (this.ref) {
932
- const refTarget = await this.refTarget();
933
- if (!refTarget) return "";
934
- return await refTarget.computeString();
935
- }
936
- // No compute-string found: generate a default one (first key field)
937
- if (this.keys && this.keys.length > 0) {
938
- const key = this.keys[0];
939
- if (key && key.fields && key.fields.length > 0 && key.fields[0])
940
- return this.schema._application.client.sdk.expandXPath(key.fields[0].nodePath);
941
- }
942
- return "";
928
+ async computeString() {
929
+ if (this.expr) return this.expr;
930
+ // if we are a ref: ask the target of the ref
931
+ if (this.ref) {
932
+ const refTarget = await this.refTarget();
933
+ if (!refTarget) return "";
934
+ return await refTarget.computeString();
935
+ }
936
+ // No compute-string found: generate a default one (first key field)
937
+ if (this.keys && this.keys.length > 0) {
938
+ const key = this.keys[0];
939
+ if (key && key.fields && key.fields.length > 0 && key.fields[0])
940
+ return this.schema._application.client.sdk.expandXPath(key.fields[0].nodePath);
941
+ }
942
+ return "";
943
943
  }
944
944
 
945
945
  /**
@@ -948,10 +948,10 @@ class XtkSchemaNode {
948
948
  * @returns Promise<Campaign.XtkEnumeration>
949
949
  */
950
950
  async enumeration(optionalName) {
951
- const name = optionalName || this.enum;
952
- if (!name) return;
953
- const enumaration = await this.schema._application.getSysEnum(name, this.schema);
954
- return enumaration;
951
+ const name = optionalName || this.enum;
952
+ if (!name) return;
953
+ const enumaration = await this.schema._application.getSysEnum(name, this.schema);
954
+ return enumaration;
955
955
  }
956
956
 
957
957
  /**
@@ -959,7 +959,7 @@ class XtkSchemaNode {
959
959
  * @returns {Campaign.XtkSchemaKey}
960
960
  */
961
961
  firstInternalKeyDef() {
962
- return this.keys.find((k) => k.isInternal);
962
+ return this.keys.find((k) => k.isInternal);
963
963
  }
964
964
 
965
965
  /**
@@ -967,7 +967,7 @@ class XtkSchemaNode {
967
967
  * @returns {Campaign.XtkSchemaKey}
968
968
  */
969
969
  firstExternalKeyDef() {
970
- return this.keys.find((k) => !k.isInternal);
970
+ return this.keys.find((k) => !k.isInternal);
971
971
  }
972
972
 
973
973
  /**
@@ -975,17 +975,17 @@ class XtkSchemaNode {
975
975
  * @returns {Campaign.XtkSchemaKey}
976
976
  */
977
977
  firstKeyDef() {
978
- let key = this.firstInternalKeyDef();
979
- if (!key) key = this.firstExternalKeyDef();
980
- return key;
978
+ let key = this.firstInternalKeyDef();
979
+ if (!key) key = this.firstExternalKeyDef();
980
+ return key;
981
981
  }
982
- }
982
+ }
983
983
 
984
- // ========================================================================================
985
- // Enumerations
986
- // ========================================================================================
984
+ // ========================================================================================
985
+ // Enumerations
986
+ // ========================================================================================
987
987
 
988
- /**
988
+ /**
989
989
  * @typedef {('string'|'byte'|'short'|'long'|'boolean')} XtkEnumerationType
990
990
  * @memberOf Campaign
991
991
  *
@@ -994,7 +994,7 @@ class XtkSchemaNode {
994
994
  */
995
995
 
996
996
 
997
- /**
997
+ /**
998
998
  * A system enumeration value
999
999
  *
1000
1000
  * @private
@@ -1005,7 +1005,7 @@ class XtkSchemaNode {
1005
1005
  * @param {string} parentTranslationId the translation id of the parent node
1006
1006
  * @memberof Campaign
1007
1007
  */
1008
- function XtkEnumerationValue(xml, baseType, parentTranslationId) {
1008
+ function XtkEnumerationValue(xml, baseType, parentTranslationId) {
1009
1009
  /**
1010
1010
  * The value (unique) name
1011
1011
  * @type {string}
@@ -1028,8 +1028,8 @@ function XtkEnumerationValue(xml, baseType, parentTranslationId) {
1028
1028
  * A human friendly long description of the value
1029
1029
  * @type {string}
1030
1030
  */
1031
- this.description = EntityAccessor.getAttributeAsString(xml, "desc");
1032
- /**
1031
+ this.description = EntityAccessor.getAttributeAsString(xml, "desc");
1032
+ /**
1033
1033
  * The value image (if any) or an empty string
1034
1034
  * @type {string}
1035
1035
  */
@@ -1046,9 +1046,9 @@ function XtkEnumerationValue(xml, baseType, parentTranslationId) {
1046
1046
  this.applicableIf = EntityAccessor.getAttributeAsString(xml, "applicableIf");
1047
1047
  let stringValue = EntityAccessor.getAttributeAsString(xml, "value");
1048
1048
  if (stringValue == "" && XtkCaster.isNumericType(baseType)) {
1049
- // Some enumerations (ex: xtk:dataTransfer:decimalCount) are of numeric type but do
1050
- // not have a "value" defined. In this case, we try to cas the name as the value
1051
- stringValue = this.name;
1049
+ // Some enumerations (ex: xtk:dataTransfer:decimalCount) are of numeric type but do
1050
+ // not have a "value" defined. In this case, we try to cas the name as the value
1051
+ stringValue = this.name;
1052
1052
  }
1053
1053
  /**
1054
1054
  * The enumeration value, casted according to the enumeration type
@@ -1057,9 +1057,9 @@ function XtkEnumerationValue(xml, baseType, parentTranslationId) {
1057
1057
  this.value = XtkCaster.as(stringValue, baseType);
1058
1058
 
1059
1059
  propagateImplicitValues(this, true);
1060
- }
1060
+ }
1061
1061
 
1062
- /**
1062
+ /**
1063
1063
  * A system enumeration
1064
1064
  *
1065
1065
  * @private
@@ -1068,96 +1068,96 @@ function XtkEnumerationValue(xml, baseType, parentTranslationId) {
1068
1068
  * @param {XML.XtkObject} xml the enumeration definition
1069
1069
  * @memberof Campaign
1070
1070
  */
1071
- class XtkEnumeration {
1071
+ class XtkEnumeration {
1072
1072
  constructor(schemaId, xml) {
1073
- /**
1073
+ /**
1074
1074
  * The system enumeration name, fully qualified, i.e. prefixed with the schema id
1075
1075
  * @type {string}
1076
1076
  */
1077
- this.name = EntityAccessor.getAttributeAsString(xml, "name");
1077
+ this.name = EntityAccessor.getAttributeAsString(xml, "name");
1078
1078
 
1079
- /**
1079
+ /**
1080
1080
  * A human friendly name for the system enumeration
1081
1081
  * @type {string}
1082
1082
  */
1083
- this.label = EntityAccessor.getAttributeAsString(xml, "label");
1083
+ this.label = EntityAccessor.getAttributeAsString(xml, "label");
1084
1084
 
1085
- /**
1085
+ /**
1086
1086
  * A human friendly long description of the enumeration
1087
1087
  * @type {string}
1088
1088
  */
1089
- this.description = EntityAccessor.getAttributeAsString(xml, "desc");
1089
+ this.description = EntityAccessor.getAttributeAsString(xml, "desc");
1090
1090
 
1091
- /**
1091
+ /**
1092
1092
  * The type of the enumeration, usually "string" or "byte"
1093
1093
  * @type {Campaign.XtkEnumerationType}
1094
1094
  */
1095
- this.baseType = EntityAccessor.getAttributeAsString(xml, "basetype");
1095
+ this.baseType = EntityAccessor.getAttributeAsString(xml, "basetype");
1096
1096
 
1097
- /**
1097
+ /**
1098
1098
  * The default value of the enumeration
1099
1099
  * @type {Campaign.XtkEnumerationValue}
1100
1100
  */
1101
- this.default = null;
1101
+ this.default = null;
1102
1102
 
1103
- /**
1103
+ /**
1104
1104
  * Indicates if the enumeration has an image, i.e. if any of its values has an image
1105
1105
  * @type {boolean}
1106
1106
  */
1107
- this.hasImage = false;
1107
+ this.hasImage = false;
1108
1108
 
1109
- /**
1109
+ /**
1110
1110
  * The enumerations values
1111
1111
  * @type {Utils.ArrayMap<Campaign.XtkEnumerationValue>}
1112
1112
  */
1113
- this.values = new ArrayMap();
1114
-
1115
- var defaultValue = EntityAccessor.getAttributeAsString(xml, "default");
1116
- this._localizationId = `${schemaId}__${this.name}`.replace(':','__');
1117
-
1118
- // Determine if the enumeration can support both access by name and by index.
1119
- // Some enumerations, such as xtk:dataTransfer:decimalCount are ambiguous since
1120
- // they have names which are string reprensentation of their values (ex: name="0").
1121
- // In this case enumValue[0] may mean either the first enumeration value (index 0)
1122
- // or the enumeration value with value "0" which happens to be the second
1123
- let supportsIndexing = true;
1124
- const values = [];
1125
- for (var child of EntityAccessor.getChildElements(xml, "value")) {
1126
- const e = new XtkEnumerationValue(child, this.baseType, this._localizationId);
1127
- values.push(e);
1128
- const numericName = +e.name;
1129
- if (numericName === numericName) {
1130
- // Name is a number
1131
- supportsIndexing = false;
1132
- }
1113
+ this.values = new ArrayMap();
1114
+
1115
+ var defaultValue = EntityAccessor.getAttributeAsString(xml, "default");
1116
+ this._localizationId = `${schemaId}__${this.name}`.replace(':','__');
1117
+
1118
+ // Determine if the enumeration can support both access by name and by index.
1119
+ // Some enumerations, such as xtk:dataTransfer:decimalCount are ambiguous since
1120
+ // they have names which are string reprensentation of their values (ex: name="0").
1121
+ // In this case enumValue[0] may mean either the first enumeration value (index 0)
1122
+ // or the enumeration value with value "0" which happens to be the second
1123
+ let supportsIndexing = true;
1124
+ const values = [];
1125
+ for (var child of EntityAccessor.getChildElements(xml, "value")) {
1126
+ const e = new XtkEnumerationValue(child, this.baseType, this._localizationId);
1127
+ values.push(e);
1128
+ const numericName = +e.name;
1129
+ if (numericName === numericName) {
1130
+ // Name is a number
1131
+ supportsIndexing = false;
1133
1132
  }
1133
+ }
1134
1134
 
1135
- for (const e of values) {
1136
- this.values._push(e.name, e, !supportsIndexing);
1137
- if (e.image != "") this.hasImage = true;
1138
- const stringValue = e.name;
1139
- if (defaultValue == stringValue)
1140
- this.default = e;
1141
- }
1135
+ for (const e of values) {
1136
+ this.values._push(e.name, e, !supportsIndexing);
1137
+ if (e.image != "") this.hasImage = true;
1138
+ const stringValue = e.name;
1139
+ if (defaultValue == stringValue)
1140
+ this.default = e;
1141
+ }
1142
1142
 
1143
- this.labelLocalizationId = this._localizationId + "__@label";
1144
- this.descriptionLocalizationId = this._localizationId + "__@desc";
1145
- propagateImplicitValues(this, true);
1143
+ this.labelLocalizationId = this._localizationId + "__@label";
1144
+ this.descriptionLocalizationId = this._localizationId + "__@desc";
1145
+ propagateImplicitValues(this, true);
1146
1146
 
1147
- /**
1147
+ /**
1148
1148
  * The system enumeration name, without the schema id prefix
1149
1149
  * @type {string}
1150
1150
  */
1151
- this.shortName = this.name;
1152
- this.name = `${schemaId}:${this.shortName}`;
1151
+ this.shortName = this.name;
1152
+ this.name = `${schemaId}:${this.shortName}`;
1153
1153
  }
1154
- }
1154
+ }
1155
1155
 
1156
- // ========================================================================================
1157
- // Schemas
1158
- // ========================================================================================
1156
+ // ========================================================================================
1157
+ // Schemas
1158
+ // ========================================================================================
1159
1159
 
1160
- /**
1160
+ /**
1161
1161
  * A schema
1162
1162
  *
1163
1163
  * @private
@@ -1168,82 +1168,82 @@ class XtkEnumeration {
1168
1168
  * @param {XML.XtkObject} xml the schema definition
1169
1169
  * @memberof Campaign
1170
1170
  */
1171
- class XtkSchema extends XtkSchemaNode {
1171
+ class XtkSchema extends XtkSchemaNode {
1172
1172
 
1173
1173
  constructor(application, xml) {
1174
- super();
1175
- this._application = application;
1174
+ super();
1175
+ this._application = application;
1176
1176
 
1177
- /**
1177
+ /**
1178
1178
  * The namespace of the schema
1179
1179
  * @type {string}
1180
1180
  */
1181
- this.namespace = EntityAccessor.getAttributeAsString(xml, "namespace");
1181
+ this.namespace = EntityAccessor.getAttributeAsString(xml, "namespace");
1182
1182
 
1183
- /**
1183
+ /**
1184
1184
  * The schema id, in the form "namespace:name"
1185
1185
  * @type {string}
1186
1186
  */
1187
- this.name = EntityAccessor.getAttributeAsString(xml, "name");
1188
- this.id = `${this.namespace}:${this.name}`;
1187
+ this.name = EntityAccessor.getAttributeAsString(xml, "name");
1188
+ this.id = `${this.namespace}:${this.name}`;
1189
1189
 
1190
- /**
1190
+ /**
1191
1191
  * Indicates whether the schema is a library schema or not
1192
1192
  * @type {boolean}
1193
1193
  */
1194
- this.isLibrary = EntityAccessor.getAttributeAsBoolean(xml, "library");
1194
+ this.isLibrary = EntityAccessor.getAttributeAsBoolean(xml, "library");
1195
1195
 
1196
- /**
1196
+ /**
1197
1197
  * A human name for the schema, in singular
1198
1198
  * @type {string}
1199
1199
  */
1200
- this.labelSingular = EntityAccessor.getAttributeAsString(xml, "labelSingular");
1201
- /**
1200
+ this.labelSingular = EntityAccessor.getAttributeAsString(xml, "labelSingular");
1201
+ /**
1202
1202
  * The schema mappgin type, following the xtk:srcSchema:mappingType enumeration
1203
1203
  * @type {Campaign.XtkSchemaMappingType}
1204
1204
  */
1205
- this.mappingType = EntityAccessor.getAttributeAsString(xml, "mappingType");
1205
+ this.mappingType = EntityAccessor.getAttributeAsString(xml, "mappingType");
1206
1206
 
1207
- /**
1207
+ /**
1208
1208
  * The MD5 checksum of the schema in the form of a hexadecimal string
1209
1209
  * @type {string}
1210
1210
  */
1211
- this.md5 = EntityAccessor.getAttributeAsString(xml, "md5");
1211
+ this.md5 = EntityAccessor.getAttributeAsString(xml, "md5");
1212
1212
 
1213
- /**
1213
+ /**
1214
1214
  * The schema definition
1215
1215
  * @private
1216
1216
  * @type {XML.XtkObject}
1217
1217
  */
1218
- this.xml = xml;
1218
+ this.xml = xml;
1219
1219
 
1220
- this.init(this, xml);
1220
+ this.init(this, xml);
1221
1221
 
1222
- /**
1222
+ /**
1223
1223
  * The schema root node, if it has one, i.e. the first child whose name matches the schema name
1224
1224
  * @type {Campaign.XtkSchemaNode}
1225
1225
  */
1226
- this.root = this.children[this.name];
1226
+ this.root = this.children[this.name];
1227
1227
 
1228
- /**
1228
+ /**
1229
1229
  * A user desciption of the node, in the form "label (name)"
1230
1230
  * @type {string}
1231
1231
  */
1232
- this.userDescription = (this.label == this.name) ? this.name : `${this.label} (${this.name})`;
1232
+ this.userDescription = (this.label == this.name) ? this.name : `${this.label} (${this.name})`;
1233
1233
 
1234
- /**
1234
+ /**
1235
1235
  * Enumerations in this schema, as a dictionary whose keys are enumeration names and values are the
1236
1236
  * corresponding enumeration definitions
1237
1237
  * @type {Utils.ArrayMap<Campaign.XtkEnumeration>}
1238
1238
  */
1239
- this.enumerations = new ArrayMap();
1240
- for (var child of EntityAccessor.getChildElements(xml, "enumeration")) {
1241
- const e = new XtkEnumeration(this.id, child);
1242
- if (this.enumerations.get(e.shortName) === undefined) {
1243
- this.enumerations._push(e.shortName, e);
1244
- }
1245
- }
1246
- }
1239
+ this.enumerations = new ArrayMap();
1240
+ for (var child of EntityAccessor.getChildElements(xml, "enumeration")) {
1241
+ const e = new XtkEnumeration(this.id, child);
1242
+ if (this.enumerations.get(e.shortName) === undefined) {
1243
+ this.enumerations._push(e.shortName, e);
1244
+ }
1245
+ }
1246
+ }
1247
1247
 
1248
1248
  /**
1249
1249
  * Creates a multi-line debug string representing the schema
@@ -1251,21 +1251,21 @@ class XtkSchema extends XtkSchemaNode {
1251
1251
  * @returns {string} a multi-line string representing the schema definition in a human readable form for troubleshooting purposes
1252
1252
  */
1253
1253
  toString() {
1254
- var s = `${this.userDescription}\n`;
1255
- for (var child of this.children) {
1256
- s = s + child.toString(" - ");
1257
- }
1258
- return s;
1254
+ var s = `${this.userDescription}\n`;
1255
+ for (var child of this.children) {
1256
+ s = s + child.toString(" - ");
1257
+ }
1258
+ return s;
1259
1259
  }
1260
- }
1260
+ }
1261
1261
 
1262
1262
 
1263
1263
 
1264
- // ========================================================================================
1265
- // Current Login
1266
- // ========================================================================================
1264
+ // ========================================================================================
1265
+ // Current Login
1266
+ // ========================================================================================
1267
1267
 
1268
- /**
1268
+ /**
1269
1269
  * Represents the currently logged operator. Do not create directly, this is available
1270
1270
  * as the sdk.application.operator variable
1271
1271
  *
@@ -1275,50 +1275,50 @@ class XtkSchema extends XtkSchemaNode {
1275
1275
  * @param {XML.XtkObject} userInfo the user info object as returned from the xtk:session#Logon call
1276
1276
  * @memberof Campaign
1277
1277
  */
1278
- class CurrentLogin {
1278
+ class CurrentLogin {
1279
1279
 
1280
1280
  constructor(userInfo) {
1281
- /**
1281
+ /**
1282
1282
  * The operator login name
1283
1283
  * @type {string}
1284
1284
  */
1285
- this.login = EntityAccessor.getAttributeAsString(userInfo, "login");
1285
+ this.login = EntityAccessor.getAttributeAsString(userInfo, "login");
1286
1286
 
1287
- /**
1287
+ /**
1288
1288
  * The operator login id
1289
1289
  * @type {number}
1290
1290
  */
1291
- this.id = EntityAccessor.getAttributeAsLong(userInfo, "loginId");
1291
+ this.id = EntityAccessor.getAttributeAsLong(userInfo, "loginId");
1292
1292
 
1293
- /**
1293
+ /**
1294
1294
  * A human friendly string naming the operator (compute string)
1295
1295
  * @type {string}
1296
1296
  */
1297
- this.computeString = EntityAccessor.getAttributeAsString(userInfo, "loginCS");
1297
+ this.computeString = EntityAccessor.getAttributeAsString(userInfo, "loginCS");
1298
1298
 
1299
- /**
1299
+ /**
1300
1300
  * The operator timezone
1301
1301
  * @type {string}
1302
1302
  */
1303
- this.timezone = EntityAccessor.getAttributeAsString(userInfo, "timezone");
1303
+ this.timezone = EntityAccessor.getAttributeAsString(userInfo, "timezone");
1304
1304
 
1305
- /**
1305
+ /**
1306
1306
  * The instance locale
1307
1307
  * @type { string }
1308
1308
  */
1309
- this.instanceLocale = EntityAccessor.getAttributeAsString(userInfo, "instanceLocale");
1309
+ this.instanceLocale = EntityAccessor.getAttributeAsString(userInfo, "instanceLocale");
1310
1310
 
1311
- /**
1311
+ /**
1312
1312
  * The llist of operator rights
1313
1313
  * @type {string[]}
1314
1314
  */
1315
- this.rights = [];
1316
- this._rightsSet = {};
1317
- for (var child of EntityAccessor.getChildElements(userInfo, "login-right")) {
1318
- const right = EntityAccessor.getAttributeAsString(child, "right");
1315
+ this.rights = [];
1316
+ this._rightsSet = {};
1317
+ for (var child of EntityAccessor.getChildElements(userInfo, "login-right")) {
1318
+ const right = EntityAccessor.getAttributeAsString(child, "right");
1319
1319
  this.rights.push(right);
1320
1320
  this._rightsSet[right] = true;
1321
- }
1321
+ }
1322
1322
  }
1323
1323
 
1324
1324
  /**
@@ -1328,12 +1328,12 @@ class CurrentLogin {
1328
1328
  * @returns {boolean} a boolean indicating whether the operator has the given right or not
1329
1329
  */
1330
1330
  hasRight(name) {
1331
- return !!this._rightsSet[name];
1331
+ return !!this._rightsSet[name];
1332
1332
  }
1333
1333
 
1334
- }
1334
+ }
1335
1335
 
1336
- /**
1336
+ /**
1337
1337
  * Creates a current login object for testing purposes
1338
1338
  *
1339
1339
  * @private
@@ -1341,21 +1341,21 @@ class CurrentLogin {
1341
1341
  * @returns the CurrentLogin object corresponding to the passed object
1342
1342
  * @memberof Campaign
1343
1343
  */
1344
- function newCurrentLogin(userInfo) {
1344
+ function newCurrentLogin(userInfo) {
1345
1345
  return new CurrentLogin(userInfo);
1346
- }
1346
+ }
1347
1347
 
1348
- // ========================================================================================
1349
- // Application
1350
- // ========================================================================================
1348
+ // ========================================================================================
1349
+ // Application
1350
+ // ========================================================================================
1351
1351
 
1352
- /**
1352
+ /**
1353
1353
  * @class
1354
1354
  * @constructor
1355
1355
  * @param {Campaign.Client} client The Campaign Client from which this Application object is created
1356
1356
  * @memberof Campaign
1357
1357
  */
1358
- class Application {
1358
+ class Application {
1359
1359
 
1360
1360
  /**
1361
1361
  * The Application object provides access to certain properties of the Campaign server.
@@ -1364,55 +1364,55 @@ class Application {
1364
1364
  * @param {Campaign.Client} client the Campaign client representing the Campaign instance
1365
1365
  */
1366
1366
  constructor(client) {
1367
- this.client = client;
1368
- this._schemaCache = new SchemaCache(client);
1369
- const info = this.client.getSessionInfo();
1370
- // When using "SessionToken" authentication, there is no actual logon, and therefore
1371
- // no "sessionInfo" object
1372
- if (info) {
1373
- const serverInfo = EntityAccessor.getElement(info, "serverInfo");
1374
- /**
1367
+ this.client = client;
1368
+ this._schemaCache = new SchemaCache(client);
1369
+ const info = this.client.getSessionInfo();
1370
+ // When using "SessionToken" authentication, there is no actual logon, and therefore
1371
+ // no "sessionInfo" object
1372
+ if (info) {
1373
+ const serverInfo = EntityAccessor.getElement(info, "serverInfo");
1374
+ /**
1375
1375
  * The server build number
1376
1376
  * @type {string}
1377
1377
  */
1378
- this.buildNumber = EntityAccessor.getAttributeAsString(serverInfo, "buildNumber");
1379
- /**
1378
+ this.buildNumber = EntityAccessor.getAttributeAsString(serverInfo, "buildNumber");
1379
+ /**
1380
1380
  * The server version, formatted as major.minor.servicePack (ex: 8.2.10)
1381
1381
  * @type {string}
1382
1382
  */
1383
- const majNumber = EntityAccessor.getAttributeAsString(serverInfo, "majNumber");
1384
- const minNumber = EntityAccessor.getAttributeAsString(serverInfo, "minNumber");
1385
- const servicePack = EntityAccessor.getAttributeAsString(serverInfo, "servicePack");
1386
- if (majNumber && minNumber && servicePack)
1387
- this.version = majNumber + "." + minNumber + "." + servicePack;
1388
- /**
1383
+ const majNumber = EntityAccessor.getAttributeAsString(serverInfo, "majNumber");
1384
+ const minNumber = EntityAccessor.getAttributeAsString(serverInfo, "minNumber");
1385
+ const servicePack = EntityAccessor.getAttributeAsString(serverInfo, "servicePack");
1386
+ if (majNumber && minNumber && servicePack)
1387
+ this.version = majNumber + "." + minNumber + "." + servicePack;
1388
+ /**
1389
1389
  * The Campaign instance name
1390
1390
  * @type {string}
1391
1391
  */
1392
- this.instanceName = EntityAccessor.getAttributeAsString(serverInfo, "instanceName");
1393
- const userInfo = EntityAccessor.getElement(info, "userInfo");
1394
- /**
1392
+ this.instanceName = EntityAccessor.getAttributeAsString(serverInfo, "instanceName");
1393
+ const userInfo = EntityAccessor.getElement(info, "userInfo");
1394
+ /**
1395
1395
  * The logged operator
1396
1396
  * @type {Campaign.CurrentLogin}
1397
1397
  */
1398
- this.operator = new CurrentLogin(userInfo);
1399
- /**
1398
+ this.operator = new CurrentLogin(userInfo);
1399
+ /**
1400
1400
  * The list of installed packages
1401
1401
  * @type {string[]}
1402
1402
  */
1403
- this.packages = [];
1404
- for (var p of EntityAccessor.getChildElements(userInfo, "installed-package")) {
1405
- this.packages.push(`${EntityAccessor.getAttributeAsString(p, "namespace")}:${EntityAccessor.getAttributeAsString(p, "name")}`);
1406
- }
1403
+ this.packages = [];
1404
+ for (var p of EntityAccessor.getChildElements(userInfo, "installed-package")) {
1405
+ this.packages.push(`${EntityAccessor.getAttributeAsString(p, "namespace")}:${EntityAccessor.getAttributeAsString(p, "name")}`);
1407
1406
  }
1407
+ }
1408
1408
  }
1409
1409
 
1410
1410
  _registerCacheChangeListener() {
1411
- this.client._registerCacheChangeListener(this._schemaCache);
1411
+ this.client._registerCacheChangeListener(this._schemaCache);
1412
1412
  }
1413
1413
 
1414
1414
  _unregisterCacheChangeListener() {
1415
- this.client._unregisterCacheChangeListener(this._schemaCache);
1415
+ this.client._unregisterCacheChangeListener(this._schemaCache);
1416
1416
  }
1417
1417
  /**
1418
1418
  * Get a schema by id. This function returns an XtkSchema object or null if the schema is not found.
@@ -1422,19 +1422,19 @@ class Application {
1422
1422
  * @param {boolean} withoutCache if true, the schema will be fetched from the server without using the cache, defaults to false
1423
1423
  * @returns {Campaign.XtkSchema} the schema, or null if the schema was not found
1424
1424
  */
1425
- async getSchema(schemaId, withoutCache = false) {
1426
- if (withoutCache) {
1427
- return this._getSchema(schemaId, withoutCache);
1428
- }
1429
- return this._schemaCache.getSchema(schemaId);
1425
+ async getSchema(schemaId, withoutCache = false) {
1426
+ if (withoutCache) {
1427
+ return this._getSchema(schemaId, withoutCache);
1428
+ }
1429
+ return this._schemaCache.getSchema(schemaId);
1430
1430
  }
1431
1431
 
1432
1432
  // Private function: get a schema without using the SchemaCache
1433
1433
  async _getSchema(schemaId, withoutCache = false) {
1434
- const xml = await this.client.getSchema(schemaId, "xml", undefined, withoutCache);
1435
- if (!xml)
1436
- return null;
1437
- return newSchema(xml, this);
1434
+ const xml = await this.client.getSchema(schemaId, "xml", undefined, withoutCache);
1435
+ if (!xml)
1436
+ return null;
1437
+ return newSchema(xml, this);
1438
1438
  }
1439
1439
 
1440
1440
  /**
@@ -1444,10 +1444,10 @@ class Application {
1444
1444
  * @returns {boolean} a boolean indicating whether the package is installed or not
1445
1445
  */
1446
1446
  hasPackage(name) {
1447
- for (var p of this.packages) {
1448
- if (p == name) return true;
1449
- }
1450
- return false;
1447
+ for (var p of this.packages) {
1448
+ if (p == name) return true;
1449
+ }
1450
+ return false;
1451
1451
  }
1452
1452
 
1453
1453
  /**
@@ -1458,32 +1458,32 @@ class Application {
1458
1458
  * @returns {XtkEnumeration} the enumeration
1459
1459
  */
1460
1460
  async getSysEnum(enumerationName, schemaOrSchemaId) {
1461
- const index = enumerationName.lastIndexOf(':');
1462
- if (index === -1) {
1463
- let schema = schemaOrSchemaId;
1464
- if (schema && typeof schema === "string")
1465
- schema = await this.getSchema(schema);
1466
- // unqualified enumeration name
1467
- if (!schema) return;
1468
- return schema.enumerations[enumerationName];
1469
- }
1470
- // qualified enumeration name
1471
- const schemaId = enumerationName.substring(0, index);
1472
- if (schemaId.indexOf(':') === -1)
1473
- throw Error(`Invalid enumeration name '${enumerationName}': expecting {name} or {schemaId}:{name}`);
1474
- let schema = await this.getSchema(schemaId);
1461
+ const index = enumerationName.lastIndexOf(':');
1462
+ if (index === -1) {
1463
+ let schema = schemaOrSchemaId;
1464
+ if (schema && typeof schema === "string")
1465
+ schema = await this.getSchema(schema);
1466
+ // unqualified enumeration name
1475
1467
  if (!schema) return;
1476
- return schema.enumerations[enumerationName.substring(index + 1)];
1468
+ return schema.enumerations[enumerationName];
1469
+ }
1470
+ // qualified enumeration name
1471
+ const schemaId = enumerationName.substring(0, index);
1472
+ if (schemaId.indexOf(':') === -1)
1473
+ throw Error(`Invalid enumeration name '${enumerationName}': expecting {name} or {schemaId}:{name}`);
1474
+ let schema = await this.getSchema(schemaId);
1475
+ if (!schema) return;
1476
+ return schema.enumerations[enumerationName.substring(index + 1)];
1477
1477
  }
1478
- }
1478
+ }
1479
1479
 
1480
1480
 
1481
1481
 
1482
- // Public exports
1483
- exports.Application = Application;
1482
+ // Public exports
1483
+ exports.Application = Application;
1484
1484
 
1485
- // For tests
1486
- exports.newSchema = newSchema;
1487
- exports.newCurrentLogin = newCurrentLogin;
1488
- exports.SchemaCache = SchemaCache;
1485
+ // For tests
1486
+ exports.newSchema = newSchema;
1487
+ exports.newCurrentLogin = newCurrentLogin;
1488
+ exports.SchemaCache = SchemaCache;
1489
1489
  })();