@adaas/a-utils 0.0.2
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/.nvmrc +1 -0
- package/LICENSE +22 -0
- package/README.md +49 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/src/constants/errors.constants.d.ts +65 -0
- package/dist/src/constants/errors.constants.js +74 -0
- package/dist/src/constants/errors.constants.js.map +1 -0
- package/dist/src/global/ASEID.class.d.ts +77 -0
- package/dist/src/global/ASEID.class.js +129 -0
- package/dist/src/global/ASEID.class.js.map +1 -0
- package/dist/src/global/A_Deferred.class.d.ts +8 -0
- package/dist/src/global/A_Deferred.class.js +19 -0
- package/dist/src/global/A_Deferred.class.js.map +1 -0
- package/dist/src/global/A_Entity.class.d.ts +49 -0
- package/dist/src/global/A_Entity.class.js +94 -0
- package/dist/src/global/A_Entity.class.js.map +1 -0
- package/dist/src/global/A_Error.class.d.ts +13 -0
- package/dist/src/global/A_Error.class.js +54 -0
- package/dist/src/global/A_Error.class.js.map +1 -0
- package/dist/src/global/A_Polyfills.d.ts +21 -0
- package/dist/src/global/A_Polyfills.js +123 -0
- package/dist/src/global/A_Polyfills.js.map +1 -0
- package/dist/src/global/A_ScheduleObject.class.d.ts +9 -0
- package/dist/src/global/A_ScheduleObject.class.js +38 -0
- package/dist/src/global/A_ScheduleObject.class.js.map +1 -0
- package/dist/src/global/A_ServerError.class.d.ts +13 -0
- package/dist/src/global/A_ServerError.class.js +57 -0
- package/dist/src/global/A_ServerError.class.js.map +1 -0
- package/dist/src/helpers/A_Common.helper.d.ts +32 -0
- package/dist/src/helpers/A_Common.helper.js +184 -0
- package/dist/src/helpers/A_Common.helper.js.map +1 -0
- package/dist/src/helpers/A_Schedule.helper.d.ts +6 -0
- package/dist/src/helpers/A_Schedule.helper.js +21 -0
- package/dist/src/helpers/A_Schedule.helper.js.map +1 -0
- package/dist/src/types/ASEID.types.d.ts +65 -0
- package/dist/src/types/ASEID.types.js +5 -0
- package/dist/src/types/ASEID.types.js.map +1 -0
- package/dist/src/types/A_Common.types.d.ts +59 -0
- package/dist/src/types/A_Common.types.js +3 -0
- package/dist/src/types/A_Common.types.js.map +1 -0
- package/dist/src/types/A_Entity.types.d.ts +13 -0
- package/dist/src/types/A_Entity.types.js +4 -0
- package/dist/src/types/A_Entity.types.js.map +1 -0
- package/dist/src/types/A_Error.type.d.ts +7 -0
- package/dist/src/types/A_Error.type.js +3 -0
- package/dist/src/types/A_Error.type.js.map +1 -0
- package/dist/src/types/A_Error.types.d.ts +7 -0
- package/dist/src/types/A_Error.types.js +3 -0
- package/dist/src/types/A_Error.types.js.map +1 -0
- package/dist/src/types/A_ScheduleObject.types.d.ts +9 -0
- package/dist/src/types/A_ScheduleObject.types.js +3 -0
- package/dist/src/types/A_ScheduleObject.types.js.map +1 -0
- package/dist/src/types/A_ServerError.types.d.ts +4 -0
- package/dist/src/types/A_ServerError.types.js +3 -0
- package/dist/src/types/A_ServerError.types.js.map +1 -0
- package/docs/a-logo-docs.png +0 -0
- package/index.ts +64 -0
- package/jest.config.ts +19 -0
- package/package.json +73 -0
- package/src/constants/errors.constants.ts +78 -0
- package/src/global/ASEID.class.ts +208 -0
- package/src/global/A_Deferred.class.ts +20 -0
- package/src/global/A_Entity.class.ts +134 -0
- package/src/global/A_Error.class.ts +75 -0
- package/src/global/A_Polyfills.ts +112 -0
- package/src/global/A_ScheduleObject.class.ts +53 -0
- package/src/global/A_ServerError.class.ts +70 -0
- package/src/helpers/A_Common.helper.ts +229 -0
- package/src/helpers/A_Schedule.helper.ts +25 -0
- package/src/types/ASEID.types.ts +86 -0
- package/src/types/A_Common.types.ts +111 -0
- package/src/types/A_Entity.types.ts +17 -0
- package/src/types/A_Error.types.ts +10 -0
- package/src/types/A_ScheduleObject.types.ts +9 -0
- package/src/types/A_ServerError.types.ts +7 -0
- package/tests/default.test.ts +160 -0
- package/tests/polyfill.test.ts +37 -0
- package/tsconfig.json +58 -0
- package/tslint.json +98 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { A_TYPES__DeepPartial } from "../types/A_Common.types";
|
|
2
|
+
|
|
3
|
+
export class A_CommonHelper {
|
|
4
|
+
|
|
5
|
+
static resolve() {
|
|
6
|
+
return new Promise<undefined>((resolve) => resolve(undefined));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static omitArrayProperties<T, S extends string>(array: Array<T>, fields: string[]): Omit<T, S>[] {
|
|
10
|
+
|
|
11
|
+
return array;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static sanitizeHTML(html: string): string {
|
|
15
|
+
// Define the regular expression pattern to match all tags except <span>
|
|
16
|
+
const regex = /<(?!\/?span(?=>|\s.*>))\/?.*?>/g;
|
|
17
|
+
|
|
18
|
+
// Replace all matched tags with an empty string
|
|
19
|
+
return html.replace(regex, '');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Omit properties from an object or array with nested objects
|
|
25
|
+
*
|
|
26
|
+
* @param input
|
|
27
|
+
* @param paths
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
static omitProperties<T, S extends string>(
|
|
31
|
+
input: T,
|
|
32
|
+
paths: string[]
|
|
33
|
+
|
|
34
|
+
): Omit<T, S> {
|
|
35
|
+
|
|
36
|
+
// Deep clone the input object or array
|
|
37
|
+
const result = JSON.parse(JSON.stringify(input));
|
|
38
|
+
|
|
39
|
+
// Helper function to recursively remove properties
|
|
40
|
+
function removeProperties(target: Record<string, any> | any[], currPath: string[]) {
|
|
41
|
+
const currKey = currPath[0];
|
|
42
|
+
if (currPath.length === 1) {
|
|
43
|
+
// If current path has only one key, delete the property
|
|
44
|
+
delete target[currKey];
|
|
45
|
+
} else if (target[currKey] !== undefined && typeof target[currKey] === 'object') {
|
|
46
|
+
// If current key exists and is an object, recursively call removeProperties
|
|
47
|
+
removeProperties(target[currKey], currPath.slice(1));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Iterate through each path and remove corresponding properties from the result
|
|
52
|
+
paths.forEach(path => {
|
|
53
|
+
const pathKeys = path.split('.');
|
|
54
|
+
removeProperties(result, pathKeys);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return result as Omit<T, S>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Format a number with leading zeros to a fixed length
|
|
63
|
+
*
|
|
64
|
+
* @param number
|
|
65
|
+
* @param maxZeros
|
|
66
|
+
* @returns
|
|
67
|
+
*/
|
|
68
|
+
static formatWithLeadingZeros(number, maxZeros = 10) {
|
|
69
|
+
const formattedNumber = String(number).padStart(maxZeros + 1, '0');
|
|
70
|
+
return formattedNumber.slice(-maxZeros);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Remove leading zeros from a formatted number
|
|
75
|
+
*/
|
|
76
|
+
static removeLeadingZeros(formattedNumber) {
|
|
77
|
+
return String(Number(formattedNumber)); // Convert to number and back to string to remove leading zeros
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
static toUpperSnakeCase(str: string): string {
|
|
83
|
+
return str
|
|
84
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2') // Handle lowercase followed by uppercase
|
|
85
|
+
.replace(/[-\s]([A-Z])/g, '_$1') // Handle non-alphabetical followed by uppercase
|
|
86
|
+
.replace('-', '_')
|
|
87
|
+
.toUpperCase();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static toCamelCase(str: string): string {
|
|
91
|
+
return str.toLowerCase().replace(/_([a-z])/g, (match, letter) => letter.toUpperCase());
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
static isObject(item: any): boolean {
|
|
97
|
+
return item !== null && typeof item === 'object' && !Array.isArray(item);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static deepMerge<T = any>(target: any, source: any, visited = new Map<any, any>()): T {
|
|
101
|
+
if (this.isObject(target) && this.isObject(source)) {
|
|
102
|
+
for (const key in source) {
|
|
103
|
+
if (this.isObject(source[key])) {
|
|
104
|
+
if (!target[key]) {
|
|
105
|
+
target[key] = {};
|
|
106
|
+
}
|
|
107
|
+
// Check if the source object has already been visited
|
|
108
|
+
if (!visited.has(source[key])) {
|
|
109
|
+
visited.set(source[key], {});
|
|
110
|
+
this.deepMerge(target[key], source[key], visited);
|
|
111
|
+
} else {
|
|
112
|
+
target[key] = visited.get(source[key]);
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
target[key] = source[key];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return target;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
static deepClone<T>(target: T): T {
|
|
124
|
+
// Check if the value is null or undefined
|
|
125
|
+
if (target === null || target === undefined) {
|
|
126
|
+
return target;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Handle primitive types (string, number, boolean, etc.)
|
|
130
|
+
if (typeof target !== 'object') {
|
|
131
|
+
return target;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Handle Date
|
|
135
|
+
if (target instanceof Date) {
|
|
136
|
+
return new Date(target.getTime()) as T;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Handle Array
|
|
140
|
+
if (Array.isArray(target)) {
|
|
141
|
+
return target.map(item => this.deepClone(item)) as unknown as T;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Handle Function
|
|
145
|
+
if (typeof target === 'function') {
|
|
146
|
+
return target;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Handle Object
|
|
150
|
+
if (target instanceof Object) {
|
|
151
|
+
const clone = {} as T;
|
|
152
|
+
for (const key in target) {
|
|
153
|
+
if (target.hasOwnProperty(key)) {
|
|
154
|
+
clone[key] = this.deepClone(target[key]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return clone;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// For any other cases
|
|
161
|
+
throw new Error('Unable to clone the object. Unsupported type.');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
static deepCloneAndMerge<T>(target: A_TYPES__DeepPartial<T>, source: T): T {
|
|
166
|
+
if (
|
|
167
|
+
(source === null || source === undefined) &&
|
|
168
|
+
(target === null || target === undefined))
|
|
169
|
+
return target;
|
|
170
|
+
|
|
171
|
+
// Check if the value is null or undefined
|
|
172
|
+
if ((target === null || target === undefined) &&
|
|
173
|
+
source
|
|
174
|
+
) {
|
|
175
|
+
return this.deepClone(source);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Handle primitive types (string, number, boolean, etc.)
|
|
179
|
+
if (typeof target !== 'object') {
|
|
180
|
+
return target
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
// Handle Date
|
|
185
|
+
if (target instanceof Date) {
|
|
186
|
+
return new Date(target.getTime()) as T;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Handle Array
|
|
190
|
+
if (Array.isArray(target)) {
|
|
191
|
+
return target.map(item => this.deepCloneAndMerge(item, source)) as unknown as T;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Handle Function
|
|
195
|
+
if (typeof target === 'function') {
|
|
196
|
+
return target;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Handle Object
|
|
200
|
+
if (target instanceof Object) {
|
|
201
|
+
const clone = {} as T;
|
|
202
|
+
for (const key in target) {
|
|
203
|
+
if (
|
|
204
|
+
source[key] !== null
|
|
205
|
+
&&
|
|
206
|
+
source[key] !== undefined
|
|
207
|
+
)
|
|
208
|
+
clone[key] = this.deepCloneAndMerge(target[key as any], source[key]);
|
|
209
|
+
else
|
|
210
|
+
clone[key as any] = this.deepClone(target[key]);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
for (const key in source) {
|
|
214
|
+
if (
|
|
215
|
+
target[key] !== undefined
|
|
216
|
+
&&
|
|
217
|
+
target[key] !== null
|
|
218
|
+
)
|
|
219
|
+
clone[key] = this.deepCloneAndMerge(target[key], source[key]);
|
|
220
|
+
else
|
|
221
|
+
clone[key] = this.deepClone(source[key]);
|
|
222
|
+
}
|
|
223
|
+
return clone;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// For any other cases
|
|
227
|
+
throw new Error('Unable to clone the object. Unsupported type.');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { A_ScheduleObject } from "../global/A_ScheduleObject.class";
|
|
2
|
+
import { A_TYPES__ScheduleObjectConfig } from "../types/A_ScheduleObject.types";
|
|
3
|
+
|
|
4
|
+
export class A_ScheduleHelper {
|
|
5
|
+
|
|
6
|
+
static delay<T = void>(ms = 1000, resolver?: Promise<T>) {
|
|
7
|
+
return new Promise<T>((resolve, reject) => setTimeout(() => {
|
|
8
|
+
if (resolver) {
|
|
9
|
+
resolver.then(resolve).catch(reject);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
resolve(0 as T);
|
|
13
|
+
}
|
|
14
|
+
}, ms))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
static schedule<T = void>(
|
|
19
|
+
ms = 1000,
|
|
20
|
+
resolver: () => Promise<T>,
|
|
21
|
+
config?: A_TYPES__ScheduleObjectConfig
|
|
22
|
+
): A_ScheduleObject<T> {
|
|
23
|
+
return new A_ScheduleObject<T>(ms, resolver, config);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export interface A_TYPES__ASEID_Constructor {
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Namespace for the ASEID
|
|
5
|
+
* Generally it is the application name or code, should correspond to the namespace of the application
|
|
6
|
+
* Could be ID or ASEID
|
|
7
|
+
*/
|
|
8
|
+
namespace?: string,
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Entity Scope the primary location of the resource
|
|
12
|
+
* Organization, or organization Unit
|
|
13
|
+
* Could be ID or ASEID
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
scope: number | string
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Entity Type the type of the resource
|
|
20
|
+
*/
|
|
21
|
+
entity: string
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Entity ID the unique identifier of the resource
|
|
25
|
+
*/
|
|
26
|
+
id: number | string
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Version of the entity (optional)
|
|
31
|
+
*/
|
|
32
|
+
version?: string
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Shard of the entity (optional)
|
|
36
|
+
*/
|
|
37
|
+
shard?: string
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
export interface A_TYPES__ASEID_ConstructorConfig {
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* If true, the entity ASEID will be distributed across multiple shards.
|
|
46
|
+
* In this case SHARD should be provided via Environment Variables (A_SHARD) or Configurations
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
sharding?: boolean
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
export type A_TYPES__ASEID_JSON = {
|
|
56
|
+
/**
|
|
57
|
+
* Namespace for the ASEID
|
|
58
|
+
*/
|
|
59
|
+
namespace: string,
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Entity Scope the primary location of the resource
|
|
63
|
+
*/
|
|
64
|
+
scope: string,
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Entity Type the type of the resource
|
|
68
|
+
*/
|
|
69
|
+
entity: string,
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Entity ID the unique identifier of the resource
|
|
73
|
+
*/
|
|
74
|
+
id: string,
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Version of the entity (optional)
|
|
78
|
+
*/
|
|
79
|
+
version?: string,
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Shard of the entity (optional)
|
|
83
|
+
*/
|
|
84
|
+
shard?: string
|
|
85
|
+
}
|
|
86
|
+
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export type A_AUTH_RequestParam = {
|
|
2
|
+
id?: string,
|
|
3
|
+
/**
|
|
4
|
+
* The issuer of the parameter. Could be system, custom, proxy, credentials or SIC to data provider service(e.g. CSS)
|
|
5
|
+
*/
|
|
6
|
+
issuer?: 'system' | 'custom' | 'proxy' | 'credentials' | string;
|
|
7
|
+
/**
|
|
8
|
+
* Common internal value, uses for proper mapping
|
|
9
|
+
*/
|
|
10
|
+
key?: string,
|
|
11
|
+
/**
|
|
12
|
+
* Allows to define the type of the parameter to convert input during the execution
|
|
13
|
+
*/
|
|
14
|
+
type: 'json' | 'array' | 'number' | 'string' | 'boolean' | 'base_64' | 'file' | 'file_url';
|
|
15
|
+
/**
|
|
16
|
+
* The name of the parameter
|
|
17
|
+
*/
|
|
18
|
+
name: string,
|
|
19
|
+
/**
|
|
20
|
+
* The value of the parameter
|
|
21
|
+
*/
|
|
22
|
+
value: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
// =======================================================
|
|
30
|
+
// ==================== COMMON TYPES =====================
|
|
31
|
+
// =======================================================
|
|
32
|
+
|
|
33
|
+
type Primitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
34
|
+
type Decrement = [never, 0, 1, 2, 3, 4, 5];
|
|
35
|
+
|
|
36
|
+
export type A_TYPES__DeepPartial<T, D extends number = 5> = {
|
|
37
|
+
[P in keyof Required<T>]?:
|
|
38
|
+
[D] extends [never] ? any :
|
|
39
|
+
|
|
40
|
+
Required<T>[P] extends Array<infer U>
|
|
41
|
+
? Array<A_TYPES__DeepPartial<U, Decrement[D]>>
|
|
42
|
+
|
|
43
|
+
: Required<T>[P] extends Function
|
|
44
|
+
? Required<T>[P]
|
|
45
|
+
|
|
46
|
+
: Required<T>[P] extends object
|
|
47
|
+
? A_TYPES__DeepPartial<T[P], Decrement[D]>
|
|
48
|
+
: T[P]
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
// export type A_TYPES__DeepPartial<T> = {
|
|
53
|
+
// [P in keyof Required<T>]?: Required<T>[P] extends object ? A_TYPES__DeepPartial<T[P]> : T[P];
|
|
54
|
+
// };
|
|
55
|
+
|
|
56
|
+
export type A_TYPES__ObjectKeyEnum<T, E> = {
|
|
57
|
+
[P in keyof Required<T>]?: T[P] extends object ? A_TYPES__ObjectKeyEnum<T[P], E> : E;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
export type A_TYPES__Dictionary<T> = {
|
|
62
|
+
[Key: string]: T;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
export type A_TYPES__NonObjectPaths<T> = T extends object ? { [K in keyof T]:
|
|
67
|
+
`${Exclude<K, symbol>}${""}`
|
|
68
|
+
}[keyof T] : never
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
export type A_TYPES__Paths<T, D extends number = 5> = [D] extends [never] ? never : (
|
|
74
|
+
T extends object ? { [K in keyof T]:
|
|
75
|
+
`${Exclude<K, symbol>}${"" | `.${A_TYPES__Paths<T[K], Decrement[D]>}`}`
|
|
76
|
+
}[keyof T] : never
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
export type A_TYPES__UnionToIntersection<U> =
|
|
80
|
+
(U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
export type A_TYPES__PathsToObject<_Obj, T extends readonly string[]> = A_TYPES__UnionToIntersection<
|
|
84
|
+
{
|
|
85
|
+
[K in keyof T]: T[K] extends `${infer Key}.${infer Rest}`
|
|
86
|
+
? { [P in Key]: P extends keyof _Obj
|
|
87
|
+
? A_TYPES__PathsToObject<Required<_Obj>[P], [Rest]>
|
|
88
|
+
: any
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
: { [P in T[K]]:
|
|
92
|
+
`${T[K]}` extends keyof Required<_Obj> ? Required<_Obj>[`${T[K]}`] : never
|
|
93
|
+
};
|
|
94
|
+
}[number]
|
|
95
|
+
>;
|
|
96
|
+
|
|
97
|
+
export type A_TYPES__Required<T, arr extends (A_TYPES__Paths<T>)[] = (A_TYPES__Paths<T>)[]> = A_TYPES__PathsToObject<T, arr> & T;
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
export type A_TYPES__ExtractNested<T, P extends string> = P extends `${infer K}.${infer Rest}`
|
|
101
|
+
? K extends keyof T
|
|
102
|
+
? { [Key in K]: A_TYPES__ExtractNested<T[K], Rest> }
|
|
103
|
+
: never
|
|
104
|
+
: P extends keyof T
|
|
105
|
+
? { [Key in P]: T[P] }
|
|
106
|
+
: never;
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
export type A_TYPES__ExtractProperties<T, P extends A_TYPES__Paths<T>[]> = A_TYPES__UnionToIntersection<{
|
|
110
|
+
[K in keyof P]: P[K] extends string ? A_TYPES__ExtractNested<T, P[K]> : never
|
|
111
|
+
}[number]>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ASEID } from "../global/ASEID.class";
|
|
2
|
+
|
|
3
|
+
export interface A_TYPES__IAEntity {
|
|
4
|
+
/**
|
|
5
|
+
* The ASEID of the entity
|
|
6
|
+
*/
|
|
7
|
+
aseid: ASEID
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export type A_TYPES__AEntity_JSON = {
|
|
12
|
+
/**
|
|
13
|
+
* The ASEID of the entity
|
|
14
|
+
*/
|
|
15
|
+
aseid: string
|
|
16
|
+
};
|
|
17
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type A_TYPES__ScheduleObjectConfig = {
|
|
2
|
+
/**
|
|
3
|
+
* If the timeout is cleared, should the promise resolve or reject?
|
|
4
|
+
* BY Default it rejects
|
|
5
|
+
*
|
|
6
|
+
* !!!NOTE: If the property is set to true, the promise will resolve with undefined
|
|
7
|
+
*/
|
|
8
|
+
resolveOnClear: boolean;
|
|
9
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { A_CommonHelper } from '@adaas/a-utils/helpers/A_Common.helper';
|
|
2
|
+
import { A_ScheduleHelper } from '@adaas/a-utils/helpers/A_Schedule.helper';
|
|
3
|
+
import { A_TYPES__DeepPartial } from '@adaas/a-utils/types/A_Common.types';
|
|
4
|
+
import { config } from 'dotenv';
|
|
5
|
+
config();
|
|
6
|
+
jest.retryTimes(0);
|
|
7
|
+
|
|
8
|
+
describe('CommonHelper Tests', () => {
|
|
9
|
+
|
|
10
|
+
it('Schedule Should execute promise and await it ', async () => {
|
|
11
|
+
|
|
12
|
+
const start = Date.now();
|
|
13
|
+
let res = '';
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const scheduler = A_ScheduleHelper.schedule(3000, async () => {
|
|
17
|
+
return 'RESOLVED';
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
res = await scheduler.promise;
|
|
22
|
+
|
|
23
|
+
} catch (error) {
|
|
24
|
+
// Handle error if any
|
|
25
|
+
} finally {
|
|
26
|
+
const end = Date.now();
|
|
27
|
+
const duration = end - start;
|
|
28
|
+
|
|
29
|
+
expect(res).toBe('RESOLVED');
|
|
30
|
+
// Check if the duration exceeds 3 seconds
|
|
31
|
+
expect(duration).toBeGreaterThan(3000);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('Schedule Should be canceled and rejected', async () => {
|
|
37
|
+
|
|
38
|
+
const start = Date.now();
|
|
39
|
+
let res = '';
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const scheduler = A_ScheduleHelper.schedule(3000, async () => {
|
|
43
|
+
return 'RESOLVED';
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
scheduler.clear();
|
|
48
|
+
res = await scheduler.promise;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
// Handle error if any
|
|
51
|
+
} finally {
|
|
52
|
+
const end = Date.now();
|
|
53
|
+
const duration = end - start;
|
|
54
|
+
|
|
55
|
+
expect(res).toBe('');
|
|
56
|
+
// Check if the duration exceeds 3 seconds
|
|
57
|
+
expect(duration).toBeLessThan(3000);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('Deep Clone and Merge ', async () => {
|
|
63
|
+
|
|
64
|
+
type TestType = {
|
|
65
|
+
a: string,
|
|
66
|
+
b: string,
|
|
67
|
+
c: {
|
|
68
|
+
d: string
|
|
69
|
+
},
|
|
70
|
+
f: (name: string) => string
|
|
71
|
+
s: Date
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const t: TestType = {
|
|
75
|
+
a: 'a',
|
|
76
|
+
b: 'b',
|
|
77
|
+
c: {
|
|
78
|
+
d: 'd'
|
|
79
|
+
},
|
|
80
|
+
f: (name: string) => { return name },
|
|
81
|
+
s: new Date()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const t2: A_TYPES__DeepPartial<TestType> = {
|
|
85
|
+
a: 'aa',
|
|
86
|
+
c: {
|
|
87
|
+
d: 'dd'
|
|
88
|
+
},
|
|
89
|
+
f: (name: string) => { return name + '2' }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const merged = A_CommonHelper.deepCloneAndMerge(t2, t);
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
const name = merged.f('names');
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
expect(merged.a).toBe('aa');
|
|
99
|
+
expect(merged.b).toBe('b');
|
|
100
|
+
expect(merged.c.d).toBe('dd');
|
|
101
|
+
expect(name).toBe('names2');
|
|
102
|
+
expect(t).not.toEqual(merged);
|
|
103
|
+
expect(t2).not.toEqual(merged);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('Deep Clone Different Types', async () => {
|
|
107
|
+
|
|
108
|
+
type TestType = {
|
|
109
|
+
a: string,
|
|
110
|
+
b: string,
|
|
111
|
+
c: {
|
|
112
|
+
d: string
|
|
113
|
+
},
|
|
114
|
+
bool:{
|
|
115
|
+
a: boolean
|
|
116
|
+
},
|
|
117
|
+
f: (name: string) => string
|
|
118
|
+
s: Date
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const t: TestType = {
|
|
122
|
+
a: 'a',
|
|
123
|
+
b: 'b',
|
|
124
|
+
c: {
|
|
125
|
+
d: 'd'
|
|
126
|
+
},
|
|
127
|
+
bool:{
|
|
128
|
+
a: true
|
|
129
|
+
},
|
|
130
|
+
f: (name: string) => { return name },
|
|
131
|
+
s: new Date()
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const t2: any = {
|
|
135
|
+
e: 'foo',
|
|
136
|
+
b: 'bb',
|
|
137
|
+
c:{
|
|
138
|
+
d: 'ddd'
|
|
139
|
+
},
|
|
140
|
+
bool:{
|
|
141
|
+
a: false
|
|
142
|
+
},
|
|
143
|
+
some: {
|
|
144
|
+
d: 'dd'
|
|
145
|
+
},
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const merged = A_CommonHelper.deepCloneAndMerge(t2, t);
|
|
149
|
+
|
|
150
|
+
console.log('merged: ', merged)
|
|
151
|
+
|
|
152
|
+
expect(merged.a).toBe('a');
|
|
153
|
+
expect(merged.b).toBe('bb');
|
|
154
|
+
expect(merged.c.d).toBe('ddd');
|
|
155
|
+
expect(merged.bool.a).toBe(false);
|
|
156
|
+
expect((merged as any).e).toBe('foo');
|
|
157
|
+
expect((merged as any).some.d).toBe('dd');
|
|
158
|
+
expect(merged.f('names')).toBe('names');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { config } from 'dotenv';
|
|
2
|
+
import { A_Polyfills } from '../src/global/A_Polyfills'
|
|
3
|
+
config();
|
|
4
|
+
jest.retryTimes(0);
|
|
5
|
+
|
|
6
|
+
describe('Polyfill Tests', () => {
|
|
7
|
+
|
|
8
|
+
it('It Should return fs', async () => {
|
|
9
|
+
|
|
10
|
+
const fs = await A_Polyfills.fs();
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
console.log('fs: ', fs)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
});
|
|
17
|
+
it('It Should return crypto', async () => {
|
|
18
|
+
|
|
19
|
+
const crypto = await A_Polyfills.crypto();
|
|
20
|
+
|
|
21
|
+
console.log('crypto: ', crypto)
|
|
22
|
+
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('Crypto should calculate Hash', async () => {
|
|
26
|
+
|
|
27
|
+
const crypto = await A_Polyfills.crypto();
|
|
28
|
+
|
|
29
|
+
const hash = await crypto.createFileHash('./index.ts', 'sha-256');
|
|
30
|
+
|
|
31
|
+
console.log('hash: ', hash)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
});
|