prostgles-types 4.0.301 → 4.0.303
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/dist/files.d.ts +90 -7
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +90 -7
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts +20 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index_umd.js +1 -1
- package/dist/joinHelpers.d.ts +27 -0
- package/dist/joinHelpers.d.ts.map +1 -1
- package/dist/joinHelpers.js +15 -1
- package/dist/joinHelpers.js.map +1 -1
- package/dist/util.d.ts +12 -10
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +18 -16
- package/dist/util.js.map +1 -1
- package/lib/files.ts +90 -7
- package/lib/index.ts +23 -1
- package/lib/joinHelpers.ts +18 -2
- package/lib/util.ts +59 -30
- package/package.json +1 -1
package/lib/files.ts
CHANGED
|
@@ -5,10 +5,22 @@ export const CONTENT_TYPE_TO_EXT = {
|
|
|
5
5
|
"text/css": ["css"],
|
|
6
6
|
"text/csv": ["csv"],
|
|
7
7
|
"text/tsv": ["tsv"],
|
|
8
|
+
"text/tab-separated-values": ["tsv"],
|
|
8
9
|
"text/xml": ["xml"],
|
|
9
10
|
"text/mathml": ["mml"],
|
|
10
|
-
"text/plain": ["txt"],
|
|
11
|
-
"text/markdown": ["md", "markdown"],
|
|
11
|
+
"text/plain": ["txt", "text", "log"],
|
|
12
|
+
"text/markdown": ["md", "markdown", "qmd", "rmd"],
|
|
13
|
+
"text/x-markdown": ["md", "markdown"],
|
|
14
|
+
"text/asciidoc": ["adoc", "asciidoc", "asc"],
|
|
15
|
+
"text/x-asciidoc": ["adoc", "asciidoc", "asc"],
|
|
16
|
+
"text/x-tex": ["tex"],
|
|
17
|
+
"text/x-latex": ["tex", "latex"],
|
|
18
|
+
"text/rtf": ["rtf"],
|
|
19
|
+
"text/vtt": ["vtt"],
|
|
20
|
+
"text/calendar": ["ics", "ifb"],
|
|
21
|
+
"text/vcard": ["vcf", "vcard"],
|
|
22
|
+
"text/javascript": ["js", "mjs", "cjs"],
|
|
23
|
+
"text/yaml": ["yaml", "yml"],
|
|
12
24
|
"text/vnd.sun.j2me.app-descriptor": ["jad"],
|
|
13
25
|
"text/vnd.wap.wml": ["wml"],
|
|
14
26
|
"text/x-component": ["htc"],
|
|
@@ -16,30 +28,81 @@ export const CONTENT_TYPE_TO_EXT = {
|
|
|
16
28
|
"image/jpeg": ["jpeg", "jpg"],
|
|
17
29
|
"image/png": ["png"],
|
|
18
30
|
"image/tiff": ["tif", "tiff"],
|
|
31
|
+
"image/bmp": ["bmp"],
|
|
32
|
+
"image/avif": ["avif"],
|
|
33
|
+
"image/heic": ["heic"],
|
|
34
|
+
"image/heif": ["heif"],
|
|
19
35
|
"image/vnd.wap.wbmp": ["wbmp"],
|
|
20
36
|
"image/x-icon": ["ico"],
|
|
37
|
+
"image/vnd.microsoft.icon": ["ico"],
|
|
21
38
|
"image/x-jng": ["jng"],
|
|
22
39
|
"image/x-ms-bmp": ["bmp"],
|
|
23
40
|
"image/svg+xml": ["svg"],
|
|
24
41
|
"image/webp": ["webp"],
|
|
25
42
|
"application/sql": ["sql"],
|
|
26
43
|
"application/json": ["json"],
|
|
44
|
+
"application/xml": ["xml", "xsl", "xsd", "nxml", "xbrl", "dclg"],
|
|
45
|
+
"application/yaml": ["yaml", "yml"],
|
|
27
46
|
"application/geo+json": ["geojson"],
|
|
47
|
+
"application/javascript": ["js", "mjs", "cjs"],
|
|
28
48
|
"application/x-javascript": ["js"],
|
|
29
49
|
"application/atom+xml": ["atom"],
|
|
30
50
|
"application/rss+xml": ["rss"],
|
|
31
51
|
"application/java-archive": ["jar", "war", "ear"],
|
|
32
52
|
"application/mac-binhex40": ["hqx"],
|
|
33
|
-
"application/msword": ["doc", "docx"],
|
|
53
|
+
"application/msword": ["doc", "docx", "dot"],
|
|
54
|
+
"application/x-msword": ["doc", "dot"],
|
|
34
55
|
"application/pdf": ["pdf"],
|
|
35
56
|
"application/postscript": ["ps", "eps", "ai"],
|
|
36
57
|
"application/rtf": ["rtf"],
|
|
37
|
-
"application/
|
|
38
|
-
"application/
|
|
58
|
+
"application/x-rtf": ["rtf"],
|
|
59
|
+
"application/epub+zip": ["epub"],
|
|
60
|
+
"application/vnd.apple.pages": ["pages"],
|
|
61
|
+
"application/vnd.apple.numbers": ["numbers"],
|
|
62
|
+
"application/vnd.apple.keynote": ["key"],
|
|
63
|
+
"application/x-iwork-pages-sffpages": ["pages"],
|
|
64
|
+
"application/x-iwork-numbers-sffnumbers": ["numbers"],
|
|
65
|
+
"application/x-iwork-keynote-sffkey": ["key"],
|
|
66
|
+
"application/vnd.box.boxnote": ["boxnote"],
|
|
67
|
+
"application/vnd.ibm.modcap": ["afp"],
|
|
68
|
+
"application/x-afp": ["afp"],
|
|
69
|
+
"application/x-ebcdic": ["ebc", "ebcdic"],
|
|
70
|
+
"application/vnd.ms-excel": ["xls", "xlsx", "xlt"],
|
|
71
|
+
"application/x-msexcel": ["xls", "xlt"],
|
|
72
|
+
"application/vnd.ms-excel.sheet.macroenabled.12": ["xlsm"],
|
|
73
|
+
"application/vnd.ms-excel.sheet.binary.macroenabled.12": ["xlsb"],
|
|
74
|
+
"application/vnd.ms-excel.template.macroenabled.12": ["xltm"],
|
|
75
|
+
"application/vnd.ms-powerpoint": ["ppt", "pptx", "pot", "pps"],
|
|
76
|
+
"application/vnd.ms-powerpoint.presentation.macroenabled.12": ["pptm"],
|
|
77
|
+
"application/vnd.ms-powerpoint.template.macroenabled.12": ["potm"],
|
|
78
|
+
"application/vnd.ms-powerpoint.slideshow.macroenabled.12": ["ppsm"],
|
|
79
|
+
"application/vnd.ms-word.document.macroenabled.12": ["docm"],
|
|
80
|
+
"application/vnd.ms-word.template.macroenabled.12": ["dotm"],
|
|
81
|
+
"application/vnd.ms-outlook": ["msg"],
|
|
82
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": ["docx"],
|
|
83
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.template": ["dotx"],
|
|
84
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ["xlsx"],
|
|
85
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.template": ["xltx"],
|
|
86
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": ["pptx"],
|
|
87
|
+
"application/vnd.openxmlformats-officedocument.presentationml.template": ["potx"],
|
|
88
|
+
"application/vnd.openxmlformats-officedocument.presentationml.slideshow": ["ppsx"],
|
|
89
|
+
"application/vnd.oasis.opendocument.text": ["odt"],
|
|
90
|
+
"application/vnd.oasis.opendocument.text-template": ["ott"],
|
|
91
|
+
"application/vnd.oasis.opendocument.spreadsheet": ["ods"],
|
|
92
|
+
"application/vnd.oasis.opendocument.spreadsheet-template": ["ots"],
|
|
93
|
+
"application/vnd.oasis.opendocument.presentation": ["odp"],
|
|
94
|
+
"application/vnd.oasis.opendocument.presentation-template": ["otp"],
|
|
95
|
+
"application/vnd.oasis.opendocument.graphics": ["odg"],
|
|
39
96
|
"application/vnd.wap.wmlc": ["wmlc"],
|
|
40
97
|
"application/vnd.google-earth.kml+xml": ["kml"],
|
|
41
98
|
"application/vnd.google-earth.kmz": ["kmz"],
|
|
42
99
|
"application/x-7z-compressed": ["7z"],
|
|
100
|
+
"application/gzip": ["gz", "tgz"],
|
|
101
|
+
"application/x-tar": ["tar"],
|
|
102
|
+
"application/x-bzip2": ["bz2", "tbz2"],
|
|
103
|
+
"application/x-xz": ["xz"],
|
|
104
|
+
"application/zstd": ["zst"],
|
|
105
|
+
"application/vnd.rar": ["rar"],
|
|
43
106
|
"application/x-cocoa": ["cco"],
|
|
44
107
|
"application/x-java-archive-diff": ["jardiff"],
|
|
45
108
|
"application/x-java-jnlp-file": ["jnlp"],
|
|
@@ -52,10 +115,13 @@ export const CONTENT_TYPE_TO_EXT = {
|
|
|
52
115
|
"application/x-shockwave-flash": ["swf"],
|
|
53
116
|
"application/x-stuffit": ["sit"],
|
|
54
117
|
"application/x-tcl": ["tcl", "tk"],
|
|
118
|
+
"application/x-tex": ["tex"],
|
|
119
|
+
"application/x-latex": ["latex"],
|
|
120
|
+
"application/x-mimearchive": ["mhtml", "mht"],
|
|
55
121
|
"application/x-x509-ca-cert": ["der", "pem", "crt"],
|
|
56
122
|
"application/x-xpinstall": ["xpi"],
|
|
57
123
|
"application/xhtml+xml": ["xhtml"],
|
|
58
|
-
"application/zip": ["zip"],
|
|
124
|
+
"application/zip": ["zip", "dclx"],
|
|
59
125
|
"application/octet-stream": [
|
|
60
126
|
"bin",
|
|
61
127
|
"exe",
|
|
@@ -71,7 +137,19 @@ export const CONTENT_TYPE_TO_EXT = {
|
|
|
71
137
|
],
|
|
72
138
|
"audio/midi": ["mid", "midi", "kar"],
|
|
73
139
|
"audio/mpeg": ["mp3"],
|
|
74
|
-
"audio/
|
|
140
|
+
"audio/mp3": ["mp3"],
|
|
141
|
+
"audio/mp4": ["m4a", "mp4a", "m4b"],
|
|
142
|
+
"audio/m4a": ["m4a"],
|
|
143
|
+
"audio/x-m4a": ["m4a"],
|
|
144
|
+
"audio/aac": ["aac", "adts"],
|
|
145
|
+
"audio/wav": ["wav"],
|
|
146
|
+
"audio/x-wav": ["wav"],
|
|
147
|
+
"audio/vnd.wave": ["wav"],
|
|
148
|
+
"audio/flac": ["flac"],
|
|
149
|
+
"audio/x-flac": ["flac"],
|
|
150
|
+
"audio/ogg": ["ogg", "oga", "opus", "spx"],
|
|
151
|
+
"audio/webm": ["weba"],
|
|
152
|
+
"audio/x-aiff": ["aif", "aiff", "aifc"],
|
|
75
153
|
"audio/x-realaudio": ["ra"],
|
|
76
154
|
"video/3gpp": ["3gpp", "3gp"],
|
|
77
155
|
"video/mpeg": ["mpeg", "mpg"],
|
|
@@ -81,8 +159,13 @@ export const CONTENT_TYPE_TO_EXT = {
|
|
|
81
159
|
"video/x-ms-asf": ["asx", "asf"],
|
|
82
160
|
"video/x-ms-wmv": ["wmv"],
|
|
83
161
|
"video/x-msvideo": ["avi"],
|
|
162
|
+
"video/avi": ["avi"],
|
|
163
|
+
"video/x-matroska": ["mkv"],
|
|
84
164
|
"video/mp4": ["m4v", "mp4"],
|
|
85
165
|
"video/webm": ["webm"],
|
|
166
|
+
"video/ogg": ["ogv"],
|
|
167
|
+
"message/rfc822": ["eml", "mime", "mht", "mhtml"],
|
|
168
|
+
"multipart/related": ["mhtml", "mht"],
|
|
86
169
|
} as const;
|
|
87
170
|
|
|
88
171
|
export type ALLOWED_CONTENT_TYPE = keyof typeof CONTENT_TYPE_TO_EXT;
|
package/lib/index.ts
CHANGED
|
@@ -563,9 +563,30 @@ export type JoinPath = {
|
|
|
563
563
|
* {
|
|
564
564
|
* leftColumn: "rightColumn"
|
|
565
565
|
* }
|
|
566
|
+
* A string selects a named, server-defined computed join.
|
|
566
567
|
*/
|
|
567
|
-
on?: Record<string, string>[];
|
|
568
|
+
on?: Record<string, string>[] | string;
|
|
569
|
+
/** Parameters validated against the server-defined computed join schema. */
|
|
570
|
+
params?: Record<string, unknown>;
|
|
571
|
+
/** Reverse a computed self-join; omitted for the declared direction. */
|
|
572
|
+
reversed?: boolean;
|
|
568
573
|
};
|
|
574
|
+
|
|
575
|
+
/** Published direct relationships. SQL implementations remain on the server. */
|
|
576
|
+
export type ClientJoin = {
|
|
577
|
+
tables: [string, string];
|
|
578
|
+
} & (
|
|
579
|
+
| {
|
|
580
|
+
on: Record<string, string>[];
|
|
581
|
+
supportsMultiHop: boolean;
|
|
582
|
+
paramsSchema?: never;
|
|
583
|
+
}
|
|
584
|
+
| {
|
|
585
|
+
on: string;
|
|
586
|
+
supportsMultiHop: boolean;
|
|
587
|
+
paramsSchema?: JSONB.ObjectType["type"];
|
|
588
|
+
}
|
|
589
|
+
);
|
|
569
590
|
/**
|
|
570
591
|
* Can be either the target table name, or the sequence of tables to join through with the target table at the end.
|
|
571
592
|
*/
|
|
@@ -1641,6 +1662,7 @@ export type TableSchemaErrors = {
|
|
|
1641
1662
|
export type ClientSchema = {
|
|
1642
1663
|
rawSQL: boolean;
|
|
1643
1664
|
joinTables: string[][];
|
|
1665
|
+
joins: ClientJoin[];
|
|
1644
1666
|
auth: AuthTypes.AuthSocketSchema | undefined;
|
|
1645
1667
|
version: any;
|
|
1646
1668
|
err?: string;
|
package/lib/joinHelpers.ts
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
|
-
import type { AnyObject, DetailedJoinSelect, JoinMaker } from "./index";
|
|
1
|
+
import type { AnyObject, DetailedJoinSelect, JoinMaker, JSONB } from "./index";
|
|
2
2
|
import { omitKeys } from "./util";
|
|
3
3
|
|
|
4
4
|
/** Preserve literal table names and selections for joined return type inference. */
|
|
5
|
-
export const defineJoin = <const J extends DetailedJoinSelect>(join: J): J =>
|
|
5
|
+
export const defineJoin = <const J extends DetailedJoinSelect>(join: J): J =>
|
|
6
|
+
join;
|
|
7
|
+
|
|
8
|
+
/** Schema for an explicit, persisted join path step. */
|
|
9
|
+
export const parsedJoinPathSchema = {
|
|
10
|
+
type: {
|
|
11
|
+
table: "string",
|
|
12
|
+
on: {
|
|
13
|
+
oneOf: [
|
|
14
|
+
{ type: "string" },
|
|
15
|
+
{ arrayOf: { record: { values: "string" } } },
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
params: { record: { values: "unknown" }, optional: true },
|
|
19
|
+
reversed: { type: "boolean", optional: true },
|
|
20
|
+
},
|
|
21
|
+
} as const satisfies JSONB.JSONBSchema;
|
|
6
22
|
|
|
7
23
|
const getJoinFunc = (joinType: "$leftJoin" | "$innerJoin" = "$leftJoin") => {
|
|
8
24
|
const joinMaker: JoinMaker = (
|
package/lib/util.ts
CHANGED
|
@@ -46,7 +46,9 @@ export function filter<T extends AnyObject, ArrFilter extends Partial<T>>(
|
|
|
46
46
|
array: T[],
|
|
47
47
|
arrFilter: ArrFilter,
|
|
48
48
|
): T[] {
|
|
49
|
-
return array.filter((d) =>
|
|
49
|
+
return array.filter((d) =>
|
|
50
|
+
Object.entries(arrFilter).every(([k, v]) => d[k] === v),
|
|
51
|
+
);
|
|
50
52
|
}
|
|
51
53
|
export function find<T extends AnyObject, ArrFilter extends Partial<T>>(
|
|
52
54
|
array: T[],
|
|
@@ -125,9 +127,13 @@ export type TextPatch = {
|
|
|
125
127
|
md5: string;
|
|
126
128
|
};
|
|
127
129
|
|
|
128
|
-
export function getTextPatch(
|
|
130
|
+
export function getTextPatch(
|
|
131
|
+
oldStr: string,
|
|
132
|
+
newStr: string,
|
|
133
|
+
): TextPatch | string {
|
|
129
134
|
/* Big change, no point getting diff */
|
|
130
|
-
if (!oldStr || !newStr || !oldStr.trim().length || !newStr.trim().length)
|
|
135
|
+
if (!oldStr || !newStr || !oldStr.trim().length || !newStr.trim().length)
|
|
136
|
+
return newStr;
|
|
131
137
|
|
|
132
138
|
/* Return no change if matching */
|
|
133
139
|
if (oldStr === newStr)
|
|
@@ -172,7 +178,10 @@ export function unpatchText(original: string | null, patch: TextPatch): string {
|
|
|
172
178
|
let res = original.slice(0, from) + text + original.slice(to);
|
|
173
179
|
if (md5Hash && md5(res) !== md5Hash)
|
|
174
180
|
throw (
|
|
175
|
-
"Patch text error: Could not match md5 hash: (original/result) \n" +
|
|
181
|
+
"Patch text error: Could not match md5 hash: (original/result) \n" +
|
|
182
|
+
original +
|
|
183
|
+
"\n" +
|
|
184
|
+
res
|
|
176
185
|
);
|
|
177
186
|
return res;
|
|
178
187
|
}
|
|
@@ -211,11 +220,15 @@ export const getObjectEntries = <T extends Record<string, any>>(
|
|
|
211
220
|
export function isObject(obj: any | undefined): obj is Record<string, any> {
|
|
212
221
|
return Boolean(obj && typeof obj === "object" && !Array.isArray(obj));
|
|
213
222
|
}
|
|
214
|
-
export function isDefined<T>(
|
|
223
|
+
export function isDefined<T>(
|
|
224
|
+
v: T | undefined | void | null,
|
|
225
|
+
): v is NonNullable<T> {
|
|
215
226
|
return v !== undefined && v !== null;
|
|
216
227
|
}
|
|
217
228
|
|
|
218
|
-
export function getKeys<T extends Record<string, any>>(
|
|
229
|
+
export function getKeys<T extends Record<string, any>>(
|
|
230
|
+
o: T,
|
|
231
|
+
): (keyof T & string)[] {
|
|
219
232
|
return Object.keys(o) as unknown as (keyof T & string)[];
|
|
220
233
|
}
|
|
221
234
|
|
|
@@ -226,15 +239,18 @@ export type Explode<T> =
|
|
|
226
239
|
: never
|
|
227
240
|
: never;
|
|
228
241
|
export type AtMostOne<T> = Explode<Partial<T>>;
|
|
229
|
-
export type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> &
|
|
242
|
+
export type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> &
|
|
243
|
+
U[keyof U];
|
|
230
244
|
export type ExactlyOne<T> = AtMostOne<T> & AtLeastOne<T>;
|
|
231
245
|
|
|
232
246
|
type UnionKeys<T> = T extends T ? keyof T : never;
|
|
233
247
|
type StrictUnionHelper<T, TAll> =
|
|
234
|
-
T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>>
|
|
248
|
+
T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>>
|
|
249
|
+
: never;
|
|
235
250
|
export type StrictUnion<T> = StrictUnionHelper<T, T>;
|
|
236
251
|
|
|
237
|
-
export type PartialByKeys<T, K extends keyof T> = Omit<T, K> &
|
|
252
|
+
export type PartialByKeys<T, K extends keyof T> = Omit<T, K> &
|
|
253
|
+
Partial<Pick<T, K>>;
|
|
238
254
|
export type Simplify<T> = { [K in keyof T]: T[K] } & {};
|
|
239
255
|
|
|
240
256
|
/**
|
|
@@ -245,7 +261,11 @@ export const tryCatch = async <T extends AnyObject>(
|
|
|
245
261
|
func: () => T | Promise<T>,
|
|
246
262
|
): Promise<
|
|
247
263
|
| (T & { hasError?: false; error?: undefined; duration: number })
|
|
248
|
-
| (Partial<Record<keyof T, undefined>> & {
|
|
264
|
+
| (Partial<Record<keyof T, undefined>> & {
|
|
265
|
+
hasError: true;
|
|
266
|
+
error: unknown;
|
|
267
|
+
duration: number;
|
|
268
|
+
})
|
|
249
269
|
> => {
|
|
250
270
|
const startTime = Date.now();
|
|
251
271
|
try {
|
|
@@ -263,31 +283,36 @@ export const tryCatch = async <T extends AnyObject>(
|
|
|
263
283
|
}
|
|
264
284
|
};
|
|
265
285
|
|
|
266
|
-
export type ParsedJoinPath =
|
|
267
|
-
export const reverseJoinOn = (on:
|
|
286
|
+
export type ParsedJoinPath = JoinPath & { on: NonNullable<JoinPath["on"]> };
|
|
287
|
+
export const reverseJoinOn = (on: Record<string, string>[]) => {
|
|
268
288
|
return on.map((constraint) =>
|
|
269
|
-
Object.fromEntries(
|
|
289
|
+
Object.fromEntries(
|
|
290
|
+
Object.entries(constraint).map(([left, right]) => [right, left]),
|
|
291
|
+
),
|
|
270
292
|
);
|
|
271
293
|
};
|
|
272
294
|
|
|
273
|
-
/**
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
295
|
+
/** Reverse each join toward its source table, then reverse the path order. */
|
|
296
|
+
export const reverseParsedPath = (
|
|
297
|
+
parsedPath: ParsedJoinPath[],
|
|
298
|
+
table: string,
|
|
299
|
+
) => {
|
|
300
|
+
return (parsedPath ?? [])
|
|
301
|
+
.map(({ table: targetTable, on, params, reversed }, index) => {
|
|
302
|
+
const sourceTable = parsedPath[index - 1]?.table ?? table;
|
|
303
|
+
if (typeof on === "string") {
|
|
304
|
+
return {
|
|
305
|
+
table: sourceTable,
|
|
306
|
+
on,
|
|
307
|
+
...(params && { params }),
|
|
308
|
+
...(targetTable === sourceTable && { reversed: !reversed }),
|
|
309
|
+
};
|
|
310
|
+
}
|
|
285
311
|
return {
|
|
286
|
-
table:
|
|
287
|
-
on: reverseJoinOn(
|
|
312
|
+
table: sourceTable,
|
|
313
|
+
on: reverseJoinOn(on),
|
|
288
314
|
};
|
|
289
315
|
})
|
|
290
|
-
.filter(isDefined)
|
|
291
316
|
.reverse();
|
|
292
317
|
};
|
|
293
318
|
|
|
@@ -368,7 +393,8 @@ export const getProperty = <T extends object, K extends string>(
|
|
|
368
393
|
): K extends keyof T ? T[K]
|
|
369
394
|
: K extends string ? T[keyof T] | undefined
|
|
370
395
|
: undefined => {
|
|
371
|
-
if (!Object.keys(obj).includes(key))
|
|
396
|
+
if (!Object.keys(obj).includes(key))
|
|
397
|
+
return undefined as K extends keyof T ? T[K] : undefined;
|
|
372
398
|
return obj[key as keyof T] as K extends keyof T ? T[K] : undefined;
|
|
373
399
|
};
|
|
374
400
|
|
|
@@ -380,7 +406,10 @@ export const withTimeout = <T>(promise: Promise<T>, ms: number): Promise<T> => {
|
|
|
380
406
|
};
|
|
381
407
|
|
|
382
408
|
export const createPromiseWithTimeout = <T>(
|
|
383
|
-
executor: (
|
|
409
|
+
executor: (
|
|
410
|
+
resolve: (value: T | PromiseLike<T>) => void,
|
|
411
|
+
reject: (reason?: any) => void,
|
|
412
|
+
) => void,
|
|
384
413
|
ms: number,
|
|
385
414
|
): Promise<T> => {
|
|
386
415
|
const timeout = new Promise<never>((_, reject) =>
|