@verisoft/core 20.0.0 → 20.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.eslintrc.json +43 -0
  2. package/jest.config.ts +22 -0
  3. package/ng-package.json +7 -0
  4. package/package.json +2 -16
  5. package/project.json +36 -0
  6. package/src/index.ts +3 -0
  7. package/src/lib/index.ts +1 -0
  8. package/src/lib/models/all-item.datasource.ts +5 -0
  9. package/src/lib/models/base-http.models.ts +144 -0
  10. package/src/lib/models/constants.ts +8 -0
  11. package/src/lib/models/datasource.model.ts +77 -0
  12. package/src/lib/models/environment.model.ts +5 -0
  13. package/src/lib/models/error-provider.model.ts +20 -0
  14. package/src/lib/models/event.models.ts +7 -0
  15. package/src/lib/models/index.ts +7 -0
  16. package/src/lib/services/base-http.service.ts +114 -0
  17. package/src/lib/services/error-provider.service.ts +33 -0
  18. package/src/lib/services/index.ts +3 -0
  19. package/src/lib/services/local-storage.service.ts +13 -0
  20. package/src/lib/services/storage.service.ts +13 -0
  21. package/src/lib/utils/array.utils.spec.ts +49 -0
  22. package/src/lib/utils/array.utils.ts +54 -0
  23. package/src/lib/utils/clear.utils.ts +53 -0
  24. package/src/lib/utils/data.utils.ts +34 -0
  25. package/src/lib/utils/date.utils.ts +30 -0
  26. package/src/lib/utils/index.ts +6 -0
  27. package/src/lib/utils/keyOrFn.utils.ts +15 -0
  28. package/src/lib/utils/object.utils.spec.ts +69 -0
  29. package/src/lib/utils/object.utils.ts +47 -0
  30. package/src/test-setup.ts +8 -0
  31. package/tsconfig.json +29 -0
  32. package/tsconfig.lib.json +17 -0
  33. package/tsconfig.lib.prod.json +9 -0
  34. package/tsconfig.spec.json +16 -0
  35. package/fesm2022/verisoft-core.mjs +0 -465
  36. package/fesm2022/verisoft-core.mjs.map +0 -1
  37. package/index.d.ts +0 -135
