xt-store 0.4.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.
- package/README.md +24 -0
- package/api-provider/xt-api-store-provider.d.ts +26 -0
- package/fesm2022/xt-store.mjs +792 -0
- package/fesm2022/xt-store.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/package.json +23 -0
- package/public-api.d.ts +9 -0
- package/store-manager/xt-store-manager.d.ts +33 -0
- package/store-provider/xt-data-transformer.d.ts +10 -0
- package/store-provider/xt-memory-store-provider.d.ts +14 -0
- package/store-provider/xt-store-provider-helper.d.ts +81 -0
- package/store-provider/xt-store-provider.d.ts +51 -0
- package/test/store-test-bed.d.ts +10 -0
- package/xt-document.d.ts +5 -0
- package/xt-reporting.d.ts +43 -0
- package/xt-store-parameters.d.ts +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Store
|
|
2
|
+
|
|
3
|
+
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.2.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Run `ng generate component component-name --project store` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project store`.
|
|
8
|
+
> Note: Don't forget to add `--project store` or else it will be added to the default project in your `angular.json` file.
|
|
9
|
+
|
|
10
|
+
## Build
|
|
11
|
+
|
|
12
|
+
Run `ng build store` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
13
|
+
|
|
14
|
+
## Publishing
|
|
15
|
+
|
|
16
|
+
After building your library with `ng build store`, go to the dist folder `cd dist/store` and run `npm publish`.
|
|
17
|
+
|
|
18
|
+
## Running unit tests
|
|
19
|
+
|
|
20
|
+
Run `ng test store` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
21
|
+
|
|
22
|
+
## Further help
|
|
23
|
+
|
|
24
|
+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Observable, Subscription } from "rxjs";
|
|
2
|
+
import { HttpClient } from "@angular/common/http";
|
|
3
|
+
import { OnDestroy } from "@angular/core";
|
|
4
|
+
import { AbstractXtStoreProvider } from '../store-provider/xt-store-provider';
|
|
5
|
+
import { XtStoreCriteria } from '../xt-store-parameters';
|
|
6
|
+
import { UploadedDocumentInfo } from '../xt-document';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
/**
|
|
9
|
+
* A Store Provider that uses the DontCode API to store / read application data
|
|
10
|
+
*/
|
|
11
|
+
export declare class XtApiStoreProvider<T = never> extends AbstractXtStoreProvider<T> implements OnDestroy {
|
|
12
|
+
protected http: HttpClient;
|
|
13
|
+
apiUrl: string;
|
|
14
|
+
docUrl: string;
|
|
15
|
+
subscriptions: Subscription;
|
|
16
|
+
constructor(http?: HttpClient);
|
|
17
|
+
ngOnDestroy(): void;
|
|
18
|
+
storeEntity(name: string, data: T): Promise<T>;
|
|
19
|
+
loadEntity(name: string, key: any): Promise<T | undefined>;
|
|
20
|
+
deleteEntity(name: string, key: any): Promise<boolean>;
|
|
21
|
+
searchEntities(name: string, ...criteria: XtStoreCriteria[]): Observable<T[]>;
|
|
22
|
+
canStoreDocument(): boolean;
|
|
23
|
+
storeDocuments(toStore: File[]): Observable<UploadedDocumentInfo>;
|
|
24
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<XtApiStoreProvider<any>, never>;
|
|
25
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<XtApiStoreProvider<any>>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,792 @@
|
|
|
1
|
+
import { map, of, throwError, Subscription, lastValueFrom } from 'rxjs';
|
|
2
|
+
import { SpecialFields, Counters } from 'xt-type';
|
|
3
|
+
import * as i1 from '@angular/common/http';
|
|
4
|
+
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
5
|
+
import * as i0 from '@angular/core';
|
|
6
|
+
import { inject, Injectable } from '@angular/core';
|
|
7
|
+
import { map as map$1, mergeAll } from 'rxjs/operators';
|
|
8
|
+
|
|
9
|
+
class XtStoreManager {
|
|
10
|
+
static { this.testProvider = null; }
|
|
11
|
+
constructor(provider) {
|
|
12
|
+
this.providerByPosition = new Map();
|
|
13
|
+
this.providerByType = new Map();
|
|
14
|
+
this._default = provider;
|
|
15
|
+
this.reset();
|
|
16
|
+
}
|
|
17
|
+
reset() {
|
|
18
|
+
this.providerByPosition.clear();
|
|
19
|
+
this.providerByType.clear();
|
|
20
|
+
}
|
|
21
|
+
getProvider(name) {
|
|
22
|
+
// Override for testing
|
|
23
|
+
if (XtStoreManager.testProvider != null)
|
|
24
|
+
return XtStoreManager.testProvider;
|
|
25
|
+
if (name == null) {
|
|
26
|
+
return this._default;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
let ret = null;
|
|
30
|
+
// Try to find if the entity is loaded from a defined source
|
|
31
|
+
/*const srcDefinition = this.modelMgr.findTargetOfProperty(
|
|
32
|
+
DontCodeModel.APP_ENTITIES_FROM_NODE,
|
|
33
|
+
position
|
|
34
|
+
)?.value as DontCodeSourceType;
|
|
35
|
+
if (srcDefinition) {
|
|
36
|
+
ret = this.providerByType.get(srcDefinition.type);
|
|
37
|
+
}
|
|
38
|
+
if (!ret) {*/
|
|
39
|
+
ret = this.providerByPosition.get(name);
|
|
40
|
+
//}
|
|
41
|
+
return ret ?? this._default;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
getProviderSafe(name) {
|
|
45
|
+
const ret = this.getProvider(name);
|
|
46
|
+
if (ret == null) {
|
|
47
|
+
throw new Error('Trying to get an undefined or null provider');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return ret;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
getDefaultProvider() {
|
|
54
|
+
return this.getProvider();
|
|
55
|
+
}
|
|
56
|
+
getDefaultProviderSafe() {
|
|
57
|
+
return this.getProviderSafe();
|
|
58
|
+
}
|
|
59
|
+
setProvider(value, name) {
|
|
60
|
+
if (name == null)
|
|
61
|
+
this._default = value;
|
|
62
|
+
else {
|
|
63
|
+
this.providerByPosition.set(name, value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
setProviderForSourceType(value, srcType) {
|
|
67
|
+
this.providerByType.set(srcType, value);
|
|
68
|
+
}
|
|
69
|
+
setDefaultProvider(value) {
|
|
70
|
+
this.setProvider(value);
|
|
71
|
+
}
|
|
72
|
+
removeProvider(name) {
|
|
73
|
+
if (name == null)
|
|
74
|
+
this._default = undefined;
|
|
75
|
+
else {
|
|
76
|
+
this.providerByPosition.delete(name);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
removeProviderForSourceType(srcType) {
|
|
80
|
+
this.providerByType.delete(srcType);
|
|
81
|
+
}
|
|
82
|
+
removeDefaultProvider() {
|
|
83
|
+
this.removeProvider();
|
|
84
|
+
}
|
|
85
|
+
storeEntity(name, entity) {
|
|
86
|
+
return this.getProviderSafe(name).storeEntity(name, entity);
|
|
87
|
+
}
|
|
88
|
+
loadEntity(name, key) {
|
|
89
|
+
return this.getProviderSafe(name).loadEntity(name, key);
|
|
90
|
+
}
|
|
91
|
+
safeLoadEntity(name, key) {
|
|
92
|
+
return this.getProviderSafe(name).safeLoadEntity(name, key);
|
|
93
|
+
}
|
|
94
|
+
deleteEntity(name, key) {
|
|
95
|
+
return this.getProviderSafe(name).deleteEntity(name, key);
|
|
96
|
+
}
|
|
97
|
+
searchEntities(name, ...criteria) {
|
|
98
|
+
return this.getProviderSafe(name).searchEntities(name, ...criteria);
|
|
99
|
+
}
|
|
100
|
+
searchAndPrepareEntities(name, sort, groupBy, dataTransformer, ...criteria) {
|
|
101
|
+
return this.getProviderSafe(name).searchAndPrepareEntities(name, sort, groupBy, dataTransformer, ...criteria);
|
|
102
|
+
}
|
|
103
|
+
canStoreDocument(name) {
|
|
104
|
+
const res = this.getProvider(name)?.canStoreDocument();
|
|
105
|
+
if (res)
|
|
106
|
+
return res;
|
|
107
|
+
else
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
storeDocuments(toStore, name) {
|
|
111
|
+
return this.getProviderSafe(name).storeDocuments(toStore);
|
|
112
|
+
}
|
|
113
|
+
static setTestMode(testProvider) {
|
|
114
|
+
this.testProvider = testProvider;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
var XtStoreCriteriaOperator;
|
|
119
|
+
(function (XtStoreCriteriaOperator) {
|
|
120
|
+
XtStoreCriteriaOperator["EQUALS"] = "=";
|
|
121
|
+
XtStoreCriteriaOperator["LESS_THAN"] = "<";
|
|
122
|
+
XtStoreCriteriaOperator["LESS_THAN_EQUAL"] = "<=";
|
|
123
|
+
})(XtStoreCriteriaOperator || (XtStoreCriteriaOperator = {}));
|
|
124
|
+
class XtStoreCriteria {
|
|
125
|
+
constructor(name, value, operator) {
|
|
126
|
+
this.name = name;
|
|
127
|
+
this.value = value;
|
|
128
|
+
if (!operator)
|
|
129
|
+
this.operator = XtStoreCriteriaOperator.EQUALS;
|
|
130
|
+
else {
|
|
131
|
+
this.operator = operator;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
var XtSortByDirection;
|
|
136
|
+
(function (XtSortByDirection) {
|
|
137
|
+
XtSortByDirection["None"] = "None";
|
|
138
|
+
XtSortByDirection["Ascending"] = "Ascending";
|
|
139
|
+
XtSortByDirection["Descending"] = "Descending";
|
|
140
|
+
})(XtSortByDirection || (XtSortByDirection = {}));
|
|
141
|
+
var XtGroupByShow;
|
|
142
|
+
(function (XtGroupByShow) {
|
|
143
|
+
XtGroupByShow["OnlyLowest"] = "OnlyLowest";
|
|
144
|
+
XtGroupByShow["OnlyHighest"] = "OnlyHighest";
|
|
145
|
+
})(XtGroupByShow || (XtGroupByShow = {}));
|
|
146
|
+
var XtGroupByOperation;
|
|
147
|
+
(function (XtGroupByOperation) {
|
|
148
|
+
XtGroupByOperation["Count"] = "Count";
|
|
149
|
+
XtGroupByOperation["Sum"] = "Sum";
|
|
150
|
+
XtGroupByOperation["Average"] = "Average";
|
|
151
|
+
XtGroupByOperation["Minimum"] = "Minimum";
|
|
152
|
+
XtGroupByOperation["Maximum"] = "Maximum";
|
|
153
|
+
})(XtGroupByOperation || (XtGroupByOperation = {}));
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Helps handle metadata information about loaded items
|
|
157
|
+
*/
|
|
158
|
+
class XtStoreProviderHelper {
|
|
159
|
+
static { this.specialFieldsCache = new Map(); }
|
|
160
|
+
/**
|
|
161
|
+
* In case some entity definition has changed, clear the cache
|
|
162
|
+
*/
|
|
163
|
+
static clearConfigCache() {
|
|
164
|
+
this.specialFieldsCache.clear();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* In case the provider source doesn't support search criteria, they can be applied here
|
|
168
|
+
* @param list
|
|
169
|
+
* @param criteria
|
|
170
|
+
*/
|
|
171
|
+
static applyFilters(list, ...criteria) {
|
|
172
|
+
if ((criteria == null) || (criteria.length == 0))
|
|
173
|
+
return list;
|
|
174
|
+
return list.filter(element => {
|
|
175
|
+
for (const criterium of criteria) {
|
|
176
|
+
const toTest = element[criterium.name];
|
|
177
|
+
switch (criterium.operator) {
|
|
178
|
+
case XtStoreCriteriaOperator.EQUALS:
|
|
179
|
+
return criterium.value == toTest;
|
|
180
|
+
case XtStoreCriteriaOperator.LESS_THAN:
|
|
181
|
+
return toTest < criterium.value;
|
|
182
|
+
case XtStoreCriteriaOperator.LESS_THAN_EQUAL:
|
|
183
|
+
return toTest <= criterium.value;
|
|
184
|
+
default:
|
|
185
|
+
throw new Error("Operator " + criterium.operator + " unknown");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return true;
|
|
189
|
+
});
|
|
190
|
+
return list;
|
|
191
|
+
}
|
|
192
|
+
/** Returns any field who is a date, in order to convert it from json. Keep the result in a cache map
|
|
193
|
+
*
|
|
194
|
+
* @param name
|
|
195
|
+
* @param entity
|
|
196
|
+
* @protected
|
|
197
|
+
*/
|
|
198
|
+
static findSpecialFields(name, entity) {
|
|
199
|
+
let specialFields = XtStoreProviderHelper.specialFieldsCache.get(name);
|
|
200
|
+
if (specialFields != null)
|
|
201
|
+
return specialFields;
|
|
202
|
+
const curScore = { score: -1, field: null };
|
|
203
|
+
specialFields = new SpecialFields();
|
|
204
|
+
const fields = entity.fields;
|
|
205
|
+
if (fields != null) {
|
|
206
|
+
let prop;
|
|
207
|
+
for (prop in fields) {
|
|
208
|
+
// Finds the date fields that will need to be converted from json to javascript Date
|
|
209
|
+
if (fields[prop]?.type === 'Date' || fields[prop]?.type === 'Date & Time') {
|
|
210
|
+
specialFields.addDateField(fields[prop]?.name);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
XtStoreProviderHelper.scoreIdFieldFromEntityField(fields[prop], curScore);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (curScore.score > 0) {
|
|
218
|
+
specialFields.idField = curScore.field;
|
|
219
|
+
}
|
|
220
|
+
XtStoreProviderHelper.specialFieldsCache.set(name, specialFields);
|
|
221
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
222
|
+
//console.debug("Found special fields for entity at position "+name, specialFields);
|
|
223
|
+
return specialFields;
|
|
224
|
+
}
|
|
225
|
+
static findSpecialFieldsFromData(data, existingFields) {
|
|
226
|
+
if ((existingFields.idField == null) && (data?.length > 0)) {
|
|
227
|
+
// We must guess the id field from data
|
|
228
|
+
const first = data[0];
|
|
229
|
+
const curScore = { score: -1, field: null };
|
|
230
|
+
let prop;
|
|
231
|
+
for (prop in first) {
|
|
232
|
+
XtStoreProviderHelper.scoreIdFieldFromProperty(prop, curScore);
|
|
233
|
+
}
|
|
234
|
+
if (curScore.score > 0) {
|
|
235
|
+
const test = data.length > 1 ? data[Math.floor((data.length + 1) / 2)] : null;
|
|
236
|
+
if ((test == null) || (test[curScore.field] != first[curScore.field])) // Just check that another element doesn't have the same value as an id should be unique
|
|
237
|
+
existingFields.idField = curScore.field;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
static scoreIdFieldFromEntityField(prop, score) {
|
|
242
|
+
return XtStoreProviderHelper.scoreIdFieldFromProperty(prop?.name, score);
|
|
243
|
+
}
|
|
244
|
+
static scoreIdFieldFromProperty(name, score) {
|
|
245
|
+
if (name == null)
|
|
246
|
+
return false;
|
|
247
|
+
const propName = name.toLowerCase();
|
|
248
|
+
// Finds if the element is the id field
|
|
249
|
+
if (propName === "_id") {
|
|
250
|
+
score.field = "_id"; // Don't need to process Id
|
|
251
|
+
score.score = 100;
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
if ((propName == "id") || (propName == "uniqueid") || (propName == "identifier") || (propName == 'key') || (propName == 'primaryKey') || (propName == 'uniqueKey')) {
|
|
256
|
+
if (score.score < 80) {
|
|
257
|
+
score.score = 80;
|
|
258
|
+
score.field = name;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else if (propName.includes("unique") || propName.includes("primary")) {
|
|
262
|
+
if (score.score < 50) {
|
|
263
|
+
score.score = 50;
|
|
264
|
+
score.field = name;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else if (propName.includes("id") || propName.includes('key')) {
|
|
268
|
+
if (score.score < 30) {
|
|
269
|
+
score.score = 30;
|
|
270
|
+
score.field = name;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Ensure _id is removed if necessary before saving the element
|
|
278
|
+
* @param listToConvert
|
|
279
|
+
* @param specialFields
|
|
280
|
+
* @protected
|
|
281
|
+
*/
|
|
282
|
+
static cleanUpDataBeforeSaving(listToConvert, specialFields) {
|
|
283
|
+
if ((specialFields?.idField != null) && (specialFields?.idField != '_id')) {
|
|
284
|
+
listToConvert.forEach(value => {
|
|
285
|
+
delete value._id;
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Converts dates and dateTimes properties of each element of the array to Typescript format
|
|
291
|
+
* Ensure _id is set with the right id
|
|
292
|
+
* @param listToConvert
|
|
293
|
+
* @param specialFields
|
|
294
|
+
* @protected
|
|
295
|
+
*/
|
|
296
|
+
static cleanUpLoadedData(listToConvert, specialFields) {
|
|
297
|
+
if (specialFields != null) {
|
|
298
|
+
if (specialFields.idField == null) {
|
|
299
|
+
XtStoreProviderHelper.findSpecialFieldsFromData(listToConvert, specialFields);
|
|
300
|
+
}
|
|
301
|
+
listToConvert.forEach((val) => {
|
|
302
|
+
if ((specialFields.idField != null) && (specialFields.idField != "_id")) // We need to copy the id to the standard _id field
|
|
303
|
+
{
|
|
304
|
+
val._id = val[specialFields.idField];
|
|
305
|
+
}
|
|
306
|
+
specialFields.dateFields?.forEach(prop => {
|
|
307
|
+
const toConvert = val[prop];
|
|
308
|
+
if (toConvert != null) {
|
|
309
|
+
let timeEpoch = Date.parse(toConvert);
|
|
310
|
+
if (isNaN(timeEpoch)) {
|
|
311
|
+
// Invalid date try to remove a possible TZ description in []
|
|
312
|
+
const tzDescIndex = toConvert.lastIndexOf('[');
|
|
313
|
+
if (tzDescIndex != -1) {
|
|
314
|
+
timeEpoch = Date.parse(toConvert.substring(0, tzDescIndex));
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (isNaN(timeEpoch)) {
|
|
318
|
+
delete val[prop];
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
val[prop] = new Date(timeEpoch);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Sort the array using the defined sort declarations across all properties.
|
|
330
|
+
*
|
|
331
|
+
* @param toSort
|
|
332
|
+
* @param sortOptions
|
|
333
|
+
*/
|
|
334
|
+
static multiSortArray(toSort, sortOptions) {
|
|
335
|
+
if (sortOptions == null)
|
|
336
|
+
return toSort;
|
|
337
|
+
return toSort;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Calculates sum, avg, min or max values per group
|
|
341
|
+
* @param values
|
|
342
|
+
* @param groupBy
|
|
343
|
+
* @param modelMgr
|
|
344
|
+
* @param position
|
|
345
|
+
* @param item
|
|
346
|
+
*/
|
|
347
|
+
static calculateGroupedByValues(name, values, groupBy) {
|
|
348
|
+
// We are counting per different value of the groupedBy Item
|
|
349
|
+
if ((groupBy != null) && (groupBy.display != null)) {
|
|
350
|
+
let fieldToGroupBy = groupBy.of;
|
|
351
|
+
if (groupBy.show != null)
|
|
352
|
+
fieldToGroupBy = groupBy.show.valueOf();
|
|
353
|
+
const counters = new Map();
|
|
354
|
+
let lastGroupDelimiter;
|
|
355
|
+
let oneGroupOfCounters = new Map();
|
|
356
|
+
const fieldsRequired = groupBy.getRequiredListOfFields();
|
|
357
|
+
for (const value of values) {
|
|
358
|
+
if (value[fieldToGroupBy] != lastGroupDelimiter) { // We change the group
|
|
359
|
+
lastGroupDelimiter = value[fieldToGroupBy];
|
|
360
|
+
const storedGroupOfCounters = counters.get(lastGroupDelimiter);
|
|
361
|
+
if (storedGroupOfCounters == null) {
|
|
362
|
+
oneGroupOfCounters = new Map();
|
|
363
|
+
counters.set(lastGroupDelimiter, oneGroupOfCounters);
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
oneGroupOfCounters = storedGroupOfCounters;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
for (const field of fieldsRequired) {
|
|
370
|
+
let counter = oneGroupOfCounters?.get(field);
|
|
371
|
+
if (counter == null) {
|
|
372
|
+
counter = new Counters();
|
|
373
|
+
oneGroupOfCounters.set(field, counter);
|
|
374
|
+
}
|
|
375
|
+
const valSrc = value[field];
|
|
376
|
+
const val = valSrc;
|
|
377
|
+
if (valSrc != null) {
|
|
378
|
+
const modelMgr = null;
|
|
379
|
+
// If it's an object, we need to set the calculated values as the object itself
|
|
380
|
+
if ((typeof valSrc === 'object') && (!(valSrc instanceof Date)) && (modelMgr != null)) {
|
|
381
|
+
if (counter.sum == null)
|
|
382
|
+
counter.sum = structuredClone(valSrc);
|
|
383
|
+
else {
|
|
384
|
+
counter.sum = modelMgr.modifyValues(counter.sum, valSrc, counter.metaData, (first, second) => {
|
|
385
|
+
if ((first != null) && (second != null))
|
|
386
|
+
return first + second;
|
|
387
|
+
else if (first == null) {
|
|
388
|
+
return second;
|
|
389
|
+
}
|
|
390
|
+
else if (second == null) {
|
|
391
|
+
return first;
|
|
392
|
+
}
|
|
393
|
+
} /*,
|
|
394
|
+
position, item*/);
|
|
395
|
+
}
|
|
396
|
+
const value = modelMgr.extractValue(valSrc, counter.metaData /*,position, item*/);
|
|
397
|
+
if (counter.minimum == null) {
|
|
398
|
+
counter.minimum = valSrc;
|
|
399
|
+
counter.minAsValue = value;
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
const minValue = counter.minAsValue;
|
|
403
|
+
if ((value != null) && ((minValue == null) || (value < minValue))) {
|
|
404
|
+
counter.minimum = valSrc;
|
|
405
|
+
counter.minAsValue = value;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (counter.maximum == null) {
|
|
409
|
+
counter.maximum = valSrc;
|
|
410
|
+
counter.maxAsValue = value;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
const maxValue = counter.maxAsValue;
|
|
414
|
+
if ((value != null) && ((maxValue == null) || (value > maxValue))) {
|
|
415
|
+
counter.maximum = valSrc;
|
|
416
|
+
counter.maxAsValue = value;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
if (value != null) {
|
|
420
|
+
counter.count++;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
else if (typeof val === 'number') {
|
|
424
|
+
if (counter.sum == null)
|
|
425
|
+
counter.sum = 0;
|
|
426
|
+
counter.sum = counter.sum + val;
|
|
427
|
+
if ((counter.minimum == null) || (val < counter.minimum)) {
|
|
428
|
+
counter.minimum = valSrc;
|
|
429
|
+
counter.minAsValue = valSrc;
|
|
430
|
+
}
|
|
431
|
+
if ((counter.maximum == null) || (val > counter.maximum)) {
|
|
432
|
+
counter.maximum = valSrc;
|
|
433
|
+
counter.maxAsValue = valSrc;
|
|
434
|
+
}
|
|
435
|
+
counter.count++;
|
|
436
|
+
}
|
|
437
|
+
else if ((val instanceof Date) && (!isNaN(val.getTime()))) {
|
|
438
|
+
counter.sum = null;
|
|
439
|
+
if ((counter.minimum == null) || (val.valueOf() < counter.minimum.valueOf())) {
|
|
440
|
+
counter.minimum = valSrc;
|
|
441
|
+
}
|
|
442
|
+
if ((counter.maximum == null) || (val.valueOf() > counter.maximum.valueOf())) {
|
|
443
|
+
counter.maximum = valSrc;
|
|
444
|
+
}
|
|
445
|
+
counter.count++;
|
|
446
|
+
}
|
|
447
|
+
else { // strings
|
|
448
|
+
counter.count++;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// Now that we have all the counters, let's generate the GroupedFields
|
|
454
|
+
let ret;
|
|
455
|
+
if (counters.size > 0) {
|
|
456
|
+
ret = new DontCodeStoreGroupedByEntities(groupBy, new Map);
|
|
457
|
+
for (const groupKey of counters.keys()) {
|
|
458
|
+
const group = counters.get(groupKey);
|
|
459
|
+
for (const aggregate of Object.values(groupBy.display)) {
|
|
460
|
+
let value;
|
|
461
|
+
const counter = group.get(aggregate.of);
|
|
462
|
+
if (counter != null) {
|
|
463
|
+
switch (aggregate.operation) {
|
|
464
|
+
case XtGroupByOperation.Count:
|
|
465
|
+
value = counter.count;
|
|
466
|
+
break;
|
|
467
|
+
case XtGroupByOperation.Sum:
|
|
468
|
+
value = counter.sum;
|
|
469
|
+
break;
|
|
470
|
+
case XtGroupByOperation.Average:
|
|
471
|
+
{
|
|
472
|
+
const modelMgr = null;
|
|
473
|
+
if ((counter.sum == null) || (counter.count == 0))
|
|
474
|
+
value = null;
|
|
475
|
+
else if ((typeof counter.sum === 'object') && (!(counter.sum instanceof Date)) && (modelMgr != null)) {
|
|
476
|
+
value = modelMgr.applyValue(structuredClone(counter.sum), modelMgr.extractValue(counter.sum, counter.metaData /*, position, item*/) / counter.count, counter.metaData, undefined /*, position, item*/);
|
|
477
|
+
}
|
|
478
|
+
else
|
|
479
|
+
value = counter.sum / counter.count;
|
|
480
|
+
}
|
|
481
|
+
break;
|
|
482
|
+
case XtGroupByOperation.Minimum:
|
|
483
|
+
value = counter.minimum;
|
|
484
|
+
break;
|
|
485
|
+
case XtGroupByOperation.Maximum:
|
|
486
|
+
value = counter.maximum;
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
let listOfValues = ret.values?.get(groupKey);
|
|
490
|
+
if (listOfValues == null) {
|
|
491
|
+
listOfValues = new Array();
|
|
492
|
+
ret.values?.set(groupKey, listOfValues);
|
|
493
|
+
}
|
|
494
|
+
listOfValues.push(new DontCodeStoreGroupedByValues(aggregate, value));
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return ret.values.size > 0 ? ret : undefined;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return undefined;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
class DontCodeStorePreparedEntities {
|
|
505
|
+
constructor(sortedData, sortInfo, groupedByEntities) {
|
|
506
|
+
this.sortedData = sortedData;
|
|
507
|
+
this.sortInfo = sortInfo;
|
|
508
|
+
this.groupedByEntities = groupedByEntities;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
class DontCodeStoreGroupedByEntities {
|
|
512
|
+
constructor(groupInfo, values) {
|
|
513
|
+
this.groupInfo = groupInfo;
|
|
514
|
+
this.values = values;
|
|
515
|
+
if (values == null)
|
|
516
|
+
this.values = new Map();
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
class DontCodeStoreGroupedByValues {
|
|
520
|
+
constructor(forAggregate, value) {
|
|
521
|
+
this.forAggregate = forAggregate;
|
|
522
|
+
this.value = value;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
class XtStoreSortBy {
|
|
527
|
+
constructor(by, direction, subSort) {
|
|
528
|
+
this.by = by;
|
|
529
|
+
this.subSort = subSort;
|
|
530
|
+
if (direction == null)
|
|
531
|
+
this.direction = XtSortByDirection.None;
|
|
532
|
+
else
|
|
533
|
+
this.direction = direction;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
class XtStoreGroupBy {
|
|
537
|
+
constructor(of, display, show) {
|
|
538
|
+
this.of = of;
|
|
539
|
+
this.show = show;
|
|
540
|
+
if (display == null)
|
|
541
|
+
this.display = {};
|
|
542
|
+
else
|
|
543
|
+
this.display = display;
|
|
544
|
+
}
|
|
545
|
+
atLeastOneGroupIsRequested() {
|
|
546
|
+
if ((this.display != null) && (Object.keys(this.display).length > 0))
|
|
547
|
+
return true;
|
|
548
|
+
return false;
|
|
549
|
+
}
|
|
550
|
+
getRequiredListOfFields() {
|
|
551
|
+
const ret = new Set();
|
|
552
|
+
if (this.display != null) {
|
|
553
|
+
for (const aggregate of Object.values(this.display)) {
|
|
554
|
+
ret.add(aggregate.of);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return ret;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
class XtStoreGroupByAggregate {
|
|
561
|
+
constructor(of, operation) {
|
|
562
|
+
this.of = of;
|
|
563
|
+
this.operation = operation;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
class AbstractXtStoreProvider {
|
|
568
|
+
constructor() {
|
|
569
|
+
}
|
|
570
|
+
safeLoadEntity(name, key) {
|
|
571
|
+
return this.loadEntity(name, key).then(value => {
|
|
572
|
+
if (value == null)
|
|
573
|
+
return Promise.reject("Not found");
|
|
574
|
+
else
|
|
575
|
+
return value;
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* If the store supports queries with criteria, this function must be implemented, if not, listEntities must be implemented, and this function will apply filters
|
|
580
|
+
* @param position
|
|
581
|
+
* @param criteria
|
|
582
|
+
*/
|
|
583
|
+
searchEntities(name, ...criteria) {
|
|
584
|
+
return this.listEntities(name).pipe(map(value => {
|
|
585
|
+
return XtStoreProviderHelper.applyFilters(value, ...criteria);
|
|
586
|
+
}));
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Returns the list of entities at a given position in the model. Implements at least this function or searchEntities depending on the capability of the store
|
|
590
|
+
* @param position
|
|
591
|
+
* @protected
|
|
592
|
+
*/
|
|
593
|
+
listEntities(name) {
|
|
594
|
+
return this.searchEntities(name);
|
|
595
|
+
}
|
|
596
|
+
searchAndPrepareEntities(name, sort, groupBy, transformer, ...criteria) {
|
|
597
|
+
return this.searchEntities(name, ...criteria).pipe(map(value => {
|
|
598
|
+
// Run the transformation if any
|
|
599
|
+
if (transformer != null)
|
|
600
|
+
return transformer.postLoadingTransformation(value);
|
|
601
|
+
else
|
|
602
|
+
return value;
|
|
603
|
+
}), map(value => {
|
|
604
|
+
let groupedByValues;
|
|
605
|
+
if ((sort != null) || (groupBy?.atLeastOneGroupIsRequested() === true)) {
|
|
606
|
+
value = XtStoreProviderHelper.multiSortArray(value, this.calculateSortHierarchy(sort, groupBy));
|
|
607
|
+
if (groupBy != null) {
|
|
608
|
+
groupedByValues = XtStoreProviderHelper.calculateGroupedByValues(name, value, groupBy);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return new DontCodeStorePreparedEntities(value, sort, groupedByValues);
|
|
612
|
+
}));
|
|
613
|
+
}
|
|
614
|
+
calculateSortHierarchy(sort, groupBy) {
|
|
615
|
+
// We must first sort by the groupBy, and then by the sort
|
|
616
|
+
let rootSort;
|
|
617
|
+
if (groupBy != null) {
|
|
618
|
+
rootSort = new XtStoreSortBy(groupBy.of, undefined, sort);
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
rootSort = sort;
|
|
622
|
+
}
|
|
623
|
+
return rootSort;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
class XtMemoryStoreProvider extends AbstractXtStoreProvider {
|
|
628
|
+
constructor() {
|
|
629
|
+
super(...arguments);
|
|
630
|
+
this.storage = new Map();
|
|
631
|
+
}
|
|
632
|
+
canStoreDocument() {
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
getSafeStore(name) {
|
|
636
|
+
let ret = this.storage.get(name);
|
|
637
|
+
if (ret == null) {
|
|
638
|
+
ret = new Map();
|
|
639
|
+
this.storage.set(name, ret);
|
|
640
|
+
}
|
|
641
|
+
return ret;
|
|
642
|
+
}
|
|
643
|
+
deleteEntity(name, key) {
|
|
644
|
+
const store = this.getSafeStore(name);
|
|
645
|
+
return Promise.resolve(store.delete(key));
|
|
646
|
+
}
|
|
647
|
+
loadEntity(name, key) {
|
|
648
|
+
const store = this.getSafeStore(name);
|
|
649
|
+
return Promise.resolve(store.get(key));
|
|
650
|
+
}
|
|
651
|
+
listEntities(name) {
|
|
652
|
+
const store = this.getSafeStore(name);
|
|
653
|
+
//console.debug("Listing entities for "+name+" with ",store);
|
|
654
|
+
return of(Array.from(store.values()));
|
|
655
|
+
}
|
|
656
|
+
storeEntity(name, entity) {
|
|
657
|
+
const store = this.getSafeStore(name);
|
|
658
|
+
if (entity._id == null) {
|
|
659
|
+
entity._id = Math
|
|
660
|
+
.random().toString(36).substring(2, 8);
|
|
661
|
+
}
|
|
662
|
+
store.set(entity._id, entity);
|
|
663
|
+
return Promise.resolve(entity);
|
|
664
|
+
}
|
|
665
|
+
storeDocuments(toStore) {
|
|
666
|
+
return throwError(() => {
|
|
667
|
+
throw new Error("Not implemented.");
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* A Store Provider that uses the DontCode API to store / read application data
|
|
674
|
+
*/
|
|
675
|
+
class XtApiStoreProvider extends AbstractXtStoreProvider {
|
|
676
|
+
constructor(http /* protected configService: CommonConfigService*/) {
|
|
677
|
+
super();
|
|
678
|
+
this.http = inject(HttpClient, { optional: true });
|
|
679
|
+
this.subscriptions = new Subscription();
|
|
680
|
+
if (http != null) {
|
|
681
|
+
this.http = http;
|
|
682
|
+
}
|
|
683
|
+
if (this.http == null) {
|
|
684
|
+
throw new Error("You must provide an HttpClient, either through constructor or injection.");
|
|
685
|
+
}
|
|
686
|
+
this.apiUrl = 'https://test.dont-code.net/data';
|
|
687
|
+
this.docUrl = 'https://test.dont-code.net/documents';
|
|
688
|
+
/*this.updateConfig (this.configService.getConfig());
|
|
689
|
+
this.subscriptions.add (this.configService.getUpdates ().pipe (map ((updatedConfig) => {
|
|
690
|
+
this.updateConfig (updatedConfig);
|
|
691
|
+
})).subscribe());*/
|
|
692
|
+
}
|
|
693
|
+
ngOnDestroy() {
|
|
694
|
+
this.subscriptions.unsubscribe();
|
|
695
|
+
}
|
|
696
|
+
/* updateConfig(newConfig: Readonly<CommonLibConfig>) {
|
|
697
|
+
if (newConfig.storeApiUrl!=null)
|
|
698
|
+
this.apiUrl = newConfig.storeApiUrl;
|
|
699
|
+
if (newConfig.documentApiUrl!=null)
|
|
700
|
+
this.docUrl = newConfig.documentApiUrl;
|
|
701
|
+
}*/
|
|
702
|
+
storeEntity(name, data) {
|
|
703
|
+
const id = data._id;
|
|
704
|
+
// Reconverts dates or Ids
|
|
705
|
+
const specialFields = XtStoreProviderHelper.findSpecialFields(name, {});
|
|
706
|
+
XtStoreProviderHelper.cleanUpDataBeforeSaving([data], specialFields);
|
|
707
|
+
if (id != undefined) {
|
|
708
|
+
return lastValueFrom(this.http.put(this.apiUrl + '/' + name + '/' + id, data, { observe: "body", responseType: "json" }));
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
return lastValueFrom(this.http.post(this.apiUrl + '/' + name, data, { observe: "body", responseType: "json" }));
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
loadEntity(name, key) {
|
|
715
|
+
const obs = this.http.get(this.apiUrl + '/' + name + '/' + key, { observe: "body", responseType: "json" });
|
|
716
|
+
const specialFields = XtStoreProviderHelper.findSpecialFields(name, {});
|
|
717
|
+
return lastValueFrom(obs).then((value) => {
|
|
718
|
+
XtStoreProviderHelper.cleanUpLoadedData([value], specialFields);
|
|
719
|
+
return value;
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
deleteEntity(name, key) {
|
|
723
|
+
return lastValueFrom(this.http.delete(this.apiUrl + '/' + name + '/' + key, { observe: "body", responseType: "json" })).then(value => {
|
|
724
|
+
return true;
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
searchEntities(name, ...criteria) {
|
|
728
|
+
const specialFields = XtStoreProviderHelper.findSpecialFields(name, {});
|
|
729
|
+
return this.http.get(this.apiUrl + '/' + name, { observe: "body", responseType: "json" }).pipe(map$1(value => {
|
|
730
|
+
XtStoreProviderHelper.cleanUpLoadedData(value, specialFields);
|
|
731
|
+
return value;
|
|
732
|
+
}), map$1(value => {
|
|
733
|
+
return XtStoreProviderHelper.applyFilters(value, ...criteria);
|
|
734
|
+
}));
|
|
735
|
+
}
|
|
736
|
+
canStoreDocument() {
|
|
737
|
+
return true;
|
|
738
|
+
}
|
|
739
|
+
storeDocuments(toStore) {
|
|
740
|
+
const myFormData = new FormData();
|
|
741
|
+
const headers = new HttpHeaders();
|
|
742
|
+
headers.append('Content-Type', 'multipart/form-data');
|
|
743
|
+
headers.append('Accept', 'application/json');
|
|
744
|
+
let count = 0;
|
|
745
|
+
// store files details into formdata
|
|
746
|
+
toStore.forEach(file => {
|
|
747
|
+
myFormData.append('document#' + count, file);
|
|
748
|
+
count++;
|
|
749
|
+
});
|
|
750
|
+
//HTTP Angular service, which will send call to Laravel API With headers and myformdata
|
|
751
|
+
return this.http.post(this.docUrl, myFormData, { headers: headers }).pipe(mergeAll());
|
|
752
|
+
}
|
|
753
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: XtApiStoreProvider, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
754
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: XtApiStoreProvider, providedIn: 'root' }); }
|
|
755
|
+
}
|
|
756
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: XtApiStoreProvider, decorators: [{
|
|
757
|
+
type: Injectable,
|
|
758
|
+
args: [{
|
|
759
|
+
providedIn: 'root'
|
|
760
|
+
}]
|
|
761
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
762
|
+
|
|
763
|
+
class StoreTestBed {
|
|
764
|
+
constructor() {
|
|
765
|
+
this.storeManager = new XtStoreManager();
|
|
766
|
+
}
|
|
767
|
+
ensureMemoryProviderOnly() {
|
|
768
|
+
XtStoreManager.setTestMode(new XtMemoryStoreProvider());
|
|
769
|
+
}
|
|
770
|
+
async defineTestDataFor(entityName, testData) {
|
|
771
|
+
for (const testEntity of testData) {
|
|
772
|
+
await this.storeManager.storeEntity(entityName, testEntity);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
getStoreManager() {
|
|
776
|
+
return this.storeManager;
|
|
777
|
+
}
|
|
778
|
+
getStoreProviderFor(entityName) {
|
|
779
|
+
return this.storeManager.getProviderSafe(entityName);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/*
|
|
784
|
+
* Public API Surface of store
|
|
785
|
+
*/
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Generated bundle index. Do not edit.
|
|
789
|
+
*/
|
|
790
|
+
|
|
791
|
+
export { AbstractXtStoreProvider, DontCodeStoreGroupedByEntities, DontCodeStoreGroupedByValues, DontCodeStorePreparedEntities, StoreTestBed, XtApiStoreProvider, XtGroupByOperation, XtGroupByShow, XtMemoryStoreProvider, XtSortByDirection, XtStoreCriteria, XtStoreCriteriaOperator, XtStoreGroupBy, XtStoreGroupByAggregate, XtStoreManager, XtStoreProviderHelper, XtStoreSortBy };
|
|
792
|
+
//# sourceMappingURL=xt-store.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xt-store.mjs","sources":["../../../projects/store/src/store-manager/xt-store-manager.ts","../../../projects/store/src/xt-store-parameters.ts","../../../projects/store/src/store-provider/xt-store-provider-helper.ts","../../../projects/store/src/xt-reporting.ts","../../../projects/store/src/store-provider/xt-store-provider.ts","../../../projects/store/src/store-provider/xt-memory-store-provider.ts","../../../projects/store/src/api-provider/xt-api-store-provider.ts","../../../projects/store/src/test/store-test-bed.ts","../../../projects/store/src/public-api.ts","../../../projects/store/src/xt-store.ts"],"sourcesContent":["import { XtStoreProvider } from '../store-provider/xt-store-provider';\nimport { Observable } from 'rxjs';\nimport { UploadedDocumentInfo } from '../xt-document';\nimport { XtStoreCriteria, XtGroupBy, XtSortBy } from '../xt-store-parameters';\nimport { DontCodeStorePreparedEntities } from '../store-provider/xt-store-provider-helper';\nimport { XtDataTransformer } from '../store-provider/xt-data-transformer';\n\nexport class XtStoreManager {\n private _default?: XtStoreProvider<any>;\n private providerByPosition = new Map<string, XtStoreProvider<any>>();\n private providerByType = new Map<string, XtStoreProvider<any>>();\n\n protected static testProvider:XtStoreProvider<any>|null = null;\n\n constructor(\n provider?: XtStoreProvider<any>\n ) {\n this._default = provider;\n this.reset();\n }\n\n reset() {\n this.providerByPosition.clear();\n this.providerByType.clear();\n }\n\n getProvider<T=never>(name?: string): XtStoreProvider<T> | undefined {\n // Override for testing\n if( XtStoreManager.testProvider!=null) return XtStoreManager.testProvider;\n\n if (name == null) {\n return this._default;\n } else {\n let ret = null;\n // Try to find if the entity is loaded from a defined source\n /*const srcDefinition = this.modelMgr.findTargetOfProperty(\n DontCodeModel.APP_ENTITIES_FROM_NODE,\n position\n )?.value as DontCodeSourceType;\n if (srcDefinition) {\n ret = this.providerByType.get(srcDefinition.type);\n }\n if (!ret) {*/\n ret = this.providerByPosition.get(name);\n //}\n return ret ?? this._default;\n }\n }\n\n getProviderSafe<T=never>(name?: string): XtStoreProvider<T> {\n const ret = this.getProvider<T>(name);\n if (ret == null) {\n throw new Error('Trying to get an undefined or null provider');\n } else {\n return ret;\n }\n }\n\n getDefaultProvider<T=never>(): XtStoreProvider<T> | undefined {\n return this.getProvider();\n }\n\n getDefaultProviderSafe<T=never>(): XtStoreProvider<T> {\n return this.getProviderSafe();\n }\n\n setProvider<T=never>(value: XtStoreProvider<T>, name?: string): void {\n if (name == null) this._default = value;\n else {\n this.providerByPosition.set(name, value);\n }\n }\n\n setProviderForSourceType<T=never>(\n value: XtStoreProvider<T>,\n srcType: string\n ): void {\n this.providerByType.set(srcType, value);\n }\n\n setDefaultProvider<T=never>(value: XtStoreProvider<T>): void {\n this.setProvider(value);\n }\n\n removeProvider(name?: string): void {\n if (name == null) this._default = undefined;\n else {\n this.providerByPosition.delete(name);\n }\n }\n\n removeProviderForSourceType(srcType: string): void {\n this.providerByType.delete(srcType);\n }\n\n removeDefaultProvider(): void {\n this.removeProvider();\n }\n\n storeEntity<T=never>(name: string, entity: T): Promise<T> {\n return this.getProviderSafe<T>(name).storeEntity(name, entity);\n }\n\n loadEntity<T=never>(name: string, key: any): Promise<T|undefined> {\n return this.getProviderSafe<T>(name).loadEntity(name, key);\n }\n\n safeLoadEntity<T=never>(name: string, key: any): Promise<T> {\n return this.getProviderSafe<T>(name).safeLoadEntity(name, key);\n }\n\n deleteEntity(name: string, key: any): Promise<boolean> {\n return this.getProviderSafe(name).deleteEntity(name, key);\n }\n\n searchEntities<T=never>(\n name: string,\n ...criteria: XtStoreCriteria[]\n ): Observable<Array<T>> {\n return this.getProviderSafe<T>(name).searchEntities(name, ...criteria);\n }\n\n searchAndPrepareEntities<T=never>(\n name: string,\n sort?:XtSortBy,\n groupBy?:XtGroupBy,\n dataTransformer?:XtDataTransformer,\n ...criteria: XtStoreCriteria[]\n ): Observable<DontCodeStorePreparedEntities<T>> {\n return this.getProviderSafe<T>(name).searchAndPrepareEntities(name, sort, groupBy, dataTransformer, ...criteria);\n }\n\n\n canStoreDocument(name?: string): boolean {\n const res = this.getProvider(name)?.canStoreDocument();\n if (res) return res;\n else return false;\n }\n\n storeDocuments(\n toStore: File[],\n name?: string\n ): Observable<UploadedDocumentInfo> {\n return this.getProviderSafe(name).storeDocuments(toStore);\n }\n\n public static setTestMode (testProvider:XtStoreProvider<any>) {\n this.testProvider=testProvider;\n }\n\n}\n\n","\nexport enum XtStoreCriteriaOperator {\n EQUALS = '=',\n LESS_THAN = '<',\n LESS_THAN_EQUAL = '<=',\n}\n\nexport class XtStoreCriteria {\n name: string;\n value: any;\n operator: XtStoreCriteriaOperator;\n\n constructor(\n name: string,\n value: any,\n operator?: XtStoreCriteriaOperator\n ) {\n this.name = name;\n this.value = value;\n if (!operator) this.operator = XtStoreCriteriaOperator.EQUALS;\n else {\n this.operator = operator;\n }\n }\n}\n\nexport type XtSortBy ={\n by:string,\n direction: XtSortByDirection\n}\n\nexport enum XtSortByDirection {\n None = \"None\",\n Ascending = \"Ascending\",\n Descending = \"Descending\"\n}\n\nexport enum XtGroupByShow {\n OnlyLowest=\"OnlyLowest\",\n OnlyHighest=\"OnlyHighest\"\n}\n\nexport enum XtGroupByOperation {\n Count= \"Count\",\n Sum=\"Sum\",\n Average=\"Average\",\n Minimum=\"Minimum\",\n Maximum=\"Maximum\"\n}\n\nexport type XtGroupBy= {\n of: string,\n display:{[key:string]:XtGroupByAggregate};\n show?:XtGroupByShow,\n label?:string\n\n atLeastOneGroupIsRequested (): boolean;\n getRequiredListOfFields(): Set<string>;\n}\n\nexport type XtGroupByAggregate = {\n operation: XtGroupByOperation;\n of:string,\n label?:string\n}\n\n\n","import { SpecialFields, Counters } from 'xt-type';\nimport {\n XtGroupByAggregate,\n XtStoreCriteria,\n XtStoreCriteriaOperator,\n XtGroupBy,\n XtSortBy, XtGroupByOperation\n} from '../xt-store-parameters';\n\n/**\n * Helps handle metadata information about loaded items\n */\nexport class XtStoreProviderHelper {\n\n static specialFieldsCache = new Map<string, SpecialFields>();\n /**\n * In case some entity definition has changed, clear the cache\n */\n public static clearConfigCache (): void {\n this.specialFieldsCache.clear();\n }\n\n /**\n * In case the provider source doesn't support search criteria, they can be applied here\n * @param list\n * @param criteria\n */\n public static applyFilters<T> (list:Array<T>, ...criteria: XtStoreCriteria[]): Array<T> {\n if ((criteria==null)||(criteria.length==0)) return list;\n return list.filter(element => {\n for (const criterium of criteria) {\n const toTest = element[criterium.name as keyof T];\n switch (criterium.operator) {\n case XtStoreCriteriaOperator.EQUALS:\n return criterium.value==toTest;\n case XtStoreCriteriaOperator.LESS_THAN:\n return toTest < criterium.value;\n case XtStoreCriteriaOperator.LESS_THAN_EQUAL:\n return toTest <= criterium.value;\n default:\n throw new Error (\"Operator \"+criterium.operator+\" unknown\");\n }\n }\n return true;\n });\n return list;\n }\n\n /** Returns any field who is a date, in order to convert it from json. Keep the result in a cache map\n *\n * @param name\n * @param entity\n * @protected\n */\n public static findSpecialFields (name:string, entity:any):SpecialFields {\n let specialFields = XtStoreProviderHelper.specialFieldsCache.get(name);\n if (specialFields!=null) return specialFields;\n\n const curScore: {score:number, field:any} = {score:-1, field:null}\n\n specialFields = new SpecialFields();\n const fields = entity.fields;\n if( fields!=null) {\n let prop: keyof typeof fields;\n for (prop in fields) {\n // Finds the date fields that will need to be converted from json to javascript Date\n if (fields[prop]?.type==='Date' || fields[prop]?.type==='Date & Time') {\n specialFields.addDateField(fields[prop]?.name);\n } else {\n XtStoreProviderHelper.scoreIdFieldFromEntityField(fields[prop], curScore);\n }\n }\n }\n if (curScore.score>0) {\n specialFields.idField=curScore.field;\n }\n XtStoreProviderHelper.specialFieldsCache.set(name, specialFields);\n\n // eslint-disable-next-line no-restricted-syntax\n //console.debug(\"Found special fields for entity at position \"+name, specialFields);\n return specialFields;\n }\n\n protected static findSpecialFieldsFromData(data: Array<any>, existingFields: SpecialFields) {\n if( (existingFields.idField==null) && (data?.length>0)) {\n // We must guess the id field from data\n const first=data[0];\n const curScore: {score:number, field:any} = {score:-1, field:null}\n let prop: keyof typeof first;\n\n for (prop in first) {\n XtStoreProviderHelper.scoreIdFieldFromProperty(prop, curScore);\n }\n if (curScore.score>0) {\n const test=data.length>1?data[Math.floor((data.length+1)/2)]:null;\n if ((test==null) || (test[curScore.field]!=first[curScore.field])) // Just check that another element doesn't have the same value as an id should be unique\n existingFields.idField=curScore.field;\n }\n }\n }\n\n protected static scoreIdFieldFromEntityField (prop:any, score:{score:number, field:any}): boolean {\n return XtStoreProviderHelper.scoreIdFieldFromProperty(prop?.name, score);\n }\n\n protected static scoreIdFieldFromProperty (name:string, score:{score:number, field:any}): boolean {\n if( name==null)\n return false;\n const propName=name.toLowerCase();\n // Finds if the element is the id field\n if( propName === \"_id\") {\n score.field=\"_id\"; // Don't need to process Id\n score.score = 100;\n return true;\n } else {\n if ((propName == \"id\")||(propName==\"uniqueid\")||(propName==\"identifier\") || (propName=='key') || (propName=='primaryKey')||(propName=='uniqueKey')) {\n if (score.score<80) {\n score.score=80;\n score.field=name;\n }\n } else if (propName.includes(\"unique\")||propName.includes(\"primary\")) {\n if (score.score<50) {\n score.score = 50;\n score.field=name;\n }\n }else if (propName.includes(\"id\")||propName.includes('key')) {\n if (score.score<30) {\n score.score = 30;\n score.field=name;\n }\n }\n return false;\n }\n\n }\n /**\n * Ensure _id is removed if necessary before saving the element\n * @param listToConvert\n * @param specialFields\n * @protected\n */\n public static cleanUpDataBeforeSaving (listToConvert:Array<any>, specialFields:SpecialFields) : void {\n if ((specialFields?.idField!=null)&&(specialFields?.idField!='_id')) {\n listToConvert.forEach(value => {\n delete value._id;\n })\n }\n }\n\n /**\n * Converts dates and dateTimes properties of each element of the array to Typescript format\n * Ensure _id is set with the right id\n * @param listToConvert\n * @param specialFields\n * @protected\n */\n public static cleanUpLoadedData (listToConvert:Array<any>, specialFields:SpecialFields) : void {\n\n if (specialFields!=null) {\n if( specialFields.idField==null) {\n XtStoreProviderHelper.findSpecialFieldsFromData (listToConvert, specialFields);\n }\n listToConvert.forEach((val)=> {\n if ((specialFields.idField!=null)&&(specialFields.idField!=\"_id\")) // We need to copy the id to the standard _id field\n {\n val._id=val[specialFields.idField];\n }\n specialFields.dateFields?.forEach(prop => {\n const toConvert = val[prop];\n if (toConvert!=null) {\n let timeEpoch =Date.parse(toConvert);\n if( isNaN(timeEpoch)) {\n // Invalid date try to remove a possible TZ description in []\n const tzDescIndex = toConvert.lastIndexOf('[');\n if (tzDescIndex!=-1) {\n timeEpoch=Date.parse(toConvert.substring(0, tzDescIndex));\n }\n }\n if (isNaN(timeEpoch)) {\n delete val[prop];\n }\n else {\n val[prop]=new Date(timeEpoch);\n\n }\n }\n })\n })\n }\n }\n\n /**\n * Sort the array using the defined sort declarations across all properties.\n *\n * @param toSort\n * @param sortOptions\n */\n static multiSortArray<T>(toSort: T[], sortOptions?: XtSortBy): T[] {\n if( sortOptions==null)\n return toSort;\n return toSort;\n }\n\n /**\n * Calculates sum, avg, min or max values per group\n * @param values\n * @param groupBy\n * @param modelMgr\n * @param position\n * @param item\n */\n static calculateGroupedByValues<T>(name: string, values: T[], groupBy: XtGroupBy):DontCodeStoreGroupedByEntities|undefined {\n // We are counting per different value of the groupedBy Item\n if ((groupBy!=null) && (groupBy.display!=null)) {\n let fieldToGroupBy=groupBy.of as keyof T;\n if (groupBy.show!=null) fieldToGroupBy=groupBy.show.valueOf() as keyof T;\n\n const counters=new Map<any,Map<keyof T, Counters>> ();\n let lastGroupDelimiter:any;\n let oneGroupOfCounters=new Map<keyof T, Counters>();\n\n const fieldsRequired = groupBy.getRequiredListOfFields() as Set<keyof T>;\n for (const value of values) {\n if (value[fieldToGroupBy]!=lastGroupDelimiter) { // We change the group\n lastGroupDelimiter=value[fieldToGroupBy];\n const storedGroupOfCounters=counters.get(lastGroupDelimiter);\n if( storedGroupOfCounters==null) {\n oneGroupOfCounters = new Map<keyof T, Counters>();\n counters.set(lastGroupDelimiter, oneGroupOfCounters);\n }else {\n oneGroupOfCounters = storedGroupOfCounters;\n }\n }\n\n for (const field of fieldsRequired) {\n let counter=oneGroupOfCounters?.get(field);\n if( counter==null) {\n counter = new Counters();\n oneGroupOfCounters.set(field, counter);\n }\n\n const valSrc=value[field];\n const val=valSrc;\n if (valSrc!=null) {\n const modelMgr:any=null;\n // If it's an object, we need to set the calculated values as the object itself\n if ((typeof valSrc === 'object') && (!(valSrc instanceof Date)) && (modelMgr!=null)) {\n if( counter.sum==null) counter.sum=structuredClone(valSrc);\n else {\n counter.sum=modelMgr.modifyValues(counter.sum, valSrc, counter.metaData,\n (first: any, second: any) => {\n if ((first!=null) && (second!=null))\n return first + second;\n else if (first == null) {\n return second;\n } else if (second==null) {\n return first;\n }\n }/*,\n position, item*/);\n }\n const value=modelMgr.extractValue(valSrc, counter.metaData/*,position, item*/);\n if( counter.minimum==null) { counter.minimum=valSrc; counter.minAsValue=value}\n else {\n const minValue=counter.minAsValue;\n if ((value!=null) && ((minValue==null) || (value < minValue)) ) { counter.minimum = valSrc; counter.minAsValue=value }\n }\n\n if( counter.maximum==null) { counter.maximum=valSrc; counter.maxAsValue=value;}\n else {\n const maxValue=counter.maxAsValue;\n\n if ((value!=null) && ((maxValue==null) || (value > maxValue)))\n { counter.maximum = valSrc; counter.maxAsValue = value;}\n\n }\n\n if (value!=null) {\n counter.count++;\n }\n\n } else if (typeof val === 'number') {\n if( counter.sum==null) counter.sum=0;\n counter.sum=counter.sum+val;\n if( (counter.minimum==null) || (val < counter.minimum))\n { counter.minimum=valSrc; counter.minAsValue=valSrc as number;}\n if( (counter.maximum==null) || (val > counter.maximum))\n { counter.maximum=valSrc; counter.maxAsValue=valSrc as number;}\n counter.count++;\n } else if ((val instanceof Date) && (!isNaN(val.getTime()))) {\n counter.sum=null;\n if ((counter.minimum==null) || (val.valueOf() < counter.minimum.valueOf())) {\n counter.minimum=valSrc;\n }\n if ((counter.maximum==null) || (val.valueOf() > counter.maximum.valueOf())) {\n counter.maximum=valSrc;\n }\n counter.count++;\n } else { // strings\n counter.count++;\n }\n }\n }\n }\n\n // Now that we have all the counters, let's generate the GroupedFields\n let ret: DontCodeStoreGroupedByEntities|undefined;\n if (counters.size>0) {\n ret = new DontCodeStoreGroupedByEntities(groupBy, new Map<any,DontCodeStoreGroupedByValues[]>);\n for (const groupKey of counters.keys()) {\n const group=counters.get(groupKey)!;\n\n for (const aggregate of Object.values(groupBy.display)) {\n let value;\n const counter = group.get(aggregate.of as keyof T);\n if (counter != null) {\n switch (aggregate.operation) {\n case XtGroupByOperation.Count:\n value = counter.count;\n break;\n case XtGroupByOperation.Sum:\n value = counter.sum;\n break;\n case XtGroupByOperation.Average: {\n const modelMgr:any=null;\n if ((counter.sum==null) || (counter.count==0)) value=null;\n else if ((typeof counter.sum === 'object') && (!(counter.sum instanceof Date)) && (modelMgr!=null)) {\n value = modelMgr.applyValue(structuredClone(counter.sum),\n modelMgr.extractValue(counter.sum, counter.metaData/*, position, item*/)/counter.count,\n counter.metaData, undefined/*, position, item*/);\n } else value = counter.sum / counter.count;\n }\n break;\n case XtGroupByOperation.Minimum:\n value = counter.minimum;\n break;\n case XtGroupByOperation.Maximum:\n value = counter.maximum;\n break;\n }\n let listOfValues= ret.values?.get(groupKey);\n if (listOfValues==null) {\n listOfValues = new Array<DontCodeStoreGroupedByValues>();\n ret.values?.set(groupKey, listOfValues);\n }\n listOfValues.push(new DontCodeStoreGroupedByValues(aggregate, value));\n }\n }\n }\n return ret.values!.size>0?ret:undefined;\n }\n }\n return undefined;\n }\n}\n\n\nexport class DontCodeStorePreparedEntities<T> {\n constructor(public sortedData:T[], public sortInfo?:XtSortBy, public groupedByEntities?:DontCodeStoreGroupedByEntities) {\n }\n}\n\nexport class DontCodeStoreGroupedByEntities {\n constructor(public groupInfo:XtGroupBy, public values?:Map<any,DontCodeStoreGroupedByValues[]>) {\n if (values==null)\n this.values=new Map<any,DontCodeStoreGroupedByValues[]>();\n }\n}\n\nexport class DontCodeStoreGroupedByValues {\n constructor(public forAggregate:XtGroupByAggregate, public value:any) {\n }\n}\n\n","import {\n XtGroupBy,\n XtGroupByAggregate, XtGroupByOperation,\n XtGroupByShow,\n XtSortBy,\n XtSortByDirection\n} from './xt-store-parameters';\n\nexport interface DontCodeReportType {\n title: string;\n for: string;\n groupedBy?: {[key:string]:XtGroupBy};\n sortedBy?: {[key:string]:XtSortBy};\n as?: {[key:string]:DontCodeReportDisplayType};\n}\n\nexport interface DontCodeReportDisplayType {\n type: string;\n of: string;\n by?:string;\n title: string;\n}\n\nexport class XtStoreSortBy implements XtSortBy {\n\n direction: XtSortByDirection;\n\n constructor(public by: string, direction?:XtSortByDirection, public subSort?:XtSortBy) {\n if (direction==null) this.direction=XtSortByDirection.None;\n else this.direction=direction;\n }\n}\n\nexport class XtStoreGroupBy implements XtGroupBy {\n display:{[key:string]:XtStoreGroupByAggregate};\n\n constructor(public of:string, display?:{[key:string]:XtStoreGroupByAggregate}, public show?:XtGroupByShow) {\n if (display==null) this.display={};\n else this.display=display;\n }\n\n public atLeastOneGroupIsRequested (): boolean {\n if( (this.display!=null) && (Object.keys(this.display).length>0))\n return true;\n return false;\n }\n\n getRequiredListOfFields(): Set<string> {\n const ret = new Set<string>();\n if( this.display!=null) {\n for (const aggregate of Object.values(this.display)) {\n ret.add(aggregate.of);\n }\n }\n return ret;\n }\n}\n\nexport class XtStoreGroupByAggregate implements XtGroupByAggregate{\n constructor(public of:string, public operation:XtGroupByOperation) {\n }\n}\n\n","import {XtDataTransformer} from \"./xt-data-transformer\";\nimport { map, Observable } from 'rxjs';\nimport { XtStoreCriteria, XtGroupBy, XtSortBy } from '../xt-store-parameters';\nimport {\n DontCodeStoreGroupedByEntities,\n DontCodeStorePreparedEntities,\n XtStoreProviderHelper\n} from './xt-store-provider-helper';\nimport { UploadedDocumentInfo } from '../xt-document';\nimport { XtStoreSortBy } from '../xt-reporting';\n\n/**\n * The standard interface for any store provider\n */\nexport type XtStoreProvider<T=never>= {\n storeEntity( name:string, entity: T): Promise<T>;\n\n /**\n * Rejects the promise if the entity is not found\n * @param name\n * @param key\n */\n safeLoadEntity( name: string, key: any): Promise<T>;\n loadEntity( name: string, key: any): Promise<T|undefined>;\n\n deleteEntity(name:string, key: any): Promise<boolean>;\n\n searchEntities(\n name: string,\n ...criteria: XtStoreCriteria[]\n ): Observable<Array<T>>;\n\n searchAndPrepareEntities(\n name: string,\n sort?:XtSortBy,\n groupBy?:XtGroupBy,\n transformer?: XtDataTransformer<T>,\n ...criteria: XtStoreCriteria[]\n ): Observable<DontCodeStorePreparedEntities<T>>;\n\n canStoreDocument(): boolean;\n\n /**\n * Upload documents to a server store and returns the url or the id needed to retrieve them.\n * @param toStore\n * @param position\n */\n storeDocuments(\n toStore: File[]\n ): Observable<UploadedDocumentInfo>;\n}\n\nexport abstract class AbstractXtStoreProvider<T=never> implements XtStoreProvider<T> {\n abstract canStoreDocument(): boolean;\n\n abstract deleteEntity(name:string, key: any): Promise<boolean>;\n\n abstract loadEntity(name:string, key: any): Promise<T|undefined>;\n\n constructor () {\n }\n\n safeLoadEntity(name: string, key: any): Promise<T> {\n return this.loadEntity(name, key).then(value => {\n if (value==null)\n return Promise.reject(\"Not found\");\n else return value;\n })\n }\n\n /**\n * If the store supports queries with criteria, this function must be implemented, if not, listEntities must be implemented, and this function will apply filters\n * @param position\n * @param criteria\n */\n searchEntities(name: string, ...criteria: XtStoreCriteria[]): Observable<T[]> {\n return this.listEntities(name).pipe(\n map (value => {\n return XtStoreProviderHelper.applyFilters(value, ...criteria) as T[];\n })\n );\n }\n\n /**\n * Returns the list of entities at a given position in the model. Implements at least this function or searchEntities depending on the capability of the store\n * @param position\n * @protected\n */\n protected listEntities (name:string): Observable<T[]> {\n return this.searchEntities(name);\n }\n\n searchAndPrepareEntities(name: string, sort?: XtSortBy, groupBy?: XtGroupBy, transformer?: XtDataTransformer<T>, ...criteria: XtStoreCriteria[]): Observable<DontCodeStorePreparedEntities<T>> {\n return this.searchEntities(name, ...criteria).pipe(\n map (value => {\n // Run the transformation if any\n if (transformer!=null) return transformer.postLoadingTransformation(value);\n else return value;\n }),\n map (value => {\n let groupedByValues:DontCodeStoreGroupedByEntities|undefined;\n if((sort!=null) || (groupBy?.atLeastOneGroupIsRequested()===true)) {\n value = XtStoreProviderHelper.multiSortArray(value, this.calculateSortHierarchy(sort, groupBy)) as T[];\n if (groupBy!=null) {\n groupedByValues = XtStoreProviderHelper.calculateGroupedByValues(name, value, groupBy);\n }\n }\n return new DontCodeStorePreparedEntities<T> (value, sort, groupedByValues);\n })\n );\n }\n\n abstract storeDocuments(toStore: File[]): Observable<UploadedDocumentInfo>;\n\n abstract storeEntity(position: string, entity: T): Promise<T>;\n\n\n protected calculateSortHierarchy(sort?: XtSortBy, groupBy?: XtGroupBy ):XtSortBy|undefined {\n // We must first sort by the groupBy, and then by the sort\n let rootSort:XtSortBy|undefined;\n if (groupBy!=null) {\n rootSort=new XtStoreSortBy(groupBy.of, undefined, sort);\n } else {\n rootSort=sort;\n }\n return rootSort;\n }\n\n}\n","import { AbstractXtStoreProvider } from './xt-store-provider';\nimport { Observable, of, throwError } from 'rxjs';\nimport { UploadedDocumentInfo } from '../xt-document';\nimport { ManagedData } from 'xt-type/src';\n\nexport class XtMemoryStoreProvider<T extends ManagedData> extends AbstractXtStoreProvider<T> {\n protected storage=new Map<string, Map<string, T>>();\n\n override canStoreDocument(): boolean {\n return false;\n }\n\n getSafeStore (name:string):Map<string,T> {\n let ret = this.storage.get(name);\n if (ret==null) {\n ret = new Map<string, T>();\n this.storage.set(name, ret);\n }\n return ret;\n }\n\n deleteEntity(name: string, key: any): Promise<boolean> {\n const store = this.getSafeStore (name);\n return Promise.resolve(store.delete(key));\n }\n\n loadEntity(name: string, key: any): Promise<T | undefined> {\n const store = this.getSafeStore (name);\n return Promise.resolve(store.get(key));\n }\n\n override listEntities(name: string): Observable<T[]> {\n const store = this.getSafeStore (name);\n //console.debug(\"Listing entities for \"+name+\" with \",store);\n return of (Array.from(store.values()));\n }\n\n storeEntity(name: string, entity: T): Promise<T> {\n const store = this.getSafeStore (name);\n if (entity._id==null) {\n entity._id = Math\n .random().toString(36).substring(2, 8);\n }\n store.set(entity._id, entity);\n return Promise.resolve(entity);\n }\n\n override storeDocuments(toStore: File[]): Observable<UploadedDocumentInfo> {\n return throwError (() => {\n throw new Error (\"Not implemented.\");\n });\n }\n\n}\n","import {lastValueFrom, Observable, Subscription, throwError} from \"rxjs\";\nimport {HttpClient, HttpHeaders} from \"@angular/common/http\";\nimport {inject, Injectable, OnDestroy, Optional} from \"@angular/core\";\nimport {map, mergeAll} from \"rxjs/operators\";\nimport { AbstractXtStoreProvider } from '../store-provider/xt-store-provider';\nimport { XtStoreProviderHelper } from '../store-provider/xt-store-provider-helper';\nimport { XtStoreCriteria } from '../xt-store-parameters';\nimport { UploadedDocumentInfo } from '../xt-document';\n\n/**\n * A Store Provider that uses the DontCode API to store / read application data\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class XtApiStoreProvider<T=never> extends AbstractXtStoreProvider<T> implements OnDestroy {\n\n protected http: HttpClient = inject (HttpClient, {optional:true}) as any;\n\n apiUrl: string;\n docUrl: string;\n subscriptions = new Subscription();\n\n constructor(http?:HttpClient/* protected configService: CommonConfigService*/) {\n super();\n if (http!=null) {\n this.http=http;\n }\n\n if (this.http==null) {\n throw new Error (\"You must provide an HttpClient, either through constructor or injection.\");\n }\n this.apiUrl = 'https://test.dont-code.net/data';\n this.docUrl = 'https://test.dont-code.net/documents';\n\n /*this.updateConfig (this.configService.getConfig());\n this.subscriptions.add (this.configService.getUpdates ().pipe (map ((updatedConfig) => {\n this.updateConfig (updatedConfig);\n })).subscribe());*/\n\n }\n\n ngOnDestroy(): void {\n this.subscriptions.unsubscribe();\n }\n\n/* updateConfig(newConfig: Readonly<CommonLibConfig>) {\n if (newConfig.storeApiUrl!=null)\n this.apiUrl = newConfig.storeApiUrl;\n if (newConfig.documentApiUrl!=null)\n this.docUrl = newConfig.documentApiUrl;\n }*/\n\n storeEntity(name: string, data: T): Promise<T> {\n\n const id=(data as any)._id;\n // Reconverts dates or Ids\n const specialFields = XtStoreProviderHelper.findSpecialFields(name, { });\n XtStoreProviderHelper.cleanUpDataBeforeSaving([data], specialFields);\n\n if( id != undefined) {\n return lastValueFrom(this.http.put<T>(this.apiUrl+'/'+name+'/'+id, data, {observe:\"body\", responseType:\"json\"}));\n } else {\n return lastValueFrom(this.http.post<T>(this.apiUrl+'/'+name, data, {observe:\"body\", responseType:\"json\"}));\n }\n }\n\n loadEntity(name: string, key: any): Promise<T|undefined> {\n const obs = this.http.get<T>(this.apiUrl+'/'+name+'/'+key, {observe:\"body\", responseType:\"json\"});\n const specialFields = XtStoreProviderHelper.findSpecialFields(name, { });\n\n return lastValueFrom(obs).then((value) => {\n XtStoreProviderHelper.cleanUpLoadedData([value], specialFields);\n return value;\n });\n }\n\n deleteEntity(name: string, key: any): Promise<boolean> {\n return lastValueFrom(this.http.delete(this.apiUrl+'/'+name+'/'+key, {observe:\"body\", responseType:\"json\"})).then(value => {\n return true;\n });\n }\n\n override searchEntities(name: string, ...criteria: XtStoreCriteria[]): Observable<T[]> {\n\n const specialFields = XtStoreProviderHelper.findSpecialFields(name, { });\n return this.http.get(this.apiUrl+'/'+name, {observe:\"body\", responseType:\"json\"}).pipe(\n map(value => {\n XtStoreProviderHelper.cleanUpLoadedData(value as T [], specialFields);\n return value as T[];\n }),map(value => {\n return XtStoreProviderHelper.applyFilters( value, ...criteria);\n }\n )\n );\n }\n\n canStoreDocument(): boolean {\n return true;\n }\n\n storeDocuments(toStore: File[]): Observable<UploadedDocumentInfo> {\n const myFormData = new FormData();\n const headers = new HttpHeaders();\n headers.append('Content-Type', 'multipart/form-data');\n headers.append('Accept', 'application/json');\n let count=0;\n // store files details into formdata\n toStore.forEach( file => {\n myFormData.append('document#'+count, file);\n count++;\n });\n //HTTP Angular service, which will send call to Laravel API With headers and myformdata\n return this.http.post<UploadedDocumentInfo[]>(this.docUrl, myFormData, { headers: headers }).pipe(\n mergeAll ()\n );\n }\n\n}\n","import { XtStoreManager } from '../store-manager/xt-store-manager';\nimport { XtMemoryStoreProvider } from '../store-provider/xt-memory-store-provider';\nimport { ManagedData } from 'xt-type';\nimport { XtStoreProvider } from '../store-provider/xt-store-provider';\n\n\nexport class StoreTestBed {\n readonly storeManager = new XtStoreManager();\n\n public ensureMemoryProviderOnly () {\n XtStoreManager.setTestMode(new XtMemoryStoreProvider<ManagedData>());\n }\n\n public async defineTestDataFor (entityName:string, testData:ManagedData[]): Promise<void> {\n for (const testEntity of testData) {\n await this.storeManager.storeEntity(entityName, testEntity);\n }\n }\n\n public getStoreManager () {\n return this.storeManager;\n }\n\n public getStoreProviderFor (entityName:string):XtStoreProvider {\n return this.storeManager.getProviderSafe(entityName);\n }\n}\n","/*\n * Public API Surface of store\n */\n\nexport * from './store-manager/xt-store-manager';\nexport * from './store-provider/xt-store-provider';\nexport * from './store-provider/xt-store-provider-helper';\nexport * from './store-provider/xt-memory-store-provider';\n\nexport * from './api-provider/xt-api-store-provider';\n\nexport * from './xt-store-parameters';\nexport * from './xt-document';\nexport * from './xt-reporting';\n\nexport * from './test/store-test-bed';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["map"],"mappings":";;;;;;;;MAOa,cAAc,CAAA;aAKR,IAAY,CAAA,YAAA,GAA6B,IAA7B,CAAkC;AAE/D,IAAA,WAAA,CACE,QAA+B,EAAA;AANzB,QAAA,IAAA,CAAA,kBAAkB,GAAG,IAAI,GAAG,EAAgC;AAC5D,QAAA,IAAA,CAAA,cAAc,GAAG,IAAI,GAAG,EAAgC;AAO9D,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;QACxB,IAAI,CAAC,KAAK,EAAE;;IAGd,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;AAC/B,QAAA,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;;AAG7B,IAAA,WAAW,CAAU,IAAa,EAAA;;AAEhC,QAAA,IAAI,cAAc,CAAC,YAAY,IAAE,IAAI;YAAE,OAAO,cAAc,CAAC,YAAY;AAEzE,QAAA,IAAI,IAAI,IAAI,IAAI,EAAE;YAChB,OAAO,IAAI,CAAC,QAAQ;;aACf;YACL,IAAI,GAAG,GAAG,IAAI;;AAEd;;;;;;;AAOa;YACX,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;;AAEzC,YAAA,OAAO,GAAG,IAAI,IAAI,CAAC,QAAQ;;;AAI/B,IAAA,eAAe,CAAU,IAAa,EAAA;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAI,IAAI,CAAC;AACrC,QAAA,IAAI,GAAG,IAAI,IAAI,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC;;aACzD;AACL,YAAA,OAAO,GAAG;;;IAId,kBAAkB,GAAA;AAChB,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE;;IAG3B,sBAAsB,GAAA;AACpB,QAAA,OAAO,IAAI,CAAC,eAAe,EAAE;;IAG/B,WAAW,CAAU,KAAyB,EAAE,IAAa,EAAA;QAC3D,IAAI,IAAI,IAAI,IAAI;AAAE,YAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;aAClC;YACH,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC;;;IAI5C,wBAAwB,CACtB,KAAyB,EACzB,OAAe,EAAA;QAEf,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;;AAGzC,IAAA,kBAAkB,CAAU,KAAyB,EAAA;AACnD,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;;AAGzB,IAAA,cAAc,CAAC,IAAa,EAAA;QAC1B,IAAI,IAAI,IAAI,IAAI;AAAE,YAAA,IAAI,CAAC,QAAQ,GAAG,SAAS;aACtC;AACH,YAAA,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC;;;AAIxC,IAAA,2BAA2B,CAAC,OAAe,EAAA;AACzC,QAAA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC;;IAGrC,qBAAqB,GAAA;QACnB,IAAI,CAAC,cAAc,EAAE;;IAGvB,WAAW,CAAU,IAAY,EAAE,MAAS,EAAA;AAC1C,QAAA,OAAO,IAAI,CAAC,eAAe,CAAI,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC;;IAGhE,UAAU,CAAU,IAAY,EAAE,GAAQ,EAAA;AACxC,QAAA,OAAO,IAAI,CAAC,eAAe,CAAI,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC;;IAG5D,cAAc,CAAU,IAAY,EAAE,GAAQ,EAAA;AAC5C,QAAA,OAAO,IAAI,CAAC,eAAe,CAAI,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC;;IAGhE,YAAY,CAAC,IAAY,EAAE,GAAQ,EAAA;AACjC,QAAA,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC;;AAG3D,IAAA,cAAc,CACZ,IAAY,EACZ,GAAG,QAA2B,EAAA;AAE9B,QAAA,OAAO,IAAI,CAAC,eAAe,CAAI,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC;;IAGxE,wBAAwB,CACtB,IAAY,EACZ,IAAc,EACd,OAAkB,EAClB,eAAkC,EAClC,GAAG,QAA2B,EAAA;QAE9B,OAAO,IAAI,CAAC,eAAe,CAAI,IAAI,CAAC,CAAC,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,QAAQ,CAAC;;AAIlH,IAAA,gBAAgB,CAAC,IAAa,EAAA;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE;AACtD,QAAA,IAAI,GAAG;AAAE,YAAA,OAAO,GAAG;;AACd,YAAA,OAAO,KAAK;;IAGnB,cAAc,CACZ,OAAe,EACf,IAAa,EAAA;QAEb,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC;;IAGpD,OAAO,WAAW,CAAE,YAAiC,EAAA;AAC1D,QAAA,IAAI,CAAC,YAAY,GAAC,YAAY;;;;IClJtB;AAAZ,CAAA,UAAY,uBAAuB,EAAA;AACjC,IAAA,uBAAA,CAAA,QAAA,CAAA,GAAA,GAAY;AACZ,IAAA,uBAAA,CAAA,WAAA,CAAA,GAAA,GAAe;AACf,IAAA,uBAAA,CAAA,iBAAA,CAAA,GAAA,IAAsB;AACxB,CAAC,EAJW,uBAAuB,KAAvB,uBAAuB,GAIlC,EAAA,CAAA,CAAA;MAEY,eAAe,CAAA;AAK1B,IAAA,WAAA,CACE,IAAY,EACZ,KAAU,EACV,QAAkC,EAAA;AAElC,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,IAAI,CAAC,QAAQ,GAAG,uBAAuB,CAAC,MAAM;aACxD;AACH,YAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;;;AAG7B;IAOW;AAAZ,CAAA,UAAY,iBAAiB,EAAA;AAC3B,IAAA,iBAAA,CAAA,MAAA,CAAA,GAAA,MAAa;AACb,IAAA,iBAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,iBAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AAC3B,CAAC,EAJW,iBAAiB,KAAjB,iBAAiB,GAI5B,EAAA,CAAA,CAAA;IAEW;AAAZ,CAAA,UAAY,aAAa,EAAA;AACvB,IAAA,aAAA,CAAA,YAAA,CAAA,GAAA,YAAuB;AACvB,IAAA,aAAA,CAAA,aAAA,CAAA,GAAA,aAAyB;AAC3B,CAAC,EAHW,aAAa,KAAb,aAAa,GAGxB,EAAA,CAAA,CAAA;IAEW;AAAZ,CAAA,UAAY,kBAAkB,EAAA;AAC5B,IAAA,kBAAA,CAAA,OAAA,CAAA,GAAA,OAAc;AACd,IAAA,kBAAA,CAAA,KAAA,CAAA,GAAA,KAAS;AACT,IAAA,kBAAA,CAAA,SAAA,CAAA,GAAA,SAAiB;AACjB,IAAA,kBAAA,CAAA,SAAA,CAAA,GAAA,SAAiB;AACjB,IAAA,kBAAA,CAAA,SAAA,CAAA,GAAA,SAAiB;AACnB,CAAC,EANW,kBAAkB,KAAlB,kBAAkB,GAM7B,EAAA,CAAA,CAAA;;ACvCD;;AAEG;MACU,qBAAqB,CAAA;AAEzB,IAAA,SAAA,IAAA,CAAA,kBAAkB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAC7D;;AAEG;AACI,IAAA,OAAO,gBAAgB,GAAA;AAC5B,QAAA,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;;AAGjC;;;;AAIG;AACI,IAAA,OAAO,YAAY,CAAK,IAAa,EAAE,GAAG,QAA2B,EAAA;AAC1E,QAAA,IAAI,CAAC,QAAQ,IAAE,IAAI,MAAI,QAAQ,CAAC,MAAM,IAAE,CAAC,CAAC;AAAE,YAAA,OAAO,IAAI;AACvD,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,IAAG;AAC3B,YAAA,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE;gBAChC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,IAAe,CAAC;AACjD,gBAAA,QAAQ,SAAS,CAAC,QAAQ;oBACxB,KAAK,uBAAuB,CAAC,MAAM;AACjC,wBAAA,OAAO,SAAS,CAAC,KAAK,IAAE,MAAM;oBAChC,KAAK,uBAAuB,CAAC,SAAS;AACpC,wBAAA,OAAO,MAAM,GAAG,SAAS,CAAC,KAAK;oBACjC,KAAK,uBAAuB,CAAC,eAAe;AAC1C,wBAAA,OAAO,MAAM,IAAI,SAAS,CAAC,KAAK;AAClC,oBAAA;wBACE,MAAM,IAAI,KAAK,CAAE,WAAW,GAAC,SAAS,CAAC,QAAQ,GAAC,UAAU,CAAC;;;AAGjE,YAAA,OAAO,IAAI;AACb,SAAC,CAAC;AACF,QAAA,OAAO,IAAI;;AAGb;;;;;AAKG;AACI,IAAA,OAAO,iBAAiB,CAAE,IAAW,EAAE,MAAU,EAAA;QACtD,IAAI,aAAa,GAAG,qBAAqB,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;QACtE,IAAI,aAAa,IAAE,IAAI;AAAE,YAAA,OAAO,aAAa;AAE7C,QAAA,MAAM,QAAQ,GAA8B,EAAC,KAAK,EAAC,CAAC,CAAC,EAAE,KAAK,EAAC,IAAI,EAAC;AAElE,QAAA,aAAa,GAAG,IAAI,aAAa,EAAE;AACnC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM;AAC5B,QAAA,IAAI,MAAM,IAAE,IAAI,EAAE;AAChB,YAAA,IAAI,IAAyB;AAC7B,YAAA,KAAK,IAAI,IAAI,MAAM,EAAE;;AAEnB,gBAAA,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,KAAG,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,KAAG,aAAa,EAAE;oBACrE,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;;qBACzC;oBACL,qBAAqB,CAAC,2BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;;;;AAI/E,QAAA,IAAI,QAAQ,CAAC,KAAK,GAAC,CAAC,EAAE;AACpB,YAAA,aAAa,CAAC,OAAO,GAAC,QAAQ,CAAC,KAAK;;QAEtC,qBAAqB,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC;;;AAIjE,QAAA,OAAO,aAAa;;AAGZ,IAAA,OAAO,yBAAyB,CAAC,IAAgB,EAAE,cAA6B,EAAA;AACxF,QAAA,IAAI,CAAC,cAAc,CAAC,OAAO,IAAE,IAAI,MAAM,IAAI,EAAE,MAAM,GAAC,CAAC,CAAC,EAAE;;AAEtD,YAAA,MAAM,KAAK,GAAC,IAAI,CAAC,CAAC,CAAC;AACnB,YAAA,MAAM,QAAQ,GAA8B,EAAC,KAAK,EAAC,CAAC,CAAC,EAAE,KAAK,EAAC,IAAI,EAAC;AAClE,YAAA,IAAI,IAAwB;AAE5B,YAAA,KAAK,IAAI,IAAI,KAAK,EAAE;AAClB,gBAAA,qBAAqB,CAAC,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC;;AAEhE,YAAA,IAAI,QAAQ,CAAC,KAAK,GAAC,CAAC,EAAE;AACpB,gBAAA,MAAM,IAAI,GAAC,IAAI,CAAC,MAAM,GAAC,CAAC,GAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAC,CAAC,IAAE,CAAC,CAAC,CAAC,GAAC,IAAI;gBACjE,IAAI,CAAC,IAAI,IAAE,IAAI,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC/D,oBAAA,cAAc,CAAC,OAAO,GAAC,QAAQ,CAAC,KAAK;;;;AAKnC,IAAA,OAAO,2BAA2B,CAAE,IAAQ,EAAE,KAA+B,EAAA;QACrF,OAAO,qBAAqB,CAAC,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;;AAGhE,IAAA,OAAO,wBAAwB,CAAE,IAAW,EAAE,KAA+B,EAAA;QACrF,IAAI,IAAI,IAAE,IAAI;AACZ,YAAA,OAAO,KAAK;AACd,QAAA,MAAM,QAAQ,GAAC,IAAI,CAAC,WAAW,EAAE;;AAEjC,QAAA,IAAI,QAAQ,KAAK,KAAK,EAAE;AACtB,YAAA,KAAK,CAAC,KAAK,GAAC,KAAK,CAAC;AAClB,YAAA,KAAK,CAAC,KAAK,GAAG,GAAG;AACjB,YAAA,OAAO,IAAI;;aACN;AACL,YAAA,IAAI,CAAC,QAAQ,IAAI,IAAI,MAAI,QAAQ,IAAE,UAAU,CAAC,KAAG,QAAQ,IAAE,YAAY,CAAC,KAAK,QAAQ,IAAE,KAAK,CAAC,KAAK,QAAQ,IAAE,YAAY,CAAC,KAAG,QAAQ,IAAE,WAAW,CAAC,EAAE;AAClJ,gBAAA,IAAI,KAAK,CAAC,KAAK,GAAC,EAAE,EAAE;AAClB,oBAAA,KAAK,CAAC,KAAK,GAAC,EAAE;AACd,oBAAA,KAAK,CAAC,KAAK,GAAC,IAAI;;;AAEb,iBAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;AACpE,gBAAA,IAAI,KAAK,CAAC,KAAK,GAAC,EAAE,EAAE;AAClB,oBAAA,KAAK,CAAC,KAAK,GAAG,EAAE;AAChB,oBAAA,KAAK,CAAC,KAAK,GAAC,IAAI;;;AAEd,iBAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC3D,gBAAA,IAAI,KAAK,CAAC,KAAK,GAAC,EAAE,EAAE;AAClB,oBAAA,KAAK,CAAC,KAAK,GAAG,EAAE;AAChB,oBAAA,KAAK,CAAC,KAAK,GAAC,IAAI;;;AAGpB,YAAA,OAAO,KAAK;;;AAIhB;;;;;AAKG;AACI,IAAA,OAAO,uBAAuB,CAAE,aAAwB,EAAE,aAA2B,EAAA;AAC1F,QAAA,IAAI,CAAC,aAAa,EAAE,OAAO,IAAE,IAAI,MAAI,aAAa,EAAE,OAAO,IAAE,KAAK,CAAC,EAAE;AACnE,YAAA,aAAa,CAAC,OAAO,CAAC,KAAK,IAAG;gBAC5B,OAAO,KAAK,CAAC,GAAG;AAClB,aAAC,CAAC;;;AAIN;;;;;;AAMG;AACI,IAAA,OAAO,iBAAiB,CAAE,aAAwB,EAAE,aAA2B,EAAA;AAEpF,QAAA,IAAI,aAAa,IAAE,IAAI,EAAE;AACvB,YAAA,IAAI,aAAa,CAAC,OAAO,IAAE,IAAI,EAAE;AAC/B,gBAAA,qBAAqB,CAAC,yBAAyB,CAAE,aAAa,EAAE,aAAa,CAAC;;AAEhF,YAAA,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,KAAG;AAC3B,gBAAA,IAAI,CAAC,aAAa,CAAC,OAAO,IAAE,IAAI,MAAI,aAAa,CAAC,OAAO,IAAE,KAAK,CAAC;iBACjE;oBACE,GAAG,CAAC,GAAG,GAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC;;AAEpC,gBAAA,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,IAAG;AACvC,oBAAA,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC;AAC3B,oBAAA,IAAI,SAAS,IAAE,IAAI,EAAE;wBACnB,IAAI,SAAS,GAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;AACpC,wBAAA,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE;;4BAEpB,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC;AAC9C,4BAAA,IAAI,WAAW,IAAE,CAAC,CAAC,EAAE;AACnB,gCAAA,SAAS,GAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;;;AAG7D,wBAAA,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE;AACpB,4BAAA,OAAO,GAAG,CAAC,IAAI,CAAC;;6BAEb;4BACH,GAAG,CAAC,IAAI,CAAC,GAAC,IAAI,IAAI,CAAC,SAAS,CAAC;;;AAInC,iBAAC,CAAC;AACJ,aAAC,CAAC;;;AAIN;;;;;AAKG;AACH,IAAA,OAAO,cAAc,CAAI,MAAW,EAAE,WAAsB,EAAA;QAC1D,IAAI,WAAW,IAAE,IAAI;AACnB,YAAA,OAAO,MAAM;AACf,QAAA,OAAO,MAAM;;AAGf;;;;;;;AAOG;AACH,IAAA,OAAO,wBAAwB,CAAI,IAAY,EAAE,MAAW,EAAE,OAAkB,EAAA;;AAE9E,QAAA,IAAI,CAAC,OAAO,IAAE,IAAI,MAAM,OAAO,CAAC,OAAO,IAAE,IAAI,CAAC,EAAE;AAC9C,YAAA,IAAI,cAAc,GAAC,OAAO,CAAC,EAAa;AACxC,YAAA,IAAI,OAAO,CAAC,IAAI,IAAE,IAAI;AAAE,gBAAA,cAAc,GAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAa;AAExE,YAAA,MAAM,QAAQ,GAAC,IAAI,GAAG,EAA+B;AACrD,YAAA,IAAI,kBAAsB;AAC1B,YAAA,IAAI,kBAAkB,GAAC,IAAI,GAAG,EAAqB;AAEnD,YAAA,MAAM,cAAc,GAAG,OAAO,CAAC,uBAAuB,EAAkB;AACxE,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC1B,IAAI,KAAK,CAAC,cAAc,CAAC,IAAE,kBAAkB,EAAE;AAC7C,oBAAA,kBAAkB,GAAC,KAAK,CAAC,cAAc,CAAC;oBACxC,MAAM,qBAAqB,GAAC,QAAQ,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAC5D,oBAAA,IAAI,qBAAqB,IAAE,IAAI,EAAE;AAC/B,wBAAA,kBAAkB,GAAG,IAAI,GAAG,EAAqB;AACjD,wBAAA,QAAQ,CAAC,GAAG,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;;yBAChD;wBACJ,kBAAkB,GAAG,qBAAqB;;;AAI9C,gBAAA,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE;oBAClC,IAAI,OAAO,GAAC,kBAAkB,EAAE,GAAG,CAAC,KAAK,CAAC;AAC1C,oBAAA,IAAI,OAAO,IAAE,IAAI,EAAE;AACjB,wBAAA,OAAO,GAAG,IAAI,QAAQ,EAAE;AACxB,wBAAA,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC;;AAGxC,oBAAA,MAAM,MAAM,GAAC,KAAK,CAAC,KAAK,CAAC;oBACzB,MAAM,GAAG,GAAC,MAAM;AAChB,oBAAA,IAAI,MAAM,IAAE,IAAI,EAAE;wBAChB,MAAM,QAAQ,GAAK,IAAI;;wBAEvB,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,MAAO,EAAE,MAAM,YAAY,IAAI,CAAC,CAAC,KAAK,QAAQ,IAAE,IAAI,CAAC,EAAE;AACpF,4BAAA,IAAI,OAAO,CAAC,GAAG,IAAE,IAAI;AAAE,gCAAA,OAAO,CAAC,GAAG,GAAC,eAAe,CAAC,MAAM,CAAC;iCACrD;gCACH,OAAO,CAAC,GAAG,GAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EACrE,CAAC,KAAU,EAAE,MAAW,KAAI;oCAC1B,IAAI,CAAC,KAAK,IAAE,IAAI,MAAM,MAAM,IAAE,IAAI,CAAC;wCACjC,OAAO,KAAK,GAAG,MAAM;AAClB,yCAAA,IAAI,KAAK,IAAI,IAAI,EAAE;AACtB,wCAAA,OAAO,MAAM;;AACR,yCAAA,IAAI,MAAM,IAAE,IAAI,EAAE;AACvB,wCAAA,OAAO,KAAK;;AAEhB,iCAAC;AACe,iDAAC;;AAErB,4BAAA,MAAM,KAAK,GAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,qBAAoB;AAC9E,4BAAA,IAAI,OAAO,CAAC,OAAO,IAAE,IAAI,EAAG;AAAE,gCAAA,OAAO,CAAC,OAAO,GAAC,MAAM;AAAE,gCAAA,OAAO,CAAC,UAAU,GAAC,KAAK;;iCACzE;AACH,gCAAA,MAAM,QAAQ,GAAC,OAAO,CAAC,UAAU;gCACjC,IAAI,CAAC,KAAK,IAAE,IAAI,MAAM,CAAC,QAAQ,IAAE,IAAI,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,EAAG;AAAE,oCAAA,OAAO,CAAC,OAAO,GAAG,MAAM;AAAE,oCAAA,OAAO,CAAC,UAAU,GAAC,KAAK;;;AAGtH,4BAAA,IAAI,OAAO,CAAC,OAAO,IAAE,IAAI,EAAE;AAAE,gCAAA,OAAO,CAAC,OAAO,GAAC,MAAM;AAAE,gCAAA,OAAO,CAAC,UAAU,GAAC,KAAK;;iCACxE;AACH,gCAAA,MAAM,QAAQ,GAAC,OAAO,CAAC,UAAU;gCAEjC,IAAI,CAAC,KAAK,IAAE,IAAI,MAAM,CAAC,QAAQ,IAAE,IAAI,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,EAC3D;AAAE,oCAAA,OAAO,CAAC,OAAO,GAAG,MAAM;AAAE,oCAAA,OAAO,CAAC,UAAU,GAAG,KAAK;;;AAI1D,4BAAA,IAAI,KAAK,IAAE,IAAI,EAAE;gCACf,OAAO,CAAC,KAAK,EAAE;;;AAGZ,6BAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAClC,4BAAA,IAAI,OAAO,CAAC,GAAG,IAAE,IAAI;AAAE,gCAAA,OAAO,CAAC,GAAG,GAAC,CAAC;4BACpC,OAAO,CAAC,GAAG,GAAC,OAAO,CAAC,GAAG,GAAC,GAAG;AAC3B,4BAAA,IAAI,CAAC,OAAO,CAAC,OAAO,IAAE,IAAI,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,EACpD;AAAE,gCAAA,OAAO,CAAC,OAAO,GAAC,MAAM;AAAE,gCAAA,OAAO,CAAC,UAAU,GAAC,MAAgB;;AAC/D,4BAAA,IAAI,CAAC,OAAO,CAAC,OAAO,IAAE,IAAI,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,EACpD;AAAE,gCAAA,OAAO,CAAC,OAAO,GAAC,MAAM;AAAE,gCAAA,OAAO,CAAC,UAAU,GAAC,MAAgB;;4BAC/D,OAAO,CAAC,KAAK,EAAE;;AACV,6BAAA,IAAI,CAAC,GAAG,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE;AAC3D,4BAAA,OAAO,CAAC,GAAG,GAAC,IAAI;4BAChB,IAAI,CAAC,OAAO,CAAC,OAAO,IAAE,IAAI,MAAM,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE;AAC1E,gCAAA,OAAO,CAAC,OAAO,GAAC,MAAM;;4BAExB,IAAI,CAAC,OAAO,CAAC,OAAO,IAAE,IAAI,MAAM,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE;AAC1E,gCAAA,OAAO,CAAC,OAAO,GAAC,MAAM;;4BAExB,OAAO,CAAC,KAAK,EAAE;;AACV,6BAAA;4BACL,OAAO,CAAC,KAAK,EAAE;;;;;;AAOvB,YAAA,IAAI,GAA6C;AACjD,YAAA,IAAI,QAAQ,CAAC,IAAI,GAAC,CAAC,EAAE;gBACnB,GAAG,GAAG,IAAI,8BAA8B,CAAC,OAAO,EAAE,IAAI,GAAuC,CAAC;gBAC9F,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE;oBACtC,MAAM,KAAK,GAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAE;AAEnC,oBAAA,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AACtD,wBAAA,IAAI,KAAK;wBACT,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAa,CAAC;AAClD,wBAAA,IAAI,OAAO,IAAI,IAAI,EAAE;AACnB,4BAAA,QAAQ,SAAS,CAAC,SAAS;gCACzB,KAAK,kBAAkB,CAAC,KAAK;AAC3B,oCAAA,KAAK,GAAG,OAAO,CAAC,KAAK;oCACrB;gCACF,KAAK,kBAAkB,CAAC,GAAG;AACzB,oCAAA,KAAK,GAAG,OAAO,CAAC,GAAG;oCACnB;gCACF,KAAK,kBAAkB,CAAC,OAAO;oCAAE;wCAC/B,MAAM,QAAQ,GAAK,IAAI;AACvB,wCAAA,IAAI,CAAC,OAAO,CAAC,GAAG,IAAE,IAAI,MAAM,OAAO,CAAC,KAAK,IAAE,CAAC,CAAC;4CAAE,KAAK,GAAC,IAAI;6CACpD,IAAI,CAAC,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,MAAO,EAAE,OAAO,CAAC,GAAG,YAAY,IAAI,CAAC,CAAC,KAAK,QAAQ,IAAE,IAAI,CAAC,EAAE;AACnG,4CAAA,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EACtD,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,sBAAqB,GAAC,OAAO,CAAC,KAAK,EACtF,OAAO,CAAC,QAAQ,EAAE,SAAS,sBAAqB;;;4CAC7C,KAAK,GAAG,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,KAAK;;oCAE1C;gCACF,KAAK,kBAAkB,CAAC,OAAO;AAC7B,oCAAA,KAAK,GAAG,OAAO,CAAC,OAAO;oCACvB;gCACF,KAAK,kBAAkB,CAAC,OAAO;AAC7B,oCAAA,KAAK,GAAG,OAAO,CAAC,OAAO;oCACvB;;4BAEJ,IAAI,YAAY,GAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;AAC3C,4BAAA,IAAI,YAAY,IAAE,IAAI,EAAE;AACtB,gCAAA,YAAY,GAAG,IAAI,KAAK,EAAgC;gCACtD,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC;;4BAE3C,YAAY,CAAC,IAAI,CAAC,IAAI,4BAA4B,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;;;;AAI3E,gBAAA,OAAO,GAAG,CAAC,MAAO,CAAC,IAAI,GAAC,CAAC,GAAC,GAAG,GAAC,SAAS;;;AAG3C,QAAA,OAAO,SAAS;;;MAKP,6BAA6B,CAAA;AACxC,IAAA,WAAA,CAAmB,UAAc,EAAS,QAAkB,EAAS,iBAAiD,EAAA;QAAnG,IAAU,CAAA,UAAA,GAAV,UAAU;QAAa,IAAQ,CAAA,QAAA,GAAR,QAAQ;QAAmB,IAAiB,CAAA,iBAAA,GAAjB,iBAAiB;;AAEvF;MAEY,8BAA8B,CAAA;IACzC,WAAmB,CAAA,SAAmB,EAAS,MAA+C,EAAA;QAA3E,IAAS,CAAA,SAAA,GAAT,SAAS;QAAmB,IAAM,CAAA,MAAA,GAAN,MAAM;QACnD,IAAI,MAAM,IAAE,IAAI;AACd,YAAA,IAAI,CAAC,MAAM,GAAC,IAAI,GAAG,EAAsC;;AAE9D;MAEY,4BAA4B,CAAA;IACvC,WAAmB,CAAA,YAA+B,EAAS,KAAS,EAAA;QAAjD,IAAY,CAAA,YAAA,GAAZ,YAAY;QAA4B,IAAK,CAAA,KAAA,GAAL,KAAK;;AAEjE;;MC7VY,aAAa,CAAA;AAIxB,IAAA,WAAA,CAAmB,EAAU,EAAE,SAA4B,EAAS,OAAiB,EAAA;QAAlE,IAAE,CAAA,EAAA,GAAF,EAAE;QAA+C,IAAO,CAAA,OAAA,GAAP,OAAO;QACzE,IAAI,SAAS,IAAE,IAAI;AAAI,YAAA,IAAI,CAAC,SAAS,GAAC,iBAAiB,CAAC,IAAI;;AACvD,YAAA,IAAI,CAAC,SAAS,GAAC,SAAS;;AAEhC;MAEY,cAAc,CAAA;AAGzB,IAAA,WAAA,CAAmB,EAAS,EAAE,OAA+C,EAAS,IAAmB,EAAA;QAAtF,IAAE,CAAA,EAAA,GAAF,EAAE;QAAiE,IAAI,CAAA,IAAA,GAAJ,IAAI;QACxF,IAAI,OAAO,IAAE,IAAI;AAAE,YAAA,IAAI,CAAC,OAAO,GAAC,EAAE;;AAC7B,YAAA,IAAI,CAAC,OAAO,GAAC,OAAO;;IAGpB,0BAA0B,GAAA;QAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,IAAE,IAAI,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAC,CAAC,CAAC;AAC9D,YAAA,OAAO,IAAI;AACb,QAAA,OAAO,KAAK;;IAGd,uBAAuB,GAAA;AACrB,QAAA,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU;AAC7B,QAAA,IAAI,IAAI,CAAC,OAAO,IAAE,IAAI,EAAE;AACtB,YAAA,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;AACnD,gBAAA,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;;;AAGzB,QAAA,OAAO,GAAG;;AAEb;MAEY,uBAAuB,CAAA;IAClC,WAAmB,CAAA,EAAS,EAAS,SAA4B,EAAA;QAA9C,IAAE,CAAA,EAAA,GAAF,EAAE;QAAgB,IAAS,CAAA,SAAA,GAAT,SAAS;;AAE/C;;MCTqB,uBAAuB,CAAA;AAO3C,IAAA,WAAA,GAAA;;IAGA,cAAc,CAAC,IAAY,EAAE,GAAQ,EAAA;AACnC,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,IAAG;YAC7C,IAAI,KAAK,IAAE,IAAI;AACb,gBAAA,OAAO,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC;;AAC/B,gBAAA,OAAO,KAAK;AACnB,SAAC,CAAC;;AAGJ;;;;AAIG;AACH,IAAA,cAAc,CAAC,IAAY,EAAE,GAAG,QAA2B,EAAA;AACzD,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CACjC,GAAG,CAAE,KAAK,IAAG;YACX,OAAO,qBAAqB,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAQ;SACrE,CAAC,CACH;;AAGH;;;;AAIG;AACO,IAAA,YAAY,CAAE,IAAW,EAAA;AACjC,QAAA,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;;IAGlC,wBAAwB,CAAC,IAAY,EAAE,IAAe,EAAE,OAAmB,EAAE,WAAkC,EAAE,GAAG,QAA2B,EAAA;AAC7I,QAAA,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC,IAAI,CAChD,GAAG,CAAE,KAAK,IAAG;;YAEX,IAAI,WAAW,IAAE,IAAI;AAAE,gBAAA,OAAO,WAAW,CAAC,yBAAyB,CAAC,KAAK,CAAC;;AACrE,gBAAA,OAAO,KAAK;AACnB,SAAC,CAAC,EACF,GAAG,CAAE,KAAK,IAAG;AACX,YAAA,IAAI,eAAwD;AAC5D,YAAA,IAAG,CAAC,IAAI,IAAE,IAAI,MAAM,OAAO,EAAE,0BAA0B,EAAE,KAAG,IAAI,CAAC,EAAE;AACjE,gBAAA,KAAK,GAAG,qBAAqB,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAQ;AACtG,gBAAA,IAAI,OAAO,IAAE,IAAI,EAAE;oBACjB,eAAe,GAAG,qBAAqB,CAAC,wBAAwB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC;;;YAG1F,OAAO,IAAI,6BAA6B,CAAK,KAAK,EAAE,IAAI,EAAE,eAAe,CAAC;SAC3E,CAAC,CACH;;IAQO,sBAAsB,CAAC,IAAe,EAAE,OAAmB,EAAA;;AAEnE,QAAA,IAAI,QAA2B;AAC/B,QAAA,IAAI,OAAO,IAAE,IAAI,EAAE;AACjB,YAAA,QAAQ,GAAC,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC;;aAClD;YACL,QAAQ,GAAC,IAAI;;AAEf,QAAA,OAAO,QAAQ;;AAGlB;;AC3HK,MAAO,qBAA6C,SAAQ,uBAA0B,CAAA;AAA5F,IAAA,WAAA,GAAA;;AACY,QAAA,IAAA,CAAA,OAAO,GAAC,IAAI,GAAG,EAA0B;;IAE1C,gBAAgB,GAAA;AACvB,QAAA,OAAO,KAAK;;AAGd,IAAA,YAAY,CAAE,IAAW,EAAA;QACvB,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AAChC,QAAA,IAAI,GAAG,IAAE,IAAI,EAAE;AACb,YAAA,GAAG,GAAG,IAAI,GAAG,EAAa;YAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;;AAE7B,QAAA,OAAO,GAAG;;IAGZ,YAAY,CAAC,IAAY,EAAE,GAAQ,EAAA;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAE,IAAI,CAAC;QACtC,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;;IAG3C,UAAU,CAAC,IAAY,EAAE,GAAQ,EAAA;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAE,IAAI,CAAC;QACtC,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;;AAG/B,IAAA,YAAY,CAAC,IAAY,EAAA;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAE,IAAI,CAAC;;AAEtC,QAAA,OAAO,EAAE,CAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;;IAGxC,WAAW,CAAC,IAAY,EAAE,MAAS,EAAA;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAE,IAAI,CAAC;AACtC,QAAA,IAAI,MAAM,CAAC,GAAG,IAAE,IAAI,EAAE;YACpB,MAAM,CAAC,GAAG,GAAG;AACV,iBAAA,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;;QAE1C,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC;AAC7B,QAAA,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;;AAGvB,IAAA,cAAc,CAAC,OAAe,EAAA;QACrC,OAAO,UAAU,CAAE,MAAK;AACtB,YAAA,MAAM,IAAI,KAAK,CAAE,kBAAkB,CAAC;AACtC,SAAC,CAAC;;AAGL;;AC5CD;;AAEG;AAIG,MAAO,kBAA4B,SAAQ,uBAA0B,CAAA;IAQzE,WAAY,CAAA,IAAgB,oDAAiD;AAC3E,QAAA,KAAK,EAAE;QAPC,IAAI,CAAA,IAAA,GAAe,MAAM,CAAE,UAAU,EAAE,EAAC,QAAQ,EAAC,IAAI,EAAC,CAAQ;AAIxE,QAAA,IAAA,CAAA,aAAa,GAAG,IAAI,YAAY,EAAE;AAIhC,QAAA,IAAI,IAAI,IAAE,IAAI,EAAE;AACd,YAAA,IAAI,CAAC,IAAI,GAAC,IAAI;;AAGhB,QAAA,IAAI,IAAI,CAAC,IAAI,IAAE,IAAI,EAAE;AACnB,YAAA,MAAM,IAAI,KAAK,CAAE,0EAA0E,CAAC;;AAE9F,QAAA,IAAI,CAAC,MAAM,GAAG,iCAAiC;AAC/C,QAAA,IAAI,CAAC,MAAM,GAAG,sCAAsC;AAEpD;;;AAGmB;;IAIrB,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE;;AAGpC;;;;;AAKK;IAEH,WAAW,CAAC,IAAY,EAAE,IAAO,EAAA;AAE/B,QAAA,MAAM,EAAE,GAAE,IAAY,CAAC,GAAG;;QAE1B,MAAM,aAAa,GAAG,qBAAqB,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAG,CAAC;QACxE,qBAAqB,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;AAEpE,QAAA,IAAI,EAAE,IAAI,SAAS,EAAE;AACnB,YAAA,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAI,IAAI,CAAC,MAAM,GAAC,GAAG,GAAC,IAAI,GAAC,GAAG,GAAC,EAAE,EAAE,IAAI,EAAE,EAAC,OAAO,EAAC,MAAM,EAAE,YAAY,EAAC,MAAM,EAAC,CAAC,CAAC;;aAC3G;AACL,YAAA,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAI,IAAI,CAAC,MAAM,GAAC,GAAG,GAAC,IAAI,EAAE,IAAI,EAAE,EAAC,OAAO,EAAC,MAAM,EAAE,YAAY,EAAC,MAAM,EAAC,CAAC,CAAC;;;IAI9G,UAAU,CAAC,IAAY,EAAE,GAAQ,EAAA;AAC/B,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAI,IAAI,CAAC,MAAM,GAAC,GAAG,GAAC,IAAI,GAAC,GAAG,GAAC,GAAG,EAAE,EAAC,OAAO,EAAC,MAAM,EAAE,YAAY,EAAC,MAAM,EAAC,CAAC;QACjG,MAAM,aAAa,GAAG,qBAAqB,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAG,CAAC;QAExE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAI;YACvC,qBAAqB,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;AAC/D,YAAA,OAAO,KAAK;AACd,SAAC,CAAC;;IAGJ,YAAY,CAAC,IAAY,EAAE,GAAQ,EAAA;AACjC,QAAA,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAC,GAAG,GAAC,IAAI,GAAC,GAAG,GAAC,GAAG,EAAE,EAAC,OAAO,EAAC,MAAM,EAAE,YAAY,EAAC,MAAM,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAG;AACvH,YAAA,OAAO,IAAI;AACb,SAAC,CAAC;;AAGK,IAAA,cAAc,CAAC,IAAY,EAAE,GAAG,QAA2B,EAAA;QAElE,MAAM,aAAa,GAAG,qBAAqB,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAG,CAAC;AACxE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAC,GAAG,GAAC,IAAI,EAAE,EAAC,OAAO,EAAC,MAAM,EAAE,YAAY,EAAC,MAAM,EAAC,CAAC,CAAC,IAAI,CAClFA,KAAG,CAAC,KAAK,IAAG;AACV,YAAA,qBAAqB,CAAC,iBAAiB,CAAC,KAAa,EAAE,aAAa,CAAC;AACrE,YAAA,OAAO,KAAY;AACrB,SAAC,CAAC,EAACA,KAAG,CAAC,KAAK,IAAG;YACb,OAAO,qBAAqB,CAAC,YAAY,CAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;SAC/D,CACF,CACF;;IAGH,gBAAgB,GAAA;AACd,QAAA,OAAO,IAAI;;AAGb,IAAA,cAAc,CAAC,OAAe,EAAA;AAC5B,QAAA,MAAM,UAAU,GAAG,IAAI,QAAQ,EAAE;AACjC,QAAA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE;AACjC,QAAA,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,qBAAqB,CAAC;AACrD,QAAA,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC;QAC5C,IAAI,KAAK,GAAC,CAAC;;AAEX,QAAA,OAAO,CAAC,OAAO,CAAE,IAAI,IAAG;YACtB,UAAU,CAAC,MAAM,CAAC,WAAW,GAAC,KAAK,EAAE,IAAI,CAAC;AAC1C,YAAA,KAAK,EAAE;AACT,SAAC,CAAC;;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAyB,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CAC/F,QAAQ,EAAG,CACZ;;8GApGQ,kBAAkB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cAFjB,MAAM,EAAA,CAAA,CAAA;;2FAEP,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAH9B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;MCRY,YAAY,CAAA;AAAzB,IAAA,WAAA,GAAA;AACW,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,cAAc,EAAE;;IAErC,wBAAwB,GAAA;AAC7B,QAAA,cAAc,CAAC,WAAW,CAAC,IAAI,qBAAqB,EAAe,CAAC;;AAG/D,IAAA,MAAM,iBAAiB,CAAE,UAAiB,EAAE,QAAsB,EAAA;AACvE,QAAA,KAAK,MAAM,UAAU,IAAI,QAAQ,EAAE;YACjC,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC;;;IAIxD,eAAe,GAAA;QACpB,OAAO,IAAI,CAAC,YAAY;;AAGnB,IAAA,mBAAmB,CAAE,UAAiB,EAAA;QAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,UAAU,CAAC;;AAEvD;;AC1BD;;AAEG;;ACFH;;AAEG;;;;"}
|
package/index.d.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xt-store",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^19.1.0",
|
|
6
|
+
"@angular/core": "^19.1.0"
|
|
7
|
+
},
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"tslib": "^2.3.0"
|
|
10
|
+
},
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"module": "fesm2022/xt-store.mjs",
|
|
13
|
+
"typings": "index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
"./package.json": {
|
|
16
|
+
"default": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./index.d.ts",
|
|
20
|
+
"default": "./fesm2022/xt-store.mjs"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
package/public-api.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './store-manager/xt-store-manager';
|
|
2
|
+
export * from './store-provider/xt-store-provider';
|
|
3
|
+
export * from './store-provider/xt-store-provider-helper';
|
|
4
|
+
export * from './store-provider/xt-memory-store-provider';
|
|
5
|
+
export * from './api-provider/xt-api-store-provider';
|
|
6
|
+
export * from './xt-store-parameters';
|
|
7
|
+
export * from './xt-document';
|
|
8
|
+
export * from './xt-reporting';
|
|
9
|
+
export * from './test/store-test-bed';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { XtStoreProvider } from '../store-provider/xt-store-provider';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { UploadedDocumentInfo } from '../xt-document';
|
|
4
|
+
import { XtStoreCriteria, XtGroupBy, XtSortBy } from '../xt-store-parameters';
|
|
5
|
+
import { DontCodeStorePreparedEntities } from '../store-provider/xt-store-provider-helper';
|
|
6
|
+
import { XtDataTransformer } from '../store-provider/xt-data-transformer';
|
|
7
|
+
export declare class XtStoreManager {
|
|
8
|
+
private _default?;
|
|
9
|
+
private providerByPosition;
|
|
10
|
+
private providerByType;
|
|
11
|
+
protected static testProvider: XtStoreProvider<any> | null;
|
|
12
|
+
constructor(provider?: XtStoreProvider<any>);
|
|
13
|
+
reset(): void;
|
|
14
|
+
getProvider<T = never>(name?: string): XtStoreProvider<T> | undefined;
|
|
15
|
+
getProviderSafe<T = never>(name?: string): XtStoreProvider<T>;
|
|
16
|
+
getDefaultProvider<T = never>(): XtStoreProvider<T> | undefined;
|
|
17
|
+
getDefaultProviderSafe<T = never>(): XtStoreProvider<T>;
|
|
18
|
+
setProvider<T = never>(value: XtStoreProvider<T>, name?: string): void;
|
|
19
|
+
setProviderForSourceType<T = never>(value: XtStoreProvider<T>, srcType: string): void;
|
|
20
|
+
setDefaultProvider<T = never>(value: XtStoreProvider<T>): void;
|
|
21
|
+
removeProvider(name?: string): void;
|
|
22
|
+
removeProviderForSourceType(srcType: string): void;
|
|
23
|
+
removeDefaultProvider(): void;
|
|
24
|
+
storeEntity<T = never>(name: string, entity: T): Promise<T>;
|
|
25
|
+
loadEntity<T = never>(name: string, key: any): Promise<T | undefined>;
|
|
26
|
+
safeLoadEntity<T = never>(name: string, key: any): Promise<T>;
|
|
27
|
+
deleteEntity(name: string, key: any): Promise<boolean>;
|
|
28
|
+
searchEntities<T = never>(name: string, ...criteria: XtStoreCriteria[]): Observable<Array<T>>;
|
|
29
|
+
searchAndPrepareEntities<T = never>(name: string, sort?: XtSortBy, groupBy?: XtGroupBy, dataTransformer?: XtDataTransformer, ...criteria: XtStoreCriteria[]): Observable<DontCodeStorePreparedEntities<T>>;
|
|
30
|
+
canStoreDocument(name?: string): boolean;
|
|
31
|
+
storeDocuments(toStore: File[], name?: string): Observable<UploadedDocumentInfo>;
|
|
32
|
+
static setTestMode(testProvider: XtStoreProvider<any>): void;
|
|
33
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enable custom transformation of data
|
|
3
|
+
*/
|
|
4
|
+
export interface XtDataTransformer<T = never> {
|
|
5
|
+
/**
|
|
6
|
+
* Enable transformation of data right after it has been loaded from the store
|
|
7
|
+
* @param source
|
|
8
|
+
*/
|
|
9
|
+
postLoadingTransformation(source: any[]): T[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AbstractXtStoreProvider } from './xt-store-provider';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { UploadedDocumentInfo } from '../xt-document';
|
|
4
|
+
import { ManagedData } from 'xt-type/src';
|
|
5
|
+
export declare class XtMemoryStoreProvider<T extends ManagedData> extends AbstractXtStoreProvider<T> {
|
|
6
|
+
protected storage: Map<string, Map<string, T>>;
|
|
7
|
+
canStoreDocument(): boolean;
|
|
8
|
+
getSafeStore(name: string): Map<string, T>;
|
|
9
|
+
deleteEntity(name: string, key: any): Promise<boolean>;
|
|
10
|
+
loadEntity(name: string, key: any): Promise<T | undefined>;
|
|
11
|
+
listEntities(name: string): Observable<T[]>;
|
|
12
|
+
storeEntity(name: string, entity: T): Promise<T>;
|
|
13
|
+
storeDocuments(toStore: File[]): Observable<UploadedDocumentInfo>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { SpecialFields } from 'xt-type';
|
|
2
|
+
import { XtGroupByAggregate, XtStoreCriteria, XtGroupBy, XtSortBy } from '../xt-store-parameters';
|
|
3
|
+
/**
|
|
4
|
+
* Helps handle metadata information about loaded items
|
|
5
|
+
*/
|
|
6
|
+
export declare class XtStoreProviderHelper {
|
|
7
|
+
static specialFieldsCache: Map<string, SpecialFields>;
|
|
8
|
+
/**
|
|
9
|
+
* In case some entity definition has changed, clear the cache
|
|
10
|
+
*/
|
|
11
|
+
static clearConfigCache(): void;
|
|
12
|
+
/**
|
|
13
|
+
* In case the provider source doesn't support search criteria, they can be applied here
|
|
14
|
+
* @param list
|
|
15
|
+
* @param criteria
|
|
16
|
+
*/
|
|
17
|
+
static applyFilters<T>(list: Array<T>, ...criteria: XtStoreCriteria[]): Array<T>;
|
|
18
|
+
/** Returns any field who is a date, in order to convert it from json. Keep the result in a cache map
|
|
19
|
+
*
|
|
20
|
+
* @param name
|
|
21
|
+
* @param entity
|
|
22
|
+
* @protected
|
|
23
|
+
*/
|
|
24
|
+
static findSpecialFields(name: string, entity: any): SpecialFields;
|
|
25
|
+
protected static findSpecialFieldsFromData(data: Array<any>, existingFields: SpecialFields): void;
|
|
26
|
+
protected static scoreIdFieldFromEntityField(prop: any, score: {
|
|
27
|
+
score: number;
|
|
28
|
+
field: any;
|
|
29
|
+
}): boolean;
|
|
30
|
+
protected static scoreIdFieldFromProperty(name: string, score: {
|
|
31
|
+
score: number;
|
|
32
|
+
field: any;
|
|
33
|
+
}): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Ensure _id is removed if necessary before saving the element
|
|
36
|
+
* @param listToConvert
|
|
37
|
+
* @param specialFields
|
|
38
|
+
* @protected
|
|
39
|
+
*/
|
|
40
|
+
static cleanUpDataBeforeSaving(listToConvert: Array<any>, specialFields: SpecialFields): void;
|
|
41
|
+
/**
|
|
42
|
+
* Converts dates and dateTimes properties of each element of the array to Typescript format
|
|
43
|
+
* Ensure _id is set with the right id
|
|
44
|
+
* @param listToConvert
|
|
45
|
+
* @param specialFields
|
|
46
|
+
* @protected
|
|
47
|
+
*/
|
|
48
|
+
static cleanUpLoadedData(listToConvert: Array<any>, specialFields: SpecialFields): void;
|
|
49
|
+
/**
|
|
50
|
+
* Sort the array using the defined sort declarations across all properties.
|
|
51
|
+
*
|
|
52
|
+
* @param toSort
|
|
53
|
+
* @param sortOptions
|
|
54
|
+
*/
|
|
55
|
+
static multiSortArray<T>(toSort: T[], sortOptions?: XtSortBy): T[];
|
|
56
|
+
/**
|
|
57
|
+
* Calculates sum, avg, min or max values per group
|
|
58
|
+
* @param values
|
|
59
|
+
* @param groupBy
|
|
60
|
+
* @param modelMgr
|
|
61
|
+
* @param position
|
|
62
|
+
* @param item
|
|
63
|
+
*/
|
|
64
|
+
static calculateGroupedByValues<T>(name: string, values: T[], groupBy: XtGroupBy): DontCodeStoreGroupedByEntities | undefined;
|
|
65
|
+
}
|
|
66
|
+
export declare class DontCodeStorePreparedEntities<T> {
|
|
67
|
+
sortedData: T[];
|
|
68
|
+
sortInfo?: XtSortBy | undefined;
|
|
69
|
+
groupedByEntities?: DontCodeStoreGroupedByEntities | undefined;
|
|
70
|
+
constructor(sortedData: T[], sortInfo?: XtSortBy | undefined, groupedByEntities?: DontCodeStoreGroupedByEntities | undefined);
|
|
71
|
+
}
|
|
72
|
+
export declare class DontCodeStoreGroupedByEntities {
|
|
73
|
+
groupInfo: XtGroupBy;
|
|
74
|
+
values?: Map<any, DontCodeStoreGroupedByValues[]> | undefined;
|
|
75
|
+
constructor(groupInfo: XtGroupBy, values?: Map<any, DontCodeStoreGroupedByValues[]> | undefined);
|
|
76
|
+
}
|
|
77
|
+
export declare class DontCodeStoreGroupedByValues {
|
|
78
|
+
forAggregate: XtGroupByAggregate;
|
|
79
|
+
value: any;
|
|
80
|
+
constructor(forAggregate: XtGroupByAggregate, value: any);
|
|
81
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { XtDataTransformer } from "./xt-data-transformer";
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { XtStoreCriteria, XtGroupBy, XtSortBy } from '../xt-store-parameters';
|
|
4
|
+
import { DontCodeStorePreparedEntities } from './xt-store-provider-helper';
|
|
5
|
+
import { UploadedDocumentInfo } from '../xt-document';
|
|
6
|
+
/**
|
|
7
|
+
* The standard interface for any store provider
|
|
8
|
+
*/
|
|
9
|
+
export type XtStoreProvider<T = never> = {
|
|
10
|
+
storeEntity(name: string, entity: T): Promise<T>;
|
|
11
|
+
/**
|
|
12
|
+
* Rejects the promise if the entity is not found
|
|
13
|
+
* @param name
|
|
14
|
+
* @param key
|
|
15
|
+
*/
|
|
16
|
+
safeLoadEntity(name: string, key: any): Promise<T>;
|
|
17
|
+
loadEntity(name: string, key: any): Promise<T | undefined>;
|
|
18
|
+
deleteEntity(name: string, key: any): Promise<boolean>;
|
|
19
|
+
searchEntities(name: string, ...criteria: XtStoreCriteria[]): Observable<Array<T>>;
|
|
20
|
+
searchAndPrepareEntities(name: string, sort?: XtSortBy, groupBy?: XtGroupBy, transformer?: XtDataTransformer<T>, ...criteria: XtStoreCriteria[]): Observable<DontCodeStorePreparedEntities<T>>;
|
|
21
|
+
canStoreDocument(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Upload documents to a server store and returns the url or the id needed to retrieve them.
|
|
24
|
+
* @param toStore
|
|
25
|
+
* @param position
|
|
26
|
+
*/
|
|
27
|
+
storeDocuments(toStore: File[]): Observable<UploadedDocumentInfo>;
|
|
28
|
+
};
|
|
29
|
+
export declare abstract class AbstractXtStoreProvider<T = never> implements XtStoreProvider<T> {
|
|
30
|
+
abstract canStoreDocument(): boolean;
|
|
31
|
+
abstract deleteEntity(name: string, key: any): Promise<boolean>;
|
|
32
|
+
abstract loadEntity(name: string, key: any): Promise<T | undefined>;
|
|
33
|
+
constructor();
|
|
34
|
+
safeLoadEntity(name: string, key: any): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* If the store supports queries with criteria, this function must be implemented, if not, listEntities must be implemented, and this function will apply filters
|
|
37
|
+
* @param position
|
|
38
|
+
* @param criteria
|
|
39
|
+
*/
|
|
40
|
+
searchEntities(name: string, ...criteria: XtStoreCriteria[]): Observable<T[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Returns the list of entities at a given position in the model. Implements at least this function or searchEntities depending on the capability of the store
|
|
43
|
+
* @param position
|
|
44
|
+
* @protected
|
|
45
|
+
*/
|
|
46
|
+
protected listEntities(name: string): Observable<T[]>;
|
|
47
|
+
searchAndPrepareEntities(name: string, sort?: XtSortBy, groupBy?: XtGroupBy, transformer?: XtDataTransformer<T>, ...criteria: XtStoreCriteria[]): Observable<DontCodeStorePreparedEntities<T>>;
|
|
48
|
+
abstract storeDocuments(toStore: File[]): Observable<UploadedDocumentInfo>;
|
|
49
|
+
abstract storeEntity(position: string, entity: T): Promise<T>;
|
|
50
|
+
protected calculateSortHierarchy(sort?: XtSortBy, groupBy?: XtGroupBy): XtSortBy | undefined;
|
|
51
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { XtStoreManager } from '../store-manager/xt-store-manager';
|
|
2
|
+
import { ManagedData } from 'xt-type';
|
|
3
|
+
import { XtStoreProvider } from '../store-provider/xt-store-provider';
|
|
4
|
+
export declare class StoreTestBed {
|
|
5
|
+
readonly storeManager: XtStoreManager;
|
|
6
|
+
ensureMemoryProviderOnly(): void;
|
|
7
|
+
defineTestDataFor(entityName: string, testData: ManagedData[]): Promise<void>;
|
|
8
|
+
getStoreManager(): XtStoreManager;
|
|
9
|
+
getStoreProviderFor(entityName: string): XtStoreProvider;
|
|
10
|
+
}
|
package/xt-document.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { XtGroupBy, XtGroupByAggregate, XtGroupByOperation, XtGroupByShow, XtSortBy, XtSortByDirection } from './xt-store-parameters';
|
|
2
|
+
export interface DontCodeReportType {
|
|
3
|
+
title: string;
|
|
4
|
+
for: string;
|
|
5
|
+
groupedBy?: {
|
|
6
|
+
[key: string]: XtGroupBy;
|
|
7
|
+
};
|
|
8
|
+
sortedBy?: {
|
|
9
|
+
[key: string]: XtSortBy;
|
|
10
|
+
};
|
|
11
|
+
as?: {
|
|
12
|
+
[key: string]: DontCodeReportDisplayType;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface DontCodeReportDisplayType {
|
|
16
|
+
type: string;
|
|
17
|
+
of: string;
|
|
18
|
+
by?: string;
|
|
19
|
+
title: string;
|
|
20
|
+
}
|
|
21
|
+
export declare class XtStoreSortBy implements XtSortBy {
|
|
22
|
+
by: string;
|
|
23
|
+
subSort?: XtSortBy | undefined;
|
|
24
|
+
direction: XtSortByDirection;
|
|
25
|
+
constructor(by: string, direction?: XtSortByDirection, subSort?: XtSortBy | undefined);
|
|
26
|
+
}
|
|
27
|
+
export declare class XtStoreGroupBy implements XtGroupBy {
|
|
28
|
+
of: string;
|
|
29
|
+
show?: XtGroupByShow | undefined;
|
|
30
|
+
display: {
|
|
31
|
+
[key: string]: XtStoreGroupByAggregate;
|
|
32
|
+
};
|
|
33
|
+
constructor(of: string, display?: {
|
|
34
|
+
[key: string]: XtStoreGroupByAggregate;
|
|
35
|
+
}, show?: XtGroupByShow | undefined);
|
|
36
|
+
atLeastOneGroupIsRequested(): boolean;
|
|
37
|
+
getRequiredListOfFields(): Set<string>;
|
|
38
|
+
}
|
|
39
|
+
export declare class XtStoreGroupByAggregate implements XtGroupByAggregate {
|
|
40
|
+
of: string;
|
|
41
|
+
operation: XtGroupByOperation;
|
|
42
|
+
constructor(of: string, operation: XtGroupByOperation);
|
|
43
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare enum XtStoreCriteriaOperator {
|
|
2
|
+
EQUALS = "=",
|
|
3
|
+
LESS_THAN = "<",
|
|
4
|
+
LESS_THAN_EQUAL = "<="
|
|
5
|
+
}
|
|
6
|
+
export declare class XtStoreCriteria {
|
|
7
|
+
name: string;
|
|
8
|
+
value: any;
|
|
9
|
+
operator: XtStoreCriteriaOperator;
|
|
10
|
+
constructor(name: string, value: any, operator?: XtStoreCriteriaOperator);
|
|
11
|
+
}
|
|
12
|
+
export type XtSortBy = {
|
|
13
|
+
by: string;
|
|
14
|
+
direction: XtSortByDirection;
|
|
15
|
+
};
|
|
16
|
+
export declare enum XtSortByDirection {
|
|
17
|
+
None = "None",
|
|
18
|
+
Ascending = "Ascending",
|
|
19
|
+
Descending = "Descending"
|
|
20
|
+
}
|
|
21
|
+
export declare enum XtGroupByShow {
|
|
22
|
+
OnlyLowest = "OnlyLowest",
|
|
23
|
+
OnlyHighest = "OnlyHighest"
|
|
24
|
+
}
|
|
25
|
+
export declare enum XtGroupByOperation {
|
|
26
|
+
Count = "Count",
|
|
27
|
+
Sum = "Sum",
|
|
28
|
+
Average = "Average",
|
|
29
|
+
Minimum = "Minimum",
|
|
30
|
+
Maximum = "Maximum"
|
|
31
|
+
}
|
|
32
|
+
export type XtGroupBy = {
|
|
33
|
+
of: string;
|
|
34
|
+
display: {
|
|
35
|
+
[key: string]: XtGroupByAggregate;
|
|
36
|
+
};
|
|
37
|
+
show?: XtGroupByShow;
|
|
38
|
+
label?: string;
|
|
39
|
+
atLeastOneGroupIsRequested(): boolean;
|
|
40
|
+
getRequiredListOfFields(): Set<string>;
|
|
41
|
+
};
|
|
42
|
+
export type XtGroupByAggregate = {
|
|
43
|
+
operation: XtGroupByOperation;
|
|
44
|
+
of: string;
|
|
45
|
+
label?: string;
|
|
46
|
+
};
|