@liase/core 1.0.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.
- package/LICENSE +9 -0
- package/README.md +62 -0
- package/dist/ActionContext.d.ts +603 -0
- package/dist/ActionContext.d.ts.map +1 -0
- package/dist/ActionContext.js +227 -0
- package/dist/DomSelection.d.ts +30 -0
- package/dist/DomSelection.d.ts.map +1 -0
- package/dist/DomSelection.js +60 -0
- package/dist/Liase.d.ts +40 -0
- package/dist/Liase.d.ts.map +1 -0
- package/dist/Liase.js +105 -0
- package/dist/LiaseQuery.d.ts +593 -0
- package/dist/LiaseQuery.d.ts.map +1 -0
- package/dist/LiaseQuery.js +145 -0
- package/dist/actionHelpers.d.ts +30 -0
- package/dist/actionHelpers.d.ts.map +1 -0
- package/dist/actionHelpers.js +73 -0
- package/dist/constructorExecution.d.ts +7 -0
- package/dist/constructorExecution.d.ts.map +1 -0
- package/dist/constructorExecution.js +149 -0
- package/dist/generateResponse.d.ts +14 -0
- package/dist/generateResponse.d.ts.map +1 -0
- package/dist/generateResponse.js +88 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/lib/fetch.d.ts +10 -0
- package/dist/lib/fetch.d.ts.map +1 -0
- package/dist/lib/fetch.js +68 -0
- package/dist/lib/hooks.d.ts +7 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +13 -0
- package/dist/lib/networkRequestsCache.d.ts +23 -0
- package/dist/lib/networkRequestsCache.d.ts.map +1 -0
- package/dist/lib/networkRequestsCache.js +81 -0
- package/dist/lib/networkRequestsHistory.d.ts +21 -0
- package/dist/lib/networkRequestsHistory.d.ts.map +1 -0
- package/dist/lib/networkRequestsHistory.js +119 -0
- package/dist/lib/time.d.ts +2 -0
- package/dist/lib/time.d.ts.map +1 -0
- package/dist/lib/time.js +31 -0
- package/dist/lib/utils.d.ts +46 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +208 -0
- package/dist/lib/zod.d.ts +35 -0
- package/dist/lib/zod.d.ts.map +1 -0
- package/dist/lib/zod.js +290 -0
- package/dist/loadUrl.d.ts +45 -0
- package/dist/loadUrl.d.ts.map +1 -0
- package/dist/loadUrl.js +111 -0
- package/dist/plugins/built-in-sources/bluesky/client.d.ts +11 -0
- package/dist/plugins/built-in-sources/bluesky/client.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/bluesky/client.js +17 -0
- package/dist/plugins/built-in-sources/bluesky/index.d.ts +1115 -0
- package/dist/plugins/built-in-sources/bluesky/index.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/bluesky/index.js +14 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/feed.d.ts +378 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/feed.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/feed.js +77 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/mediaSearch.d.ts +390 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/mediaSearch.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/mediaSearch.js +87 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/singleMedia.d.ts +351 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/singleMedia.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/bluesky/requestHandlers/singleMedia.js +56 -0
- package/dist/plugins/built-in-sources/bluesky/shared.d.ts +53 -0
- package/dist/plugins/built-in-sources/bluesky/shared.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/bluesky/shared.js +127 -0
- package/dist/plugins/built-in-sources/bluesky/types.d.ts +488 -0
- package/dist/plugins/built-in-sources/bluesky/types.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/bluesky/types.js +48 -0
- package/dist/plugins/built-in-sources/giphy/index.d.ts +584 -0
- package/dist/plugins/built-in-sources/giphy/index.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/giphy/index.js +9 -0
- package/dist/plugins/built-in-sources/giphy/requestHandlers/mediaSearch.d.ts +310 -0
- package/dist/plugins/built-in-sources/giphy/requestHandlers/mediaSearch.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/giphy/requestHandlers/mediaSearch.js +71 -0
- package/dist/plugins/built-in-sources/giphy/requestHandlers/singleMedia.d.ts +274 -0
- package/dist/plugins/built-in-sources/giphy/requestHandlers/singleMedia.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/giphy/requestHandlers/singleMedia.js +43 -0
- package/dist/plugins/built-in-sources/giphy/shared.d.ts +24 -0
- package/dist/plugins/built-in-sources/giphy/shared.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/giphy/shared.js +30 -0
- package/dist/plugins/built-in-sources/giphy/types.d.ts +398 -0
- package/dist/plugins/built-in-sources/giphy/types.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/giphy/types.js +46 -0
- package/dist/plugins/built-in-sources/index.d.ts +1698 -0
- package/dist/plugins/built-in-sources/index.d.ts.map +1 -0
- package/dist/plugins/built-in-sources/index.js +5 -0
- package/dist/schemas/constructor.d.ts +14 -0
- package/dist/schemas/constructor.d.ts.map +1 -0
- package/dist/schemas/constructor.js +33 -0
- package/dist/schemas/file.d.ts +124 -0
- package/dist/schemas/file.d.ts.map +1 -0
- package/dist/schemas/file.js +28 -0
- package/dist/schemas/finderOptions.d.ts +389 -0
- package/dist/schemas/finderOptions.d.ts.map +1 -0
- package/dist/schemas/finderOptions.js +7 -0
- package/dist/schemas/media.d.ts +433 -0
- package/dist/schemas/media.d.ts.map +1 -0
- package/dist/schemas/media.js +81 -0
- package/dist/schemas/plugin.d.ts +298 -0
- package/dist/schemas/plugin.d.ts.map +1 -0
- package/dist/schemas/plugin.js +19 -0
- package/dist/schemas/primitives.d.ts +4 -0
- package/dist/schemas/primitives.d.ts.map +1 -0
- package/dist/schemas/primitives.js +11 -0
- package/dist/schemas/queryOptions.d.ts +19 -0
- package/dist/schemas/queryOptions.d.ts.map +1 -0
- package/dist/schemas/queryOptions.js +9 -0
- package/dist/schemas/request.d.ts +77 -0
- package/dist/schemas/request.d.ts.map +1 -0
- package/dist/schemas/request.js +21 -0
- package/dist/schemas/requestHandler.d.ts +126 -0
- package/dist/schemas/requestHandler.d.ts.map +1 -0
- package/dist/schemas/requestHandler.js +26 -0
- package/dist/schemas/response.d.ts +4673 -0
- package/dist/schemas/response.d.ts.map +1 -0
- package/dist/schemas/response.js +51 -0
- package/dist/schemas/secrets.d.ts +4 -0
- package/dist/schemas/secrets.d.ts.map +1 -0
- package/dist/schemas/secrets.js +2 -0
- package/dist/schemas/source.d.ts +202 -0
- package/dist/schemas/source.d.ts.map +1 -0
- package/dist/schemas/source.js +10 -0
- package/dist/test/fixtures/currentTimeSource.d.ts +53 -0
- package/dist/test/fixtures/currentTimeSource.d.ts.map +1 -0
- package/dist/test/fixtures/currentTimeSource.js +76 -0
- package/dist/test/fixtures/examplePlugin.d.ts +266 -0
- package/dist/test/fixtures/examplePlugin.d.ts.map +1 -0
- package/dist/test/fixtures/examplePlugin.js +4 -0
- package/dist/test/fixtures/exampleSource.d.ts +265 -0
- package/dist/test/fixtures/exampleSource.d.ts.map +1 -0
- package/dist/test/fixtures/exampleSource.js +107 -0
- package/dist/test/testFiles/internal/caching.test.d.ts +2 -0
- package/dist/test/testFiles/internal/caching.test.d.ts.map +1 -0
- package/dist/test/testFiles/internal/caching.test.js +116 -0
- package/dist/test/testFiles/internal/mediaTypeGuessing.test.d.ts +2 -0
- package/dist/test/testFiles/internal/mediaTypeGuessing.test.d.ts.map +1 -0
- package/dist/test/testFiles/internal/mediaTypeGuessing.test.js +86 -0
- package/dist/test/testFiles/sources/bluesky.test.d.ts +2 -0
- package/dist/test/testFiles/sources/bluesky.test.d.ts.map +1 -0
- package/dist/test/testFiles/sources/bluesky.test.js +40 -0
- package/dist/test/testFiles/sources/exampleSource.test.d.ts +2 -0
- package/dist/test/testFiles/sources/exampleSource.test.d.ts.map +1 -0
- package/dist/test/testFiles/sources/exampleSource.test.js +27 -0
- package/dist/test/testFiles/sources/giphy.test.d.ts +2 -0
- package/dist/test/testFiles/sources/giphy.test.d.ts.map +1 -0
- package/dist/test/testFiles/sources/giphy.test.js +17 -0
- package/dist/test/utils/general.d.ts +3 -0
- package/dist/test/utils/general.d.ts.map +1 -0
- package/dist/test/utils/general.js +24 -0
- package/dist/test/utils/globalSetup.d.ts +3 -0
- package/dist/test/utils/globalSetup.d.ts.map +1 -0
- package/dist/test/utils/globalSetup.js +12 -0
- package/dist/test/utils/vitest.d.ts +551 -0
- package/dist/test/utils/vitest.d.ts.map +1 -0
- package/dist/test/utils/vitest.js +166 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { OptionsInit as GotOptionsInit } from "got-scraping";
|
|
2
|
+
import type { QueryOptions } from "../schemas/queryOptions.js";
|
|
3
|
+
type CacheableRequest = {
|
|
4
|
+
url: string;
|
|
5
|
+
method: string;
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
body: string;
|
|
8
|
+
headerGeneratorOptions: GotOptionsInit["headerGeneratorOptions"];
|
|
9
|
+
};
|
|
10
|
+
type CachedResponse = {
|
|
11
|
+
body: string;
|
|
12
|
+
statusCode: number;
|
|
13
|
+
headers: Record<string, string>;
|
|
14
|
+
cachedOn: Date;
|
|
15
|
+
request: {
|
|
16
|
+
headers: Record<string, string>;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export declare function getCachedResponse(req: CacheableRequest): Promise<CachedResponse | undefined>;
|
|
20
|
+
export declare function cacheResponse(req: CacheableRequest, res: Omit<CachedResponse, "cachedOn">): Promise<void>;
|
|
21
|
+
export declare function addCachingFetchWrapper(originalFetch: typeof fetch, cacheNetworkRequests: QueryOptions["cacheNetworkRequests"]): typeof fetch;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=networkRequestsCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"networkRequestsCache.d.ts","sourceRoot":"","sources":["../../src/lib/networkRequestsCache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,IAAI,cAAc,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAK/D,KAAK,gBAAgB,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IAIb,sBAAsB,EAAE,cAAc,CAAC,wBAAwB,CAAC,CAAC;CAClE,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,QAAQ,EAAE,IAAI,CAAC;IACf,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,CAAC;CACH,CAAC;AAEF,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAoBrC;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,iBAQtC;AASD,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,OAAO,KAAK,EAC3B,oBAAoB,EAAE,YAAY,CAAC,sBAAsB,CAAC,GACzD,OAAO,KAAK,CAkDd"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import cacache from "cacache";
|
|
2
|
+
import stringify from "json-stable-stringify";
|
|
3
|
+
import { headersToNormalisedBasicObject, parseFetchArgs } from "./fetch.js";
|
|
4
|
+
const cacheDir = "/tmp/liase/network-requests-cache/custom";
|
|
5
|
+
export async function getCachedResponse(req) {
|
|
6
|
+
const key = getCacheKeyFromReq(req);
|
|
7
|
+
try {
|
|
8
|
+
const { data } = await cacache.get(cacheDir, key);
|
|
9
|
+
const cachedValue = JSON.parse(data.toString());
|
|
10
|
+
return {
|
|
11
|
+
...cachedValue,
|
|
12
|
+
cachedOn: new Date(cachedValue.cachedOn),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (typeof error === "object" &&
|
|
17
|
+
error &&
|
|
18
|
+
"code" in error &&
|
|
19
|
+
error.code === "ENOENT") {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export async function cacheResponse(req, res) {
|
|
26
|
+
const key = getCacheKeyFromReq(req);
|
|
27
|
+
const value = {
|
|
28
|
+
...res,
|
|
29
|
+
cachedOn: Date.now(),
|
|
30
|
+
};
|
|
31
|
+
await cacache.put(cacheDir, key, JSON.stringify(value));
|
|
32
|
+
}
|
|
33
|
+
function getCacheKeyFromReq(req) {
|
|
34
|
+
return (stringify([req.url, req.method, Object.entries(req.headers), req.body]) ||
|
|
35
|
+
"");
|
|
36
|
+
}
|
|
37
|
+
export function addCachingFetchWrapper(originalFetch, cacheNetworkRequests) {
|
|
38
|
+
return async (input, init) => {
|
|
39
|
+
if (cacheNetworkRequests === "auto") {
|
|
40
|
+
throw Error(`The "auto" value for the cacheNetworkRequests option is not yet supported. Sorry!`);
|
|
41
|
+
}
|
|
42
|
+
const { url, body, headers, method } = parseFetchArgs(input, init);
|
|
43
|
+
const cacheableRequest = {
|
|
44
|
+
url: url.href,
|
|
45
|
+
body: await body,
|
|
46
|
+
headers,
|
|
47
|
+
method,
|
|
48
|
+
headerGeneratorOptions: undefined,
|
|
49
|
+
};
|
|
50
|
+
let res;
|
|
51
|
+
if (cacheNetworkRequests === "always") {
|
|
52
|
+
res = await getCachedResponse(cacheableRequest);
|
|
53
|
+
if (res) {
|
|
54
|
+
return new Response(res.body, {
|
|
55
|
+
headers: res.headers,
|
|
56
|
+
status: res.statusCode,
|
|
57
|
+
statusText: `Cached on: ${res.cachedOn.getTime()}`,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
cacheNetworkRequests;
|
|
63
|
+
}
|
|
64
|
+
res = await originalFetch(input, init);
|
|
65
|
+
if (cacheNetworkRequests === "always") {
|
|
66
|
+
const clonedRes = res.clone();
|
|
67
|
+
await cacheResponse(cacheableRequest, {
|
|
68
|
+
statusCode: clonedRes.status,
|
|
69
|
+
body: await clonedRes.text(),
|
|
70
|
+
headers: headersToNormalisedBasicObject(clonedRes.headers),
|
|
71
|
+
request: {
|
|
72
|
+
headers,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
cacheNetworkRequests;
|
|
78
|
+
}
|
|
79
|
+
return res;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type NetworkRequestsHistoryItem = {
|
|
2
|
+
constructorPath: (string | number)[];
|
|
3
|
+
request: {
|
|
4
|
+
url: URL;
|
|
5
|
+
method: string;
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
body?: string | Promise<string>;
|
|
8
|
+
};
|
|
9
|
+
response: {
|
|
10
|
+
headers: Record<string, string>;
|
|
11
|
+
body: string | Promise<string>;
|
|
12
|
+
statusCode: number;
|
|
13
|
+
cached: boolean;
|
|
14
|
+
cachedOn: Date | null;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare function exportNetworkRequestsHistory({ networkRequestsHistory, }: {
|
|
18
|
+
networkRequestsHistory: NetworkRequestsHistoryItem[];
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
export declare function exportNetworkRequestsHistoryIfRelevantError(error: unknown): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=networkRequestsHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"networkRequestsHistory.d.ts","sourceRoot":"","sources":["../../src/lib/networkRequestsHistory.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,0BAA0B,GAAG;IACvC,eAAe,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACrC,OAAO,EAAE;QACP,GAAG,EAAE,GAAG,CAAC;QACT,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;KACjC,CAAC;IACF,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;KACvB,CAAC;CACH,CAAC;AAEF,wBAAsB,4BAA4B,CAAC,EACjD,sBAAsB,GACvB,EAAE;IACD,sBAAsB,EAAE,0BAA0B,EAAE,CAAC;CACtD,iBA+FA;AAED,wBAAsB,2CAA2C,CAC/D,KAAK,EAAE,OAAO,iBAgCf"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import mimeTypes from "mime-types";
|
|
7
|
+
import { ActionContext } from "../ActionContext.js";
|
|
8
|
+
import { timeSince } from "./time.js";
|
|
9
|
+
export async function exportNetworkRequestsHistory({ networkRequestsHistory, }) {
|
|
10
|
+
if (!networkRequestsHistory.length) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const tmpDir = path.join(os.tmpdir(), "liase-exports", Date.now().toString());
|
|
14
|
+
try {
|
|
15
|
+
await fs.access(tmpDir);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
await fs.mkdir(tmpDir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
const constructorPathCount = {};
|
|
21
|
+
for (const networkRequestsHistoryItem of networkRequestsHistory) {
|
|
22
|
+
const constructorPath = networkRequestsHistoryItem.constructorPath.join(".");
|
|
23
|
+
if (!constructorPathCount[constructorPath]) {
|
|
24
|
+
constructorPathCount[constructorPath] = 1;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
constructorPathCount[constructorPath]++;
|
|
28
|
+
}
|
|
29
|
+
const mimeType = networkRequestsHistoryItem.response.headers["content-type"];
|
|
30
|
+
const ext = mimeTypes.extension(mimeType ?? "") || "txt";
|
|
31
|
+
const constructorPathStr = networkRequestsHistoryItem.constructorPath
|
|
32
|
+
.map((value) => (typeof value === "number" ? `[${value}]` : value))
|
|
33
|
+
.join(".");
|
|
34
|
+
const count = constructorPathCount[constructorPath];
|
|
35
|
+
const urlPart = networkRequestsHistoryItem.request.url.href
|
|
36
|
+
.replaceAll(/(?:^\w+:\/\/|\/+$)/g, "")
|
|
37
|
+
.replaceAll("/", ".");
|
|
38
|
+
const makeBasename = (url) => `${[constructorPathStr, count, url].join("_")}.${ext}`;
|
|
39
|
+
// Most OSes enforce a 255-character limit on filenames. URLs (especially
|
|
40
|
+
// those with long query strings) can easily exceed this, so we truncate the
|
|
41
|
+
// URL portion and append a short hash to keep the name unique.
|
|
42
|
+
const MAX_BASENAME_LENGTH = 242; // 255 minus len(".metadata.txt")
|
|
43
|
+
let basename = makeBasename(urlPart);
|
|
44
|
+
if (basename.length > MAX_BASENAME_LENGTH) {
|
|
45
|
+
const hash = crypto
|
|
46
|
+
.createHash("sha256")
|
|
47
|
+
.update(urlPart)
|
|
48
|
+
.digest("hex")
|
|
49
|
+
.slice(0, 12);
|
|
50
|
+
const prefix = `${[constructorPathStr, count].join("_")}_`;
|
|
51
|
+
const suffix = `_${hash}.${ext}`;
|
|
52
|
+
const availableForUrl = MAX_BASENAME_LENGTH - prefix.length - suffix.length;
|
|
53
|
+
const truncatedUrl = availableForUrl > 0 ? urlPart.slice(0, availableForUrl) : "";
|
|
54
|
+
basename = `${prefix}${truncatedUrl}${suffix}`;
|
|
55
|
+
}
|
|
56
|
+
const filename = path.join(tmpDir, basename);
|
|
57
|
+
let body;
|
|
58
|
+
if (ext === "json") {
|
|
59
|
+
body = JSON.stringify(JSON.parse(await networkRequestsHistoryItem.response.body), null, 2);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
body = await networkRequestsHistoryItem.response.body;
|
|
63
|
+
}
|
|
64
|
+
await fs.writeFile(filename, body);
|
|
65
|
+
await fs.writeFile(`${filename}.metadata.txt`, [
|
|
66
|
+
`Request URL: ${networkRequestsHistoryItem.request.url.href}`,
|
|
67
|
+
"",
|
|
68
|
+
`Request method: ${networkRequestsHistoryItem.request.method}`,
|
|
69
|
+
"",
|
|
70
|
+
"Request headers:",
|
|
71
|
+
Object.entries(networkRequestsHistoryItem.request.headers)
|
|
72
|
+
.map(([key, value]) => ` ${key}: ${value}`)
|
|
73
|
+
.join("\n"),
|
|
74
|
+
"",
|
|
75
|
+
`Response cached: ${networkRequestsHistoryItem.response.cachedOn
|
|
76
|
+
? `Yes (${timeSince(networkRequestsHistoryItem.response.cachedOn)})`
|
|
77
|
+
: "No"}`,
|
|
78
|
+
"",
|
|
79
|
+
"Response headers:",
|
|
80
|
+
Object.entries(networkRequestsHistoryItem.response.headers)
|
|
81
|
+
.map(([key, value]) => ` ${key}: ${value}`)
|
|
82
|
+
.join("\n"),
|
|
83
|
+
"",
|
|
84
|
+
`Status code: ${networkRequestsHistoryItem.response.statusCode}`,
|
|
85
|
+
].join("\n"));
|
|
86
|
+
}
|
|
87
|
+
console.info(chalk.bold("To assist with debugging all requests made with loadUrl have been exported to:"), tmpDir);
|
|
88
|
+
}
|
|
89
|
+
export async function exportNetworkRequestsHistoryIfRelevantError(error) {
|
|
90
|
+
if (!(error instanceof Error)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
let networkRequestsHistory;
|
|
94
|
+
if ("actionContext" in error &&
|
|
95
|
+
error.actionContext instanceof ActionContext) {
|
|
96
|
+
// Most likely error is an instance of ConstructorExecutionError
|
|
97
|
+
networkRequestsHistory = error.actionContext.networkRequestsHistory;
|
|
98
|
+
}
|
|
99
|
+
else if ("context" in error && error.context instanceof ActionContext) {
|
|
100
|
+
// Most likely error is an instance of ZodFriendlyError thrown when parsing the result.
|
|
101
|
+
const rootActionContext = error.context;
|
|
102
|
+
const allActionContexts = [
|
|
103
|
+
rootActionContext,
|
|
104
|
+
...rootActionContext.descendants,
|
|
105
|
+
];
|
|
106
|
+
const networkRequestsHistorySet = new Set();
|
|
107
|
+
for (const actionContext of allActionContexts) {
|
|
108
|
+
for (const networkRequestsHistoryItem of actionContext.networkRequestsHistory) {
|
|
109
|
+
networkRequestsHistorySet.add(networkRequestsHistoryItem);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
networkRequestsHistory = [...networkRequestsHistorySet];
|
|
113
|
+
}
|
|
114
|
+
if (networkRequestsHistory) {
|
|
115
|
+
await exportNetworkRequestsHistory({
|
|
116
|
+
networkRequestsHistory,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/lib/time.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,UA4BnC"}
|
package/dist/lib/time.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const timePeriodFormatter = new Intl.RelativeTimeFormat("en", {
|
|
2
|
+
localeMatcher: "best fit",
|
|
3
|
+
numeric: "auto",
|
|
4
|
+
});
|
|
5
|
+
export function timeSince(date) {
|
|
6
|
+
if (Number.isNaN(date.getTime())) {
|
|
7
|
+
throw Error("Invalid date");
|
|
8
|
+
}
|
|
9
|
+
const seconds = Math.floor((date.getTime() - Date.now()) / 1000);
|
|
10
|
+
let interval = seconds / 31536000;
|
|
11
|
+
if (interval < -1) {
|
|
12
|
+
return timePeriodFormatter.format(Math.trunc(interval), "year");
|
|
13
|
+
}
|
|
14
|
+
interval = seconds / 2592000;
|
|
15
|
+
if (interval < -1) {
|
|
16
|
+
return timePeriodFormatter.format(Math.trunc(interval), "month");
|
|
17
|
+
}
|
|
18
|
+
interval = seconds / 86400;
|
|
19
|
+
if (interval < -1) {
|
|
20
|
+
return timePeriodFormatter.format(Math.trunc(interval), "day");
|
|
21
|
+
}
|
|
22
|
+
interval = seconds / 3600;
|
|
23
|
+
if (interval < -1) {
|
|
24
|
+
return timePeriodFormatter.format(Math.trunc(interval), "hours");
|
|
25
|
+
}
|
|
26
|
+
interval = seconds / 60;
|
|
27
|
+
if (interval < -1) {
|
|
28
|
+
return timePeriodFormatter.format(Math.trunc(interval), "minutes");
|
|
29
|
+
}
|
|
30
|
+
return timePeriodFormatter.format(Math.trunc(interval), "seconds");
|
|
31
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ActionContext } from "../ActionContext.js";
|
|
2
|
+
export declare function createCounter(): () => number;
|
|
3
|
+
export declare function getRandomIntOfScale(scale?: number): number;
|
|
4
|
+
export declare function getRandomIntInRange(min?: number, max?: number): number;
|
|
5
|
+
export declare const getUniqueId: () => string;
|
|
6
|
+
export declare function mergeInUnsetProperties(a: object, b: object): {};
|
|
7
|
+
export declare const formatObjectPath: (path: (string | number)[]) => string;
|
|
8
|
+
export declare const formatObjectPathAsTree: (path: (string | number)[], options: {
|
|
9
|
+
lineIndent?: number;
|
|
10
|
+
overallIndent?: number;
|
|
11
|
+
lastNodeExtraInfo?: string;
|
|
12
|
+
}) => string;
|
|
13
|
+
declare const returnType: (v: unknown) => "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
|
|
14
|
+
type TypeOfTypes = ReturnType<typeof returnType>;
|
|
15
|
+
export declare const capitaliseType: (type: TypeOfTypes | "array" | "set" | "date") => string;
|
|
16
|
+
type ConstructorExecutionErrorOptions = {
|
|
17
|
+
cause?: Error;
|
|
18
|
+
log: string[];
|
|
19
|
+
message?: string;
|
|
20
|
+
actionContext: ActionContext;
|
|
21
|
+
};
|
|
22
|
+
export declare class ConstructorExecutionError extends Error {
|
|
23
|
+
errorOccurredAtPath: (string | number)[];
|
|
24
|
+
log: string[];
|
|
25
|
+
actionContext: ActionContext;
|
|
26
|
+
constructor({ message, cause, actionContext, log, }: ConstructorExecutionErrorOptions);
|
|
27
|
+
getFormattedErrorInfo(): string;
|
|
28
|
+
}
|
|
29
|
+
type ValueType = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "array";
|
|
30
|
+
export declare const getType: (value: unknown) => ValueType;
|
|
31
|
+
export declare function hasNoDuplicates(array: unknown[]): boolean;
|
|
32
|
+
export declare function getDuplicates<T>(array: T[]): T[];
|
|
33
|
+
export declare function getOrdinal(number: number): string;
|
|
34
|
+
export declare function getPromiseWithResolvers<Expected = unknown>(): {
|
|
35
|
+
promise: Promise<Expected>;
|
|
36
|
+
resolve: (value: Expected) => void;
|
|
37
|
+
reject: (reason?: any) => void;
|
|
38
|
+
};
|
|
39
|
+
export type ObjectEntry<BaseType> = [keyof BaseType, BaseType[keyof BaseType]];
|
|
40
|
+
export declare function waitForAllPropertiesToResolve<ObjectWithPromises>(object: {
|
|
41
|
+
[key in keyof ObjectWithPromises]: ObjectWithPromises[key];
|
|
42
|
+
}): Promise<{
|
|
43
|
+
[key in keyof ObjectWithPromises]: Awaited<ObjectWithPromises[key]>;
|
|
44
|
+
}>;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,wBAAgB,aAAa,iBAM5B;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,SAAI,UAI5C;AAGD,wBAAgB,mBAAmB,CAAC,GAAG,SAAI,EAAE,GAAG,SAAU,UAIzD;AAED,eAAO,MAAM,WAAW,cAGpB,CAAC;AAGL,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,MAE1D;AAED,eAAO,MAAM,gBAAgB,GAAI,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,WAK3C,CAAC;AAEhB,eAAO,MAAM,sBAAsB,GACjC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,SAAS;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,WA0CF,CAAC;AAKF,QAAA,MAAM,UAAU,GAAI,GAAG,OAAO,gGAAa,CAAC;AAC5C,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAEjD,eAAO,MAAM,cAAc,GACzB,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,KAC3C,MAoBF,CAAC;AAEF,KAAK,gCAAgC,GAAG;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AACF,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,mBAAmB,sBAAC;IACpB,GAAG,WAAC;IACJ,aAAa,gBAAC;gBAEF,EACV,OAAO,EACP,KAAK,EACL,aAAa,EACb,GAAG,GACJ,EAAE,gCAAgC;IAoBnC,qBAAqB;CAqBtB;AAED,KAAK,SAAS,GACV,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,UAAU,GACV,OAAO,CAAC;AAEZ,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,SAKxC,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAEzD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAUhD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,UAgBxC;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,GAAG,OAAO;;qBACnC,QAAQ,KAAK,IAAI;sBAEhB,GAAG,KAAK,IAAI;EAcnC;AAED,MAAM,MAAM,WAAW,CAAC,QAAQ,IAAI,CAAC,MAAM,QAAQ,EAAE,QAAQ,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC;AAG/E,wBAAsB,6BAA6B,CAAC,kBAAkB,EACpE,MAAM,EAAE;KACL,GAAG,IAAI,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,GAAG,CAAC;CAC3D,GACA,OAAO,CAAC;KACR,GAAG,IAAI,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;CACpE,CAAC,CAqBD"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
export function createCounter() {
|
|
3
|
+
let counter = -1;
|
|
4
|
+
return () => {
|
|
5
|
+
counter = counter === Number.MAX_SAFE_INTEGER ? 0 : counter + 1;
|
|
6
|
+
return counter;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
// Now that getUniqueId uses a counter to ensure there are no id clashes due to having the same timestamp,
|
|
10
|
+
// we don't really need to use a random int but I had fun writing these functions and don't want to get rid
|
|
11
|
+
// of them. So until there's a reason to I'm not going to.
|
|
12
|
+
export function getRandomIntOfScale(scale = 6) {
|
|
13
|
+
const min = 10 ** (scale - 1);
|
|
14
|
+
const max = 10 ** scale - 1;
|
|
15
|
+
return getRandomIntInRange(min, max);
|
|
16
|
+
}
|
|
17
|
+
// Both min and max are inclusive
|
|
18
|
+
export function getRandomIntInRange(min = 0, max = 999_999) {
|
|
19
|
+
return Math.floor(Math.random() * (Math.floor(max) - Math.ceil(min) + 1) + Math.ceil(min));
|
|
20
|
+
}
|
|
21
|
+
export const getUniqueId = (() => {
|
|
22
|
+
const counter = createCounter();
|
|
23
|
+
return () => `${Date.now()}-${counter()}-${getRandomIntOfScale(6)}`;
|
|
24
|
+
})();
|
|
25
|
+
// Used to increase readability in some places
|
|
26
|
+
export function mergeInUnsetProperties(a, b) {
|
|
27
|
+
return { ...b, ...a };
|
|
28
|
+
}
|
|
29
|
+
export const formatObjectPath = (path) => `$${path
|
|
30
|
+
.map((segment) => typeof segment === "number" ? `[${segment}]` : `.${segment}`)
|
|
31
|
+
.join("")}`;
|
|
32
|
+
export const formatObjectPathAsTree = (path, options) => {
|
|
33
|
+
const lineIndent = options.lineIndent ?? 2;
|
|
34
|
+
const overallIndent = options.overallIndent ?? 0;
|
|
35
|
+
const lastNodeExtraInfo = options.lastNodeExtraInfo ?? "";
|
|
36
|
+
if (lineIndent < 2) {
|
|
37
|
+
throw Error("Line indent can not be less than 2");
|
|
38
|
+
}
|
|
39
|
+
let formattedTree = path
|
|
40
|
+
.reduce((segments, segment) => {
|
|
41
|
+
if (typeof segment === "number") {
|
|
42
|
+
const formattedSegment = `[${segment}]`;
|
|
43
|
+
if (segments.length) {
|
|
44
|
+
segments[segments.length - 1] += formattedSegment;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
segments.push(formattedSegment);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
segments.push(segment);
|
|
52
|
+
}
|
|
53
|
+
return segments;
|
|
54
|
+
}, [])
|
|
55
|
+
// If segment is a number then wrap square brackets around it to signal that
|
|
56
|
+
.map((segment) => typeof segment === "number" ? `[${segment}]` : `${segment}`)
|
|
57
|
+
.map((segment) => chalk.bold(segment))
|
|
58
|
+
// Add arrow between segments
|
|
59
|
+
// Indent each segment by lineIndent more than the last + add arrow between segments
|
|
60
|
+
.map((segment, index) => (index ? " ".repeat(index * lineIndent - 2) + chalk.dim("↳ ") : "") +
|
|
61
|
+
segment)
|
|
62
|
+
.join("\n");
|
|
63
|
+
if (lastNodeExtraInfo) {
|
|
64
|
+
formattedTree = `${formattedTree} - ${lastNodeExtraInfo.replace(/\n/, `\n${" ".repeat((path.length - 1) * lineIndent)}`)}`;
|
|
65
|
+
}
|
|
66
|
+
return formattedTree
|
|
67
|
+
.split("\n")
|
|
68
|
+
.map((line) => " ".repeat(overallIndent) + line)
|
|
69
|
+
.join("\n");
|
|
70
|
+
};
|
|
71
|
+
const capitalisedFirstLetter = (string) => string[0].toUpperCase() + string.substring(1);
|
|
72
|
+
const returnType = (v) => typeof v;
|
|
73
|
+
export const capitaliseType = (type) => {
|
|
74
|
+
let result;
|
|
75
|
+
switch (type) {
|
|
76
|
+
case "string":
|
|
77
|
+
case "number":
|
|
78
|
+
case "boolean":
|
|
79
|
+
case "symbol":
|
|
80
|
+
case "undefined":
|
|
81
|
+
case "object":
|
|
82
|
+
case "function":
|
|
83
|
+
case "array":
|
|
84
|
+
case "set":
|
|
85
|
+
case "date":
|
|
86
|
+
result = capitalisedFirstLetter(type);
|
|
87
|
+
break;
|
|
88
|
+
case "bigint":
|
|
89
|
+
result = "BigInt";
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
};
|
|
94
|
+
export class ConstructorExecutionError extends Error {
|
|
95
|
+
errorOccurredAtPath;
|
|
96
|
+
log;
|
|
97
|
+
actionContext;
|
|
98
|
+
constructor({ message, cause, actionContext, log, }) {
|
|
99
|
+
super(message ?? cause?.message ?? "Error when executing constructor");
|
|
100
|
+
if (cause) {
|
|
101
|
+
this.stack = cause.stack;
|
|
102
|
+
}
|
|
103
|
+
// Use class name as the name of the error
|
|
104
|
+
ConstructorExecutionError.prototype.name = this.constructor.name;
|
|
105
|
+
this.errorOccurredAtPath = actionContext.path;
|
|
106
|
+
this.log = log;
|
|
107
|
+
this.actionContext = actionContext;
|
|
108
|
+
this.message = this.getFormattedErrorInfo();
|
|
109
|
+
// Explicitly set the prototype to maintain the correct prototype chain is
|
|
110
|
+
// required for "instanceOf" to work as expected
|
|
111
|
+
Object.setPrototypeOf(this, ConstructorExecutionError.prototype);
|
|
112
|
+
}
|
|
113
|
+
getFormattedErrorInfo() {
|
|
114
|
+
const stack = this.cause instanceof Error
|
|
115
|
+
? this.cause.stack?.replace(`${this.cause.toString()}\n`, "")
|
|
116
|
+
: this.stack;
|
|
117
|
+
const lastConstructorProp = this.errorOccurredAtPath[this.errorOccurredAtPath.length - 1];
|
|
118
|
+
const errorLocation = stack
|
|
119
|
+
?.split("\n")
|
|
120
|
+
.find((line) => line.startsWith(` at ${lastConstructorProp}`))
|
|
121
|
+
?.match(/\((.*)\)/)?.[1];
|
|
122
|
+
return [
|
|
123
|
+
"Failed to render the following response constructor property",
|
|
124
|
+
formatObjectPathAsTree(this.errorOccurredAtPath, {
|
|
125
|
+
lineIndent: 3,
|
|
126
|
+
overallIndent: 2,
|
|
127
|
+
lastNodeExtraInfo: `${chalk.bold(this.message)}\n(${chalk.blue(errorLocation)})`,
|
|
128
|
+
}),
|
|
129
|
+
"",
|
|
130
|
+
].join("\n");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export const getType = (value) => {
|
|
134
|
+
if (Array.isArray(value)) {
|
|
135
|
+
return "array";
|
|
136
|
+
}
|
|
137
|
+
return typeof value;
|
|
138
|
+
};
|
|
139
|
+
export function hasNoDuplicates(array) {
|
|
140
|
+
return new Set(array).size === array.length;
|
|
141
|
+
}
|
|
142
|
+
export function getDuplicates(array) {
|
|
143
|
+
const duplicates = new Set();
|
|
144
|
+
for (let i = 0; i < array.length; i++) {
|
|
145
|
+
for (let j = i + 1; j < array.length; j++) {
|
|
146
|
+
if (array[i] === array[j]) {
|
|
147
|
+
duplicates.add(array[i]);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return [...duplicates];
|
|
152
|
+
}
|
|
153
|
+
export function getOrdinal(number) {
|
|
154
|
+
let suffix;
|
|
155
|
+
switch (number % 10) {
|
|
156
|
+
case 1:
|
|
157
|
+
suffix = "st";
|
|
158
|
+
break;
|
|
159
|
+
case 2:
|
|
160
|
+
suffix = "nd";
|
|
161
|
+
break;
|
|
162
|
+
case 3:
|
|
163
|
+
suffix = "rd";
|
|
164
|
+
break;
|
|
165
|
+
default:
|
|
166
|
+
suffix = "th";
|
|
167
|
+
}
|
|
168
|
+
return `${number}${suffix}`;
|
|
169
|
+
}
|
|
170
|
+
export function getPromiseWithResolvers() {
|
|
171
|
+
let resolve;
|
|
172
|
+
// biome-ignore lint/suspicious/noExplicitAny: reject reason is intentionally untyped
|
|
173
|
+
let reject;
|
|
174
|
+
const promise = new Promise((...resolvers) => {
|
|
175
|
+
resolve = resolvers[0];
|
|
176
|
+
reject = resolvers[1];
|
|
177
|
+
});
|
|
178
|
+
// @ts-expect-error The point of this is to make sure the resolvers are defined
|
|
179
|
+
if (typeof resolve === "undefined" || typeof reject === "undefined") {
|
|
180
|
+
throw Error("Resolvers not set yet");
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
promise,
|
|
184
|
+
resolve,
|
|
185
|
+
reject,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
// Takes an object and if any property values are promises it will wait until they're resolved.
|
|
189
|
+
export async function waitForAllPropertiesToResolve(object) {
|
|
190
|
+
// So that we can use Promise.all() to resolve every prop in object we first convert
|
|
191
|
+
// object to an array of entries, then we swap each entry with a promise that resolves
|
|
192
|
+
// to the entry. That way we can can use Promise.all() on it to get us back to an array
|
|
193
|
+
// of entries (but now with any promises resolved), then use Object.fromEntry() to
|
|
194
|
+
// re-assemble the entries back into an object.
|
|
195
|
+
const entriesAsPromises = Object.entries(object).map((entry) => {
|
|
196
|
+
const [entryKey, entryValue] = entry;
|
|
197
|
+
if (entryValue instanceof Promise) {
|
|
198
|
+
return entryValue.then((resolvedEntryValue) => [
|
|
199
|
+
entryKey,
|
|
200
|
+
resolvedEntryValue,
|
|
201
|
+
]);
|
|
202
|
+
}
|
|
203
|
+
// biome-ignore lint/suspicious/noExplicitAny: entry tuple cast needed for Promise.all compatibility
|
|
204
|
+
return new Promise((resolve) => resolve(entry));
|
|
205
|
+
});
|
|
206
|
+
const entriesResolved = await Promise.all(entriesAsPromises);
|
|
207
|
+
return Object.fromEntries(entriesResolved);
|
|
208
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
export declare function zodParseOrThrow<Output, Def extends z.ZodTypeDef, Input>(zodSchema: z.ZodType<Output, Def, Input>, input: any, options?: {
|
|
3
|
+
errorMessage?: string;
|
|
4
|
+
context?: unknown;
|
|
5
|
+
}): Output;
|
|
6
|
+
type ValueType = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "array";
|
|
7
|
+
export declare const getType: (value: unknown) => ValueType;
|
|
8
|
+
type FriendlyZodErrorOptions = {
|
|
9
|
+
message?: string;
|
|
10
|
+
inputData?: unknown;
|
|
11
|
+
context?: unknown;
|
|
12
|
+
};
|
|
13
|
+
type FriendlyZodErrorIssue = {
|
|
14
|
+
zodIssue: z.ZodIssue;
|
|
15
|
+
depth: number;
|
|
16
|
+
formattedMessage: string;
|
|
17
|
+
};
|
|
18
|
+
type FriendlyZodErrorIssuesTree = {
|
|
19
|
+
issues: FriendlyZodErrorIssue[];
|
|
20
|
+
children: Record<string | number, FriendlyZodErrorIssuesTree>;
|
|
21
|
+
};
|
|
22
|
+
export declare class FriendlyZodError extends Error {
|
|
23
|
+
#private;
|
|
24
|
+
zodError: z.ZodError;
|
|
25
|
+
context: unknown;
|
|
26
|
+
constructor(error: z.ZodError, { message, inputData, context }?: FriendlyZodErrorOptions);
|
|
27
|
+
formatZodIssue(issue: z.ZodIssue, includePath?: boolean): string;
|
|
28
|
+
formatZodErrorIssues(error?: z.ZodError, depth?: number, includePath?: boolean): FriendlyZodErrorIssue[];
|
|
29
|
+
formatZodErrorIssuesAsDotPoints(error?: z.ZodError, depth?: number, indentSize?: number): string;
|
|
30
|
+
formatZodErrorIssuesAsTree(error?: z.ZodError): FriendlyZodErrorIssuesTree;
|
|
31
|
+
formatZodErrorIssuesAsTreeString(error?: z.ZodError, depth?: number, indentSize?: number): string;
|
|
32
|
+
get formattedErrorInfo(): string;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=zod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/lib/zod.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAO7B,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,UAAU,EAAE,KAAK,EACrE,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,EAExC,KAAK,EAAE,GAAG,EACV,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GACzD,MAAM,CAiBR;AAED,KAAK,SAAS,GACV,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,UAAU,GACV,OAAO,CAAC;AAEZ,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,SAKxC,CAAC;AA0CF,KAAK,uBAAuB,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AACF,KAAK,0BAA0B,GAAG;IAChC,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,0BAA0B,CAAC,CAAC;CAC/D,CAAC;AACF,qBAAa,gBAAiB,SAAQ,KAAK;;IAEzC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;gBAGf,KAAK,EAAE,CAAC,CAAC,QAAQ,EACjB,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAE,uBAA4B;IAqB/D,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,WAAW,UAAO,GAAG,MAAM;IAyF7D,oBAAoB,CAClB,KAAK,GAAE,CAAC,CAAC,QAAwB,EACjC,KAAK,SAAI,EACT,WAAW,UAAO,GACjB,qBAAqB,EAAE;IAsD1B,+BAA+B,CAC7B,KAAK,GAAE,CAAC,CAAC,QAAwB,EACjC,KAAK,SAAI,EACT,UAAU,SAAI,GACb,MAAM;IAST,0BAA0B,CACxB,KAAK,GAAE,CAAC,CAAC,QAAwB,GAChC,0BAA0B;IAqC7B,gCAAgC,CAC9B,KAAK,GAAE,CAAC,CAAC,QAAwB,EACjC,KAAK,SAAI,EACT,UAAU,SAAI,GACb,MAAM;IAgCT,IAAI,kBAAkB,IAAI,MAAM,CAY/B;CACF"}
|