@@ -0,0 +1,54 @@
1
+ import { Sort } from "../models";
2
+ import { getValueByPath } from "./object.utils";
3
+
4
+ type ArrayIntersectionType = (string | number)[]
5
+
6
+ export function isArrayIntersected(
7
+ array1: ArrayIntersectionType,
8
+ array2: ArrayIntersectionType,
9
+ ) {
10
+ const filteredArray = array1.filter(value => array2.includes(value));
11
+ return filteredArray.length > 0;
12
+ }
13
+
14
+ export function multiSort<T>(values: T[], sorts: Sort[]): T[] {
15
+ return [...values].sort((a, b) => {
16
+ for (const sort of sorts) {
17
+ const { field, direction } = sort;
18
+ const valueA = getValueByPath(a, field);
19
+ const valueB = getValueByPath(b, field);
20
+
21
+ if (valueA !== valueB) {
22
+ if (isComparable(valueA) && isComparable(valueB)) {
23
+ if (typeof valueA === 'string' && typeof valueB === 'string') {
24
+ const baseCompare = valueA.localeCompare(valueB, undefined, {
25
+ sensitivity: 'base',
26
+ });
27
+
28
+ if (baseCompare === 0) {
29
+ return valueA < valueB ? -1 : valueA > valueB ? 1 : 0;
30
+ }
31
+
32
+ return direction === 'asc' ? baseCompare : -baseCompare;
33
+ } else {
34
+ if (valueA < valueB) {
35
+ return direction === 'asc' ? -1 : 1;
36
+ }
37
+ if (valueA > valueB) {
38
+ return direction === 'asc' ? 1 : -1;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ return 0;
46
+ });
47
+ }
48
+
49
+ function isComparable(value: unknown): value is string | number | Date {
50
+ return typeof value === 'string'
51
+ || typeof value === 'number'
52
+ || typeof value === 'boolean'
53
+ || value instanceof Date;
54
+ }
@@ -0,0 +1,53 @@
1
+ export class ClearUtils {
2
+
3
+ static recursiveObjectAttributesTransformation(obj: any): void {
4
+ ClearUtils.recursiveObjectAttributesTraversal(
5
+ obj,
6
+ ClearUtils.transformEmptyStringToNullStringFn
7
+ );
8
+ }
9
+ static recursiveObjectAttributesDeletation(obj: any): void {
10
+ ClearUtils.recursiveObjectAttributesTraversal(
11
+ obj,
12
+ ClearUtils.deleteEmptyStringToNullStringFn
13
+ );
14
+ }
15
+
16
+ static transformEmptyStringToNullStringFn(obj: any, key: string) {
17
+ if (typeof obj[key] === 'string' && obj[key] === '') {
18
+ obj[key] = null;
19
+ }
20
+ }
21
+ static deleteEmptyStringToNullStringFn(obj: any, key: string) {
22
+ if (obj[key] === '' || obj[key] === null || obj[key] === undefined) {
23
+ delete obj[key]
24
+ }
25
+ }
26
+
27
+
28
+ static recursiveObjectAttributesTraversal(
29
+ obj: any,
30
+ transformationFn: (obj: any, key: string) => void
31
+ ) {
32
+ if (
33
+ obj === null ||
34
+ transformationFn === null ||
35
+ typeof transformationFn !== 'function'
36
+ ) {
37
+ return;
38
+ }
39
+
40
+ Object.keys(obj).forEach((key) => {
41
+ transformationFn(obj, key);
42
+
43
+ if (typeof obj[key] === 'object') {
44
+ this.recursiveObjectAttributesTraversal(obj[key], transformationFn);
45
+
46
+ if (!Object.keys(obj[key]).length) {
47
+ delete obj[key];
48
+ }
49
+ }
50
+ });
51
+ }
52
+
53
+ }
@@ -0,0 +1,34 @@
1
+ import moment from 'moment';
2
+
3
+ export function transformData(data: any) {
4
+ if (data) {
5
+ if (moment.isMoment(data)) {
6
+ return moment(data)
7
+ .toDate()
8
+ .toISOString();
9
+ }
10
+ else if (data instanceof Date) {
11
+ return data.toISOString();
12
+ }
13
+ }
14
+ return data;
15
+ }
16
+
17
+ export function convertToDate(data: any) {
18
+ if (data) {
19
+ if (!isNaN(Date.parse(data))) {
20
+ return new Date(data);
21
+ }
22
+ }
23
+ return data;
24
+ }
25
+
26
+ export function convertToDateTime(data: any) {
27
+ if (data) {
28
+ if (!isNaN(Date.parse(data))) {
29
+ const date = new Date(data);
30
+ return moment(date).format('DD.MM.yyyy HH:mm');
31
+ }
32
+ }
33
+ return data;
34
+ }
@@ -0,0 +1,30 @@
1
+ const czechDateFormat = new Intl.DateTimeFormat("cs-CZ", {
2
+ day: "numeric",
3
+ month: "numeric",
4
+ year: "numeric"
5
+ });
6
+
7
+ const czechDateTimeFormat = new Intl.DateTimeFormat("cs-CZ", {
8
+ second: "numeric",
9
+ minute: "numeric",
10
+ hour: "numeric",
11
+ day: "numeric",
12
+ month: "numeric",
13
+ year: "numeric"
14
+ });
15
+
16
+ export function toCzechDateTimeString(value?: Date | string, time = false): string {
17
+ if (!value) {
18
+ return "";
19
+ }
20
+
21
+ if (typeof value === "string") {
22
+ value = new Date(value);
23
+ }
24
+
25
+ if (time) {
26
+ return czechDateTimeFormat.format(value);
27
+ }
28
+
29
+ return czechDateFormat.format(value);
30
+ }
@@ -0,0 +1,6 @@
1
+ export * from './clear.utils';
2
+ export * from './keyOrFn.utils';
3
+ export * from './array.utils';
4
+ export * from './data.utils';
5
+ export * from './object.utils';
6
+ export * from './date.utils';
@@ -0,0 +1,15 @@
1
+ export function keyOrFn(keyOrFn: ((row: any) => string | undefined) | string, row: any) {
2
+ if (keyOrFn instanceof Function) {
3
+ return keyOrFn(row);
4
+ }
5
+ else if (typeof keyOrFn === 'string') {
6
+ const value = row[keyOrFn];
7
+ if (value) {
8
+ return value;
9
+ }
10
+ }
11
+ else if (typeof keyOrFn === 'boolean') {
12
+ return keyOrFn;
13
+ }
14
+ return '';
15
+ }
@@ -0,0 +1,69 @@
1
+ import { getValueByPath, sortBy } from './object.utils';
2
+
3
+ describe('object.utils', () => {
4
+ describe('sortBy', () => {
5
+ const items = [
6
+ { name: undefined, age: 60 },
7
+ { name: 'Martin', age: 40 },
8
+ { name: 'Alena', age: 28 },
9
+ { name: 'Karel', age: 15 },
10
+ ];
11
+
12
+ test('Should sort items by name ascending.', () => {
13
+ const sortedItems = sortBy(items, (x) => x.name);
14
+
15
+ expect(items).not.toBe(sortedItems);
16
+ expect(sortedItems).toBeDefined();
17
+ expect(sortedItems?.[0].name).toBeUndefined();
18
+ expect(sortedItems?.[1].name).toBe('Alena');
19
+ expect(sortedItems?.[2].name).toBe('Karel');
20
+ expect(sortedItems?.[3].name).toBe('Martin');
21
+ });
22
+
23
+ test('Should sort items by name descending.', () => {
24
+ const sortedItems = sortBy(items, (x) => x.name, false);
25
+
26
+ expect(items).not.toBe(sortedItems);
27
+ expect(sortedItems).toBeDefined();
28
+ expect(sortedItems?.[0].name).toBe('Martin');
29
+ expect(sortedItems?.[1].name).toBe('Karel');
30
+ expect(sortedItems?.[2].name).toBe('Alena');
31
+ expect(sortedItems?.[3].name).toBeUndefined();
32
+ });
33
+ });
34
+
35
+ describe('getValueByPath', () => {
36
+ const complexObject = {
37
+ name: 'Martin',
38
+ age: 40,
39
+ address: {
40
+ city: 'Brno',
41
+ street: 'Kralova',
42
+ },
43
+ };
44
+
45
+ test('Should return property value when name of property is provided.', () => {
46
+ const value = getValueByPath(complexObject, 'name');
47
+
48
+ expect(value).toBe('Martin');
49
+ });
50
+
51
+ test('Should return undefined when name is nonexistent.', () => {
52
+ const value = getValueByPath(complexObject, 'nonexistentProperty');
53
+
54
+ expect(value).toBeUndefined();
55
+ });
56
+
57
+ test('Should return property value when name of property is complex path.', () => {
58
+ const value = getValueByPath(complexObject, 'address.city');
59
+
60
+ expect(value).toBe('Brno');
61
+ });
62
+
63
+ test('Should return undefined when some object on complex path missing.', () => {
64
+ const value = getValueByPath(complexObject, 'car.model');
65
+
66
+ expect(value).toBeUndefined();
67
+ });
68
+ });
69
+ });
@@ -0,0 +1,47 @@
1
+ export function sortBy<TEntity, TProperty>(
2
+ items: TEntity[],
3
+ selector: (item: TEntity) => TProperty,
4
+ ascending = true
5
+ ): TEntity[] {
6
+ return [...items].sort((item, other) => {
7
+ const value = selector(item);
8
+ const otherValue = selector(other);
9
+ const direction = ascending ? 1 : -1;
10
+ if (value == undefined && other == undefined) {
11
+ return 0;
12
+ }
13
+
14
+ if (value == undefined) {
15
+ return -1 * direction;
16
+ }
17
+ if (otherValue == undefined) {
18
+ return 1 * direction;
19
+ }
20
+
21
+ if (value < otherValue) {
22
+ return -1 * direction;
23
+ }
24
+
25
+ if (value > otherValue) {
26
+ return 1 * direction;
27
+ }
28
+
29
+ return 0;
30
+ });
31
+ }
32
+
33
+ export function getValueByPath<T, TValue>(
34
+ obj: T,
35
+ path: string | undefined,
36
+ ): TValue | undefined {
37
+ if (path == undefined || path == ''){
38
+ return obj as unknown as TValue;
39
+ }
40
+
41
+ return path.split('.').reduce((acc, key) => {
42
+ if (acc && typeof acc === 'object' && key in acc) {
43
+ return (acc as Record<string, TValue>)[key];
44
+ }
45
+ return undefined;
46
+ }, obj as unknown) as TValue;
47
+ }
@@ -0,0 +1,8 @@
1
+ // @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment
2
+ globalThis.ngJest = {
3
+ testEnvironmentOptions: {
4
+ errorOnUnknownElements: true,
5
+ errorOnUnknownProperties: true,
6
+ },
7
+ };
8
+ import 'jest-preset-angular/setup-jest';
package/tsconfig.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2022",
4
+ "useDefineForClassFields": false,
5
+ "forceConsistentCasingInFileNames": true,
6
+ "strict": true,
7
+ "noImplicitOverride": true,
8
+ "noPropertyAccessFromIndexSignature": true,
9
+ "noImplicitReturns": true,
10
+ "noFallthroughCasesInSwitch": true
11
+ },
12
+ "files": [],
13
+ "include": [],
14
+ "references": [
15
+ {
16
+ "path": "./tsconfig.lib.json"
17
+ },
18
+ {
19
+ "path": "./tsconfig.spec.json"
20
+ }
21
+ ],
22
+ "extends": "../../../tsconfig.base.json",
23
+ "angularCompilerOptions": {
24
+ "enableI18nLegacyMessageIdFormat": false,
25
+ "strictInjectionParameters": true,
26
+ "strictInputAccessModifiers": true,
27
+ "strictTemplates": true
28
+ }
29
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../../dist/out-tsc",
5
+ "declaration": true,
6
+ "declarationMap": true,
7
+ "inlineSources": true,
8
+ "types": []
9
+ },
10
+ "exclude": [
11
+ "src/**/*.spec.ts",
12
+ "src/test-setup.ts",
13
+ "jest.config.ts",
14
+ "src/**/*.test.ts"
15
+ ],
16
+ "include": ["src/**/*.ts"]
17
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.lib.json",
3
+ "compilerOptions": {
4
+ "declarationMap": false
5
+ },
6
+ "angularCompilerOptions": {
7
+ "compilationMode": "partial"
8
+ }
9
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../../dist/out-tsc",
5
+ "module": "commonjs",
6
+ "target": "es2016",
7
+ "types": ["jest", "node"]
8
+ },
9
+ "files": ["src/test-setup.ts"],
10
+ "include": [
11
+ "jest.config.ts",
12
+ "src/**/*.test.ts",
13
+ "src/**/*.spec.ts",
14
+ "src/**/*.d.ts"
15
+ ]
16
+ }