@sisense/sdk-data 1.11.0 → 1.13.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 (99) hide show
  1. package/dist/cjs/dimensional-model/analytics/factory.d.ts +47 -0
  2. package/dist/cjs/dimensional-model/analytics/factory.js +153 -0
  3. package/dist/cjs/dimensional-model/analytics/factory.test.d.ts +1 -0
  4. package/dist/cjs/dimensional-model/analytics/factory.test.js +99 -0
  5. package/dist/cjs/dimensional-model/attributes.d.ts +139 -0
  6. package/dist/cjs/dimensional-model/attributes.js +342 -0
  7. package/dist/cjs/dimensional-model/attributes.test.d.ts +1 -0
  8. package/dist/cjs/dimensional-model/attributes.test.js +154 -0
  9. package/dist/cjs/dimensional-model/base.d.ts +43 -0
  10. package/dist/cjs/dimensional-model/base.js +58 -0
  11. package/dist/cjs/dimensional-model/base.test.d.ts +1 -0
  12. package/dist/cjs/dimensional-model/base.test.js +17 -0
  13. package/dist/cjs/dimensional-model/data-model.d.ts +13 -0
  14. package/dist/cjs/dimensional-model/data-model.js +37 -0
  15. package/dist/cjs/dimensional-model/dimensions.d.ts +167 -0
  16. package/dist/cjs/dimensional-model/dimensions.js +307 -0
  17. package/dist/cjs/dimensional-model/dimensions.test.d.ts +1 -0
  18. package/dist/cjs/dimensional-model/dimensions.test.js +54 -0
  19. package/dist/cjs/dimensional-model/factory.d.ts +17 -0
  20. package/dist/cjs/dimensional-model/factory.js +54 -0
  21. package/dist/cjs/dimensional-model/filters/factory.d.ts +797 -0
  22. package/dist/cjs/dimensional-model/filters/factory.js +962 -0
  23. package/dist/cjs/dimensional-model/filters/factory.test.d.ts +1 -0
  24. package/dist/cjs/dimensional-model/filters/factory.test.js +366 -0
  25. package/dist/cjs/dimensional-model/filters/filters.d.ts +344 -0
  26. package/dist/cjs/dimensional-model/filters/filters.js +663 -0
  27. package/dist/cjs/dimensional-model/filters/filters.test.d.ts +1 -0
  28. package/dist/cjs/dimensional-model/filters/filters.test.js +225 -0
  29. package/dist/cjs/dimensional-model/filters/utils/attribute-measure-util.d.ts +47 -0
  30. package/dist/cjs/dimensional-model/filters/utils/attribute-measure-util.js +111 -0
  31. package/dist/cjs/dimensional-model/filters/utils/condition-filter-util.d.ts +21 -0
  32. package/dist/cjs/dimensional-model/filters/utils/condition-filter-util.js +196 -0
  33. package/dist/cjs/dimensional-model/filters/utils/date-time-filter-util.d.ts +2 -0
  34. package/dist/cjs/dimensional-model/filters/utils/date-time-filter-util.js +12 -0
  35. package/dist/cjs/dimensional-model/filters/utils/filter-code-util.d.ts +13 -0
  36. package/dist/cjs/dimensional-model/filters/utils/filter-code-util.js +58 -0
  37. package/dist/cjs/dimensional-model/filters/utils/filter-code-util.test.d.ts +1 -0
  38. package/dist/cjs/dimensional-model/filters/utils/filter-code-util.test.js +32 -0
  39. package/dist/cjs/dimensional-model/filters/utils/filter-from-jaql-util.d.ts +82 -0
  40. package/dist/cjs/dimensional-model/filters/utils/filter-from-jaql-util.js +215 -0
  41. package/dist/cjs/dimensional-model/filters/utils/filter-from-jaql-util.test.d.ts +1 -0
  42. package/dist/cjs/dimensional-model/filters/utils/filter-from-jaql-util.test.js +623 -0
  43. package/dist/cjs/dimensional-model/filters/utils/filter-matcher-utils.d.ts +5 -0
  44. package/dist/cjs/dimensional-model/filters/utils/filter-matcher-utils.js +174 -0
  45. package/dist/cjs/dimensional-model/filters/utils/filter-matcher-utils.test.d.ts +1 -0
  46. package/dist/cjs/dimensional-model/filters/utils/filter-matcher-utils.test.js +236 -0
  47. package/dist/cjs/dimensional-model/filters/utils/filter-types-util.d.ts +17 -0
  48. package/dist/cjs/dimensional-model/filters/utils/filter-types-util.js +79 -0
  49. package/dist/cjs/dimensional-model/filters/utils/types.d.ts +206 -0
  50. package/dist/cjs/dimensional-model/filters/utils/types.js +99 -0
  51. package/dist/cjs/dimensional-model/interfaces.d.ts +512 -0
  52. package/dist/cjs/dimensional-model/interfaces.js +31 -0
  53. package/dist/cjs/dimensional-model/measures/factory.d.ts +920 -0
  54. package/dist/cjs/dimensional-model/measures/factory.js +1188 -0
  55. package/dist/cjs/dimensional-model/measures/factory.test.d.ts +1 -0
  56. package/dist/cjs/dimensional-model/measures/factory.test.js +481 -0
  57. package/dist/cjs/dimensional-model/measures/measures.d.ts +217 -0
  58. package/dist/cjs/dimensional-model/measures/measures.js +416 -0
  59. package/dist/cjs/dimensional-model/measures/measures.test.d.ts +1 -0
  60. package/dist/cjs/dimensional-model/measures/measures.test.js +79 -0
  61. package/dist/cjs/dimensional-model/simple-column-types.d.ts +39 -0
  62. package/dist/cjs/dimensional-model/simple-column-types.js +134 -0
  63. package/dist/cjs/dimensional-model/simple-column-types.test.d.ts +1 -0
  64. package/dist/cjs/dimensional-model/simple-column-types.test.js +85 -0
  65. package/dist/cjs/dimensional-model/types.d.ts +256 -0
  66. package/dist/cjs/dimensional-model/types.js +298 -0
  67. package/dist/cjs/dimensional-model/types.test.d.ts +1 -0
  68. package/dist/cjs/dimensional-model/types.test.js +33 -0
  69. package/dist/cjs/index.d.ts +93 -0
  70. package/dist/cjs/index.js +123 -0
  71. package/dist/cjs/interfaces.d.ts +367 -0
  72. package/dist/cjs/interfaces.js +21 -0
  73. package/dist/cjs/translation/initialize-i18n.d.ts +2 -0
  74. package/dist/cjs/translation/initialize-i18n.js +14 -0
  75. package/dist/cjs/translation/resources/en.d.ts +28 -0
  76. package/dist/cjs/translation/resources/en.js +30 -0
  77. package/dist/cjs/translation/resources/index.d.ts +53 -0
  78. package/dist/cjs/translation/resources/index.js +10 -0
  79. package/dist/cjs/translation/resources/uk.d.ts +5 -0
  80. package/dist/cjs/translation/resources/uk.js +30 -0
  81. package/dist/cjs/translation/translatable-error.d.ts +5 -0
  82. package/dist/cjs/translation/translatable-error.js +15 -0
  83. package/dist/cjs/utils.d.ts +37 -0
  84. package/dist/cjs/utils.js +105 -0
  85. package/dist/cjs/utils.test.d.ts +1 -0
  86. package/dist/cjs/utils.test.js +158 -0
  87. package/dist/dimensional-model/analytics/factory.js +6 -4
  88. package/dist/dimensional-model/filters/factory.d.ts +81 -42
  89. package/dist/dimensional-model/filters/factory.js +125 -87
  90. package/dist/dimensional-model/filters/filters.d.ts +58 -13
  91. package/dist/dimensional-model/filters/filters.js +117 -27
  92. package/dist/dimensional-model/filters/utils/condition-filter-util.d.ts +4 -2
  93. package/dist/dimensional-model/filters/utils/condition-filter-util.js +30 -26
  94. package/dist/dimensional-model/filters/utils/filter-code-util.js +5 -1
  95. package/dist/dimensional-model/filters/utils/filter-from-jaql-util.d.ts +26 -11
  96. package/dist/dimensional-model/filters/utils/filter-from-jaql-util.js +58 -27
  97. package/dist/dimensional-model/filters/utils/filter-types-util.js +3 -3
  98. package/dist/dimensional-model/filters/utils/types.d.ts +6 -0
  99. package/package.json +18 -9
