@grest-ts/common 0.0.6 → 0.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.
- package/LICENSE +21 -21
- package/README.md +81 -81
- package/dist/src/GGExtensionDiscovery.d.ts.map +1 -1
- package/dist/src/GGExtensionDiscovery.js +3 -1
- package/dist/src/GGExtensionDiscovery.js.map +1 -1
- package/dist/tsconfig.publish.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/GGAsyncStorage.ts +27 -27
- package/src/GGError.ts +74 -74
- package/src/GGExtensionDiscovery.ts +316 -314
- package/src/Secret.ts +76 -76
- package/src/UnreachableCode.ts +9 -9
- package/src/deepClone.ts +43 -43
- package/src/deepFreeze.ts +21 -21
- package/src/environment.ts +22 -22
- package/src/http.ts +51 -51
- package/src/index-browser.ts +12 -12
- package/src/index-node.ts +11 -11
- package/src/sleep.ts +2 -2
- package/src/types.ts +15 -15
- package/src/withTimeout.ts +20 -20
package/src/Secret.ts
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Secret - A wrapper for sensitive values that prevents accidental logging.
|
|
3
|
-
*
|
|
4
|
-
* Secrets are automatically redacted when:
|
|
5
|
-
* - Converted to string (toString)
|
|
6
|
-
* - Serialized to JSON (toJSON)
|
|
7
|
-
* - Logged with console.log or util.inspect
|
|
8
|
-
*
|
|
9
|
-
* To access the actual value, you must explicitly call unwrap().
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* const dbPassword = new Secret('super-secret-password');
|
|
14
|
-
*
|
|
15
|
-
* console.log(dbPassword); // "[REDACTED]"
|
|
16
|
-
* console.log(JSON.stringify(dbPassword)); // "[REDACTED]"
|
|
17
|
-
*
|
|
18
|
-
* // Explicit unwrap required to get value
|
|
19
|
-
* const password = dbPassword.unwrap();
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export class Secret {
|
|
23
|
-
#value: string;
|
|
24
|
-
constructor(value: string) {
|
|
25
|
-
this.#value = value;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Get the actual secret value.
|
|
30
|
-
* Use with care - avoid logging the result.
|
|
31
|
-
*/
|
|
32
|
-
unwrap(): string {
|
|
33
|
-
return this.#value;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Check if the secret has a non-empty value.
|
|
38
|
-
*/
|
|
39
|
-
hasValue(): boolean {
|
|
40
|
-
return this.#value.length > 0;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Compare with another secret without exposing either value.
|
|
45
|
-
*/
|
|
46
|
-
equals(other: Secret): boolean {
|
|
47
|
-
return this.#value === other.#value;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Prevent accidental logging/serialization
|
|
51
|
-
|
|
52
|
-
toString(): string {
|
|
53
|
-
return '[REDACTED]';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
toJSON(): string {
|
|
57
|
-
return '[REDACTED]';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Node.js console.log and util.inspect use this
|
|
61
|
-
[Symbol.for('nodejs.util.inspect.custom')](): string {
|
|
62
|
-
return '[REDACTED]';
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Prevent valueOf from leaking
|
|
66
|
-
valueOf(): string {
|
|
67
|
-
return '[REDACTED]';
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Type guard to check if a value is a Secret.
|
|
73
|
-
*/
|
|
74
|
-
export function isSecret(value: unknown): value is Secret {
|
|
75
|
-
return value instanceof Secret;
|
|
76
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Secret - A wrapper for sensitive values that prevents accidental logging.
|
|
3
|
+
*
|
|
4
|
+
* Secrets are automatically redacted when:
|
|
5
|
+
* - Converted to string (toString)
|
|
6
|
+
* - Serialized to JSON (toJSON)
|
|
7
|
+
* - Logged with console.log or util.inspect
|
|
8
|
+
*
|
|
9
|
+
* To access the actual value, you must explicitly call unwrap().
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const dbPassword = new Secret('super-secret-password');
|
|
14
|
+
*
|
|
15
|
+
* console.log(dbPassword); // "[REDACTED]"
|
|
16
|
+
* console.log(JSON.stringify(dbPassword)); // "[REDACTED]"
|
|
17
|
+
*
|
|
18
|
+
* // Explicit unwrap required to get value
|
|
19
|
+
* const password = dbPassword.unwrap();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class Secret {
|
|
23
|
+
#value: string;
|
|
24
|
+
constructor(value: string) {
|
|
25
|
+
this.#value = value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the actual secret value.
|
|
30
|
+
* Use with care - avoid logging the result.
|
|
31
|
+
*/
|
|
32
|
+
unwrap(): string {
|
|
33
|
+
return this.#value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check if the secret has a non-empty value.
|
|
38
|
+
*/
|
|
39
|
+
hasValue(): boolean {
|
|
40
|
+
return this.#value.length > 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Compare with another secret without exposing either value.
|
|
45
|
+
*/
|
|
46
|
+
equals(other: Secret): boolean {
|
|
47
|
+
return this.#value === other.#value;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Prevent accidental logging/serialization
|
|
51
|
+
|
|
52
|
+
toString(): string {
|
|
53
|
+
return '[REDACTED]';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
toJSON(): string {
|
|
57
|
+
return '[REDACTED]';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Node.js console.log and util.inspect use this
|
|
61
|
+
[Symbol.for('nodejs.util.inspect.custom')](): string {
|
|
62
|
+
return '[REDACTED]';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Prevent valueOf from leaking
|
|
66
|
+
valueOf(): string {
|
|
67
|
+
return '[REDACTED]';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Type guard to check if a value is a Secret.
|
|
73
|
+
*/
|
|
74
|
+
export function isSecret(value: unknown): value is Secret {
|
|
75
|
+
return value instanceof Secret;
|
|
76
|
+
}
|
package/src/UnreachableCode.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export class UnreachableCode {
|
|
2
|
-
public static never<T>(input: never, defaultValue?: T): T {
|
|
3
|
-
return defaultValue;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
public static throwNever<T>(input: never, defaultValue?: Error): T {
|
|
7
|
-
throw defaultValue;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
1
|
+
export class UnreachableCode {
|
|
2
|
+
public static never<T>(input: never, defaultValue?: T): T {
|
|
3
|
+
return defaultValue;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
public static throwNever<T>(input: never, defaultValue?: Error): T {
|
|
7
|
+
throw defaultValue;
|
|
8
|
+
}
|
|
9
|
+
}
|
package/src/deepClone.ts
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Recursively clones an object and all its nested properties.
|
|
3
|
-
* Handles: primitives, arrays, plain objects, Date, Map, Set.
|
|
4
|
-
*/
|
|
5
|
-
export function deepClone<T>(obj: T): T {
|
|
6
|
-
if (obj === null || obj === undefined) {
|
|
7
|
-
return obj;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (typeof obj !== 'object') {
|
|
11
|
-
return obj;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (obj instanceof Date) {
|
|
15
|
-
return new Date(obj.getTime()) as T;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (obj instanceof Map) {
|
|
19
|
-
const clonedMap = new Map();
|
|
20
|
-
for (const [key, value] of obj) {
|
|
21
|
-
clonedMap.set(deepClone(key), deepClone(value));
|
|
22
|
-
}
|
|
23
|
-
return clonedMap as T;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (obj instanceof Set) {
|
|
27
|
-
const clonedSet = new Set();
|
|
28
|
-
for (const value of obj) {
|
|
29
|
-
clonedSet.add(deepClone(value));
|
|
30
|
-
}
|
|
31
|
-
return clonedSet as T;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (Array.isArray(obj)) {
|
|
35
|
-
return obj.map(item => deepClone(item)) as T;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const clonedObj: Record<string, unknown> = {};
|
|
39
|
-
for (const key of Object.keys(obj)) {
|
|
40
|
-
clonedObj[key] = deepClone((obj as Record<string, unknown>)[key]);
|
|
41
|
-
}
|
|
42
|
-
return clonedObj as T;
|
|
43
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Recursively clones an object and all its nested properties.
|
|
3
|
+
* Handles: primitives, arrays, plain objects, Date, Map, Set.
|
|
4
|
+
*/
|
|
5
|
+
export function deepClone<T>(obj: T): T {
|
|
6
|
+
if (obj === null || obj === undefined) {
|
|
7
|
+
return obj;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (typeof obj !== 'object') {
|
|
11
|
+
return obj;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (obj instanceof Date) {
|
|
15
|
+
return new Date(obj.getTime()) as T;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (obj instanceof Map) {
|
|
19
|
+
const clonedMap = new Map();
|
|
20
|
+
for (const [key, value] of obj) {
|
|
21
|
+
clonedMap.set(deepClone(key), deepClone(value));
|
|
22
|
+
}
|
|
23
|
+
return clonedMap as T;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (obj instanceof Set) {
|
|
27
|
+
const clonedSet = new Set();
|
|
28
|
+
for (const value of obj) {
|
|
29
|
+
clonedSet.add(deepClone(value));
|
|
30
|
+
}
|
|
31
|
+
return clonedSet as T;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (Array.isArray(obj)) {
|
|
35
|
+
return obj.map(item => deepClone(item)) as T;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const clonedObj: Record<string, unknown> = {};
|
|
39
|
+
for (const key of Object.keys(obj)) {
|
|
40
|
+
clonedObj[key] = deepClone((obj as Record<string, unknown>)[key]);
|
|
41
|
+
}
|
|
42
|
+
return clonedObj as T;
|
|
43
|
+
}
|
package/src/deepFreeze.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Recursively freezes an object and all its nested properties.
|
|
3
|
-
* Used to create immutable objects.
|
|
4
|
-
*/
|
|
5
|
-
export function deepFreeze<T>(o: T): T {
|
|
6
|
-
if (o === undefined) {
|
|
7
|
-
return o;
|
|
8
|
-
}
|
|
9
|
-
Object.freeze(o);
|
|
10
|
-
Object.getOwnPropertyNames(o).forEach(function (prop) {
|
|
11
|
-
if (prop === "renderers") {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
if ((o as any)[prop] !== null
|
|
15
|
-
&& (typeof (o as any)[prop] === "object" || typeof (o as any)[prop] === "function")
|
|
16
|
-
&& !Object.isFrozen((o as any)[prop])) {
|
|
17
|
-
deepFreeze((o as any)[prop]);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
return o;
|
|
21
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Recursively freezes an object and all its nested properties.
|
|
3
|
+
* Used to create immutable objects.
|
|
4
|
+
*/
|
|
5
|
+
export function deepFreeze<T>(o: T): T {
|
|
6
|
+
if (o === undefined) {
|
|
7
|
+
return o;
|
|
8
|
+
}
|
|
9
|
+
Object.freeze(o);
|
|
10
|
+
Object.getOwnPropertyNames(o).forEach(function (prop) {
|
|
11
|
+
if (prop === "renderers") {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if ((o as any)[prop] !== null
|
|
15
|
+
&& (typeof (o as any)[prop] === "object" || typeof (o as any)[prop] === "function")
|
|
16
|
+
&& !Object.isFrozen((o as any)[prop])) {
|
|
17
|
+
deepFreeze((o as any)[prop]);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return o;
|
|
21
|
+
}
|
package/src/environment.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Environment detection utilities that work without DOM lib
|
|
3
|
-
* Uses type assertions to avoid TypeScript errors in Node-only contexts
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Declare window type to avoid TS errors when DOM lib is not included
|
|
7
|
-
declare const window: { document?: unknown } | undefined
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Check if code is running in a browser environment
|
|
11
|
-
* Works in both Node.js and browser contexts without requiring DOM lib
|
|
12
|
-
*/
|
|
13
|
-
export function isBrowser(): boolean {
|
|
14
|
-
return typeof window !== 'undefined' && typeof window.document !== 'undefined'
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Check if code is running in a Node.js environment
|
|
19
|
-
*/
|
|
20
|
-
export function isNode(): boolean {
|
|
21
|
-
return !isBrowser()
|
|
22
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Environment detection utilities that work without DOM lib
|
|
3
|
+
* Uses type assertions to avoid TypeScript errors in Node-only contexts
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Declare window type to avoid TS errors when DOM lib is not included
|
|
7
|
+
declare const window: { document?: unknown } | undefined
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Check if code is running in a browser environment
|
|
11
|
+
* Works in both Node.js and browser contexts without requiring DOM lib
|
|
12
|
+
*/
|
|
13
|
+
export function isBrowser(): boolean {
|
|
14
|
+
return typeof window !== 'undefined' && typeof window.document !== 'undefined'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check if code is running in a Node.js environment
|
|
19
|
+
*/
|
|
20
|
+
export function isNode(): boolean {
|
|
21
|
+
return !isBrowser()
|
|
22
|
+
}
|
package/src/http.ts
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
export enum HttpStatusCode {
|
|
2
|
-
OK200 = 200,
|
|
3
|
-
/**
|
|
4
|
-
* Completely fails to handle the request
|
|
5
|
-
*/
|
|
6
|
-
BadRequest400 = 400,
|
|
7
|
-
/**
|
|
8
|
-
* User must send auth headers or in other ways be "logged in".
|
|
9
|
-
*/
|
|
10
|
-
Unauthorized401 = 401,
|
|
11
|
-
/**
|
|
12
|
-
* User does not have access to resource
|
|
13
|
-
*/
|
|
14
|
-
Forbidden403 = 403,
|
|
15
|
-
/**
|
|
16
|
-
* Entity not found
|
|
17
|
-
*/
|
|
18
|
-
NotFound404 = 404,
|
|
19
|
-
/**
|
|
20
|
-
* Duplicate entity somewhere
|
|
21
|
-
*/
|
|
22
|
-
Exists409 = 409,
|
|
23
|
-
/**
|
|
24
|
-
* These are validation errors - automatic or manual.
|
|
25
|
-
*/
|
|
26
|
-
ValidationError422 = 422,
|
|
27
|
-
/**
|
|
28
|
-
* Method not allowed on this resource.
|
|
29
|
-
*/
|
|
30
|
-
MethodNotAllowed405 = 405,
|
|
31
|
-
/**
|
|
32
|
-
* Generic "something went wrong".
|
|
33
|
-
*/
|
|
34
|
-
InternalServerError500 = 500,
|
|
35
|
-
/**
|
|
36
|
-
* Bad Gateway - proxy/gateway received invalid response.
|
|
37
|
-
*/
|
|
38
|
-
BadGateway502 = 502,
|
|
39
|
-
/**
|
|
40
|
-
* Server is shutting down and is not able to handle the request.
|
|
41
|
-
*/
|
|
42
|
-
ServerTemporarilyNotAvailable503 = 503,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Non standard HTTP error! This is used in the test framework in case request failes because of some testing check.
|
|
47
|
-
* Request itself maybe succeeded, but some check caused it to still fail. This never comes up in production, only in automated tests.
|
|
48
|
-
*/
|
|
49
|
-
TestingError = 800
|
|
50
|
-
}
|
|
51
|
-
|
|
1
|
+
export enum HttpStatusCode {
|
|
2
|
+
OK200 = 200,
|
|
3
|
+
/**
|
|
4
|
+
* Completely fails to handle the request
|
|
5
|
+
*/
|
|
6
|
+
BadRequest400 = 400,
|
|
7
|
+
/**
|
|
8
|
+
* User must send auth headers or in other ways be "logged in".
|
|
9
|
+
*/
|
|
10
|
+
Unauthorized401 = 401,
|
|
11
|
+
/**
|
|
12
|
+
* User does not have access to resource
|
|
13
|
+
*/
|
|
14
|
+
Forbidden403 = 403,
|
|
15
|
+
/**
|
|
16
|
+
* Entity not found
|
|
17
|
+
*/
|
|
18
|
+
NotFound404 = 404,
|
|
19
|
+
/**
|
|
20
|
+
* Duplicate entity somewhere
|
|
21
|
+
*/
|
|
22
|
+
Exists409 = 409,
|
|
23
|
+
/**
|
|
24
|
+
* These are validation errors - automatic or manual.
|
|
25
|
+
*/
|
|
26
|
+
ValidationError422 = 422,
|
|
27
|
+
/**
|
|
28
|
+
* Method not allowed on this resource.
|
|
29
|
+
*/
|
|
30
|
+
MethodNotAllowed405 = 405,
|
|
31
|
+
/**
|
|
32
|
+
* Generic "something went wrong".
|
|
33
|
+
*/
|
|
34
|
+
InternalServerError500 = 500,
|
|
35
|
+
/**
|
|
36
|
+
* Bad Gateway - proxy/gateway received invalid response.
|
|
37
|
+
*/
|
|
38
|
+
BadGateway502 = 502,
|
|
39
|
+
/**
|
|
40
|
+
* Server is shutting down and is not able to handle the request.
|
|
41
|
+
*/
|
|
42
|
+
ServerTemporarilyNotAvailable503 = 503,
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Non standard HTTP error! This is used in the test framework in case request failes because of some testing check.
|
|
47
|
+
* Request itself maybe succeeded, but some check caused it to still fail. This never comes up in production, only in automated tests.
|
|
48
|
+
*/
|
|
49
|
+
TestingError = 800
|
|
50
|
+
}
|
|
51
|
+
|
|
52
52
|
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS";
|
package/src/index-browser.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export * from './deepFreeze';
|
|
2
|
-
export * from './deepClone';
|
|
3
|
-
export * from './withTimeout';
|
|
4
|
-
export * from './GGError';
|
|
5
|
-
export * from './UnreachableCode';
|
|
6
|
-
export * from './types';
|
|
7
|
-
export * from './http';
|
|
8
|
-
export * from './Secret';
|
|
9
|
-
export * from "./sleep"
|
|
10
|
-
export * from "./environment"
|
|
11
|
-
export * from "./GGAsyncStorage"
|
|
12
|
-
// GGExtensionDiscovery excluded — uses Node.js fs/path/url
|
|
1
|
+
export * from './deepFreeze';
|
|
2
|
+
export * from './deepClone';
|
|
3
|
+
export * from './withTimeout';
|
|
4
|
+
export * from './GGError';
|
|
5
|
+
export * from './UnreachableCode';
|
|
6
|
+
export * from './types';
|
|
7
|
+
export * from './http';
|
|
8
|
+
export * from './Secret';
|
|
9
|
+
export * from "./sleep"
|
|
10
|
+
export * from "./environment"
|
|
11
|
+
export * from "./GGAsyncStorage"
|
|
12
|
+
// GGExtensionDiscovery excluded — uses Node.js fs/path/url
|
package/src/index-node.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export * from './deepFreeze';
|
|
2
|
-
export * from './deepClone';
|
|
3
|
-
export * from './withTimeout';
|
|
4
|
-
export * from './GGError';
|
|
5
|
-
export * from './UnreachableCode';
|
|
6
|
-
export * from './types';
|
|
7
|
-
export * from './http';
|
|
8
|
-
export * from './Secret';
|
|
9
|
-
export * from "./sleep"
|
|
10
|
-
export * from "./environment"
|
|
11
|
-
export * from "./GGAsyncStorage"
|
|
1
|
+
export * from './deepFreeze';
|
|
2
|
+
export * from './deepClone';
|
|
3
|
+
export * from './withTimeout';
|
|
4
|
+
export * from './GGError';
|
|
5
|
+
export * from './UnreachableCode';
|
|
6
|
+
export * from './types';
|
|
7
|
+
export * from './http';
|
|
8
|
+
export * from './Secret';
|
|
9
|
+
export * from "./sleep"
|
|
10
|
+
export * from "./environment"
|
|
11
|
+
export * from "./GGAsyncStorage"
|
|
12
12
|
export * from "./GGExtensionDiscovery"
|
package/src/sleep.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function sleep(ms: number, _reason?: string): Promise<void> {
|
|
2
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
1
|
+
export function sleep(ms: number, _reason?: string): Promise<void> {
|
|
2
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
3
3
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Recursively makes all properties of an object optional.
|
|
3
|
-
* Useful for partial matching in tests and validation.
|
|
4
|
-
*/
|
|
5
|
-
export type DeepPartial<T> = T extends object
|
|
6
|
-
? T extends Array<infer U>
|
|
7
|
-
? Array<DeepPartial<U>>
|
|
8
|
-
: { [P in keyof T]?: DeepPartial<T[P]> }
|
|
9
|
-
: T
|
|
10
|
-
|
|
11
|
-
export type ConstructorOf<T> = new (...args: any[]) => T;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Returns the instance of a class. T would be the class reference.
|
|
15
|
-
*/
|
|
1
|
+
/**
|
|
2
|
+
* Recursively makes all properties of an object optional.
|
|
3
|
+
* Useful for partial matching in tests and validation.
|
|
4
|
+
*/
|
|
5
|
+
export type DeepPartial<T> = T extends object
|
|
6
|
+
? T extends Array<infer U>
|
|
7
|
+
? Array<DeepPartial<U>>
|
|
8
|
+
: { [P in keyof T]?: DeepPartial<T[P]> }
|
|
9
|
+
: T
|
|
10
|
+
|
|
11
|
+
export type ConstructorOf<T> = new (...args: any[]) => T;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Returns the instance of a class. T would be the class reference.
|
|
15
|
+
*/
|
|
16
16
|
export type InstanceOf<T> = T extends { new(...args: any[]): infer S } ? S : undefined
|
package/src/withTimeout.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wraps a promise with a timeout. If the promise doesn't resolve/reject within
|
|
3
|
-
* the specified timeout, the returned promise will reject with an error.
|
|
4
|
-
*
|
|
5
|
-
* @param promise - The promise to wrap
|
|
6
|
-
* @param timeoutMs - Timeout in milliseconds
|
|
7
|
-
* @param errorMessage - Error message to use when timeout occurs
|
|
8
|
-
* @returns A promise that resolves/rejects with the original promise or times out
|
|
9
|
-
*/
|
|
10
|
-
export async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage: string): Promise<T> {
|
|
11
|
-
let timeoutId: any;
|
|
12
|
-
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
13
|
-
timeoutId = setTimeout(() => reject(new Error(errorMessage)), timeoutMs);
|
|
14
|
-
});
|
|
15
|
-
try {
|
|
16
|
-
return await Promise.race([promise, timeoutPromise]);
|
|
17
|
-
} finally {
|
|
18
|
-
clearTimeout(timeoutId!);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Wraps a promise with a timeout. If the promise doesn't resolve/reject within
|
|
3
|
+
* the specified timeout, the returned promise will reject with an error.
|
|
4
|
+
*
|
|
5
|
+
* @param promise - The promise to wrap
|
|
6
|
+
* @param timeoutMs - Timeout in milliseconds
|
|
7
|
+
* @param errorMessage - Error message to use when timeout occurs
|
|
8
|
+
* @returns A promise that resolves/rejects with the original promise or times out
|
|
9
|
+
*/
|
|
10
|
+
export async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage: string): Promise<T> {
|
|
11
|
+
let timeoutId: any;
|
|
12
|
+
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
13
|
+
timeoutId = setTimeout(() => reject(new Error(errorMessage)), timeoutMs);
|
|
14
|
+
});
|
|
15
|
+
try {
|
|
16
|
+
return await Promise.race([promise, timeoutPromise]);
|
|
17
|
+
} finally {
|
|
18
|
+
clearTimeout(timeoutId!);
|
|
19
|
+
}
|
|
20
|
+
}
|