ngx-material-entity 20.0.5 → 20.0.7

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.
@@ -2057,6 +2057,9 @@ class EntityService {
2057
2057
  * @returns A Promise of all received Entities.
2058
2058
  */
2059
2059
  async read(baseUrl = this.baseUrl) {
2060
+ if (this.lastRead != undefined && (Date.now() - this.lastRead.getTime()) <= this.READ_EXPIRATION_IN_MS) {
2061
+ return this.entitiesSubject.value;
2062
+ }
2060
2063
  const e = await firstValueFrom(this.http.get(baseUrl));
2061
2064
  this.entitiesSubject.next(e);
2062
2065
  this.lastRead = new Date();
@@ -2204,7 +2207,7 @@ class ValidationUtilities {
2204
2207
  static async getEntityValidationErrors(entity, injector, omit) {
2205
2208
  const res = [];
2206
2209
  for (const key of EntityUtilities.keysOf(entity, injector)) {
2207
- const err = await this.getPropertyValidationError(entity, key, omit);
2210
+ const err = await this.getPropertyValidationError(entity, key, injector, omit);
2208
2211
  if (err) {
2209
2212
  res.push(err);
2210
2213
  }
@@ -2231,177 +2234,180 @@ class ValidationUtilities {
2231
2234
  * Validates the property on the given entity with the given key.
2232
2235
  * @param entity - The entity on which the property to check is.
2233
2236
  * @param key - The key of the property to validate.
2237
+ * @param injector - An angular environment injector.
2234
2238
  * @param omit - What keys not to check. An empty value means no keys are omitted.
2235
2239
  * @returns A validation error when the property is not valid, undefined otherwise.
2236
2240
  * @throws When the type of the property is not known.
2237
2241
  */
2238
- // eslint-disable-next-line sonar/cognitive-complexity
2239
- static async getPropertyValidationError(entity, key, omit) {
2240
- const type = EntityUtilities.getPropertyType(entity, key);
2241
- if (type == undefined) {
2242
- return undefined;
2243
- }
2244
- const metadata = EntityUtilities.getPropertyMetadata(entity, key, type);
2245
- // istanbul ignore next
2246
- if (metadata == undefined) {
2247
- return undefined;
2248
- }
2249
- if (metadata.omitForCreate && omit === 'create') {
2250
- return undefined;
2251
- }
2252
- if (metadata.omitForUpdate && omit === 'update') {
2253
- return undefined;
2254
- }
2255
- if (type !== DecoratorTypes.HAS_MANY && metadata.required(entity) && (entity[key] == undefined || entity[key] === '')) {
2256
- return {
2257
- property: metadata.displayName,
2258
- message: 'required'
2259
- };
2260
- }
2261
- if (!metadata.required(entity) && (entity[key] == undefined || entity[key] === '')) {
2262
- return undefined;
2263
- }
2264
- switch (type) {
2265
- case DecoratorTypes.BOOLEAN_DROPDOWN: {
2266
- // Because only valid values can be selected, this is always true when it has a value
2242
+ static async getPropertyValidationError(entity, key, injector, omit) {
2243
+ // eslint-disable-next-line sonar/cognitive-complexity
2244
+ return runInInjectionContext(injector, async () => {
2245
+ const type = EntityUtilities.getPropertyType(entity, key);
2246
+ if (type == undefined) {
2267
2247
  return undefined;
2268
2248
  }
2269
- case DecoratorTypes.BOOLEAN_CHECKBOX:
2270
- case DecoratorTypes.BOOLEAN_TOGGLE: {
2271
- const entityBoolean = entity[key];
2272
- const booleanMetadata = metadata;
2273
- return this.getBooleanValidationError(entity, entityBoolean, booleanMetadata);
2274
- }
2275
- case DecoratorTypes.STRING_DROPDOWN: {
2276
- // Because only valid values can be selected, this is always true when it has a value
2249
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key, type);
2250
+ // istanbul ignore next
2251
+ if (metadata == undefined) {
2277
2252
  return undefined;
2278
2253
  }
2279
- case DecoratorTypes.STRING: {
2280
- const entityString = entity[key];
2281
- const stringMetadata = metadata;
2282
- return this.getStringValidationError(entityString, stringMetadata);
2283
- }
2284
- case DecoratorTypes.STRING_AUTOCOMPLETE: {
2285
- const entityAutocompleteString = entity[key];
2286
- // eslint-disable-next-line stylistic/max-len
2287
- const stringAutocompleteMetadata = metadata;
2288
- return this.getAutocompleteStringValidationError(entity, entityAutocompleteString, stringAutocompleteMetadata);
2254
+ if (metadata.omitForCreate && omit === 'create') {
2255
+ return undefined;
2289
2256
  }
2290
- case DecoratorTypes.STRING_TEXTBOX: {
2291
- const entityTextbox = entity[key];
2292
- const textboxMetadata = metadata;
2293
- return this.getTextboxValidationError(entityTextbox, textboxMetadata);
2257
+ if (metadata.omitForUpdate && omit === 'update') {
2258
+ return undefined;
2294
2259
  }
2295
- case DecoratorTypes.STRING_PASSWORD: {
2296
- const entityPassword = entity[key];
2297
- const passwordMetadata = metadata;
2298
- const confirmPassword = ReflectUtilities.getMetadata(EntityUtilities.CONFIRM_PASSWORD_KEY, entity, key);
2299
- return this.getPasswordValidationError(entityPassword, passwordMetadata, confirmPassword);
2260
+ if (type !== DecoratorTypes.HAS_MANY && metadata.required(entity) && (entity[key] == undefined || entity[key] === '')) {
2261
+ return {
2262
+ property: metadata.displayName,
2263
+ message: 'required'
2264
+ };
2300
2265
  }
2301
- case DecoratorTypes.NUMBER_DROPDOWN: {
2302
- // Because only valid values can be selected, this is always true when it has a value
2266
+ if (!metadata.required(entity) && (entity[key] == undefined || entity[key] === '')) {
2303
2267
  return undefined;
2304
2268
  }
2305
- case DecoratorTypes.NUMBER:
2306
- case DecoratorTypes.NUMBER_SLIDER: {
2307
- const entityNumber = entity[key];
2308
- const numberMetadata = metadata;
2309
- return this.getNumberValidationError(entityNumber, numberMetadata);
2310
- }
2311
- case DecoratorTypes.OBJECT: {
2312
- const entityObject = entity[key];
2313
- for (const parameterKey in entityObject) {
2314
- const value = entityObject[parameterKey];
2315
- if (!metadata.omit.includes(parameterKey)
2316
- && !(!metadata.required(entity) && (value == undefined || value == ''))) {
2317
- const err = await this.getPropertyValidationError(entityObject, parameterKey, omit);
2318
- if (err) {
2319
- return {
2320
- property: metadata.displayName,
2321
- message: `${err.property} is invalid: ${err.message}`
2322
- };
2269
+ switch (type) {
2270
+ case DecoratorTypes.BOOLEAN_DROPDOWN: {
2271
+ // Because only valid values can be selected, this is always true when it has a value
2272
+ return undefined;
2273
+ }
2274
+ case DecoratorTypes.BOOLEAN_CHECKBOX:
2275
+ case DecoratorTypes.BOOLEAN_TOGGLE: {
2276
+ const entityBoolean = entity[key];
2277
+ const booleanMetadata = metadata;
2278
+ return this.getBooleanValidationError(entity, entityBoolean, booleanMetadata);
2279
+ }
2280
+ case DecoratorTypes.STRING_DROPDOWN: {
2281
+ // Because only valid values can be selected, this is always true when it has a value
2282
+ return undefined;
2283
+ }
2284
+ case DecoratorTypes.STRING: {
2285
+ const entityString = entity[key];
2286
+ const stringMetadata = metadata;
2287
+ return this.getStringValidationError(entityString, stringMetadata);
2288
+ }
2289
+ case DecoratorTypes.STRING_AUTOCOMPLETE: {
2290
+ const entityAutocompleteString = entity[key];
2291
+ // eslint-disable-next-line stylistic/max-len
2292
+ const stringAutocompleteMetadata = metadata;
2293
+ return this.getAutocompleteStringValidationError(entity, entityAutocompleteString, stringAutocompleteMetadata);
2294
+ }
2295
+ case DecoratorTypes.STRING_TEXTBOX: {
2296
+ const entityTextbox = entity[key];
2297
+ const textboxMetadata = metadata;
2298
+ return this.getTextboxValidationError(entityTextbox, textboxMetadata);
2299
+ }
2300
+ case DecoratorTypes.STRING_PASSWORD: {
2301
+ const entityPassword = entity[key];
2302
+ const passwordMetadata = metadata;
2303
+ const confirmPassword = ReflectUtilities.getMetadata(EntityUtilities.CONFIRM_PASSWORD_KEY, entity, key);
2304
+ return this.getPasswordValidationError(entityPassword, passwordMetadata, confirmPassword);
2305
+ }
2306
+ case DecoratorTypes.NUMBER_DROPDOWN: {
2307
+ // Because only valid values can be selected, this is always true when it has a value
2308
+ return undefined;
2309
+ }
2310
+ case DecoratorTypes.NUMBER:
2311
+ case DecoratorTypes.NUMBER_SLIDER: {
2312
+ const entityNumber = entity[key];
2313
+ const numberMetadata = metadata;
2314
+ return this.getNumberValidationError(entityNumber, numberMetadata);
2315
+ }
2316
+ case DecoratorTypes.OBJECT: {
2317
+ const entityObject = entity[key];
2318
+ for (const parameterKey in entityObject) {
2319
+ const value = entityObject[parameterKey];
2320
+ if (!metadata.omit.includes(parameterKey)
2321
+ && !(!metadata.required(entity) && (value == undefined || value == ''))) {
2322
+ const err = await this.getPropertyValidationError(entityObject, parameterKey, injector, omit);
2323
+ if (err) {
2324
+ return {
2325
+ property: metadata.displayName,
2326
+ message: `${err.property} is invalid: ${err.message}`
2327
+ };
2328
+ }
2323
2329
  }
2324
2330
  }
2331
+ break;
2325
2332
  }
2326
- break;
2327
- }
2328
- case DecoratorTypes.OBJECT_DROPDOWN: {
2329
- // Because only valid values can be selected, this is always true when it has a value
2330
- return undefined;
2331
- }
2332
- case DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS: {
2333
- const stringAutocompleteArray = entity[key];
2334
- // eslint-disable-next-line stylistic/max-len
2335
- const stringAutocompleteArrayMetadata = metadata;
2336
- // eslint-disable-next-line stylistic/max-len
2337
- return await this.getArrayStringAutocompleteChipsValidationError(entity, stringAutocompleteArrayMetadata, stringAutocompleteArray);
2338
- }
2339
- case DecoratorTypes.ARRAY_STRING_DROPDOWN: {
2340
- const stringDropdownArray = entity[key];
2341
- // eslint-disable-next-line stylistic/max-len
2342
- const stringDropdownArrayMetadata = metadata;
2343
- return await this.getArrayStringDropdownValidationError(entity, stringDropdownArrayMetadata, stringDropdownArray);
2344
- }
2345
- case DecoratorTypes.ARRAY_STRING_CHIPS:
2346
- case DecoratorTypes.ARRAY_DATE:
2347
- case DecoratorTypes.ARRAY_DATE_TIME:
2348
- case DecoratorTypes.ARRAY_DATE_RANGE:
2349
- case DecoratorTypes.ARRAY:
2350
- case DecoratorTypes.REFERENCES_MANY: {
2351
- const entityArray = entity[key];
2352
- // eslint-disable-next-line stylistic/max-len
2353
- const arrayMetadata = metadata;
2354
- if (arrayMetadata.required(entity) && !entityArray.length) {
2355
- return {
2356
- property: metadata.displayName,
2357
- // eslint-disable-next-line sonar/no-duplicate-string
2358
- message: 'no items in array'
2359
- };
2333
+ case DecoratorTypes.OBJECT_DROPDOWN: {
2334
+ // Because only valid values can be selected, this is always true when it has a value
2335
+ return undefined;
2360
2336
  }
2361
- break;
2362
- }
2363
- case DecoratorTypes.DATE: {
2364
- const entityDate = new Date(entity[key]);
2365
- const dateMetadata = metadata;
2366
- return this.getDateValidationError(entityDate, dateMetadata);
2367
- }
2368
- case DecoratorTypes.DATE_RANGE: {
2369
- const entityDateRange = LodashUtilities.cloneDeep(entity[key]);
2370
- const dateRangeMetadata = metadata;
2371
- return this.getDateRangeValidationError(entity, entityDateRange, dateRangeMetadata);
2372
- }
2373
- case DecoratorTypes.DATE_TIME: {
2374
- const entityDateTime = new Date(entity[key]);
2375
- const dateTimeMetadata = metadata;
2376
- const hasTime = ReflectUtilities.hasMetadata(EntityUtilities.TIME_KEY, entity, key);
2377
- return this.getDateTimeValidationError(entityDateTime, dateTimeMetadata, hasTime);
2378
- }
2379
- case DecoratorTypes.FILE_DEFAULT:
2380
- case DecoratorTypes.FILE_IMAGE: {
2381
- const entityFile = entity[key];
2382
- const entityFileMetadata = metadata;
2383
- return this.getFileDataValidationError(entityFile, entityFileMetadata);
2384
- }
2385
- case DecoratorTypes.REFERENCES_ONE:
2386
- case DecoratorTypes.HAS_MANY: {
2387
- break;
2388
- }
2389
- case DecoratorTypes.CUSTOM: {
2390
- // eslint-disable-next-line typescript/no-explicit-any, stylistic/max-len
2391
- const customMetadata = metadata;
2392
- if (!customMetadata.isValid(entity[key], omit)) {
2393
- return {
2394
- property: metadata.displayName,
2395
- message: 'invalid'
2396
- };
2337
+ case DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS: {
2338
+ const stringAutocompleteArray = entity[key];
2339
+ // eslint-disable-next-line stylistic/max-len
2340
+ const stringAutocompleteArrayMetadata = metadata;
2341
+ // eslint-disable-next-line stylistic/max-len
2342
+ return await this.getArrayStringAutocompleteChipsValidationError(entity, stringAutocompleteArrayMetadata, stringAutocompleteArray);
2343
+ }
2344
+ case DecoratorTypes.ARRAY_STRING_DROPDOWN: {
2345
+ const stringDropdownArray = entity[key];
2346
+ // eslint-disable-next-line stylistic/max-len
2347
+ const stringDropdownArrayMetadata = metadata;
2348
+ return await this.getArrayStringDropdownValidationError(entity, stringDropdownArrayMetadata, stringDropdownArray);
2349
+ }
2350
+ case DecoratorTypes.ARRAY_STRING_CHIPS:
2351
+ case DecoratorTypes.ARRAY_DATE:
2352
+ case DecoratorTypes.ARRAY_DATE_TIME:
2353
+ case DecoratorTypes.ARRAY_DATE_RANGE:
2354
+ case DecoratorTypes.ARRAY:
2355
+ case DecoratorTypes.REFERENCES_MANY: {
2356
+ const entityArray = entity[key];
2357
+ // eslint-disable-next-line stylistic/max-len
2358
+ const arrayMetadata = metadata;
2359
+ if (arrayMetadata.required(entity) && !entityArray.length) {
2360
+ return {
2361
+ property: metadata.displayName,
2362
+ // eslint-disable-next-line sonar/no-duplicate-string
2363
+ message: 'no items in array'
2364
+ };
2365
+ }
2366
+ break;
2367
+ }
2368
+ case DecoratorTypes.DATE: {
2369
+ const entityDate = new Date(entity[key]);
2370
+ const dateMetadata = metadata;
2371
+ return this.getDateValidationError(entityDate, dateMetadata);
2372
+ }
2373
+ case DecoratorTypes.DATE_RANGE: {
2374
+ const entityDateRange = LodashUtilities.cloneDeep(entity[key]);
2375
+ const dateRangeMetadata = metadata;
2376
+ return this.getDateRangeValidationError(entity, entityDateRange, dateRangeMetadata);
2377
+ }
2378
+ case DecoratorTypes.DATE_TIME: {
2379
+ const entityDateTime = new Date(entity[key]);
2380
+ const dateTimeMetadata = metadata;
2381
+ const hasTime = ReflectUtilities.hasMetadata(EntityUtilities.TIME_KEY, entity, key);
2382
+ return this.getDateTimeValidationError(entityDateTime, dateTimeMetadata, hasTime);
2383
+ }
2384
+ case DecoratorTypes.FILE_DEFAULT:
2385
+ case DecoratorTypes.FILE_IMAGE: {
2386
+ const entityFile = entity[key];
2387
+ const entityFileMetadata = metadata;
2388
+ return this.getFileDataValidationError(entityFile, entityFileMetadata);
2389
+ }
2390
+ case DecoratorTypes.REFERENCES_ONE:
2391
+ case DecoratorTypes.HAS_MANY: {
2392
+ break;
2393
+ }
2394
+ case DecoratorTypes.CUSTOM: {
2395
+ // eslint-disable-next-line typescript/no-explicit-any, stylistic/max-len
2396
+ const customMetadata = metadata;
2397
+ if (!customMetadata.isValid(entity[key], omit)) {
2398
+ return {
2399
+ property: metadata.displayName,
2400
+ message: 'invalid'
2401
+ };
2402
+ }
2403
+ break;
2404
+ }
2405
+ default: {
2406
+ throw new Error(`Could not validate the input because the DecoratorType ${type} is not known`);
2397
2407
  }
2398
- break;
2399
- }
2400
- default: {
2401
- throw new Error(`Could not validate the input because the DecoratorType ${type} is not known`);
2402
2408
  }
2403
- }
2404
- return undefined;
2409
+ return undefined;
2410
+ });
2405
2411
  }
2406
2412
  static async getArrayStringAutocompleteChipsValidationError(entity, metadata, stringAutocompleteArray) {
2407
2413
  if (metadata.required(entity) && !stringAutocompleteArray.length) {