@@ -0,0 +1,342 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeAttributeName = exports.createLevel = exports.createAttribute = exports.DimensionalLevelAttribute = exports.DimensionalAttribute = exports.jaqlSimpleColumnType = void 0;
4
+ const types_js_1 = require("./types.js");
5
+ const base_js_1 = require("./base.js");
6
+ const simple_column_types_js_1 = require("./simple-column-types.js");
7
+ /**
8
+ * @internal
9
+ */
10
+ const jaqlSimpleColumnType = (datatype) => (0, simple_column_types_js_1.simpleColumnType)(datatype).replace('number', 'numeric');
11
+ exports.jaqlSimpleColumnType = jaqlSimpleColumnType;
12
+ /**
13
+ * @internal
14
+ */
15
+ class DimensionalAttribute extends base_js_1.DimensionalElement {
16
+ constructor(name, expression, type, desc, sort) {
17
+ super((0, base_js_1.normalizeName)(name), type || types_js_1.MetadataTypes.Attribute, desc);
18
+ this._sort = types_js_1.Sort.None;
19
+ this.expression = expression;
20
+ this._sort = sort || types_js_1.Sort.None;
21
+ }
22
+ /**
23
+ * gets the element's ID
24
+ */
25
+ get id() {
26
+ return this.expression;
27
+ }
28
+ /**
29
+ * Gets the sort definition of this instance
30
+ *
31
+ * @returns The Sort definition of this instance
32
+ */
33
+ getSort() {
34
+ return this._sort;
35
+ }
36
+ /**
37
+ * Gets a sorted {@link Attribute} with the given definition
38
+ *
39
+ * @param sort - Sort definition
40
+ * @returns An instance representing the sorted {@link Attribute} of this instance
41
+ */
42
+ sort(sort) {
43
+ return new DimensionalAttribute(this.name, this.expression, this.type, this.description, sort);
44
+ }
45
+ /**
46
+ * Gets the JAQL representation of this instance
47
+ *
48
+ * @param nested - defines whether the JAQL is nested within parent JAQL statement or a root JAQL element
49
+ */
50
+ jaql(nested) {
51
+ const result = {
52
+ jaql: {
53
+ title: this.name,
54
+ dim: this.expression,
55
+ datatype: (0, exports.jaqlSimpleColumnType)(this.type),
56
+ },
57
+ };
58
+ if (this._sort != types_js_1.Sort.None) {
59
+ result.jaql.sort = this._sort == types_js_1.Sort.Ascending ? 'asc' : 'desc';
60
+ }
61
+ return nested === true ? result.jaql : result;
62
+ }
63
+ /**
64
+ * Gets a serializable representation of the element
65
+ */
66
+ serializable() {
67
+ const result = super.serializable();
68
+ result.expression = this.expression;
69
+ if (this.getSort() !== types_js_1.Sort.None) {
70
+ result.sort = this.getSort().toString();
71
+ }
72
+ return result;
73
+ }
74
+ }
75
+ exports.DimensionalAttribute = DimensionalAttribute;
76
+ /**
77
+ * @internal
78
+ */
79
+ class DimensionalLevelAttribute extends DimensionalAttribute {
80
+ constructor(l, expression, granularity, format, desc, sort) {
81
+ super(l, expression, types_js_1.MetadataTypes.DateLevel, desc, sort);
82
+ this._format = format;
83
+ this.granularity = granularity;
84
+ }
85
+ /**
86
+ * gets the element's ID
87
+ */
88
+ get id() {
89
+ let id = `${this.expression}`;
90
+ const { level = '', dateTimeLevel = '', bucket } = this.translateGranularityToJaql();
91
+ id += `_${(level || dateTimeLevel).toLowerCase()}`;
92
+ if (bucket) {
93
+ id += `_${bucket}`;
94
+ }
95
+ return id;
96
+ }
97
+ /**
98
+ * Gets the sort definition of this instance
99
+ *
100
+ * @returns The Sort definition of this instance
101
+ */
102
+ getSort() {
103
+ return this._sort;
104
+ }
105
+ /**
106
+ * Gets a sorted {@link LevelAttribute} with the given definition
107
+ *
108
+ * @param sort - Sort definition
109
+ * @returns An instance representing the sorted {@link LevelAttribute} of this instance
110
+ */
111
+ sort(sort) {
112
+ return new DimensionalLevelAttribute(this.name, this.expression, this.granularity, this._format, this.description, sort);
113
+ }
114
+ /**
115
+ * The string formatting of this instance
116
+ *
117
+ * @returns string formatting
118
+ */
119
+ getFormat() {
120
+ return this._format;
121
+ }
122
+ /**
123
+ * Gets a formatted {@link LevelAttribute} with the given definition
124
+ *
125
+ * @param format - Format string
126
+ * @returns An instance representing the formatted {@link LevelAttribute} of this instance
127
+ */
128
+ format(format) {
129
+ return new DimensionalLevelAttribute(this.name, this.expression, this.granularity, format, this.description, this._sort);
130
+ }
131
+ /**
132
+ * Gets a serializable representation of the element
133
+ */
134
+ serializable() {
135
+ const result = super.serializable();
136
+ result.granularity = this.granularity;
137
+ if (this.getFormat() !== undefined) {
138
+ result.format = this.getFormat();
139
+ }
140
+ return result;
141
+ }
142
+ /**
143
+ * Gets the JAQL representation of this instance
144
+ *
145
+ * @param nested - defines whether the JAQL is nested within parent JAQL statement or a root JAQL element
146
+ */
147
+ jaql(nested) {
148
+ const r = {
149
+ jaql: Object.assign({ title: this.name, dim: this.expression, datatype: (0, exports.jaqlSimpleColumnType)(this.type) }, this.translateGranularityToJaql()),
150
+ };
151
+ if (this._format !== undefined) {
152
+ const levelName = r.jaql.dateTimeLevel || r.jaql.level;
153
+ r.format = { mask: {} };
154
+ r.format.mask[levelName] = this._format;
155
+ }
156
+ if (this._sort != types_js_1.Sort.None) {
157
+ r.jaql.sort = this._sort == types_js_1.Sort.Ascending ? 'asc' : 'desc';
158
+ }
159
+ return nested === true ? r.jaql : r;
160
+ }
161
+ /**
162
+ * Obtain the JAQL representation of the level that depends on the granularity
163
+ */
164
+ translateGranularityToJaql() {
165
+ const MINUTES_LEVEL = 'minutes';
166
+ switch (this.granularity) {
167
+ case types_js_1.DateLevels.Years:
168
+ case types_js_1.DateLevels.Quarters:
169
+ case types_js_1.DateLevels.Months:
170
+ case types_js_1.DateLevels.Weeks:
171
+ case types_js_1.DateLevels.Days:
172
+ return { level: this.granularity.toLowerCase() };
173
+ case types_js_1.DateLevels.Hours:
174
+ return {
175
+ dateTimeLevel: MINUTES_LEVEL,
176
+ bucket: '60',
177
+ };
178
+ case types_js_1.DateLevels.MinutesRoundTo30:
179
+ return {
180
+ dateTimeLevel: MINUTES_LEVEL,
181
+ bucket: '30',
182
+ };
183
+ case types_js_1.DateLevels.MinutesRoundTo15:
184
+ return {
185
+ dateTimeLevel: MINUTES_LEVEL,
186
+ bucket: '15',
187
+ };
188
+ case types_js_1.DateLevels.AggHours:
189
+ return {
190
+ level: MINUTES_LEVEL,
191
+ bucket: '60',
192
+ };
193
+ case types_js_1.DateLevels.AggMinutesRoundTo30:
194
+ return {
195
+ level: MINUTES_LEVEL,
196
+ bucket: '30',
197
+ };
198
+ case types_js_1.DateLevels.AggMinutesRoundTo15:
199
+ return {
200
+ level: MINUTES_LEVEL,
201
+ bucket: '15',
202
+ };
203
+ case types_js_1.DateLevels.AggMinutesRoundTo1:
204
+ return {
205
+ level: MINUTES_LEVEL,
206
+ bucket: '1',
207
+ };
208
+ default:
209
+ console.warn('Unsupported level');
210
+ return { level: this.granularity };
211
+ }
212
+ }
213
+ static translateJaqlToGranularity(json) {
214
+ const returnUnsupported = (lvl) => {
215
+ console.warn('Unsupported granularity', lvl);
216
+ return lvl;
217
+ };
218
+ if (json.dateTimeLevel) {
219
+ if (json.dateTimeLevel !== 'minutes') {
220
+ return returnUnsupported(json.dateTimeLevel);
221
+ }
222
+ switch (json.bucket) {
223
+ case '60':
224
+ return types_js_1.DateLevels.Hours;
225
+ case '30':
226
+ return types_js_1.DateLevels.MinutesRoundTo30;
227
+ case '15':
228
+ return types_js_1.DateLevels.MinutesRoundTo15;
229
+ default:
230
+ return returnUnsupported(json.dateTimeLevel);
231
+ }
232
+ }
233
+ switch (json.level) {
234
+ case 'years':
235
+ return types_js_1.DateLevels.Years;
236
+ case 'quarters':
237
+ return types_js_1.DateLevels.Quarters;
238
+ case 'months':
239
+ return types_js_1.DateLevels.Months;
240
+ case 'weeks':
241
+ return types_js_1.DateLevels.Weeks;
242
+ case 'days':
243
+ return types_js_1.DateLevels.Days;
244
+ case 'minutes':
245
+ switch (json.bucket) {
246
+ case '60':
247
+ return types_js_1.DateLevels.AggHours;
248
+ case '30':
249
+ return types_js_1.DateLevels.AggMinutesRoundTo30;
250
+ case '15':
251
+ return types_js_1.DateLevels.AggMinutesRoundTo15;
252
+ case '1':
253
+ return types_js_1.DateLevels.AggMinutesRoundTo1;
254
+ default:
255
+ return returnUnsupported(json.level);
256
+ }
257
+ default:
258
+ return returnUnsupported(json.level);
259
+ }
260
+ }
261
+ static getDefaultFormatForGranularity(granularity) {
262
+ switch (granularity) {
263
+ case types_js_1.DateLevels.Years:
264
+ return 'yyyy';
265
+ case types_js_1.DateLevels.Quarters:
266
+ return 'Q yyyy';
267
+ case types_js_1.DateLevels.Months:
268
+ return 'yyyy-MM';
269
+ case types_js_1.DateLevels.Weeks:
270
+ return 'ww yyyy';
271
+ case types_js_1.DateLevels.Days:
272
+ return 'yyyy-MM-dd';
273
+ case types_js_1.DateLevels.Hours:
274
+ // eslint-disable-next-line sonarjs/no-duplicate-string
275
+ return 'yyyy-MM-dd HH:mm';
276
+ case types_js_1.DateLevels.MinutesRoundTo30:
277
+ return 'yyyy-MM-dd HH:mm';
278
+ case types_js_1.DateLevels.MinutesRoundTo15:
279
+ return 'yyyy-MM-dd HH:mm';
280
+ case types_js_1.DateLevels.AggHours:
281
+ return 'HH:mm';
282
+ case types_js_1.DateLevels.AggMinutesRoundTo30:
283
+ return 'HH:mm';
284
+ case types_js_1.DateLevels.AggMinutesRoundTo15:
285
+ return 'HH:mm';
286
+ case types_js_1.DateLevels.AggMinutesRoundTo1:
287
+ return 'HH:mm';
288
+ default:
289
+ return '';
290
+ }
291
+ }
292
+ }
293
+ exports.DimensionalLevelAttribute = DimensionalLevelAttribute;
294
+ /**
295
+ * Creates an Attribute instance from the given JSON object.
296
+ * If the JSON object contains a granularity property, a {@link LevelAttribute} instance is created.
297
+ *
298
+ * This function is used in the generated data model code to create dimension attributes from an input data source.
299
+ *
300
+ * See also functions {@link createDimension} and {@link createDateDimension}.
301
+ *
302
+ * @param json - JSON object representing the attribute
303
+ * @returns An Attribute instance
304
+ * @group Data Model Utilities
305
+ */
306
+ function createAttribute(json) {
307
+ if (json.granularity) {
308
+ return createLevel(json);
309
+ }
310
+ return new DimensionalAttribute(json.name || json.title, json.attribute || json.expression || json.dim, json.type, json.desc || json.description);
311
+ }
312
+ exports.createAttribute = createAttribute;
313
+ /**
314
+ * Creates a LevelAttribute instance from the given JSON object.
315
+ *
316
+ * @param json - JSON object representing the level attribute
317
+ * @internal
318
+ */
319
+ function createLevel(json) {
320
+ return new DimensionalLevelAttribute(json.name || json.title, json.attribute || json.expression || json.dim, json.granularity, json.format, json.desc || json.description);
321
+ }
322
+ exports.createLevel = createLevel;
323
+ /**
324
+ * Normalize attribute name
325
+ *
326
+ * @param tableName - Table name (e.g., Commerce Sales)
327
+ * @param columnName - Column name (e.g., Order Date)
328
+ * @param dateLevel - Date level (e.g., Years)
329
+ * @param modelName - module name (e.g., DM)
330
+ * @return full normalized attribute name (e.g., DM.CommerceSales.OrderDate.Years)
331
+ * @internal
332
+ */
333
+ function normalizeAttributeName(tableName, columnName, dateLevel, modelName) {
334
+ return ((modelName && modelName.length > 0 ? modelName + '.' : '') +
335
+ (0, base_js_1.normalizeName)(tableName) +
336
+ '.' +
337
+ (0, base_js_1.normalizeName)(columnName) +
338
+ (dateLevel && dateLevel.length > 0
339
+ ? '.' + DimensionalLevelAttribute.translateJaqlToGranularity({ level: dateLevel })
340
+ : ''));
341
+ }
342
+ exports.normalizeAttributeName = normalizeAttributeName;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
5
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
6
+ /* eslint-disable vitest/no-identical-title */
7
+ const attributes_js_1 = require("./attributes.js");
8
+ const types_js_1 = require("./types.js");
9
+ describe('Attributes jaql preparations', () => {
10
+ it('must prepare simple attribute jaql', () => {
11
+ const result = { jaql: { title: 'Brand', dim: '[Brand.Brand ID]', datatype: 'text' } };
12
+ const attribute = new attributes_js_1.DimensionalAttribute('Brand', '[Brand.Brand ID]');
13
+ const jaql = attribute.jaql();
14
+ expect(jaql).toStrictEqual(result);
15
+ });
16
+ it('must prepare simple level attribute jaql', () => {
17
+ const result = {
18
+ jaql: {
19
+ title: 'Years',
20
+ dim: '[Commerce.Date (Calendar)]',
21
+ level: 'years',
22
+ datatype: 'datetime',
23
+ },
24
+ };
25
+ const level = new attributes_js_1.DimensionalLevelAttribute('Years', '[Commerce.Date (Calendar)]', types_js_1.DateLevels.Years);
26
+ const jaql = level.jaql();
27
+ expect(jaql).toStrictEqual(result);
28
+ });
29
+ it('must prepare minutes level attribute jaql', () => {
30
+ const result = {
31
+ jaql: {
32
+ title: types_js_1.DateLevels.MinutesRoundTo30,
33
+ dim: '[Commerce.Date (Calendar)]',
34
+ dateTimeLevel: 'minutes',
35
+ bucket: '30',
36
+ datatype: 'datetime',
37
+ },
38
+ };
39
+ const level = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.MinutesRoundTo30, '[Commerce.Date (Calendar)]', types_js_1.DateLevels.MinutesRoundTo30);
40
+ const jaql = level.jaql();
41
+ expect(jaql).toStrictEqual(result);
42
+ });
43
+ it('must prepare minutes level attribute jaql', () => {
44
+ const result = {
45
+ jaql: {
46
+ title: types_js_1.DateLevels.AggMinutesRoundTo1,
47
+ dim: '[Commerce.Date (Calendar)]',
48
+ level: 'minutes',
49
+ bucket: '1',
50
+ datatype: 'datetime',
51
+ },
52
+ };
53
+ const level = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.AggMinutesRoundTo1, '[Commerce.Date (Calendar)]', types_js_1.DateLevels.AggMinutesRoundTo1);
54
+ const jaql = level.jaql();
55
+ expect(jaql).toStrictEqual(result);
56
+ });
57
+ it('must apply format during transform level attribute jaql', () => {
58
+ var _a, _b;
59
+ const format = 'yyyy MM dd';
60
+ const level = new attributes_js_1.DimensionalLevelAttribute('Years', '[Commerce.Date (Calendar)]', 'Years', format);
61
+ const jaql = level.jaql();
62
+ expect((_b = (_a = jaql.format) === null || _a === void 0 ? void 0 : _a.mask) === null || _b === void 0 ? void 0 : _b.years).toEqual(format);
63
+ });
64
+ });
65
+ describe('createAttribute', () => {
66
+ it('should create attribute from json', () => {
67
+ const numericAttribute = (0, attributes_js_1.createAttribute)({
68
+ name: 'BrandID',
69
+ type: 'numeric-attribute',
70
+ expression: '[Commerce.Brand ID]',
71
+ description: 'Fortune999 Brands',
72
+ });
73
+ expect(numericAttribute).toBeInstanceOf(attributes_js_1.DimensionalAttribute);
74
+ expect(numericAttribute.name).toBe('BrandID');
75
+ expect(numericAttribute.expression).toBe('[Commerce.Brand ID]');
76
+ expect(numericAttribute.type).toBe('numeric-attribute');
77
+ expect(numericAttribute.description).toBe('Fortune999 Brands');
78
+ });
79
+ });
80
+ describe('translateJaqlToGranularity', () => {
81
+ it('should handle unsupported dateTimeLevel', () => {
82
+ const json = { dateTimeLevel: 'unsupported', bucket: '15' };
83
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe('unsupported');
84
+ });
85
+ it('should handle unsupported level', () => {
86
+ const json = { level: 'unsupported' };
87
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe('unsupported');
88
+ });
89
+ it('should translate years level', () => {
90
+ const json = { level: 'years' };
91
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.Years);
92
+ });
93
+ it('should translate quarters level', () => {
94
+ const json = { level: 'quarters' };
95
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.Quarters);
96
+ });
97
+ it('should translate months level', () => {
98
+ const json = { level: 'months' };
99
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.Months);
100
+ });
101
+ it('should translate weeks level', () => {
102
+ const json = { level: 'weeks' };
103
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.Weeks);
104
+ });
105
+ it('should translate days level', () => {
106
+ const json = { level: 'days' };
107
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.Days);
108
+ });
109
+ it('should translate aggregated minutes level with 60 bucket', () => {
110
+ const json = { level: 'minutes', bucket: '60' };
111
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.AggHours);
112
+ });
113
+ it('should translate aggregated minutes level with 30 bucket', () => {
114
+ const json = { level: 'minutes', bucket: '30' };
115
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.AggMinutesRoundTo30);
116
+ });
117
+ it('should translate aggregated minutes level with 15 bucket', () => {
118
+ const json = { level: 'minutes', bucket: '15' };
119
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.AggMinutesRoundTo15);
120
+ });
121
+ it('should translate aggregated minutes level with 1 bucket', () => {
122
+ const json = { level: 'minutes', bucket: '1' };
123
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.AggMinutesRoundTo1);
124
+ });
125
+ it('should translate minutes level with 60 bucket', () => {
126
+ const json = { dateTimeLevel: 'minutes', bucket: '60' };
127
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.Hours);
128
+ });
129
+ it('should translate minutes level with 30 bucket', () => {
130
+ const json = { dateTimeLevel: 'minutes', bucket: '30' };
131
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.MinutesRoundTo30);
132
+ });
133
+ it('should translate minutes level with 15 bucket', () => {
134
+ const json = { dateTimeLevel: 'minutes', bucket: '15' };
135
+ expect(attributes_js_1.DimensionalLevelAttribute.translateJaqlToGranularity(json)).toBe(types_js_1.DateLevels.MinutesRoundTo15);
136
+ });
137
+ });
138
+ describe('getDefaultFormatForGranularity', () => {
139
+ it('should return default format', () => {
140
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.Years)).toBe('yyyy');
141
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.Quarters)).toBe('Q yyyy');
142
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.Months)).toBe('yyyy-MM');
143
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.Weeks)).toBe('ww yyyy');
144
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.Days)).toBe('yyyy-MM-dd');
145
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.Hours)).toBe('yyyy-MM-dd HH:mm');
146
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.MinutesRoundTo30)).toBe('yyyy-MM-dd HH:mm');
147
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.MinutesRoundTo15)).toBe('yyyy-MM-dd HH:mm');
148
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.AggHours)).toBe('HH:mm');
149
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.AggMinutesRoundTo30)).toBe('HH:mm');
150
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.AggMinutesRoundTo15)).toBe('HH:mm');
151
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(types_js_1.DateLevels.AggMinutesRoundTo1)).toBe('HH:mm');
152
+ expect(attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity('unrecognized-level')).toBe('');
153
+ });
154
+ });
@@ -0,0 +1,43 @@
1
+ import { Element } from './interfaces.js';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare abstract class DimensionalElement implements Element {
6
+ /**
7
+ * @internal
8
+ */
9
+ private _name;
10
+ /**
11
+ * Defines the element's name
12
+ */
13
+ get name(): string;
14
+ set name(value: string);
15
+ constructor(name: string, type: string, desc?: string);
16
+ /**
17
+ * gets the element's description
18
+ */
19
+ readonly description: string;
20
+ /**
21
+ * gets the element's type
22
+ */
23
+ readonly type: string;
24
+ /**
25
+ * gets the element's ID
26
+ */
27
+ abstract get id(): string;
28
+ /**
29
+ * Gets a serializable representation of the element
30
+ */
31
+ serializable(): any;
32
+ toJSON(): any;
33
+ abstract jaql(nested?: boolean): any;
34
+ /**
35
+ * Gets a string representation of the element
36
+ */
37
+ toString(): string;
38
+ }
39
+ /**
40
+ * @param name
41
+ * @internal
42
+ */
43
+ export declare function normalizeName(name: string): string;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeName = exports.DimensionalElement = void 0;
4
+ /**
5
+ * @internal
6
+ */
7
+ class DimensionalElement {
8
+ constructor(name, type, desc) {
9
+ this._name = name;
10
+ this.type = type;
11
+ this.description = desc || '';
12
+ }
13
+ /**
14
+ * Defines the element's name
15
+ */
16
+ get name() {
17
+ return this._name;
18
+ }
19
+ set name(value) {
20
+ this._name = value;
21
+ }
22
+ /**
23
+ * Gets a serializable representation of the element
24
+ */
25
+ serializable() {
26
+ return {
27
+ name: this.name,
28
+ type: this.type,
29
+ desc: this.description,
30
+ __serializable: 'DimensionalElement',
31
+ };
32
+ }
33
+ toJSON() {
34
+ return this.serializable();
35
+ }
36
+ /**
37
+ * Gets a string representation of the element
38
+ */
39
+ toString() {
40
+ return this.jaql();
41
+ }
42
+ }
43
+ exports.DimensionalElement = DimensionalElement;
44
+ /**
45
+ * @param name
46
+ * @internal
47
+ */
48
+ function normalizeName(name) {
49
+ // Remove all invalid characters
50
+ let normalizedName = name.replace(/[^a-zA-Z0-9_]/g, '');
51
+ // Prefix with '_' if it starts with a number
52
+ const firstChar = normalizedName.charAt(0);
53
+ if (firstChar.match(/[0-9]/)) {
54
+ normalizedName = '_' + normalizedName;
55
+ }
56
+ return normalizedName;
57
+ }
58
+ exports.normalizeName = normalizeName;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_js_1 = require("./base.js");
4
+ describe('normalizeName', () => {
5
+ it('should remove invalid characters', () => {
6
+ expect((0, base_js_1.normalizeName)('my!name!is!awesome!')).toBe('mynameisawesome');
7
+ });
8
+ it('should prefix name with underscore if it starts with a non-alphabetical character', () => {
9
+ expect((0, base_js_1.normalizeName)('123name')).toBe('_123name');
10
+ });
11
+ it('should keep the name unchanged if it has no invalid characters and starts with an alphabetical character', () => {
12
+ expect((0, base_js_1.normalizeName)('validName')).toBe('validName');
13
+ });
14
+ it('should keep the name unchanged if it has no invalid characters and starts with an underscore', () => {
15
+ expect((0, base_js_1.normalizeName)('_validName')).toBe('_validName');
16
+ });
17
+ });
@@ -0,0 +1,13 @@
1
+ import { DataModel, Element } from './interfaces.js';
2
+ import { DataSource, DataSourceInfo } from '../interfaces.js';
3
+ /**
4
+ * @internal
5
+ */
6
+ export declare class DimensionalDataModel implements DataModel {
7
+ static fromConfig(config: any): DimensionalDataModel;
8
+ constructor(name: string, dataSource: DataSourceInfo, metadata: Element[]);
9
+ readonly name: string;
10
+ readonly dataSource: DataSource;
11
+ readonly metadata: Element[];
12
+ [propName: string]: any;
13
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DimensionalDataModel = void 0;
4
+ const factory_js_1 = require("./factory.js");
5
+ const translatable_error_js_1 = require("../translation/translatable-error.js");
6
+ /**
7
+ * @internal
8
+ */
9
+ class DimensionalDataModel {
10
+ constructor(name, dataSource, metadata) {
11
+ this.name = name;
12
+ this.dataSource = dataSource;
13
+ this.metadata = metadata;
14
+ let key;
15
+ for (let i = 0; i < metadata.length; i++) {
16
+ key = metadata[i].name;
17
+ if (this[metadata[i].name]) {
18
+ key = `${key} (${Math.random()})`;
19
+ }
20
+ this[key] = metadata[i];
21
+ }
22
+ }
23
+ static fromConfig(config) {
24
+ if (config && !config.name) {
25
+ throw new translatable_error_js_1.TranslatableError('errors.dataModel.noName');
26
+ }
27
+ if (config && !config.metadata) {
28
+ throw new translatable_error_js_1.TranslatableError('errors.dataModel.noMetadata');
29
+ }
30
+ const metadata = new Array();
31
+ for (let i = 0; i < config.metadata.length; i++) {
32
+ metadata.push((0, factory_js_1.create)(config.metadata[i]));
33
+ }
34
+ return new DimensionalDataModel(config.name, config.dataSource, metadata);
35
+ }
36
+ }
37
+ exports.DimensionalDataModel = DimensionalDataModel;