@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
package/dist/lib/zod.js
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import util from "node:util";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import pluralize from "pluralize";
|
|
4
|
+
import { capitaliseType, formatObjectPath } from "./utils.js";
|
|
5
|
+
function isZodError(error) {
|
|
6
|
+
return error?.constructor?.name === "ZodError";
|
|
7
|
+
}
|
|
8
|
+
export function zodParseOrThrow(zodSchema,
|
|
9
|
+
// biome-ignore lint/suspicious/noExplicitAny: zod schema accepts any input for runtime validation
|
|
10
|
+
input, options = {}) {
|
|
11
|
+
try {
|
|
12
|
+
return zodSchema.parse(input);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
// We might be passing a zodSchema from a plugin with a different instance of the Zod library
|
|
16
|
+
// and thus if that gives an error it might not be an instance of the ZodError from the exact Zod library
|
|
17
|
+
// we're using. Thus we match using the constructor name to be safe.
|
|
18
|
+
if (isZodError(error)) {
|
|
19
|
+
const friendlyError = new FriendlyZodError(error, {
|
|
20
|
+
message: options.errorMessage,
|
|
21
|
+
inputData: input,
|
|
22
|
+
context: options.context,
|
|
23
|
+
});
|
|
24
|
+
throw friendlyError;
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export const getType = (value) => {
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
return "array";
|
|
32
|
+
}
|
|
33
|
+
return typeof value;
|
|
34
|
+
};
|
|
35
|
+
function getPathInfo(inputData, path) {
|
|
36
|
+
// biome-ignore lint/suspicious/noExplicitAny: complex accumulator type in path traversal
|
|
37
|
+
return path.reduce(
|
|
38
|
+
// biome-ignore lint/suspicious/noExplicitAny: complex accumulator type in path traversal
|
|
39
|
+
(accumulator, currentArrayValue) => {
|
|
40
|
+
const exists = typeof accumulator.value !== "undefined" &&
|
|
41
|
+
currentArrayValue in accumulator.value;
|
|
42
|
+
const value = accumulator.value?.[currentArrayValue];
|
|
43
|
+
const type = getType(value);
|
|
44
|
+
return {
|
|
45
|
+
exists,
|
|
46
|
+
value,
|
|
47
|
+
type,
|
|
48
|
+
longestExistingPath: exists
|
|
49
|
+
? [...accumulator.longestExistingPath, currentArrayValue]
|
|
50
|
+
: accumulator.longestExistingPath,
|
|
51
|
+
typeAtLongestExistingPath: exists
|
|
52
|
+
? type
|
|
53
|
+
: accumulator.typeAtLongestExistingPath,
|
|
54
|
+
};
|
|
55
|
+
}, {
|
|
56
|
+
exists: true,
|
|
57
|
+
value: inputData,
|
|
58
|
+
longestExistingPath: [],
|
|
59
|
+
typeAtLongestExistingPath: getType(inputData),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export class FriendlyZodError extends Error {
|
|
63
|
+
#inputData;
|
|
64
|
+
zodError;
|
|
65
|
+
context;
|
|
66
|
+
constructor(error, { message, inputData, context } = {}) {
|
|
67
|
+
super(message ?? error?.message ?? "Error when validating data");
|
|
68
|
+
// Use class name as the name of the error
|
|
69
|
+
this.name = this.constructor.name;
|
|
70
|
+
this.zodError = error;
|
|
71
|
+
this.stack = error.stack;
|
|
72
|
+
this.context = context;
|
|
73
|
+
this.#inputData = inputData;
|
|
74
|
+
this.message = this.formattedErrorInfo;
|
|
75
|
+
// Explicitly set the prototype to maintain the correct prototype chain is
|
|
76
|
+
// required for "instanceOf" to work as expected
|
|
77
|
+
Object.setPrototypeOf(this, FriendlyZodError.prototype);
|
|
78
|
+
}
|
|
79
|
+
formatZodIssue(issue, includePath = true) {
|
|
80
|
+
const { path, ...detailWithoutPath } = issue;
|
|
81
|
+
const formattedPath = formatObjectPath(path);
|
|
82
|
+
let pathInfo = getPathInfo(this.#inputData, path);
|
|
83
|
+
let issueMessage;
|
|
84
|
+
if (issue.code === "invalid_type") {
|
|
85
|
+
if (pathInfo.exists) {
|
|
86
|
+
const includeValue = ["string", "number"].includes(pathInfo.type);
|
|
87
|
+
issueMessage = `Expected ${includePath ? `${formattedPath} to be an` : ""}${issue.expected} but ${includeValue
|
|
88
|
+
? `the received value ${JSON.stringify(pathInfo.value)} was`
|
|
89
|
+
: "received"} a ${issue.received}.`;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const keyOrIndex = path.at(-1);
|
|
93
|
+
const parentPath = formatObjectPath(path.slice(0, -1));
|
|
94
|
+
const isIndex = pathInfo.typeAtLongestExistingPath === "array" &&
|
|
95
|
+
typeof keyOrIndex === "number";
|
|
96
|
+
issueMessage =
|
|
97
|
+
`Missing ${isIndex ? "element" : "key"} "${keyOrIndex}" at ${parentPath},` +
|
|
98
|
+
` expected to receive a ${issue.expected}.`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else if (issue.code === "unrecognized_keys") {
|
|
102
|
+
const keys = issue.keys.map((key) => {
|
|
103
|
+
pathInfo = getPathInfo(this.#inputData, [...path, key]);
|
|
104
|
+
const includeValue = ["string", "number"].includes(pathInfo.type);
|
|
105
|
+
const formattedValue = includeValue
|
|
106
|
+
? JSON.stringify(pathInfo.value)
|
|
107
|
+
: `is a ${pathInfo.type}`;
|
|
108
|
+
return `"${key}" (value ${formattedValue})`;
|
|
109
|
+
});
|
|
110
|
+
issueMessage = `Unexpected ${pluralize("key", keys.length)} found${includePath ? ` at ${formattedPath}` : ""}: ${keys.join(", ")}`;
|
|
111
|
+
}
|
|
112
|
+
else if (issue.code === "invalid_string") {
|
|
113
|
+
issueMessage = `${includePath ? `${formattedPath} failed` : "Failed"} ${issue.validation} validation, received ${JSON.stringify(pathInfo.value)}`;
|
|
114
|
+
}
|
|
115
|
+
else if (issue.code === "too_small" || issue.code === "too_big") {
|
|
116
|
+
let condition = "";
|
|
117
|
+
let threshold = 0;
|
|
118
|
+
if (issue.code === "too_small") {
|
|
119
|
+
threshold = issue.minimum;
|
|
120
|
+
if (issue.exact) {
|
|
121
|
+
condition = "";
|
|
122
|
+
}
|
|
123
|
+
else if (issue.inclusive) {
|
|
124
|
+
condition = "a minimum of";
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
condition = "more than";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else if (issue.code === "too_big") {
|
|
131
|
+
threshold = issue.maximum;
|
|
132
|
+
if (issue.exact) {
|
|
133
|
+
condition = "";
|
|
134
|
+
}
|
|
135
|
+
else if (issue.inclusive) {
|
|
136
|
+
condition = "a maximum of";
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
condition = "less than";
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (issue.type === "number" ||
|
|
143
|
+
issue.type === "bigint" ||
|
|
144
|
+
issue.type === "date") {
|
|
145
|
+
const capitalisedType = capitaliseType(issue.type);
|
|
146
|
+
issueMessage =
|
|
147
|
+
`${capitalisedType} ${includePath ? `at ${formattedPath} ` : ""}must be ${condition}` +
|
|
148
|
+
` ${threshold} but was ${pathInfo.value}.`;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const nameForTypeElement = {
|
|
152
|
+
string: "character",
|
|
153
|
+
array: "element",
|
|
154
|
+
set: "element",
|
|
155
|
+
}[issue.type];
|
|
156
|
+
const capitalisedType = capitaliseType(issue.type);
|
|
157
|
+
const length = pathInfo.value.length;
|
|
158
|
+
issueMessage =
|
|
159
|
+
`${capitalisedType} ${includePath ? ` at ${formattedPath} ` : ""}must have ${condition}` +
|
|
160
|
+
` ${threshold} ${nameForTypeElement}(s) but the received ${issue.type} had ${length}.`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if (issue.code === "invalid_date") {
|
|
164
|
+
issueMessage = `Expected date ${includePath ? `at ${formattedPath} ` : ""}but received value ${JSON.stringify(pathInfo.value)} is not a valid date.`;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
pathInfo = getPathInfo(this.#inputData, path);
|
|
168
|
+
issueMessage = `Issue with${includePath ? ` ${formattedPath}` : ""}: ${JSON.stringify(detailWithoutPath)} - ${JSON.stringify(pathInfo.value)}`;
|
|
169
|
+
}
|
|
170
|
+
return `${issueMessage}`;
|
|
171
|
+
}
|
|
172
|
+
formatZodErrorIssues(error = this.zodError, depth = 0, includePath = true) {
|
|
173
|
+
const indentSize = 2;
|
|
174
|
+
const formattedIssues = [];
|
|
175
|
+
for (const issue of error.issues) {
|
|
176
|
+
if (issue.code === "invalid_union") {
|
|
177
|
+
formattedIssues.push({
|
|
178
|
+
formattedMessage: `${" ".repeat(depth * indentSize)}Invalid union:`,
|
|
179
|
+
zodIssue: issue,
|
|
180
|
+
depth,
|
|
181
|
+
});
|
|
182
|
+
for (const error of issue.unionErrors) {
|
|
183
|
+
formattedIssues.push(...this.formatZodErrorIssues(error, depth + 1, includePath));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else if (issue.code === "invalid_arguments") {
|
|
187
|
+
formattedIssues.push({
|
|
188
|
+
formattedMessage: `${" ".repeat(depth * indentSize)}Invalid arguments:`,
|
|
189
|
+
zodIssue: issue,
|
|
190
|
+
depth,
|
|
191
|
+
});
|
|
192
|
+
formattedIssues.push(...this.formatZodErrorIssues(issue.argumentsError, depth + 1, includePath));
|
|
193
|
+
}
|
|
194
|
+
else if (issue.code === "invalid_return_type") {
|
|
195
|
+
formattedIssues.push({
|
|
196
|
+
formattedMessage: `${" ".repeat(depth * indentSize)}Invalid return type:`,
|
|
197
|
+
zodIssue: issue,
|
|
198
|
+
depth,
|
|
199
|
+
});
|
|
200
|
+
formattedIssues.push(...this.formatZodErrorIssues(issue.returnTypeError, depth + 1, includePath));
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
formattedIssues.push({
|
|
204
|
+
formattedMessage: " ".repeat(depth * indentSize) +
|
|
205
|
+
this.formatZodIssue(issue, includePath),
|
|
206
|
+
zodIssue: issue,
|
|
207
|
+
depth,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return formattedIssues;
|
|
212
|
+
}
|
|
213
|
+
formatZodErrorIssuesAsDotPoints(error = this.zodError, depth = 0, indentSize = 2) {
|
|
214
|
+
return this.formatZodErrorIssues(error)
|
|
215
|
+
.map((friendlyZodIssue) => `${" ".repeat((depth + friendlyZodIssue.depth) * indentSize)}- ${friendlyZodIssue.formattedMessage}`)
|
|
216
|
+
.join("\n");
|
|
217
|
+
}
|
|
218
|
+
formatZodErrorIssuesAsTree(error = this.zodError) {
|
|
219
|
+
const issuesTree = {
|
|
220
|
+
issues: [],
|
|
221
|
+
children: {},
|
|
222
|
+
};
|
|
223
|
+
for (const friendlyZodIssue of this.formatZodErrorIssues(error, 0, false)) {
|
|
224
|
+
let issueSubtree = issuesTree;
|
|
225
|
+
const path = friendlyZodIssue.zodIssue.path.reduce((segments, segment) => {
|
|
226
|
+
if (typeof segment === "number") {
|
|
227
|
+
const formattedSegment = `[${segment}]`;
|
|
228
|
+
if (segments.length) {
|
|
229
|
+
segments[segments.length - 1] += formattedSegment;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
segments.push(formattedSegment);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
segments.push(segment);
|
|
237
|
+
}
|
|
238
|
+
return segments;
|
|
239
|
+
}, []);
|
|
240
|
+
for (const pathSegment of path) {
|
|
241
|
+
if (!(pathSegment in issueSubtree.children)) {
|
|
242
|
+
issueSubtree.children[pathSegment] = {
|
|
243
|
+
issues: [],
|
|
244
|
+
children: {},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
issueSubtree = issueSubtree.children[pathSegment];
|
|
248
|
+
}
|
|
249
|
+
issueSubtree.issues.push(friendlyZodIssue);
|
|
250
|
+
}
|
|
251
|
+
return issuesTree;
|
|
252
|
+
}
|
|
253
|
+
formatZodErrorIssuesAsTreeString(error = this.zodError, depth = 0, indentSize = 2) {
|
|
254
|
+
function formatSubtree(issuesTree, depth) {
|
|
255
|
+
const lines = [];
|
|
256
|
+
const baseIndentation = " ".repeat(depth * indentSize);
|
|
257
|
+
for (const friendlyZodIssue of issuesTree.issues) {
|
|
258
|
+
const indentation = baseIndentation + " ".repeat(friendlyZodIssue.depth * indentSize);
|
|
259
|
+
lines.push(`${indentation}- ${friendlyZodIssue.formattedMessage.replace(/^\s+/, "")}`);
|
|
260
|
+
}
|
|
261
|
+
for (const [index, key] of Object.keys(issuesTree.children).entries()) {
|
|
262
|
+
const issuesSubtree = issuesTree.children[key];
|
|
263
|
+
if (index) {
|
|
264
|
+
lines.push("");
|
|
265
|
+
}
|
|
266
|
+
lines.push(baseIndentation + chalk.bold(key));
|
|
267
|
+
const subtreeLines = formatSubtree(issuesSubtree, depth + 1);
|
|
268
|
+
if (subtreeLines.length) {
|
|
269
|
+
lines.push(formatSubtree(issuesSubtree, depth + 1));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return lines.join("\n");
|
|
273
|
+
}
|
|
274
|
+
const issuesTree = this.formatZodErrorIssuesAsTree(error);
|
|
275
|
+
return formatSubtree(issuesTree, depth);
|
|
276
|
+
}
|
|
277
|
+
get formattedErrorInfo() {
|
|
278
|
+
return [
|
|
279
|
+
this.message,
|
|
280
|
+
...(this.#inputData
|
|
281
|
+
? [
|
|
282
|
+
`Input data: \n${util.inspect(this.#inputData, { depth: null, colors: true })}`,
|
|
283
|
+
]
|
|
284
|
+
: []),
|
|
285
|
+
"",
|
|
286
|
+
`The following ${this.zodError.issues.length > 1 ? "issues were" : "issue was"} found:`,
|
|
287
|
+
this.formatZodErrorIssuesAsTreeString(this.zodError, 1),
|
|
288
|
+
].join("\n");
|
|
289
|
+
}
|
|
290
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type OptionsInit as GotOptionsInit } from "got-scraping";
|
|
2
|
+
import { type DomSelection } from "./DomSelection.js";
|
|
3
|
+
type LoadUrlOptionsPlaywright = {
|
|
4
|
+
agent: "playwright";
|
|
5
|
+
responseType?: "dom";
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
};
|
|
8
|
+
type LoadUrlOptionsGot = {
|
|
9
|
+
agent?: "got";
|
|
10
|
+
responseType?: "dom" | "text" | "json";
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
body?: string;
|
|
13
|
+
retryAdditional?: GotOptionsInit["retry"];
|
|
14
|
+
} & Omit<GotOptionsInit, "responseType" | "headers" | "body" | "retry" | "hooks" | "resolveBodyOnly" | "isStream" | "url" | "json" | "form">;
|
|
15
|
+
export type LoadUrlOptions = LoadUrlOptionsPlaywright | LoadUrlOptionsGot;
|
|
16
|
+
type LoadURLSharedResponse = {
|
|
17
|
+
statusCode: number;
|
|
18
|
+
headers: Record<string, string>;
|
|
19
|
+
cached: boolean;
|
|
20
|
+
cachedOn: Date | null;
|
|
21
|
+
request: {
|
|
22
|
+
headers: Record<string, string>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
type LoadUrlResponseDom = LoadURLSharedResponse & {
|
|
26
|
+
root: DomSelection;
|
|
27
|
+
};
|
|
28
|
+
type LoadUrlResponseJson = LoadURLSharedResponse & {
|
|
29
|
+
data: unknown;
|
|
30
|
+
};
|
|
31
|
+
type LoadUrlResponseText = LoadURLSharedResponse & {
|
|
32
|
+
data: string;
|
|
33
|
+
};
|
|
34
|
+
export type LoadUrlResponse = LoadUrlResponseDom | LoadUrlResponseJson | LoadUrlResponseText;
|
|
35
|
+
export declare function loadUrl(url: string, options: LoadUrlOptions & {
|
|
36
|
+
responseType: "json";
|
|
37
|
+
}): Promise<LoadUrlResponseJson>;
|
|
38
|
+
export declare function loadUrl(url: string, options?: LoadUrlOptions & {
|
|
39
|
+
responseType?: "dom";
|
|
40
|
+
}): Promise<LoadUrlResponseDom>;
|
|
41
|
+
export declare function loadUrl(url: string, options: LoadUrlOptions & {
|
|
42
|
+
responseType: "text";
|
|
43
|
+
}): Promise<LoadUrlResponseText>;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=loadUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadUrl.d.ts","sourceRoot":"","sources":["../src/loadUrl.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,WAAW,IAAI,cAAc,EAEnC,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAO3E,KAAK,wBAAwB,GAAG;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,YAAY,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;CAC3C,GAAG,IAAI,CACN,cAAc,EACZ,cAAc,GACd,SAAS,GACT,MAAM,GACN,OAAO,GACP,OAAO,GACP,iBAAiB,GACjB,UAAU,GACV,KAAK,GACL,MAAM,GACN,MAAM,CACT,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,wBAAwB,GAAG,iBAAiB,CAAC;AAE1E,KAAK,qBAAqB,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,CAAC;CACH,CAAC;AAEF,KAAK,kBAAkB,GAAG,qBAAqB,GAAG;IAChD,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AACF,KAAK,mBAAmB,GAAG,qBAAqB,GAAG;IACjD,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AACF,KAAK,mBAAmB,GAAG,qBAAqB,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB,kBAAkB,GAClB,mBAAmB,GACnB,mBAAmB,CAAC;AACxB,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,cAAc,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAChC,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,cAAc,GAAG;IAAE,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE,GAClD,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAC/B,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,cAAc,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,mBAAmB,CAAC,CAAC"}
|
package/dist/loadUrl.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as cheerio from "cheerio";
|
|
2
|
+
import deepmerge from "deepmerge";
|
|
3
|
+
import { Options as GotOptions, gotScraping, } from "got-scraping";
|
|
4
|
+
import { CheerioDomSelection } from "./DomSelection.js";
|
|
5
|
+
import { headersToNormalisedBasicObject } from "./lib/fetch.js";
|
|
6
|
+
import { cacheResponse, getCachedResponse, } from "./lib/networkRequestsCache.js";
|
|
7
|
+
export async function loadUrl(url, options) {
|
|
8
|
+
if (!options) {
|
|
9
|
+
// biome-ignore lint/style/noParameterAssign: assigning default value to optional parameter
|
|
10
|
+
options = {};
|
|
11
|
+
}
|
|
12
|
+
if (this.cacheNetworkRequests === "auto") {
|
|
13
|
+
throw Error(`The "auto" value for the cacheNetworkRequests option is not yet supported. Sorry!`);
|
|
14
|
+
}
|
|
15
|
+
if (!options.agent) {
|
|
16
|
+
options.agent = "got";
|
|
17
|
+
}
|
|
18
|
+
if (options.agent === "got") {
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- we define only to exclude from requestOptions
|
|
20
|
+
const { agent, retryAdditional, responseType, ...requestOptions } = options;
|
|
21
|
+
const defaultGotOptions = new GotOptions();
|
|
22
|
+
let retry = defaultGotOptions.retry;
|
|
23
|
+
if (options.retryAdditional) {
|
|
24
|
+
retry = deepmerge(retry, options.retryAdditional);
|
|
25
|
+
}
|
|
26
|
+
let cache;
|
|
27
|
+
let res;
|
|
28
|
+
const cacheableRequest = {
|
|
29
|
+
url,
|
|
30
|
+
method: requestOptions.method ?? "",
|
|
31
|
+
headers: requestOptions.headers ?? {},
|
|
32
|
+
body: requestOptions.body ?? "",
|
|
33
|
+
headerGeneratorOptions: requestOptions.headerGeneratorOptions,
|
|
34
|
+
};
|
|
35
|
+
if (this.cacheNetworkRequests === "always") {
|
|
36
|
+
res = await getCachedResponse(cacheableRequest);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.cacheNetworkRequests;
|
|
40
|
+
}
|
|
41
|
+
if (!res) {
|
|
42
|
+
let sentHeaders = {};
|
|
43
|
+
const gotRes = await gotScraping({
|
|
44
|
+
url,
|
|
45
|
+
...requestOptions,
|
|
46
|
+
responseType: "text",
|
|
47
|
+
retry,
|
|
48
|
+
cache,
|
|
49
|
+
http2: false, // Seems to be necessary otherwise got will throw "Unknown HTTP2 promise event: destroy"
|
|
50
|
+
// when caching.
|
|
51
|
+
hooks: {
|
|
52
|
+
beforeRequest: [
|
|
53
|
+
(options) => {
|
|
54
|
+
sentHeaders = headersToNormalisedBasicObject(options.headers);
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
if (!gotRes.ok) {
|
|
60
|
+
throw Error(`Got response status ${gotRes.statusCode} (retry count: ${gotRes.retryCount}) with body: ${gotRes.body}`);
|
|
61
|
+
}
|
|
62
|
+
res = {
|
|
63
|
+
body: gotRes.body,
|
|
64
|
+
statusCode: gotRes.statusCode,
|
|
65
|
+
headers: headersToNormalisedBasicObject(gotRes.headers),
|
|
66
|
+
request: {
|
|
67
|
+
headers: sentHeaders ?? {},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
await cacheResponse(cacheableRequest, res);
|
|
71
|
+
}
|
|
72
|
+
const { body, statusCode, headers, cachedOn } = res;
|
|
73
|
+
if (options.responseType === "dom" || !options.responseType) {
|
|
74
|
+
return {
|
|
75
|
+
root: new CheerioDomSelection(cheerio.load(body)),
|
|
76
|
+
statusCode,
|
|
77
|
+
headers,
|
|
78
|
+
cached: Boolean(cachedOn),
|
|
79
|
+
cachedOn: cachedOn ?? null,
|
|
80
|
+
request: res.request,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (options.responseType === "json") {
|
|
84
|
+
return {
|
|
85
|
+
data: JSON.parse(body),
|
|
86
|
+
statusCode,
|
|
87
|
+
headers,
|
|
88
|
+
cached: Boolean(cachedOn),
|
|
89
|
+
cachedOn: cachedOn ?? null,
|
|
90
|
+
request: res.request,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (options.responseType === "text") {
|
|
94
|
+
return {
|
|
95
|
+
data: body,
|
|
96
|
+
statusCode,
|
|
97
|
+
headers,
|
|
98
|
+
cached: Boolean(cachedOn),
|
|
99
|
+
cachedOn: cachedOn ?? null,
|
|
100
|
+
request: res.request,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
options.responseType;
|
|
104
|
+
throw Error(`Unknown response type "${options.responseType}"`);
|
|
105
|
+
}
|
|
106
|
+
if (options.agent === "playwright") {
|
|
107
|
+
throw Error("Playwright not supported yet");
|
|
108
|
+
}
|
|
109
|
+
options.agent;
|
|
110
|
+
throw Error(`Unknown agent "${options.agent}"`);
|
|
111
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ActionContext } from "../../../ActionContext.js";
|
|
2
|
+
import { AtpAgent } from "@atproto/api";
|
|
3
|
+
type Props = {
|
|
4
|
+
$: ActionContext;
|
|
5
|
+
handle?: string;
|
|
6
|
+
password?: string;
|
|
7
|
+
serviceUrl?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const getAgent: (props: Props) => Promise<AtpAgent>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/plugins/built-in-sources/bluesky/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,KAAK,KAAK,GAAG;IACX,CAAC,EAAE,aAAa,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAU,OAAO,KAAK,KAAG,OAAO,CAAC,QAAQ,CAiB7D,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AtpAgent } from "@atproto/api";
|
|
2
|
+
export const getAgent = async (props) => {
|
|
3
|
+
const defaultServiceUrl = props.handle && props.password
|
|
4
|
+
? "https://bsky.social"
|
|
5
|
+
: "https://public.api.bsky.app";
|
|
6
|
+
const agent = new AtpAgent({
|
|
7
|
+
service: props.serviceUrl || defaultServiceUrl,
|
|
8
|
+
fetch: props.$.fetch,
|
|
9
|
+
});
|
|
10
|
+
if (props.handle && props.password) {
|
|
11
|
+
await agent.login({
|
|
12
|
+
identifier: props.handle,
|
|
13
|
+
password: props.password,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return agent;
|
|
17
|
+
};
|