azot 5.0.0-alpha.12 → 5.0.0-alpha.13
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/azt.cjs +195 -1
- package/dist/azt.mjs +194 -1
- package/dist/chunk-BmvPcxpV.cjs +41 -0
- package/dist/chunk-DEt8GZDa.mjs +8 -0
- package/dist/context-AYnteC1j.cjs +2267 -0
- package/dist/context-BJuUj_Q4.mjs +2255 -0
- package/dist/context.cjs +4 -1
- package/dist/context.mjs +3 -1
- package/dist/main.cjs +39 -1
- package/dist/main.mjs +28 -1
- package/dist/open-BByf1H2f.mjs +548 -0
- package/dist/open-C0aYOBn3.cjs +555 -0
- package/dist/vitest.cjs +15 -1
- package/dist/vitest.mjs +15 -1
- package/package.json +1 -1
- package/dist/chunk-350yNsax.cjs +0 -1
- package/dist/chunk-DtROqxiw.mjs +0 -1
- package/dist/context-BhNE2Whq.mjs +0 -4
- package/dist/context-DJcvCJWU.cjs +0 -4
- package/dist/open--CgxJiTk.cjs +0 -2
- package/dist/open-DxsWuSWk.mjs +0 -2
|
@@ -0,0 +1,2267 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-BmvPcxpV.cjs');
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
node_path = require_chunk.__toESM(node_path);
|
|
5
|
+
let node_os = require("node:os");
|
|
6
|
+
node_os = require_chunk.__toESM(node_os);
|
|
7
|
+
let node_timers_promises = require("node:timers/promises");
|
|
8
|
+
let _inquirer_prompts = require("@inquirer/prompts");
|
|
9
|
+
let node_fs_promises = require("node:fs/promises");
|
|
10
|
+
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
11
|
+
let _logtape_logtape = require("@logtape/logtape");
|
|
12
|
+
let _logtape_file = require("@logtape/file");
|
|
13
|
+
let _logtape_pretty = require("@logtape/pretty");
|
|
14
|
+
let node_process = require("node:process");
|
|
15
|
+
let node_events = require("node:events");
|
|
16
|
+
node_events = require_chunk.__toESM(node_events);
|
|
17
|
+
require("urlpattern-polyfill");
|
|
18
|
+
let node_readline_promises = require("node:readline/promises");
|
|
19
|
+
let impit = require("impit");
|
|
20
|
+
let undici = require("undici");
|
|
21
|
+
let metavm = require("metavm");
|
|
22
|
+
metavm = require_chunk.__toESM(metavm);
|
|
23
|
+
let node_child_process = require("node:child_process");
|
|
24
|
+
require("picocolors");
|
|
25
|
+
require("nanospinner");
|
|
26
|
+
let conf = require("conf");
|
|
27
|
+
conf = require_chunk.__toESM(conf);
|
|
28
|
+
|
|
29
|
+
//#region ../../apps/desktop/package.json
|
|
30
|
+
var name = "azot-desktop";
|
|
31
|
+
var version$1 = "5.0.0-alpha.41";
|
|
32
|
+
var productName = "Azot";
|
|
33
|
+
var package_default = {
|
|
34
|
+
name,
|
|
35
|
+
version: version$1,
|
|
36
|
+
description: "A powerful, extensible app for downloading videos",
|
|
37
|
+
keywords: ["downloader"],
|
|
38
|
+
homepage: "https://azot.mov",
|
|
39
|
+
author: "Vitaly Gashkov <vitalygashkov@vk.com>",
|
|
40
|
+
repository: {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/azot-labs/azot.git"
|
|
43
|
+
},
|
|
44
|
+
funding: [{
|
|
45
|
+
"type": "individual",
|
|
46
|
+
"url": "https://t.me/tribute/app?startapp=dqW2"
|
|
47
|
+
}],
|
|
48
|
+
files: ["out"],
|
|
49
|
+
os: [
|
|
50
|
+
"darwin",
|
|
51
|
+
"linux",
|
|
52
|
+
"win32"
|
|
53
|
+
],
|
|
54
|
+
main: "./out/main.js",
|
|
55
|
+
scripts: {
|
|
56
|
+
"start": "tsx --env-file .env ./src/main/cli.ts",
|
|
57
|
+
"preview": "electron-vite preview --config vite.desktop.config.mjs",
|
|
58
|
+
"dev": "electron-vite dev --config vite.desktop.config.mjs --watch",
|
|
59
|
+
"cli": "pnpm run bundle:extensions && bun run ./src/main/cli.ts --env-file .env",
|
|
60
|
+
"test": "vitest",
|
|
61
|
+
"coverage": "vitest run --coverage",
|
|
62
|
+
"bundle:extensions": "node ./scripts/bundle-extensions.mjs",
|
|
63
|
+
"bundle:cli": "pnpm run bundle:extensions && node ./scripts/bundle-cli.mjs",
|
|
64
|
+
"bundle": "pnpm run bundle:extensions && electron-vite build --config vite.cli.config.mjs && electron-vite build --config vite.desktop.config.mjs",
|
|
65
|
+
"prebuild": "pnpm -C ../../packages/api build",
|
|
66
|
+
"build:cli": "pnpm -C ../../packages/molnia build && pnpm run bundle:cli && bun build --compile ./out/cli.mjs --minify --outfile ./release/azot",
|
|
67
|
+
"build": "pnpm run bundle && electron-builder build --config electron-builder.config.js",
|
|
68
|
+
"build:mac": "pnpm run bundle && electron-builder build --mac --arm64 --config electron-builder.config.js",
|
|
69
|
+
"build:mac:intel": "pnpm run bundle && electron-builder build --mac --x64 --config electron-builder.config.js",
|
|
70
|
+
"build:win": "pnpm run bundle && electron-builder build --win --config electron-builder.config.js",
|
|
71
|
+
"build:linux": "pnpm run bundle && electron-builder build --linux --config electron-builder.config.js",
|
|
72
|
+
"publish:desktop": "pnpm run bundle && electron-builder build --publish always --config electron-builder.config.js",
|
|
73
|
+
"typecheck": "pnpm run typecheck:node && pnpm run typecheck:web",
|
|
74
|
+
"typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
|
|
75
|
+
"typecheck:web": "vue-tsc --noEmit -p tsconfig.web.json --composite false",
|
|
76
|
+
"lint": "../../node_modules/.bin/oxlint -c ../../.oxlintrc.json .",
|
|
77
|
+
"lint:fix": "../../node_modules/.bin/oxlint -c ../../.oxlintrc.json --fix .",
|
|
78
|
+
"fmt": "../../node_modules/.bin/oxfmt -c ../../.oxfmtrc.json .",
|
|
79
|
+
"fmt:check": "../../node_modules/.bin/oxfmt -c ../../.oxfmtrc.json --check ."
|
|
80
|
+
},
|
|
81
|
+
dependencies: {
|
|
82
|
+
"@electron-toolkit/preload": "^3.0.2",
|
|
83
|
+
"@electron-toolkit/utils": "^4.0.0",
|
|
84
|
+
"@gitbeaker/rest": "^43.8.0",
|
|
85
|
+
"@inquirer/prompts": "^8.2.1",
|
|
86
|
+
"@logtape/file": "^2.0.2",
|
|
87
|
+
"@logtape/logtape": "^2.0.2",
|
|
88
|
+
"@logtape/pretty": "^2.0.2",
|
|
89
|
+
"@tanstack/query-core": "^5.90.20",
|
|
90
|
+
"@tribute-tg/better-auth": "^2.1.8",
|
|
91
|
+
"azot": "workspace:*",
|
|
92
|
+
"better-auth": "^1.4.18",
|
|
93
|
+
"bytenode": "^1.5.7",
|
|
94
|
+
"conf": "^15.1.0",
|
|
95
|
+
"cookie": "^1.1.1",
|
|
96
|
+
"cross-spawn": "^7.0.6",
|
|
97
|
+
"dasha": "4.0.0-alpha.11",
|
|
98
|
+
"electron-squirrel-startup": "^1.0.1",
|
|
99
|
+
"electron-updater": "^6.8.3",
|
|
100
|
+
"impit": "^0.9.2",
|
|
101
|
+
"ky": "^1.14.3",
|
|
102
|
+
"mediabunny": "^1.34.4",
|
|
103
|
+
"metavm": "^1.4.5",
|
|
104
|
+
"molnia": "workspace:*",
|
|
105
|
+
"nanospinner": "^1.2.2",
|
|
106
|
+
"okova": "^0.10.5",
|
|
107
|
+
"open": "^11.0.0",
|
|
108
|
+
"p-queue": "^9.1.0",
|
|
109
|
+
"picocolors": "^1.1.1",
|
|
110
|
+
"posthog-js": "^1.342.1",
|
|
111
|
+
"semver": "^7.7.4",
|
|
112
|
+
"telegram-better-auth": "^0.0.8",
|
|
113
|
+
"undici": "^7.22.0",
|
|
114
|
+
"urlpattern-polyfill": "^10.1.0",
|
|
115
|
+
"yargs": "^18.0.0",
|
|
116
|
+
"yauzl": "^3.2.0",
|
|
117
|
+
"zod": "^4.3.6"
|
|
118
|
+
},
|
|
119
|
+
devDependencies: {
|
|
120
|
+
"@electron-toolkit/tsconfig": "^2.0.0",
|
|
121
|
+
"@iconify/vue": "^5.0.0",
|
|
122
|
+
"@intlify/unplugin-vue-i18n": "^11.0.7",
|
|
123
|
+
"@tailwindcss/vite": "^4.2.0",
|
|
124
|
+
"@tanstack/vue-query": "^5.92.9",
|
|
125
|
+
"@types/node": "^25.3.0",
|
|
126
|
+
"@types/semver": "^7.7.1",
|
|
127
|
+
"@types/wicg-file-system-access": "^2023.10.7",
|
|
128
|
+
"@types/yargs": "^17.0.35",
|
|
129
|
+
"@vee-validate/zod": "^4.15.1",
|
|
130
|
+
"@vitejs/plugin-vue": "^6.0.4",
|
|
131
|
+
"@vueuse/core": "^14.2.1",
|
|
132
|
+
"class-variance-authority": "^0.7.1",
|
|
133
|
+
"clsx": "^2.1.1",
|
|
134
|
+
"dotenv": "^17.3.1",
|
|
135
|
+
"electron": "39.5.1",
|
|
136
|
+
"electron-builder": "^26.8.1",
|
|
137
|
+
"electron-vite": "^5.0.0",
|
|
138
|
+
"esbuild": "^0.27.3",
|
|
139
|
+
"execa": "^9.6.0",
|
|
140
|
+
"lucide-vue-next": "^0.575.0",
|
|
141
|
+
"non.geist": "^1.0.4",
|
|
142
|
+
"pinia": "^3.0.4",
|
|
143
|
+
"postcss": "^8.5.6",
|
|
144
|
+
"reka-ui": "^2.8.2",
|
|
145
|
+
"rolldown": "^1.0.0-rc.5",
|
|
146
|
+
"sass": "^1.97.3",
|
|
147
|
+
"tailwind-merge": "^3.5.0",
|
|
148
|
+
"tailwindcss": "^4.2.0",
|
|
149
|
+
"tailwindcss-animate": "^1.0.7",
|
|
150
|
+
"tsdown": "^0.20.3",
|
|
151
|
+
"tsx": "^4.21.0",
|
|
152
|
+
"typescript": "^5.9.3",
|
|
153
|
+
"vee-validate": "^4.15.1",
|
|
154
|
+
"vite": "^7.3.1",
|
|
155
|
+
"vite-plugin-static-copy": "^3.1.2",
|
|
156
|
+
"vitest": "^4.0.18",
|
|
157
|
+
"vue": "^3.5.28",
|
|
158
|
+
"vue-i18n": "^11.2.8",
|
|
159
|
+
"vue-sonner": "^2.0.9",
|
|
160
|
+
"vue-tsc": "^3.2.5"
|
|
161
|
+
},
|
|
162
|
+
peerDependencies: { "vitest": ">=3.2.0" },
|
|
163
|
+
engines: { "node": ">=22" },
|
|
164
|
+
productName,
|
|
165
|
+
readmeFilename: "README.md"
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region ../../apps/desktop/src/main/config.ts
|
|
170
|
+
const isPkg = "pkg" in process && process.pkg !== void 0;
|
|
171
|
+
const isElectron = !!process.versions.electron && false;
|
|
172
|
+
const isCLI = !isElectron;
|
|
173
|
+
const fullVersion = `v${version$1} ${node_process.platform}-${node_process.arch} node-${node_process.version}`;
|
|
174
|
+
const shortVersion = `v${version$1}`;
|
|
175
|
+
const APP_NAME = name.split("/")[0]?.split("-")[0]?.replace("@", "");
|
|
176
|
+
const APP_TITLE = productName;
|
|
177
|
+
const OS_TITLE_MAP = {
|
|
178
|
+
darwin: "macOS",
|
|
179
|
+
win32: "Windows",
|
|
180
|
+
linux: "Linux"
|
|
181
|
+
};
|
|
182
|
+
const OS_TITLE = OS_TITLE_MAP[process.platform];
|
|
183
|
+
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region ../../apps/desktop/src/main/path.ts
|
|
186
|
+
const resolveDir = (input) => {
|
|
187
|
+
const dir = typeof input === "string" ? input : input[OS_TITLE];
|
|
188
|
+
if (!(0, node_fs.existsSync)(dir)) (0, node_fs.mkdirSync)(dir, { recursive: true });
|
|
189
|
+
return dir;
|
|
190
|
+
};
|
|
191
|
+
const HOME_DIR = (0, node_os.homedir)();
|
|
192
|
+
const TEMP_DIR = (0, node_os.tmpdir)();
|
|
193
|
+
const DATA_DIR = resolveDir({
|
|
194
|
+
Windows: process.env.APPDATA || (0, node_path.join)(HOME_DIR, "AppData", "Roaming"),
|
|
195
|
+
macOS: (0, node_path.join)(HOME_DIR, "Library", "Application Support"),
|
|
196
|
+
Linux: process.env.XDG_DATA_HOME || (0, node_path.join)(HOME_DIR, ".local", "share")
|
|
197
|
+
});
|
|
198
|
+
const CONFIG_DIR = resolveDir({
|
|
199
|
+
Windows: process.env.APPDATA || (0, node_path.join)(HOME_DIR, "AppData", "Roaming"),
|
|
200
|
+
macOS: (0, node_path.join)(HOME_DIR, "Library", "Application Support"),
|
|
201
|
+
Linux: process.env.XDG_CONFIG_HOME || (0, node_path.join)(HOME_DIR, ".config")
|
|
202
|
+
});
|
|
203
|
+
const CACHE_DIR = resolveDir({
|
|
204
|
+
Windows: process.env.LOCALAPPDATA || (0, node_path.join)(HOME_DIR, "AppData", "Local"),
|
|
205
|
+
macOS: (0, node_path.join)(HOME_DIR, "Library", "Caches"),
|
|
206
|
+
Linux: process.env.XDG_CACHE_HOME || (0, node_path.join)(HOME_DIR, ".cache")
|
|
207
|
+
});
|
|
208
|
+
const DOWNLOAD_DIR = resolveDir({
|
|
209
|
+
Windows: (0, node_path.join)(HOME_DIR, "Downloads"),
|
|
210
|
+
macOS: (0, node_path.join)(HOME_DIR, "Downloads"),
|
|
211
|
+
Linux: process.env.XDG_DOWNLOAD_DIR || (0, node_path.join)(HOME_DIR, "Downloads")
|
|
212
|
+
});
|
|
213
|
+
const APP_DATA_DIR = resolveDir({
|
|
214
|
+
Windows: (0, node_path.join)(DATA_DIR, APP_TITLE),
|
|
215
|
+
macOS: (0, node_path.join)(DATA_DIR, APP_TITLE),
|
|
216
|
+
Linux: (0, node_path.join)(DATA_DIR, APP_TITLE.toLowerCase())
|
|
217
|
+
});
|
|
218
|
+
const APP_CONFIG_DIR = resolveDir({
|
|
219
|
+
Windows: (0, node_path.join)(CONFIG_DIR, APP_TITLE),
|
|
220
|
+
macOS: (0, node_path.join)(CONFIG_DIR, APP_TITLE),
|
|
221
|
+
Linux: (0, node_path.join)(CONFIG_DIR, APP_TITLE.toLowerCase())
|
|
222
|
+
});
|
|
223
|
+
const APP_LOG_DIR = resolveDir({
|
|
224
|
+
Windows: (0, node_path.join)(CONFIG_DIR, APP_TITLE, "logs"),
|
|
225
|
+
macOS: (0, node_path.join)(HOME_DIR, "Library", "Logs", APP_TITLE),
|
|
226
|
+
Linux: (0, node_path.join)(CONFIG_DIR, APP_TITLE.toLowerCase(), "logs")
|
|
227
|
+
});
|
|
228
|
+
const APP_TEMP_DIR = (0, node_path.join)(TEMP_DIR, APP_TITLE.toLowerCase());
|
|
229
|
+
const EXTENSIONS_DIR = resolveDir((0, node_path.join)(APP_DATA_DIR, "extensions"));
|
|
230
|
+
const EXTENSIONS_SOURCES_DIR = resolveDir((0, node_path.join)(EXTENSIONS_DIR, "installed"));
|
|
231
|
+
const EXTENSIONS_DATA_DIR = resolveDir((0, node_path.join)(EXTENSIONS_DIR, "work"));
|
|
232
|
+
const EXTENSIONS_INDEX_PATH = resolveDir((0, node_path.join)(EXTENSIONS_DIR, "index.json"));
|
|
233
|
+
const SETTINGS_PATH = (0, node_path.join)(APP_CONFIG_DIR, "settings.json");
|
|
234
|
+
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region ../../apps/desktop/src/main/core/logger.ts
|
|
237
|
+
const isDev = process.argv.includes("-d") || process.argv.includes("--debug") || process.env.NODE_ENV_ELECTRON_VITE === "development" || !!process.env.ELECTRON_CLI_ARGS;
|
|
238
|
+
const getLogFileName = () => {
|
|
239
|
+
return `Azot_${(/* @__PURE__ */ new Date()).toISOString().split(".")[0].replace("T", "_").replaceAll("-", "").replaceAll(":", "")}.log`;
|
|
240
|
+
};
|
|
241
|
+
const getLogFilePath = () => (0, node_path.join)(APP_LOG_DIR, getLogFileName());
|
|
242
|
+
(0, _logtape_logtape.configureSync)({
|
|
243
|
+
sinks: {
|
|
244
|
+
console: (0, _logtape_logtape.withFilter)((0, _logtape_logtape.getConsoleSink)({ formatter: (0, _logtape_pretty.getPrettyFormatter)({
|
|
245
|
+
timestamp: "time",
|
|
246
|
+
messageColor: null,
|
|
247
|
+
messageStyle: null,
|
|
248
|
+
levelStyle: null,
|
|
249
|
+
icons: false,
|
|
250
|
+
colors: true,
|
|
251
|
+
level: "FULL",
|
|
252
|
+
categoryWidth: 0,
|
|
253
|
+
categoryStyle: null,
|
|
254
|
+
categoryTruncate: "end",
|
|
255
|
+
wordWrap: true
|
|
256
|
+
}) }), isDev ? "debug" : "info"),
|
|
257
|
+
file: (0, _logtape_file.getFileSink)(getLogFilePath(), { flushInterval: 0 })
|
|
258
|
+
},
|
|
259
|
+
loggers: [{
|
|
260
|
+
category: [],
|
|
261
|
+
lowestLevel: "trace",
|
|
262
|
+
sinks: ["console", "file"]
|
|
263
|
+
}, {
|
|
264
|
+
category: ["logtape", "meta"],
|
|
265
|
+
lowestLevel: "error",
|
|
266
|
+
sinks: ["console"]
|
|
267
|
+
}]
|
|
268
|
+
});
|
|
269
|
+
const logger = (0, _logtape_logtape.getLogger)([]);
|
|
270
|
+
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region ../../apps/desktop/src/main/core/feedback.ts
|
|
273
|
+
var Feedback = class Feedback extends node_events.EventEmitter {
|
|
274
|
+
static requestEventName = "feedback";
|
|
275
|
+
static responseEventName = "feedback:response";
|
|
276
|
+
#queue = Promise.resolve();
|
|
277
|
+
async ask(request) {
|
|
278
|
+
const run = () => new Promise((resolve) => {
|
|
279
|
+
this.once(Feedback.responseEventName, (response) => {
|
|
280
|
+
resolve(response);
|
|
281
|
+
});
|
|
282
|
+
this.emit(Feedback.requestEventName, request);
|
|
283
|
+
});
|
|
284
|
+
const next = this.#queue.then(run, run);
|
|
285
|
+
this.#queue = next.then(() => void 0, () => void 0);
|
|
286
|
+
return next;
|
|
287
|
+
}
|
|
288
|
+
listen(listener) {
|
|
289
|
+
this.addListener(Feedback.requestEventName, async (request) => {
|
|
290
|
+
const answer = await listener(request);
|
|
291
|
+
this.emit(Feedback.responseEventName, answer);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
const feedback = new Feedback();
|
|
296
|
+
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region ../../apps/desktop/src/main/core/utils.ts
|
|
299
|
+
const sanitizeString = (text) => {
|
|
300
|
+
const forbidden = [
|
|
301
|
+
"}",
|
|
302
|
+
"{",
|
|
303
|
+
"%",
|
|
304
|
+
">",
|
|
305
|
+
"<",
|
|
306
|
+
"^",
|
|
307
|
+
";",
|
|
308
|
+
"`",
|
|
309
|
+
"$",
|
|
310
|
+
"\"",
|
|
311
|
+
"@",
|
|
312
|
+
"="
|
|
313
|
+
];
|
|
314
|
+
let result = text;
|
|
315
|
+
for (const i in forbidden) result = result.replaceAll("/", "_").replaceAll(forbidden[i], "");
|
|
316
|
+
return result;
|
|
317
|
+
};
|
|
318
|
+
const execUrlPatterns = (url, patterns, baseUrls) => {
|
|
319
|
+
const pathname = {};
|
|
320
|
+
const search = {};
|
|
321
|
+
for (const baseUrl of baseUrls) for (const path of patterns) {
|
|
322
|
+
const patternResult = new URLPattern(path, baseUrl).exec(url);
|
|
323
|
+
if (patternResult) {
|
|
324
|
+
Object.assign(pathname, patternResult.pathname.groups);
|
|
325
|
+
Object.assign(search, patternResult.search.groups);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
pathname,
|
|
330
|
+
search
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
const extendEpisodes = (episodesBySeasons = /* @__PURE__ */ new Map()) => {
|
|
334
|
+
const has = (episode, season) => {
|
|
335
|
+
for (const s of episodesBySeasons.keys()) for (const e of episodesBySeasons.get(s) || []) {
|
|
336
|
+
const seasonEmpty = season === void 0 || isNaN(season);
|
|
337
|
+
const episodeEmpty = episode === void 0 || isNaN(episode);
|
|
338
|
+
let hasMatch = false;
|
|
339
|
+
if (episodeEmpty) hasMatch = s === season;
|
|
340
|
+
else hasMatch = (seasonEmpty ? isNaN(s) : s === season) && e === episode;
|
|
341
|
+
if (hasMatch) return true;
|
|
342
|
+
}
|
|
343
|
+
return false;
|
|
344
|
+
};
|
|
345
|
+
const set = (episode, season) => {
|
|
346
|
+
const s = season || NaN;
|
|
347
|
+
const e = episode || NaN;
|
|
348
|
+
if (episodesBySeasons.has(s)) episodesBySeasons.get(s)?.add(e);
|
|
349
|
+
else episodesBySeasons.set(s, new Set([e]));
|
|
350
|
+
};
|
|
351
|
+
const getAllEpisodeNumbers = () => Array.from(episodesBySeasons.values()).flatMap((value) => Array.from(value));
|
|
352
|
+
const seasonsCount = episodesBySeasons.size;
|
|
353
|
+
const episodes = getAllEpisodeNumbers();
|
|
354
|
+
const episodesCount = episodes.length;
|
|
355
|
+
const getMin = () => Math.min(...episodes);
|
|
356
|
+
const getMax = () => Math.max(...episodes);
|
|
357
|
+
return {
|
|
358
|
+
items: episodesBySeasons,
|
|
359
|
+
has,
|
|
360
|
+
set,
|
|
361
|
+
getMin,
|
|
362
|
+
getMax,
|
|
363
|
+
seasonsCount,
|
|
364
|
+
episodesCount
|
|
365
|
+
};
|
|
366
|
+
};
|
|
367
|
+
const dateTimeFormatter = new Intl.DateTimeFormat("en-US", {
|
|
368
|
+
year: "numeric",
|
|
369
|
+
month: "2-digit",
|
|
370
|
+
day: "2-digit",
|
|
371
|
+
hour: "2-digit",
|
|
372
|
+
minute: "2-digit",
|
|
373
|
+
second: "2-digit",
|
|
374
|
+
hour12: false
|
|
375
|
+
});
|
|
376
|
+
const timeFormatter = new Intl.DateTimeFormat("en-US", {
|
|
377
|
+
hour: "2-digit",
|
|
378
|
+
minute: "2-digit",
|
|
379
|
+
second: "2-digit",
|
|
380
|
+
hour12: false
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
//#endregion
|
|
384
|
+
//#region ../../apps/desktop/src/main/core/prompt.ts
|
|
385
|
+
var Prompt = class Prompt extends node_events.EventEmitter {
|
|
386
|
+
static requestEventName = "form";
|
|
387
|
+
static responseEventName = "form:response";
|
|
388
|
+
title;
|
|
389
|
+
#queue = Promise.resolve();
|
|
390
|
+
constructor(defaults = {}) {
|
|
391
|
+
super();
|
|
392
|
+
this.title = defaults.title;
|
|
393
|
+
if (isCLI) this.listen(async (form) => {
|
|
394
|
+
const readline = (0, node_readline_promises.createInterface)({
|
|
395
|
+
input: node_process.stdin,
|
|
396
|
+
output: node_process.stdout
|
|
397
|
+
});
|
|
398
|
+
const { title, description, fields, ...restFields } = form;
|
|
399
|
+
const response = {};
|
|
400
|
+
for (const [field, { label, type }] of Object.entries(fields || restFields)) {
|
|
401
|
+
const isBooleanQuestion = type === "confirm";
|
|
402
|
+
const formattedMessage = [
|
|
403
|
+
title,
|
|
404
|
+
description,
|
|
405
|
+
label
|
|
406
|
+
].filter(Boolean).join(". ") + (isBooleanQuestion ? " (y/n)" : "") + ": ";
|
|
407
|
+
response[field] = await Promise.race([readline.question(formattedMessage), (0, node_timers_promises.setTimeout)(TIMEOUT, "")]);
|
|
408
|
+
}
|
|
409
|
+
readline.close();
|
|
410
|
+
return response;
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
async ask(request) {
|
|
414
|
+
const run = () => new Promise((resolve) => {
|
|
415
|
+
this.once(Prompt.responseEventName, (response) => {
|
|
416
|
+
resolve(response);
|
|
417
|
+
});
|
|
418
|
+
this.emit(Prompt.requestEventName, request);
|
|
419
|
+
});
|
|
420
|
+
const next = this.#queue.then(run, run);
|
|
421
|
+
this.#queue = next.then(() => void 0, () => void 0);
|
|
422
|
+
return next;
|
|
423
|
+
}
|
|
424
|
+
listen(listener) {
|
|
425
|
+
this.addListener(Prompt.requestEventName, async (request) => {
|
|
426
|
+
const answer = await listener(request);
|
|
427
|
+
this.emit(Prompt.responseEventName, answer);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
const prompt = new Prompt();
|
|
432
|
+
const input = async (message, options) => {
|
|
433
|
+
const fields = options?.fields ?? { answer: { label: message } };
|
|
434
|
+
return await prompt.ask({
|
|
435
|
+
title: options?.title,
|
|
436
|
+
description: message,
|
|
437
|
+
fields
|
|
438
|
+
});
|
|
439
|
+
};
|
|
440
|
+
const TIMEOUT = 12e4;
|
|
441
|
+
|
|
442
|
+
//#endregion
|
|
443
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/HTTPError.js
|
|
444
|
+
var HTTPError = class extends Error {
|
|
445
|
+
response;
|
|
446
|
+
request;
|
|
447
|
+
options;
|
|
448
|
+
constructor(response, request, options) {
|
|
449
|
+
const status = `${response.status || response.status === 0 ? response.status : ""} ${response.statusText ?? ""}`.trim();
|
|
450
|
+
const reason = status ? `status code ${status}` : "an unknown error";
|
|
451
|
+
super(`Request failed with ${reason}: ${request.method} ${request.url}`);
|
|
452
|
+
this.name = "HTTPError";
|
|
453
|
+
this.response = response;
|
|
454
|
+
this.request = request;
|
|
455
|
+
this.options = options;
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/NonError.js
|
|
461
|
+
/**
|
|
462
|
+
Wrapper for non-Error values that were thrown.
|
|
463
|
+
|
|
464
|
+
In JavaScript, any value can be thrown (not just Error instances). This class wraps such values to ensure consistent error handling.
|
|
465
|
+
*/
|
|
466
|
+
var NonError = class extends Error {
|
|
467
|
+
name = "NonError";
|
|
468
|
+
value;
|
|
469
|
+
constructor(value) {
|
|
470
|
+
let message = "Non-error value was thrown";
|
|
471
|
+
try {
|
|
472
|
+
if (typeof value === "string") message = value;
|
|
473
|
+
else if (value && typeof value === "object" && "message" in value && typeof value.message === "string") message = value.message;
|
|
474
|
+
} catch {}
|
|
475
|
+
super(message);
|
|
476
|
+
this.value = value;
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
//#endregion
|
|
481
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/ForceRetryError.js
|
|
482
|
+
/**
|
|
483
|
+
Internal error used to signal a forced retry from afterResponse hooks.
|
|
484
|
+
This is thrown when a user returns ky.retry() from an afterResponse hook.
|
|
485
|
+
*/
|
|
486
|
+
var ForceRetryError = class extends Error {
|
|
487
|
+
name = "ForceRetryError";
|
|
488
|
+
customDelay;
|
|
489
|
+
code;
|
|
490
|
+
customRequest;
|
|
491
|
+
constructor(options) {
|
|
492
|
+
const cause = options?.cause ? options.cause instanceof Error ? options.cause : new NonError(options.cause) : void 0;
|
|
493
|
+
super(options?.code ? `Forced retry: ${options.code}` : "Forced retry", cause ? { cause } : void 0);
|
|
494
|
+
this.customDelay = options?.delay;
|
|
495
|
+
this.code = options?.code;
|
|
496
|
+
this.customRequest = options?.request;
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/core/constants.js
|
|
502
|
+
const supportsRequestStreams = (() => {
|
|
503
|
+
let duplexAccessed = false;
|
|
504
|
+
let hasContentType = false;
|
|
505
|
+
const supportsReadableStream = typeof globalThis.ReadableStream === "function";
|
|
506
|
+
const supportsRequest = typeof globalThis.Request === "function";
|
|
507
|
+
if (supportsReadableStream && supportsRequest) try {
|
|
508
|
+
hasContentType = new globalThis.Request("https://empty.invalid", {
|
|
509
|
+
body: new globalThis.ReadableStream(),
|
|
510
|
+
method: "POST",
|
|
511
|
+
get duplex() {
|
|
512
|
+
duplexAccessed = true;
|
|
513
|
+
return "half";
|
|
514
|
+
}
|
|
515
|
+
}).headers.has("Content-Type");
|
|
516
|
+
} catch (error) {
|
|
517
|
+
if (error instanceof Error && error.message === "unsupported BodyInit type") return false;
|
|
518
|
+
throw error;
|
|
519
|
+
}
|
|
520
|
+
return duplexAccessed && !hasContentType;
|
|
521
|
+
})();
|
|
522
|
+
const supportsAbortController = typeof globalThis.AbortController === "function";
|
|
523
|
+
const supportsAbortSignal = typeof globalThis.AbortSignal === "function" && typeof globalThis.AbortSignal.any === "function";
|
|
524
|
+
const supportsResponseStreams = typeof globalThis.ReadableStream === "function";
|
|
525
|
+
const supportsFormData = typeof globalThis.FormData === "function";
|
|
526
|
+
const requestMethods = [
|
|
527
|
+
"get",
|
|
528
|
+
"post",
|
|
529
|
+
"put",
|
|
530
|
+
"patch",
|
|
531
|
+
"head",
|
|
532
|
+
"delete"
|
|
533
|
+
];
|
|
534
|
+
const validate = () => void 0;
|
|
535
|
+
validate();
|
|
536
|
+
const responseTypes = {
|
|
537
|
+
json: "application/json",
|
|
538
|
+
text: "text/*",
|
|
539
|
+
formData: "multipart/form-data",
|
|
540
|
+
arrayBuffer: "*/*",
|
|
541
|
+
blob: "*/*",
|
|
542
|
+
bytes: "*/*"
|
|
543
|
+
};
|
|
544
|
+
const maxSafeTimeout = 2147483647;
|
|
545
|
+
const usualFormBoundarySize = new TextEncoder().encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length;
|
|
546
|
+
const stop = Symbol("stop");
|
|
547
|
+
/**
|
|
548
|
+
Marker returned by ky.retry() to signal a forced retry from afterResponse hooks.
|
|
549
|
+
*/
|
|
550
|
+
var RetryMarker = class {
|
|
551
|
+
options;
|
|
552
|
+
constructor(options) {
|
|
553
|
+
this.options = options;
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
/**
|
|
557
|
+
Force a retry from an `afterResponse` hook.
|
|
558
|
+
|
|
559
|
+
This allows you to retry a request based on the response content, even if the response has a successful status code. The retry will respect the `retry.limit` option and skip the `shouldRetry` check. The forced retry is observable in `beforeRetry` hooks, where the error will be a `ForceRetryError`.
|
|
560
|
+
|
|
561
|
+
@param options - Optional configuration for the retry.
|
|
562
|
+
|
|
563
|
+
@example
|
|
564
|
+
```
|
|
565
|
+
import ky, {isForceRetryError} from 'ky';
|
|
566
|
+
|
|
567
|
+
const api = ky.extend({
|
|
568
|
+
hooks: {
|
|
569
|
+
afterResponse: [
|
|
570
|
+
async (request, options, response) => {
|
|
571
|
+
// Retry based on response body content
|
|
572
|
+
if (response.status === 200) {
|
|
573
|
+
const data = await response.clone().json();
|
|
574
|
+
|
|
575
|
+
// Simple retry with default delay
|
|
576
|
+
if (data.error?.code === 'TEMPORARY_ERROR') {
|
|
577
|
+
return ky.retry();
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Retry with custom delay from API response
|
|
581
|
+
if (data.error?.code === 'RATE_LIMIT') {
|
|
582
|
+
return ky.retry({
|
|
583
|
+
delay: data.error.retryAfter * 1000,
|
|
584
|
+
code: 'RATE_LIMIT'
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// Retry with a modified request (e.g., fallback endpoint)
|
|
589
|
+
if (data.error?.code === 'FALLBACK_TO_BACKUP') {
|
|
590
|
+
return ky.retry({
|
|
591
|
+
request: new Request('https://backup-api.com/endpoint', {
|
|
592
|
+
method: request.method,
|
|
593
|
+
headers: request.headers,
|
|
594
|
+
}),
|
|
595
|
+
code: 'BACKUP_ENDPOINT'
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// Retry with refreshed authentication
|
|
600
|
+
if (data.error?.code === 'TOKEN_REFRESH' && data.newToken) {
|
|
601
|
+
return ky.retry({
|
|
602
|
+
request: new Request(request, {
|
|
603
|
+
headers: {
|
|
604
|
+
...Object.fromEntries(request.headers),
|
|
605
|
+
'Authorization': `Bearer ${data.newToken}`
|
|
606
|
+
}
|
|
607
|
+
}),
|
|
608
|
+
code: 'TOKEN_REFRESHED'
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Retry with cause to preserve error chain
|
|
613
|
+
try {
|
|
614
|
+
validateResponse(data);
|
|
615
|
+
} catch (error) {
|
|
616
|
+
return ky.retry({
|
|
617
|
+
code: 'VALIDATION_FAILED',
|
|
618
|
+
cause: error
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
],
|
|
624
|
+
beforeRetry: [
|
|
625
|
+
({error, retryCount}) => {
|
|
626
|
+
// Observable in beforeRetry hooks
|
|
627
|
+
if (isForceRetryError(error)) {
|
|
628
|
+
console.log(`Forced retry #${retryCount}: ${error.message}`);
|
|
629
|
+
// Example output: "Forced retry #1: Forced retry: RATE_LIMIT"
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
]
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
const response = await api.get('https://example.com/api');
|
|
637
|
+
```
|
|
638
|
+
*/
|
|
639
|
+
const retry = (options) => new RetryMarker(options);
|
|
640
|
+
const kyOptionKeys = {
|
|
641
|
+
json: true,
|
|
642
|
+
parseJson: true,
|
|
643
|
+
stringifyJson: true,
|
|
644
|
+
searchParams: true,
|
|
645
|
+
prefixUrl: true,
|
|
646
|
+
retry: true,
|
|
647
|
+
timeout: true,
|
|
648
|
+
hooks: true,
|
|
649
|
+
throwHttpErrors: true,
|
|
650
|
+
onDownloadProgress: true,
|
|
651
|
+
onUploadProgress: true,
|
|
652
|
+
fetch: true,
|
|
653
|
+
context: true
|
|
654
|
+
};
|
|
655
|
+
const vendorSpecificOptions = { next: true };
|
|
656
|
+
const requestOptionsRegistry = {
|
|
657
|
+
method: true,
|
|
658
|
+
headers: true,
|
|
659
|
+
body: true,
|
|
660
|
+
mode: true,
|
|
661
|
+
credentials: true,
|
|
662
|
+
cache: true,
|
|
663
|
+
redirect: true,
|
|
664
|
+
referrer: true,
|
|
665
|
+
referrerPolicy: true,
|
|
666
|
+
integrity: true,
|
|
667
|
+
keepalive: true,
|
|
668
|
+
signal: true,
|
|
669
|
+
window: true,
|
|
670
|
+
duplex: true
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
//#endregion
|
|
674
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/body.js
|
|
675
|
+
const getBodySize = (body) => {
|
|
676
|
+
if (!body) return 0;
|
|
677
|
+
if (body instanceof FormData) {
|
|
678
|
+
let size = 0;
|
|
679
|
+
for (const [key, value] of body) {
|
|
680
|
+
size += usualFormBoundarySize;
|
|
681
|
+
size += new TextEncoder().encode(`Content-Disposition: form-data; name="${key}"`).length;
|
|
682
|
+
size += typeof value === "string" ? new TextEncoder().encode(value).length : value.size;
|
|
683
|
+
}
|
|
684
|
+
return size;
|
|
685
|
+
}
|
|
686
|
+
if (body instanceof Blob) return body.size;
|
|
687
|
+
if (body instanceof ArrayBuffer) return body.byteLength;
|
|
688
|
+
if (typeof body === "string") return new TextEncoder().encode(body).length;
|
|
689
|
+
if (body instanceof URLSearchParams) return new TextEncoder().encode(body.toString()).length;
|
|
690
|
+
if ("byteLength" in body) return body.byteLength;
|
|
691
|
+
if (typeof body === "object" && body !== null) try {
|
|
692
|
+
const jsonString = JSON.stringify(body);
|
|
693
|
+
return new TextEncoder().encode(jsonString).length;
|
|
694
|
+
} catch {
|
|
695
|
+
return 0;
|
|
696
|
+
}
|
|
697
|
+
return 0;
|
|
698
|
+
};
|
|
699
|
+
const withProgress = (stream, totalBytes, onProgress) => {
|
|
700
|
+
let previousChunk;
|
|
701
|
+
let transferredBytes = 0;
|
|
702
|
+
return stream.pipeThrough(new TransformStream({
|
|
703
|
+
transform(currentChunk, controller) {
|
|
704
|
+
controller.enqueue(currentChunk);
|
|
705
|
+
if (previousChunk) {
|
|
706
|
+
transferredBytes += previousChunk.byteLength;
|
|
707
|
+
let percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
|
|
708
|
+
if (percent >= 1) percent = 1 - Number.EPSILON;
|
|
709
|
+
onProgress?.({
|
|
710
|
+
percent,
|
|
711
|
+
totalBytes: Math.max(totalBytes, transferredBytes),
|
|
712
|
+
transferredBytes
|
|
713
|
+
}, previousChunk);
|
|
714
|
+
}
|
|
715
|
+
previousChunk = currentChunk;
|
|
716
|
+
},
|
|
717
|
+
flush() {
|
|
718
|
+
if (previousChunk) {
|
|
719
|
+
transferredBytes += previousChunk.byteLength;
|
|
720
|
+
onProgress?.({
|
|
721
|
+
percent: 1,
|
|
722
|
+
totalBytes: Math.max(totalBytes, transferredBytes),
|
|
723
|
+
transferredBytes
|
|
724
|
+
}, previousChunk);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}));
|
|
728
|
+
};
|
|
729
|
+
const streamResponse = (response, onDownloadProgress) => {
|
|
730
|
+
if (!response.body) return response;
|
|
731
|
+
if (response.status === 204) return new Response(null, {
|
|
732
|
+
status: response.status,
|
|
733
|
+
statusText: response.statusText,
|
|
734
|
+
headers: response.headers
|
|
735
|
+
});
|
|
736
|
+
const totalBytes = Math.max(0, Number(response.headers.get("content-length")) || 0);
|
|
737
|
+
return new Response(withProgress(response.body, totalBytes, onDownloadProgress), {
|
|
738
|
+
status: response.status,
|
|
739
|
+
statusText: response.statusText,
|
|
740
|
+
headers: response.headers
|
|
741
|
+
});
|
|
742
|
+
};
|
|
743
|
+
const streamRequest = (request, onUploadProgress, originalBody) => {
|
|
744
|
+
if (!request.body) return request;
|
|
745
|
+
const totalBytes = getBodySize(originalBody ?? request.body);
|
|
746
|
+
return new Request(request, {
|
|
747
|
+
duplex: "half",
|
|
748
|
+
body: withProgress(request.body, totalBytes, onUploadProgress)
|
|
749
|
+
});
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
//#endregion
|
|
753
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/is.js
|
|
754
|
+
const isObject = (value) => value !== null && typeof value === "object";
|
|
755
|
+
|
|
756
|
+
//#endregion
|
|
757
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/merge.js
|
|
758
|
+
const validateAndMerge = (...sources) => {
|
|
759
|
+
for (const source of sources) if ((!isObject(source) || Array.isArray(source)) && source !== void 0) throw new TypeError("The `options` argument must be an object");
|
|
760
|
+
return deepMerge({}, ...sources);
|
|
761
|
+
};
|
|
762
|
+
const mergeHeaders = (source1 = {}, source2 = {}) => {
|
|
763
|
+
const result = new globalThis.Headers(source1);
|
|
764
|
+
const isHeadersInstance = source2 instanceof globalThis.Headers;
|
|
765
|
+
const source = new globalThis.Headers(source2);
|
|
766
|
+
for (const [key, value] of source.entries()) if (isHeadersInstance && value === "undefined" || value === void 0) result.delete(key);
|
|
767
|
+
else result.set(key, value);
|
|
768
|
+
return result;
|
|
769
|
+
};
|
|
770
|
+
function newHookValue(original, incoming, property) {
|
|
771
|
+
return Object.hasOwn(incoming, property) && incoming[property] === void 0 ? [] : deepMerge(original[property] ?? [], incoming[property] ?? []);
|
|
772
|
+
}
|
|
773
|
+
const mergeHooks = (original = {}, incoming = {}) => ({
|
|
774
|
+
beforeRequest: newHookValue(original, incoming, "beforeRequest"),
|
|
775
|
+
beforeRetry: newHookValue(original, incoming, "beforeRetry"),
|
|
776
|
+
afterResponse: newHookValue(original, incoming, "afterResponse"),
|
|
777
|
+
beforeError: newHookValue(original, incoming, "beforeError")
|
|
778
|
+
});
|
|
779
|
+
const appendSearchParameters = (target, source) => {
|
|
780
|
+
const result = new URLSearchParams();
|
|
781
|
+
for (const input of [target, source]) {
|
|
782
|
+
if (input === void 0) continue;
|
|
783
|
+
if (input instanceof URLSearchParams) for (const [key, value] of input.entries()) result.append(key, value);
|
|
784
|
+
else if (Array.isArray(input)) for (const pair of input) {
|
|
785
|
+
if (!Array.isArray(pair) || pair.length !== 2) throw new TypeError("Array search parameters must be provided in [[key, value], ...] format");
|
|
786
|
+
result.append(String(pair[0]), String(pair[1]));
|
|
787
|
+
}
|
|
788
|
+
else if (isObject(input)) {
|
|
789
|
+
for (const [key, value] of Object.entries(input)) if (value !== void 0) result.append(key, String(value));
|
|
790
|
+
} else {
|
|
791
|
+
const parameters = new URLSearchParams(input);
|
|
792
|
+
for (const [key, value] of parameters.entries()) result.append(key, value);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
return result;
|
|
796
|
+
};
|
|
797
|
+
const deepMerge = (...sources) => {
|
|
798
|
+
let returnValue = {};
|
|
799
|
+
let headers = {};
|
|
800
|
+
let hooks = {};
|
|
801
|
+
let searchParameters;
|
|
802
|
+
const signals = [];
|
|
803
|
+
for (const source of sources) if (Array.isArray(source)) {
|
|
804
|
+
if (!Array.isArray(returnValue)) returnValue = [];
|
|
805
|
+
returnValue = [...returnValue, ...source];
|
|
806
|
+
} else if (isObject(source)) {
|
|
807
|
+
for (let [key, value] of Object.entries(source)) {
|
|
808
|
+
if (key === "signal" && value instanceof globalThis.AbortSignal) {
|
|
809
|
+
signals.push(value);
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
if (key === "context") {
|
|
813
|
+
if (value !== void 0 && value !== null && (!isObject(value) || Array.isArray(value))) throw new TypeError("The `context` option must be an object");
|
|
814
|
+
returnValue = {
|
|
815
|
+
...returnValue,
|
|
816
|
+
context: value === void 0 || value === null ? {} : {
|
|
817
|
+
...returnValue.context,
|
|
818
|
+
...value
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
continue;
|
|
822
|
+
}
|
|
823
|
+
if (key === "searchParams") {
|
|
824
|
+
if (value === void 0 || value === null) searchParameters = void 0;
|
|
825
|
+
else searchParameters = searchParameters === void 0 ? value : appendSearchParameters(searchParameters, value);
|
|
826
|
+
continue;
|
|
827
|
+
}
|
|
828
|
+
if (isObject(value) && key in returnValue) value = deepMerge(returnValue[key], value);
|
|
829
|
+
returnValue = {
|
|
830
|
+
...returnValue,
|
|
831
|
+
[key]: value
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
if (isObject(source.hooks)) {
|
|
835
|
+
hooks = mergeHooks(hooks, source.hooks);
|
|
836
|
+
returnValue.hooks = hooks;
|
|
837
|
+
}
|
|
838
|
+
if (isObject(source.headers)) {
|
|
839
|
+
headers = mergeHeaders(headers, source.headers);
|
|
840
|
+
returnValue.headers = headers;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
if (searchParameters !== void 0) returnValue.searchParams = searchParameters;
|
|
844
|
+
if (signals.length > 0) if (signals.length === 1) returnValue.signal = signals[0];
|
|
845
|
+
else if (supportsAbortSignal) returnValue.signal = AbortSignal.any(signals);
|
|
846
|
+
else returnValue.signal = signals.at(-1);
|
|
847
|
+
return returnValue;
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
//#endregion
|
|
851
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/normalize.js
|
|
852
|
+
const normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;
|
|
853
|
+
const defaultRetryOptions = {
|
|
854
|
+
limit: 2,
|
|
855
|
+
methods: [
|
|
856
|
+
"get",
|
|
857
|
+
"put",
|
|
858
|
+
"head",
|
|
859
|
+
"delete",
|
|
860
|
+
"options",
|
|
861
|
+
"trace"
|
|
862
|
+
],
|
|
863
|
+
statusCodes: [
|
|
864
|
+
408,
|
|
865
|
+
413,
|
|
866
|
+
429,
|
|
867
|
+
500,
|
|
868
|
+
502,
|
|
869
|
+
503,
|
|
870
|
+
504
|
|
871
|
+
],
|
|
872
|
+
afterStatusCodes: [
|
|
873
|
+
413,
|
|
874
|
+
429,
|
|
875
|
+
503
|
|
876
|
+
],
|
|
877
|
+
maxRetryAfter: Number.POSITIVE_INFINITY,
|
|
878
|
+
backoffLimit: Number.POSITIVE_INFINITY,
|
|
879
|
+
delay: (attemptCount) => .3 * 2 ** (attemptCount - 1) * 1e3,
|
|
880
|
+
jitter: void 0,
|
|
881
|
+
retryOnTimeout: false
|
|
882
|
+
};
|
|
883
|
+
const normalizeRetryOptions = (retry = {}) => {
|
|
884
|
+
if (typeof retry === "number") return {
|
|
885
|
+
...defaultRetryOptions,
|
|
886
|
+
limit: retry
|
|
887
|
+
};
|
|
888
|
+
if (retry.methods && !Array.isArray(retry.methods)) throw new Error("retry.methods must be an array");
|
|
889
|
+
retry.methods &&= retry.methods.map((method) => method.toLowerCase());
|
|
890
|
+
if (retry.statusCodes && !Array.isArray(retry.statusCodes)) throw new Error("retry.statusCodes must be an array");
|
|
891
|
+
const normalizedRetry = Object.fromEntries(Object.entries(retry).filter(([, value]) => value !== void 0));
|
|
892
|
+
return {
|
|
893
|
+
...defaultRetryOptions,
|
|
894
|
+
...normalizedRetry
|
|
895
|
+
};
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
//#endregion
|
|
899
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/TimeoutError.js
|
|
900
|
+
var TimeoutError = class extends Error {
|
|
901
|
+
request;
|
|
902
|
+
constructor(request) {
|
|
903
|
+
super(`Request timed out: ${request.method} ${request.url}`);
|
|
904
|
+
this.name = "TimeoutError";
|
|
905
|
+
this.request = request;
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
|
|
909
|
+
//#endregion
|
|
910
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js
|
|
911
|
+
async function timeout(request, init, abortController, options) {
|
|
912
|
+
return new Promise((resolve, reject) => {
|
|
913
|
+
const timeoutId = setTimeout(() => {
|
|
914
|
+
if (abortController) abortController.abort();
|
|
915
|
+
reject(new TimeoutError(request));
|
|
916
|
+
}, options.timeout);
|
|
917
|
+
options.fetch(request, init).then(resolve).catch(reject).then(() => {
|
|
918
|
+
clearTimeout(timeoutId);
|
|
919
|
+
});
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
//#endregion
|
|
924
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/delay.js
|
|
925
|
+
async function delay(ms, { signal }) {
|
|
926
|
+
return new Promise((resolve, reject) => {
|
|
927
|
+
if (signal) {
|
|
928
|
+
signal.throwIfAborted();
|
|
929
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
930
|
+
}
|
|
931
|
+
function abortHandler() {
|
|
932
|
+
clearTimeout(timeoutId);
|
|
933
|
+
reject(signal.reason);
|
|
934
|
+
}
|
|
935
|
+
const timeoutId = setTimeout(() => {
|
|
936
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
937
|
+
resolve();
|
|
938
|
+
}, ms);
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
//#endregion
|
|
943
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/options.js
|
|
944
|
+
const findUnknownOptions = (request, options) => {
|
|
945
|
+
const unknownOptions = {};
|
|
946
|
+
for (const key in options) {
|
|
947
|
+
if (!Object.hasOwn(options, key)) continue;
|
|
948
|
+
if (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && (!(key in request) || key in vendorSpecificOptions)) unknownOptions[key] = options[key];
|
|
949
|
+
}
|
|
950
|
+
return unknownOptions;
|
|
951
|
+
};
|
|
952
|
+
const hasSearchParameters = (search) => {
|
|
953
|
+
if (search === void 0) return false;
|
|
954
|
+
if (Array.isArray(search)) return search.length > 0;
|
|
955
|
+
if (search instanceof URLSearchParams) return search.size > 0;
|
|
956
|
+
if (typeof search === "object") return Object.keys(search).length > 0;
|
|
957
|
+
if (typeof search === "string") return search.trim().length > 0;
|
|
958
|
+
return Boolean(search);
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
//#endregion
|
|
962
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/type-guards.js
|
|
963
|
+
/**
|
|
964
|
+
Type guard to check if an error is an HTTPError.
|
|
965
|
+
|
|
966
|
+
@param error - The error to check
|
|
967
|
+
@returns `true` if the error is an HTTPError, `false` otherwise
|
|
968
|
+
|
|
969
|
+
@example
|
|
970
|
+
```
|
|
971
|
+
import ky, {isHTTPError} from 'ky';
|
|
972
|
+
try {
|
|
973
|
+
const response = await ky.get('/api/data');
|
|
974
|
+
} catch (error) {
|
|
975
|
+
if (isHTTPError(error)) {
|
|
976
|
+
console.log('HTTP error status:', error.response.status);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
```
|
|
980
|
+
*/
|
|
981
|
+
function isHTTPError(error) {
|
|
982
|
+
return error instanceof HTTPError || error?.name === HTTPError.name;
|
|
983
|
+
}
|
|
984
|
+
/**
|
|
985
|
+
Type guard to check if an error is a TimeoutError.
|
|
986
|
+
|
|
987
|
+
@param error - The error to check
|
|
988
|
+
@returns `true` if the error is a TimeoutError, `false` otherwise
|
|
989
|
+
|
|
990
|
+
@example
|
|
991
|
+
```
|
|
992
|
+
import ky, {isTimeoutError} from 'ky';
|
|
993
|
+
try {
|
|
994
|
+
const response = await ky.get('/api/data', { timeout: 1000 });
|
|
995
|
+
} catch (error) {
|
|
996
|
+
if (isTimeoutError(error)) {
|
|
997
|
+
console.log('Request timed out:', error.request.url);
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
```
|
|
1001
|
+
*/
|
|
1002
|
+
function isTimeoutError(error) {
|
|
1003
|
+
return error instanceof TimeoutError || error?.name === TimeoutError.name;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
//#endregion
|
|
1007
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/core/Ky.js
|
|
1008
|
+
var Ky = class Ky {
|
|
1009
|
+
static create(input, options) {
|
|
1010
|
+
const ky = new Ky(input, options);
|
|
1011
|
+
const function_ = async () => {
|
|
1012
|
+
if (typeof ky.#options.timeout === "number" && ky.#options.timeout > maxSafeTimeout) throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
|
|
1013
|
+
await Promise.resolve();
|
|
1014
|
+
let response = await ky.#fetch();
|
|
1015
|
+
for (const hook of ky.#options.hooks.afterResponse) {
|
|
1016
|
+
const clonedResponse = ky.#decorateResponse(response.clone());
|
|
1017
|
+
let modifiedResponse;
|
|
1018
|
+
try {
|
|
1019
|
+
modifiedResponse = await hook(ky.request, ky.#getNormalizedOptions(), clonedResponse, { retryCount: ky.#retryCount });
|
|
1020
|
+
} catch (error) {
|
|
1021
|
+
ky.#cancelResponseBody(clonedResponse);
|
|
1022
|
+
ky.#cancelResponseBody(response);
|
|
1023
|
+
throw error;
|
|
1024
|
+
}
|
|
1025
|
+
if (modifiedResponse instanceof RetryMarker) {
|
|
1026
|
+
ky.#cancelResponseBody(clonedResponse);
|
|
1027
|
+
ky.#cancelResponseBody(response);
|
|
1028
|
+
throw new ForceRetryError(modifiedResponse.options);
|
|
1029
|
+
}
|
|
1030
|
+
const nextResponse = modifiedResponse instanceof globalThis.Response ? modifiedResponse : response;
|
|
1031
|
+
if (clonedResponse !== nextResponse) ky.#cancelResponseBody(clonedResponse);
|
|
1032
|
+
if (response !== nextResponse) ky.#cancelResponseBody(response);
|
|
1033
|
+
response = nextResponse;
|
|
1034
|
+
}
|
|
1035
|
+
ky.#decorateResponse(response);
|
|
1036
|
+
if (!response.ok && (typeof ky.#options.throwHttpErrors === "function" ? ky.#options.throwHttpErrors(response.status) : ky.#options.throwHttpErrors)) {
|
|
1037
|
+
let error = new HTTPError(response, ky.request, ky.#getNormalizedOptions());
|
|
1038
|
+
for (const hook of ky.#options.hooks.beforeError) error = await hook(error, { retryCount: ky.#retryCount });
|
|
1039
|
+
throw error;
|
|
1040
|
+
}
|
|
1041
|
+
if (ky.#options.onDownloadProgress) {
|
|
1042
|
+
if (typeof ky.#options.onDownloadProgress !== "function") throw new TypeError("The `onDownloadProgress` option must be a function");
|
|
1043
|
+
if (!supportsResponseStreams) throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");
|
|
1044
|
+
const progressResponse = response.clone();
|
|
1045
|
+
ky.#cancelResponseBody(response);
|
|
1046
|
+
return streamResponse(progressResponse, ky.#options.onDownloadProgress);
|
|
1047
|
+
}
|
|
1048
|
+
return response;
|
|
1049
|
+
};
|
|
1050
|
+
const result = ky.#retry(function_).finally(() => {
|
|
1051
|
+
const originalRequest = ky.#originalRequest;
|
|
1052
|
+
ky.#cancelBody(originalRequest?.body ?? void 0);
|
|
1053
|
+
ky.#cancelBody(ky.request.body ?? void 0);
|
|
1054
|
+
});
|
|
1055
|
+
for (const [type, mimeType] of Object.entries(responseTypes)) {
|
|
1056
|
+
if (type === "bytes" && typeof globalThis.Response?.prototype?.bytes !== "function") continue;
|
|
1057
|
+
result[type] = async () => {
|
|
1058
|
+
ky.request.headers.set("accept", ky.request.headers.get("accept") || mimeType);
|
|
1059
|
+
const response = await result;
|
|
1060
|
+
if (type === "json") {
|
|
1061
|
+
if (response.status === 204) return "";
|
|
1062
|
+
const text = await response.text();
|
|
1063
|
+
if (text === "") return "";
|
|
1064
|
+
if (options.parseJson) return options.parseJson(text);
|
|
1065
|
+
return JSON.parse(text);
|
|
1066
|
+
}
|
|
1067
|
+
return response[type]();
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
return result;
|
|
1071
|
+
}
|
|
1072
|
+
static #normalizeSearchParams(searchParams) {
|
|
1073
|
+
if (searchParams && typeof searchParams === "object" && !Array.isArray(searchParams) && !(searchParams instanceof URLSearchParams)) return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => value !== void 0));
|
|
1074
|
+
return searchParams;
|
|
1075
|
+
}
|
|
1076
|
+
request;
|
|
1077
|
+
#abortController;
|
|
1078
|
+
#retryCount = 0;
|
|
1079
|
+
#input;
|
|
1080
|
+
#options;
|
|
1081
|
+
#originalRequest;
|
|
1082
|
+
#userProvidedAbortSignal;
|
|
1083
|
+
#cachedNormalizedOptions;
|
|
1084
|
+
constructor(input, options = {}) {
|
|
1085
|
+
this.#input = input;
|
|
1086
|
+
this.#options = {
|
|
1087
|
+
...options,
|
|
1088
|
+
headers: mergeHeaders(this.#input.headers, options.headers),
|
|
1089
|
+
hooks: mergeHooks({
|
|
1090
|
+
beforeRequest: [],
|
|
1091
|
+
beforeRetry: [],
|
|
1092
|
+
beforeError: [],
|
|
1093
|
+
afterResponse: []
|
|
1094
|
+
}, options.hooks),
|
|
1095
|
+
method: normalizeRequestMethod(options.method ?? this.#input.method ?? "GET"),
|
|
1096
|
+
prefixUrl: String(options.prefixUrl || ""),
|
|
1097
|
+
retry: normalizeRetryOptions(options.retry),
|
|
1098
|
+
throwHttpErrors: options.throwHttpErrors ?? true,
|
|
1099
|
+
timeout: options.timeout ?? 1e4,
|
|
1100
|
+
fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
|
|
1101
|
+
context: options.context ?? {}
|
|
1102
|
+
};
|
|
1103
|
+
if (typeof this.#input !== "string" && !(this.#input instanceof URL || this.#input instanceof globalThis.Request)) throw new TypeError("`input` must be a string, URL, or Request");
|
|
1104
|
+
if (this.#options.prefixUrl && typeof this.#input === "string") {
|
|
1105
|
+
if (this.#input.startsWith("/")) throw new Error("`input` must not begin with a slash when using `prefixUrl`");
|
|
1106
|
+
if (!this.#options.prefixUrl.endsWith("/")) this.#options.prefixUrl += "/";
|
|
1107
|
+
this.#input = this.#options.prefixUrl + this.#input;
|
|
1108
|
+
}
|
|
1109
|
+
if (supportsAbortController && supportsAbortSignal) {
|
|
1110
|
+
this.#userProvidedAbortSignal = this.#options.signal ?? this.#input.signal;
|
|
1111
|
+
this.#abortController = new globalThis.AbortController();
|
|
1112
|
+
this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;
|
|
1113
|
+
}
|
|
1114
|
+
if (supportsRequestStreams) this.#options.duplex = "half";
|
|
1115
|
+
if (this.#options.json !== void 0) {
|
|
1116
|
+
this.#options.body = this.#options.stringifyJson?.(this.#options.json) ?? JSON.stringify(this.#options.json);
|
|
1117
|
+
this.#options.headers.set("content-type", this.#options.headers.get("content-type") ?? "application/json");
|
|
1118
|
+
}
|
|
1119
|
+
const userProvidedContentType = options.headers && new globalThis.Headers(options.headers).has("content-type");
|
|
1120
|
+
if (this.#input instanceof globalThis.Request && (supportsFormData && this.#options.body instanceof globalThis.FormData || this.#options.body instanceof URLSearchParams) && !userProvidedContentType) this.#options.headers.delete("content-type");
|
|
1121
|
+
this.request = new globalThis.Request(this.#input, this.#options);
|
|
1122
|
+
if (hasSearchParameters(this.#options.searchParams)) {
|
|
1123
|
+
const searchParams = "?" + (typeof this.#options.searchParams === "string" ? this.#options.searchParams.replace(/^\?/, "") : new URLSearchParams(Ky.#normalizeSearchParams(this.#options.searchParams)).toString());
|
|
1124
|
+
const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams);
|
|
1125
|
+
this.request = new globalThis.Request(url, this.#options);
|
|
1126
|
+
}
|
|
1127
|
+
if (this.#options.onUploadProgress) {
|
|
1128
|
+
if (typeof this.#options.onUploadProgress !== "function") throw new TypeError("The `onUploadProgress` option must be a function");
|
|
1129
|
+
if (!supportsRequestStreams) throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");
|
|
1130
|
+
this.request = this.#wrapRequestWithUploadProgress(this.request, this.#options.body ?? void 0);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
#calculateDelay() {
|
|
1134
|
+
const retryDelay = this.#options.retry.delay(this.#retryCount);
|
|
1135
|
+
let jitteredDelay = retryDelay;
|
|
1136
|
+
if (this.#options.retry.jitter === true) jitteredDelay = Math.random() * retryDelay;
|
|
1137
|
+
else if (typeof this.#options.retry.jitter === "function") {
|
|
1138
|
+
jitteredDelay = this.#options.retry.jitter(retryDelay);
|
|
1139
|
+
if (!Number.isFinite(jitteredDelay) || jitteredDelay < 0) jitteredDelay = retryDelay;
|
|
1140
|
+
}
|
|
1141
|
+
const backoffLimit = this.#options.retry.backoffLimit ?? Number.POSITIVE_INFINITY;
|
|
1142
|
+
return Math.min(backoffLimit, jitteredDelay);
|
|
1143
|
+
}
|
|
1144
|
+
async #calculateRetryDelay(error) {
|
|
1145
|
+
this.#retryCount++;
|
|
1146
|
+
if (this.#retryCount > this.#options.retry.limit) throw error;
|
|
1147
|
+
const errorObject = error instanceof Error ? error : new NonError(error);
|
|
1148
|
+
if (errorObject instanceof ForceRetryError) return errorObject.customDelay ?? this.#calculateDelay();
|
|
1149
|
+
if (!this.#options.retry.methods.includes(this.request.method.toLowerCase())) throw error;
|
|
1150
|
+
if (this.#options.retry.shouldRetry !== void 0) {
|
|
1151
|
+
const result = await this.#options.retry.shouldRetry({
|
|
1152
|
+
error: errorObject,
|
|
1153
|
+
retryCount: this.#retryCount
|
|
1154
|
+
});
|
|
1155
|
+
if (result === false) throw error;
|
|
1156
|
+
if (result === true) return this.#calculateDelay();
|
|
1157
|
+
}
|
|
1158
|
+
if (isTimeoutError(error) && !this.#options.retry.retryOnTimeout) throw error;
|
|
1159
|
+
if (isHTTPError(error)) {
|
|
1160
|
+
if (!this.#options.retry.statusCodes.includes(error.response.status)) throw error;
|
|
1161
|
+
const retryAfter = error.response.headers.get("Retry-After") ?? error.response.headers.get("RateLimit-Reset") ?? error.response.headers.get("X-RateLimit-Retry-After") ?? error.response.headers.get("X-RateLimit-Reset") ?? error.response.headers.get("X-Rate-Limit-Reset");
|
|
1162
|
+
if (retryAfter && this.#options.retry.afterStatusCodes.includes(error.response.status)) {
|
|
1163
|
+
let after = Number(retryAfter) * 1e3;
|
|
1164
|
+
if (Number.isNaN(after)) after = Date.parse(retryAfter) - Date.now();
|
|
1165
|
+
else if (after >= Date.parse("2024-01-01")) after -= Date.now();
|
|
1166
|
+
const max = this.#options.retry.maxRetryAfter ?? after;
|
|
1167
|
+
return after < max ? after : max;
|
|
1168
|
+
}
|
|
1169
|
+
if (error.response.status === 413) throw error;
|
|
1170
|
+
}
|
|
1171
|
+
return this.#calculateDelay();
|
|
1172
|
+
}
|
|
1173
|
+
#decorateResponse(response) {
|
|
1174
|
+
if (this.#options.parseJson) response.json = async () => this.#options.parseJson(await response.text());
|
|
1175
|
+
return response;
|
|
1176
|
+
}
|
|
1177
|
+
#cancelBody(body) {
|
|
1178
|
+
if (!body) return;
|
|
1179
|
+
body.cancel().catch(() => void 0);
|
|
1180
|
+
}
|
|
1181
|
+
#cancelResponseBody(response) {
|
|
1182
|
+
this.#cancelBody(response.body ?? void 0);
|
|
1183
|
+
}
|
|
1184
|
+
async #retry(function_) {
|
|
1185
|
+
try {
|
|
1186
|
+
return await function_();
|
|
1187
|
+
} catch (error) {
|
|
1188
|
+
const ms = Math.min(await this.#calculateRetryDelay(error), maxSafeTimeout);
|
|
1189
|
+
if (this.#retryCount < 1) throw error;
|
|
1190
|
+
await delay(ms, this.#userProvidedAbortSignal ? { signal: this.#userProvidedAbortSignal } : {});
|
|
1191
|
+
if (error instanceof ForceRetryError && error.customRequest) {
|
|
1192
|
+
const managedRequest = this.#options.signal ? new globalThis.Request(error.customRequest, { signal: this.#options.signal }) : new globalThis.Request(error.customRequest);
|
|
1193
|
+
this.#assignRequest(managedRequest);
|
|
1194
|
+
}
|
|
1195
|
+
for (const hook of this.#options.hooks.beforeRetry) {
|
|
1196
|
+
const hookResult = await hook({
|
|
1197
|
+
request: this.request,
|
|
1198
|
+
options: this.#getNormalizedOptions(),
|
|
1199
|
+
error,
|
|
1200
|
+
retryCount: this.#retryCount
|
|
1201
|
+
});
|
|
1202
|
+
if (hookResult instanceof globalThis.Request) {
|
|
1203
|
+
this.#assignRequest(hookResult);
|
|
1204
|
+
break;
|
|
1205
|
+
}
|
|
1206
|
+
if (hookResult instanceof globalThis.Response) return hookResult;
|
|
1207
|
+
if (hookResult === stop) return;
|
|
1208
|
+
}
|
|
1209
|
+
return this.#retry(function_);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
async #fetch() {
|
|
1213
|
+
if (this.#abortController?.signal.aborted) {
|
|
1214
|
+
this.#abortController = new globalThis.AbortController();
|
|
1215
|
+
this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;
|
|
1216
|
+
this.request = new globalThis.Request(this.request, { signal: this.#options.signal });
|
|
1217
|
+
}
|
|
1218
|
+
for (const hook of this.#options.hooks.beforeRequest) {
|
|
1219
|
+
const result = await hook(this.request, this.#getNormalizedOptions(), { retryCount: this.#retryCount });
|
|
1220
|
+
if (result instanceof Response) return result;
|
|
1221
|
+
if (result instanceof globalThis.Request) {
|
|
1222
|
+
this.#assignRequest(result);
|
|
1223
|
+
break;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
const nonRequestOptions = findUnknownOptions(this.request, this.#options);
|
|
1227
|
+
this.#originalRequest = this.request;
|
|
1228
|
+
this.request = this.#originalRequest.clone();
|
|
1229
|
+
if (this.#options.timeout === false) return this.#options.fetch(this.#originalRequest, nonRequestOptions);
|
|
1230
|
+
return timeout(this.#originalRequest, nonRequestOptions, this.#abortController, this.#options);
|
|
1231
|
+
}
|
|
1232
|
+
#getNormalizedOptions() {
|
|
1233
|
+
if (!this.#cachedNormalizedOptions) {
|
|
1234
|
+
const { hooks, ...normalizedOptions } = this.#options;
|
|
1235
|
+
this.#cachedNormalizedOptions = Object.freeze(normalizedOptions);
|
|
1236
|
+
}
|
|
1237
|
+
return this.#cachedNormalizedOptions;
|
|
1238
|
+
}
|
|
1239
|
+
#assignRequest(request) {
|
|
1240
|
+
this.#cachedNormalizedOptions = void 0;
|
|
1241
|
+
this.request = this.#wrapRequestWithUploadProgress(request);
|
|
1242
|
+
}
|
|
1243
|
+
#wrapRequestWithUploadProgress(request, originalBody) {
|
|
1244
|
+
if (!this.#options.onUploadProgress || !request.body) return request;
|
|
1245
|
+
return streamRequest(request, this.#options.onUploadProgress, originalBody ?? this.#options.body ?? void 0);
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
|
|
1249
|
+
//#endregion
|
|
1250
|
+
//#region ../../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/index.js
|
|
1251
|
+
/*! MIT License © Sindre Sorhus */
|
|
1252
|
+
const createInstance = (defaults) => {
|
|
1253
|
+
const ky = (input, options) => Ky.create(input, validateAndMerge(defaults, options));
|
|
1254
|
+
for (const method of requestMethods) ky[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }));
|
|
1255
|
+
ky.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));
|
|
1256
|
+
ky.extend = (newDefaults) => {
|
|
1257
|
+
if (typeof newDefaults === "function") newDefaults = newDefaults(defaults ?? {});
|
|
1258
|
+
return createInstance(validateAndMerge(defaults, newDefaults));
|
|
1259
|
+
};
|
|
1260
|
+
ky.stop = stop;
|
|
1261
|
+
ky.retry = retry;
|
|
1262
|
+
return ky;
|
|
1263
|
+
};
|
|
1264
|
+
const ky$1 = createInstance();
|
|
1265
|
+
|
|
1266
|
+
//#endregion
|
|
1267
|
+
//#region ../../node_modules/.pnpm/cookie@1.1.1/node_modules/cookie/dist/index.js
|
|
1268
|
+
var require_dist = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) => {
|
|
1269
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1270
|
+
exports.stringifySetCookie = stringifySetCookie;
|
|
1271
|
+
exports.serialize = stringifySetCookie;
|
|
1272
|
+
exports.parseSetCookie = parseSetCookie;
|
|
1273
|
+
exports.stringifySetCookie = stringifySetCookie;
|
|
1274
|
+
exports.serialize = stringifySetCookie;
|
|
1275
|
+
/**
|
|
1276
|
+
* RegExp to match cookie-name in RFC 6265 sec 4.1.1
|
|
1277
|
+
* This refers out to the obsoleted definition of token in RFC 2616 sec 2.2
|
|
1278
|
+
* which has been replaced by the token definition in RFC 7230 appendix B.
|
|
1279
|
+
*
|
|
1280
|
+
* cookie-name = token
|
|
1281
|
+
* token = 1*tchar
|
|
1282
|
+
* tchar = "!" / "#" / "$" / "%" / "&" / "'" /
|
|
1283
|
+
* "*" / "+" / "-" / "." / "^" / "_" /
|
|
1284
|
+
* "`" / "|" / "~" / DIGIT / ALPHA
|
|
1285
|
+
*
|
|
1286
|
+
* Note: Allowing more characters - https://github.com/jshttp/cookie/issues/191
|
|
1287
|
+
* Allow same range as cookie value, except `=`, which delimits end of name.
|
|
1288
|
+
*/
|
|
1289
|
+
const cookieNameRegExp = /^[\u0021-\u003A\u003C\u003E-\u007E]+$/;
|
|
1290
|
+
/**
|
|
1291
|
+
* RegExp to match cookie-value in RFC 6265 sec 4.1.1
|
|
1292
|
+
*
|
|
1293
|
+
* cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
|
|
1294
|
+
* cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
|
|
1295
|
+
* ; US-ASCII characters excluding CTLs,
|
|
1296
|
+
* ; whitespace DQUOTE, comma, semicolon,
|
|
1297
|
+
* ; and backslash
|
|
1298
|
+
*
|
|
1299
|
+
* Allowing more characters: https://github.com/jshttp/cookie/issues/191
|
|
1300
|
+
* Comma, backslash, and DQUOTE are not part of the parsing algorithm.
|
|
1301
|
+
*/
|
|
1302
|
+
const cookieValueRegExp = /^[\u0021-\u003A\u003C-\u007E]*$/;
|
|
1303
|
+
/**
|
|
1304
|
+
* RegExp to match domain-value in RFC 6265 sec 4.1.1
|
|
1305
|
+
*
|
|
1306
|
+
* domain-value = <subdomain>
|
|
1307
|
+
* ; defined in [RFC1034], Section 3.5, as
|
|
1308
|
+
* ; enhanced by [RFC1123], Section 2.1
|
|
1309
|
+
* <subdomain> = <label> | <subdomain> "." <label>
|
|
1310
|
+
* <label> = <let-dig> [ [ <ldh-str> ] <let-dig> ]
|
|
1311
|
+
* Labels must be 63 characters or less.
|
|
1312
|
+
* 'let-dig' not 'letter' in the first char, per RFC1123
|
|
1313
|
+
* <ldh-str> = <let-dig-hyp> | <let-dig-hyp> <ldh-str>
|
|
1314
|
+
* <let-dig-hyp> = <let-dig> | "-"
|
|
1315
|
+
* <let-dig> = <letter> | <digit>
|
|
1316
|
+
* <letter> = any one of the 52 alphabetic characters A through Z in
|
|
1317
|
+
* upper case and a through z in lower case
|
|
1318
|
+
* <digit> = any one of the ten digits 0 through 9
|
|
1319
|
+
*
|
|
1320
|
+
* Keep support for leading dot: https://github.com/jshttp/cookie/issues/173
|
|
1321
|
+
*
|
|
1322
|
+
* > (Note that a leading %x2E ("."), if present, is ignored even though that
|
|
1323
|
+
* character is not permitted, but a trailing %x2E ("."), if present, will
|
|
1324
|
+
* cause the user agent to ignore the attribute.)
|
|
1325
|
+
*/
|
|
1326
|
+
const domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
|
|
1327
|
+
/**
|
|
1328
|
+
* RegExp to match path-value in RFC 6265 sec 4.1.1
|
|
1329
|
+
*
|
|
1330
|
+
* path-value = <any CHAR except CTLs or ";">
|
|
1331
|
+
* CHAR = %x01-7F
|
|
1332
|
+
* ; defined in RFC 5234 appendix B.1
|
|
1333
|
+
*/
|
|
1334
|
+
const pathValueRegExp = /^[\u0020-\u003A\u003D-\u007E]*$/;
|
|
1335
|
+
/**
|
|
1336
|
+
* RegExp to match max-age-value in RFC 6265 sec 5.6.2
|
|
1337
|
+
*/
|
|
1338
|
+
const maxAgeRegExp = /^-?\d+$/;
|
|
1339
|
+
const __toString = Object.prototype.toString;
|
|
1340
|
+
function stringifySetCookie(_name, _val, _opts) {
|
|
1341
|
+
const cookie = typeof _name === "object" ? _name : {
|
|
1342
|
+
..._opts,
|
|
1343
|
+
name: _name,
|
|
1344
|
+
value: String(_val)
|
|
1345
|
+
};
|
|
1346
|
+
const enc = (typeof _val === "object" ? _val : _opts)?.encode || encodeURIComponent;
|
|
1347
|
+
if (!cookieNameRegExp.test(cookie.name)) throw new TypeError(`argument name is invalid: ${cookie.name}`);
|
|
1348
|
+
const value = cookie.value ? enc(cookie.value) : "";
|
|
1349
|
+
if (!cookieValueRegExp.test(value)) throw new TypeError(`argument val is invalid: ${cookie.value}`);
|
|
1350
|
+
let str = cookie.name + "=" + value;
|
|
1351
|
+
if (cookie.maxAge !== void 0) {
|
|
1352
|
+
if (!Number.isInteger(cookie.maxAge)) throw new TypeError(`option maxAge is invalid: ${cookie.maxAge}`);
|
|
1353
|
+
str += "; Max-Age=" + cookie.maxAge;
|
|
1354
|
+
}
|
|
1355
|
+
if (cookie.domain) {
|
|
1356
|
+
if (!domainValueRegExp.test(cookie.domain)) throw new TypeError(`option domain is invalid: ${cookie.domain}`);
|
|
1357
|
+
str += "; Domain=" + cookie.domain;
|
|
1358
|
+
}
|
|
1359
|
+
if (cookie.path) {
|
|
1360
|
+
if (!pathValueRegExp.test(cookie.path)) throw new TypeError(`option path is invalid: ${cookie.path}`);
|
|
1361
|
+
str += "; Path=" + cookie.path;
|
|
1362
|
+
}
|
|
1363
|
+
if (cookie.expires) {
|
|
1364
|
+
if (!isDate(cookie.expires) || !Number.isFinite(cookie.expires.valueOf())) throw new TypeError(`option expires is invalid: ${cookie.expires}`);
|
|
1365
|
+
str += "; Expires=" + cookie.expires.toUTCString();
|
|
1366
|
+
}
|
|
1367
|
+
if (cookie.httpOnly) str += "; HttpOnly";
|
|
1368
|
+
if (cookie.secure) str += "; Secure";
|
|
1369
|
+
if (cookie.partitioned) str += "; Partitioned";
|
|
1370
|
+
if (cookie.priority) switch (typeof cookie.priority === "string" ? cookie.priority.toLowerCase() : void 0) {
|
|
1371
|
+
case "low":
|
|
1372
|
+
str += "; Priority=Low";
|
|
1373
|
+
break;
|
|
1374
|
+
case "medium":
|
|
1375
|
+
str += "; Priority=Medium";
|
|
1376
|
+
break;
|
|
1377
|
+
case "high":
|
|
1378
|
+
str += "; Priority=High";
|
|
1379
|
+
break;
|
|
1380
|
+
default: throw new TypeError(`option priority is invalid: ${cookie.priority}`);
|
|
1381
|
+
}
|
|
1382
|
+
if (cookie.sameSite) switch (typeof cookie.sameSite === "string" ? cookie.sameSite.toLowerCase() : cookie.sameSite) {
|
|
1383
|
+
case true:
|
|
1384
|
+
case "strict":
|
|
1385
|
+
str += "; SameSite=Strict";
|
|
1386
|
+
break;
|
|
1387
|
+
case "lax":
|
|
1388
|
+
str += "; SameSite=Lax";
|
|
1389
|
+
break;
|
|
1390
|
+
case "none":
|
|
1391
|
+
str += "; SameSite=None";
|
|
1392
|
+
break;
|
|
1393
|
+
default: throw new TypeError(`option sameSite is invalid: ${cookie.sameSite}`);
|
|
1394
|
+
}
|
|
1395
|
+
return str;
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* Deserialize a `Set-Cookie` header into an object.
|
|
1399
|
+
*
|
|
1400
|
+
* deserialize('foo=bar; httpOnly')
|
|
1401
|
+
* => { name: 'foo', value: 'bar', httpOnly: true }
|
|
1402
|
+
*/
|
|
1403
|
+
function parseSetCookie(str, options) {
|
|
1404
|
+
const dec = options?.decode || decode;
|
|
1405
|
+
const len = str.length;
|
|
1406
|
+
const endIdx = endIndex(str, 0, len);
|
|
1407
|
+
const eqIdx = eqIndex(str, 0, endIdx);
|
|
1408
|
+
const setCookie = eqIdx === -1 ? {
|
|
1409
|
+
name: "",
|
|
1410
|
+
value: dec(valueSlice(str, 0, endIdx))
|
|
1411
|
+
} : {
|
|
1412
|
+
name: valueSlice(str, 0, eqIdx),
|
|
1413
|
+
value: dec(valueSlice(str, eqIdx + 1, endIdx))
|
|
1414
|
+
};
|
|
1415
|
+
let index = endIdx + 1;
|
|
1416
|
+
while (index < len) {
|
|
1417
|
+
const endIdx = endIndex(str, index, len);
|
|
1418
|
+
const eqIdx = eqIndex(str, index, endIdx);
|
|
1419
|
+
const attr = eqIdx === -1 ? valueSlice(str, index, endIdx) : valueSlice(str, index, eqIdx);
|
|
1420
|
+
const val = eqIdx === -1 ? void 0 : valueSlice(str, eqIdx + 1, endIdx);
|
|
1421
|
+
switch (attr.toLowerCase()) {
|
|
1422
|
+
case "httponly":
|
|
1423
|
+
setCookie.httpOnly = true;
|
|
1424
|
+
break;
|
|
1425
|
+
case "secure":
|
|
1426
|
+
setCookie.secure = true;
|
|
1427
|
+
break;
|
|
1428
|
+
case "partitioned":
|
|
1429
|
+
setCookie.partitioned = true;
|
|
1430
|
+
break;
|
|
1431
|
+
case "domain":
|
|
1432
|
+
setCookie.domain = val;
|
|
1433
|
+
break;
|
|
1434
|
+
case "path":
|
|
1435
|
+
setCookie.path = val;
|
|
1436
|
+
break;
|
|
1437
|
+
case "max-age":
|
|
1438
|
+
if (val && maxAgeRegExp.test(val)) setCookie.maxAge = Number(val);
|
|
1439
|
+
break;
|
|
1440
|
+
case "expires":
|
|
1441
|
+
if (!val) break;
|
|
1442
|
+
const date = new Date(val);
|
|
1443
|
+
if (Number.isFinite(date.valueOf())) setCookie.expires = date;
|
|
1444
|
+
break;
|
|
1445
|
+
case "priority":
|
|
1446
|
+
if (!val) break;
|
|
1447
|
+
const priority = val.toLowerCase();
|
|
1448
|
+
if (priority === "low" || priority === "medium" || priority === "high") setCookie.priority = priority;
|
|
1449
|
+
break;
|
|
1450
|
+
case "samesite":
|
|
1451
|
+
if (!val) break;
|
|
1452
|
+
const sameSite = val.toLowerCase();
|
|
1453
|
+
if (sameSite === "lax" || sameSite === "strict" || sameSite === "none") setCookie.sameSite = sameSite;
|
|
1454
|
+
break;
|
|
1455
|
+
}
|
|
1456
|
+
index = endIdx + 1;
|
|
1457
|
+
}
|
|
1458
|
+
return setCookie;
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* Find the `;` character between `min` and `len` in str.
|
|
1462
|
+
*/
|
|
1463
|
+
function endIndex(str, min, len) {
|
|
1464
|
+
const index = str.indexOf(";", min);
|
|
1465
|
+
return index === -1 ? len : index;
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Find the `=` character between `min` and `max` in str.
|
|
1469
|
+
*/
|
|
1470
|
+
function eqIndex(str, min, max) {
|
|
1471
|
+
const index = str.indexOf("=", min);
|
|
1472
|
+
return index < max ? index : -1;
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Slice out a value between startPod to max.
|
|
1476
|
+
*/
|
|
1477
|
+
function valueSlice(str, min, max) {
|
|
1478
|
+
let start = min;
|
|
1479
|
+
let end = max;
|
|
1480
|
+
do {
|
|
1481
|
+
const code = str.charCodeAt(start);
|
|
1482
|
+
if (code !== 32 && code !== 9) break;
|
|
1483
|
+
} while (++start < end);
|
|
1484
|
+
while (end > start) {
|
|
1485
|
+
const code = str.charCodeAt(end - 1);
|
|
1486
|
+
if (code !== 32 && code !== 9) break;
|
|
1487
|
+
end--;
|
|
1488
|
+
}
|
|
1489
|
+
return str.slice(start, end);
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* URL-decode string value. Optimized to skip native call when no %.
|
|
1493
|
+
*/
|
|
1494
|
+
function decode(str) {
|
|
1495
|
+
if (str.indexOf("%") === -1) return str;
|
|
1496
|
+
try {
|
|
1497
|
+
return decodeURIComponent(str);
|
|
1498
|
+
} catch (e) {
|
|
1499
|
+
return str;
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Determine if value is a Date.
|
|
1504
|
+
*/
|
|
1505
|
+
function isDate(val) {
|
|
1506
|
+
return __toString.call(val) === "[object Date]";
|
|
1507
|
+
}
|
|
1508
|
+
}));
|
|
1509
|
+
|
|
1510
|
+
//#endregion
|
|
1511
|
+
//#region ../../apps/desktop/src/main/core/cookie-store.ts
|
|
1512
|
+
var import_dist = require_dist();
|
|
1513
|
+
const parseSetCookieList = (setCookieList) => {
|
|
1514
|
+
const cookies = [];
|
|
1515
|
+
for (const setCookieString of setCookieList) try {
|
|
1516
|
+
const setCookie = (0, import_dist.parseSetCookie)(setCookieString);
|
|
1517
|
+
const cookie = {
|
|
1518
|
+
...setCookie,
|
|
1519
|
+
expires: setCookie.expires instanceof Date ? setCookie.expires.getTime() : setCookie.expires,
|
|
1520
|
+
sameSite: typeof setCookie.sameSite === "boolean" ? "strict" : setCookie.sameSite
|
|
1521
|
+
};
|
|
1522
|
+
cookies.push(cookie);
|
|
1523
|
+
} catch (e) {
|
|
1524
|
+
logger.debug(e);
|
|
1525
|
+
}
|
|
1526
|
+
return cookies;
|
|
1527
|
+
};
|
|
1528
|
+
const importCookies = async (cookiesTxtPath) => {
|
|
1529
|
+
const text = await (0, node_fs_promises.readFile)(cookiesTxtPath, "utf8").catch(() => "");
|
|
1530
|
+
if (!text) return [];
|
|
1531
|
+
const rows = text.split(node_os.EOL).flatMap((line) => line.split("\n")).filter((line) => !!line.trim() && !line.startsWith("# ")).map((line) => line.split(" "));
|
|
1532
|
+
const cookies = [];
|
|
1533
|
+
for (const row of rows) {
|
|
1534
|
+
const [domain, _includeSubdomains, path, secure, expires, name, value] = row;
|
|
1535
|
+
cookies.push({
|
|
1536
|
+
name,
|
|
1537
|
+
value,
|
|
1538
|
+
expires: Number(expires),
|
|
1539
|
+
maxAge: void 0,
|
|
1540
|
+
domain: domain.replace("#HttpOnly_", ""),
|
|
1541
|
+
path,
|
|
1542
|
+
secure: secure === "TRUE",
|
|
1543
|
+
httpOnly: void 0,
|
|
1544
|
+
sameSite: void 0
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
return cookies;
|
|
1548
|
+
};
|
|
1549
|
+
var CookieStore = class {
|
|
1550
|
+
#data = {};
|
|
1551
|
+
#cookies;
|
|
1552
|
+
#storagePath;
|
|
1553
|
+
#hasBeenRead = false;
|
|
1554
|
+
static parse(setCookieList) {
|
|
1555
|
+
return parseSetCookieList(setCookieList);
|
|
1556
|
+
}
|
|
1557
|
+
constructor({ storagePath } = {}) {
|
|
1558
|
+
this.#storagePath = storagePath;
|
|
1559
|
+
this.#cookies = [];
|
|
1560
|
+
}
|
|
1561
|
+
async import(cookiesTxtPath) {
|
|
1562
|
+
if ((await (0, node_fs_promises.stat)(cookiesTxtPath).catch(() => null))?.isFile()) {
|
|
1563
|
+
this.#cookies = await importCookies(cookiesTxtPath);
|
|
1564
|
+
await (0, node_fs_promises.rm)(cookiesTxtPath, {
|
|
1565
|
+
recursive: true,
|
|
1566
|
+
force: true
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
async #read() {
|
|
1571
|
+
if (!this.#storagePath || this.#hasBeenRead) return;
|
|
1572
|
+
if ((await (0, node_fs_promises.stat)(this.#storagePath).catch(() => null))?.isFile()) {
|
|
1573
|
+
const data = await (0, node_fs_promises.readFile)(this.#storagePath, "utf8");
|
|
1574
|
+
this.#data = data ? JSON.parse(data) : {};
|
|
1575
|
+
this.#cookies = "cookies" in this.#data ? this.#data.cookies : [];
|
|
1576
|
+
}
|
|
1577
|
+
this.#hasBeenRead = true;
|
|
1578
|
+
}
|
|
1579
|
+
async #write() {
|
|
1580
|
+
if (!this.#storagePath) return;
|
|
1581
|
+
const data = JSON.stringify({
|
|
1582
|
+
...this.#data,
|
|
1583
|
+
cookies: this.#cookies
|
|
1584
|
+
}, null, 2);
|
|
1585
|
+
await (0, node_fs_promises.writeFile)(this.#storagePath, data, "utf8");
|
|
1586
|
+
}
|
|
1587
|
+
async get(cookie) {
|
|
1588
|
+
await this.#read();
|
|
1589
|
+
const name = typeof cookie === "string" ? cookie : cookie.name;
|
|
1590
|
+
return this.#cookies.find((c) => c.name === name) ?? null;
|
|
1591
|
+
}
|
|
1592
|
+
async getAll(cookie) {
|
|
1593
|
+
await this.#read();
|
|
1594
|
+
if (!cookie) return this.#cookies;
|
|
1595
|
+
const name = typeof cookie === "string" ? cookie : cookie.name;
|
|
1596
|
+
return this.#cookies.filter((c) => c.name === name) ?? null;
|
|
1597
|
+
}
|
|
1598
|
+
async set(cookie) {
|
|
1599
|
+
await this.#read();
|
|
1600
|
+
this.#cookies = this.#cookies.filter((c) => !(c.name === cookie.name && c.domain === cookie.domain));
|
|
1601
|
+
this.#cookies.push(cookie);
|
|
1602
|
+
await this.#write();
|
|
1603
|
+
}
|
|
1604
|
+
async delete(cookie) {
|
|
1605
|
+
await this.#read();
|
|
1606
|
+
if (!cookie) this.#cookies = [];
|
|
1607
|
+
else {
|
|
1608
|
+
const name = typeof cookie === "string" ? cookie : cookie.name;
|
|
1609
|
+
this.#cookies = this.#cookies.filter((c) => c.name !== name);
|
|
1610
|
+
}
|
|
1611
|
+
await this.#write();
|
|
1612
|
+
}
|
|
1613
|
+
toString() {
|
|
1614
|
+
return this.#cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1617
|
+
|
|
1618
|
+
//#endregion
|
|
1619
|
+
//#region ../../apps/desktop/src/main/core/http-client.ts
|
|
1620
|
+
const ky = ky$1.default ?? ky$1;
|
|
1621
|
+
const hasUserAgent = (headers) => {
|
|
1622
|
+
if (!headers) return false;
|
|
1623
|
+
if (headers instanceof Headers) return headers.has("User-Agent");
|
|
1624
|
+
if (typeof headers === "object" && headers !== null) return "User-Agent" in headers || "user-agent" in headers;
|
|
1625
|
+
return false;
|
|
1626
|
+
};
|
|
1627
|
+
const getInputUrl = (input) => {
|
|
1628
|
+
if (input instanceof URL) return input;
|
|
1629
|
+
if (input instanceof Request) return new URL(input.url);
|
|
1630
|
+
return new URL(input);
|
|
1631
|
+
};
|
|
1632
|
+
var HttpClient = class {
|
|
1633
|
+
cookieStore;
|
|
1634
|
+
headers;
|
|
1635
|
+
#client;
|
|
1636
|
+
#chrome;
|
|
1637
|
+
constructor(options = {}) {
|
|
1638
|
+
this.headers = new Headers();
|
|
1639
|
+
this.configure(options);
|
|
1640
|
+
}
|
|
1641
|
+
configure({ maxRetries = 3, proxyUrl, allowH2 = true, cookieStore } = {}) {
|
|
1642
|
+
this.cookieStore = cookieStore ?? this.cookieStore ?? new CookieStore();
|
|
1643
|
+
const agent = proxyUrl ? new undici.ProxyAgent({
|
|
1644
|
+
uri: proxyUrl,
|
|
1645
|
+
allowH2
|
|
1646
|
+
}) : new undici.Agent({ allowH2 });
|
|
1647
|
+
const defaultOptions = { retry: maxRetries };
|
|
1648
|
+
this.#client = ky.create({
|
|
1649
|
+
dispatcher: agent,
|
|
1650
|
+
proxy: proxyUrl,
|
|
1651
|
+
...defaultOptions
|
|
1652
|
+
});
|
|
1653
|
+
const impit$1 = new impit.Impit({
|
|
1654
|
+
browser: "chrome",
|
|
1655
|
+
proxyUrl,
|
|
1656
|
+
ignoreTlsErrors: true,
|
|
1657
|
+
followRedirects: true
|
|
1658
|
+
});
|
|
1659
|
+
this.#chrome = ky.create({
|
|
1660
|
+
fetch: impit$1.fetch.bind(impit$1),
|
|
1661
|
+
...defaultOptions
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
async fetch(input, init = {}) {
|
|
1665
|
+
const headers = this.appendHeaders(init?.headers);
|
|
1666
|
+
const cookies = await this.cookieStore.getAll();
|
|
1667
|
+
const filteredCookies = cookies.filter((c) => !c.domain || getInputUrl(input).hostname.includes(c.domain));
|
|
1668
|
+
for (const cookie of cookies) {
|
|
1669
|
+
if (filteredCookies.find((c) => c.name === cookie.name)) continue;
|
|
1670
|
+
if (!cookie.domain) filteredCookies.push(cookie);
|
|
1671
|
+
}
|
|
1672
|
+
const cookieHeaderValue = filteredCookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
|
|
1673
|
+
if (!headers.has("cookie")) headers.set("cookie", cookieHeaderValue);
|
|
1674
|
+
else if (!headers.get("cookie")) headers.delete("cookie");
|
|
1675
|
+
const fetchFn = (hasUserAgent(init?.headers) ? this.#client : this.#chrome)[init?.method?.toLowerCase() ?? "get"];
|
|
1676
|
+
const response = await fetchFn(input, {
|
|
1677
|
+
...init,
|
|
1678
|
+
headers
|
|
1679
|
+
});
|
|
1680
|
+
const setCookie = response.headers.getSetCookie();
|
|
1681
|
+
if (setCookie) await this.setCookies(setCookie);
|
|
1682
|
+
return response;
|
|
1683
|
+
}
|
|
1684
|
+
async setCookies(setCookie) {
|
|
1685
|
+
const newCookies = [];
|
|
1686
|
+
if (typeof setCookie === "string") {
|
|
1687
|
+
const [newCookie] = parseSetCookieList([setCookie]);
|
|
1688
|
+
if (newCookie) newCookies.push(newCookie);
|
|
1689
|
+
} else if (Array.isArray(setCookie) && typeof setCookie.at(0) === "string") {
|
|
1690
|
+
const cookies = parseSetCookieList(setCookie);
|
|
1691
|
+
newCookies.push(...cookies);
|
|
1692
|
+
} else if (Array.isArray(setCookie) && typeof setCookie[0] !== "string") newCookies.push(...setCookie);
|
|
1693
|
+
if (!newCookies || !newCookies?.length) return;
|
|
1694
|
+
for (const cookie of newCookies) await this.cookieStore.set(cookie);
|
|
1695
|
+
}
|
|
1696
|
+
appendHeaders(headers) {
|
|
1697
|
+
const newHeaders = new Headers(this.headers);
|
|
1698
|
+
for (const [name, value] of Object.entries(headers ?? {})) newHeaders.set(name, value);
|
|
1699
|
+
return newHeaders;
|
|
1700
|
+
}
|
|
1701
|
+
setHeader(name, value) {
|
|
1702
|
+
this.headers.set(name, value);
|
|
1703
|
+
}
|
|
1704
|
+
removeHeader(name) {
|
|
1705
|
+
this.headers.delete(name);
|
|
1706
|
+
}
|
|
1707
|
+
};
|
|
1708
|
+
const httpClient = new HttpClient();
|
|
1709
|
+
|
|
1710
|
+
//#endregion
|
|
1711
|
+
//#region ../../apps/desktop/src/main/core/loader.ts
|
|
1712
|
+
const { COMMON_CONTEXT } = metavm.default;
|
|
1713
|
+
const create = (src, name = "Eval", options) => {
|
|
1714
|
+
try {
|
|
1715
|
+
return metavm.default.createScript(name, src, options);
|
|
1716
|
+
} catch (e) {
|
|
1717
|
+
console.debug(e);
|
|
1718
|
+
console.debug(src);
|
|
1719
|
+
console.error(`Syntax Error: ${e.message}`);
|
|
1720
|
+
return null;
|
|
1721
|
+
}
|
|
1722
|
+
};
|
|
1723
|
+
|
|
1724
|
+
//#endregion
|
|
1725
|
+
//#region ../../apps/desktop/src/main/cli/utils.ts
|
|
1726
|
+
const getRandomElements = (array, count = 1) => {
|
|
1727
|
+
if (Array.isArray(array) || typeof array === "string") {
|
|
1728
|
+
const elements = [];
|
|
1729
|
+
for (let i = 1; i <= count; i++) elements.push(array[Math.floor(Math.random() * array.length)]);
|
|
1730
|
+
return elements;
|
|
1731
|
+
} else return [];
|
|
1732
|
+
};
|
|
1733
|
+
|
|
1734
|
+
//#endregion
|
|
1735
|
+
//#region ../../apps/desktop/src/main/core/storage.ts
|
|
1736
|
+
const createConf = (partialOptions) => {
|
|
1737
|
+
return new ("default" in conf.default ? conf.default.default : conf.default)(partialOptions);
|
|
1738
|
+
};
|
|
1739
|
+
var FileStorage = class {
|
|
1740
|
+
#store;
|
|
1741
|
+
constructor(filePath) {
|
|
1742
|
+
this.#store = createConf({
|
|
1743
|
+
cwd: (0, node_path.dirname)(filePath),
|
|
1744
|
+
configName: (0, node_path.basename)(filePath, ".json")
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
get length() {
|
|
1748
|
+
return Object.keys(this.#store.store).length;
|
|
1749
|
+
}
|
|
1750
|
+
clear() {
|
|
1751
|
+
this.#store.clear();
|
|
1752
|
+
}
|
|
1753
|
+
getItem(key) {
|
|
1754
|
+
return this.#store.get(key) ?? null;
|
|
1755
|
+
}
|
|
1756
|
+
key(index) {
|
|
1757
|
+
return Object.keys(this.#store.store).at(index) ?? null;
|
|
1758
|
+
}
|
|
1759
|
+
removeItem(key) {
|
|
1760
|
+
this.#store.delete(key);
|
|
1761
|
+
}
|
|
1762
|
+
setItem(key, value) {
|
|
1763
|
+
this.#store.set(key, value);
|
|
1764
|
+
}
|
|
1765
|
+
};
|
|
1766
|
+
|
|
1767
|
+
//#endregion
|
|
1768
|
+
//#region ../../apps/desktop/src/main/errors.ts
|
|
1769
|
+
const errors = new node_events.default();
|
|
1770
|
+
|
|
1771
|
+
//#endregion
|
|
1772
|
+
//#region ../../apps/desktop/src/main/extensions/context.ts
|
|
1773
|
+
const isPromptCancelError = (error) => {
|
|
1774
|
+
if (!error || typeof error !== "object") return false;
|
|
1775
|
+
const name = "name" in error ? String(error.name) : "";
|
|
1776
|
+
return name === "ExitPromptError" || name === "AbortPromptError";
|
|
1777
|
+
};
|
|
1778
|
+
const capitalize = (text) => text[0].toUpperCase() + text.slice(1);
|
|
1779
|
+
const parseBoolean = (value, fallback = false) => {
|
|
1780
|
+
if (typeof value === "boolean") return value;
|
|
1781
|
+
if (typeof value !== "string") return fallback;
|
|
1782
|
+
const normalized = value.trim().toLowerCase();
|
|
1783
|
+
if ([
|
|
1784
|
+
"1",
|
|
1785
|
+
"true",
|
|
1786
|
+
"yes",
|
|
1787
|
+
"y",
|
|
1788
|
+
"on"
|
|
1789
|
+
].includes(normalized)) return true;
|
|
1790
|
+
if ([
|
|
1791
|
+
"0",
|
|
1792
|
+
"false",
|
|
1793
|
+
"no",
|
|
1794
|
+
"n",
|
|
1795
|
+
"off"
|
|
1796
|
+
].includes(normalized)) return false;
|
|
1797
|
+
return fallback;
|
|
1798
|
+
};
|
|
1799
|
+
const parseNumber = (value, fallback = 0) => {
|
|
1800
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1801
|
+
if (typeof value !== "string") return fallback;
|
|
1802
|
+
const parsed = Number(value);
|
|
1803
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
1804
|
+
};
|
|
1805
|
+
const getEmptyFieldValue = (field) => {
|
|
1806
|
+
switch (field.type) {
|
|
1807
|
+
case "checkbox": return parseBoolean(field.defaultValue, false);
|
|
1808
|
+
case "number": return parseNumber(field.defaultValue, 0);
|
|
1809
|
+
default: return field.defaultValue ?? "";
|
|
1810
|
+
}
|
|
1811
|
+
};
|
|
1812
|
+
const coerceFieldValue = (field, value) => {
|
|
1813
|
+
switch (field.type) {
|
|
1814
|
+
case "checkbox": return parseBoolean(value, parseBoolean(field.defaultValue, false));
|
|
1815
|
+
case "number": return parseNumber(value, parseNumber(field.defaultValue, 0));
|
|
1816
|
+
default:
|
|
1817
|
+
if (typeof value === "string") return value;
|
|
1818
|
+
if (value === void 0 || value === null) return field.defaultValue ?? "";
|
|
1819
|
+
return String(value);
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
const createEmptyAskResult = (form) => {
|
|
1823
|
+
const entries = Object.entries(form).map(([name, field]) => [name, getEmptyFieldValue(field)]);
|
|
1824
|
+
return Object.fromEntries(entries);
|
|
1825
|
+
};
|
|
1826
|
+
const coerceAskResult = (form, values) => {
|
|
1827
|
+
const entries = Object.entries(form).map(([name, field]) => [name, coerceFieldValue(field, values[name])]);
|
|
1828
|
+
return Object.fromEntries(entries);
|
|
1829
|
+
};
|
|
1830
|
+
const runAction = async (action) => {
|
|
1831
|
+
if (!action?.onAction) return;
|
|
1832
|
+
await action.onAction();
|
|
1833
|
+
};
|
|
1834
|
+
const openExternalLink = async (url) => {
|
|
1835
|
+
if (isCLI) {
|
|
1836
|
+
const { default: open } = await Promise.resolve().then(() => require("./open-C0aYOBn3.cjs"));
|
|
1837
|
+
await open(url);
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1840
|
+
const { shell } = await import("electron");
|
|
1841
|
+
await shell.openExternal(url);
|
|
1842
|
+
};
|
|
1843
|
+
const openWindow = (url, _target, _features) => {
|
|
1844
|
+
const href = typeof url === "string" ? url : url?.toString();
|
|
1845
|
+
if (!href?.trim()) return null;
|
|
1846
|
+
openExternalLink(href).catch((error) => {
|
|
1847
|
+
logger.error(`Failed to open URL: ${href}`);
|
|
1848
|
+
logger.debug(error instanceof Error ? error.message : String(error));
|
|
1849
|
+
});
|
|
1850
|
+
return null;
|
|
1851
|
+
};
|
|
1852
|
+
const chooseActionWithSelect = async (message, actions) => {
|
|
1853
|
+
if (!actions.length) return "dismiss";
|
|
1854
|
+
try {
|
|
1855
|
+
return await (0, _inquirer_prompts.select)({
|
|
1856
|
+
message,
|
|
1857
|
+
loop: false,
|
|
1858
|
+
choices: actions.map((entry) => ({
|
|
1859
|
+
name: entry.action.title,
|
|
1860
|
+
value: entry.kind
|
|
1861
|
+
}))
|
|
1862
|
+
});
|
|
1863
|
+
} catch (error) {
|
|
1864
|
+
if (isPromptCancelError(error)) return "dismiss";
|
|
1865
|
+
throw error;
|
|
1866
|
+
}
|
|
1867
|
+
};
|
|
1868
|
+
const getOS = () => {
|
|
1869
|
+
switch (node_os.default.type()) {
|
|
1870
|
+
case "Darwin": return "macOS";
|
|
1871
|
+
case "Windows_NT": return "Windows";
|
|
1872
|
+
default: return "Linux";
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
Object.defineProperties(Uint8Array.prototype, {
|
|
1876
|
+
toBase64: {
|
|
1877
|
+
value: function() {
|
|
1878
|
+
return Buffer.from(this).toString("base64");
|
|
1879
|
+
},
|
|
1880
|
+
writable: true,
|
|
1881
|
+
configurable: true
|
|
1882
|
+
},
|
|
1883
|
+
toHex: {
|
|
1884
|
+
value: function() {
|
|
1885
|
+
return Buffer.from(this).toString("hex");
|
|
1886
|
+
},
|
|
1887
|
+
writable: true,
|
|
1888
|
+
configurable: true
|
|
1889
|
+
}
|
|
1890
|
+
});
|
|
1891
|
+
Object.defineProperties(Uint8Array, {
|
|
1892
|
+
fromBase64: {
|
|
1893
|
+
value: function(base64String) {
|
|
1894
|
+
return new Uint8Array(Buffer.from(base64String, "base64"));
|
|
1895
|
+
},
|
|
1896
|
+
writable: true,
|
|
1897
|
+
configurable: true
|
|
1898
|
+
},
|
|
1899
|
+
fromHex: {
|
|
1900
|
+
value: function(hexString) {
|
|
1901
|
+
return new Uint8Array(Buffer.from(hexString, "hex"));
|
|
1902
|
+
},
|
|
1903
|
+
writable: true,
|
|
1904
|
+
configurable: true
|
|
1905
|
+
}
|
|
1906
|
+
});
|
|
1907
|
+
const macOSVersionMap = new Map([
|
|
1908
|
+
[24, ["Sequoia", "15"]],
|
|
1909
|
+
[23, ["Sonoma", "14"]],
|
|
1910
|
+
[22, ["Ventura", "13"]],
|
|
1911
|
+
[21, ["Monterey", "12"]],
|
|
1912
|
+
[20, ["Big Sur", "11"]],
|
|
1913
|
+
[19, ["Catalina", "10.15"]],
|
|
1914
|
+
[18, ["Mojave", "10.14"]],
|
|
1915
|
+
[17, ["High Sierra", "10.13"]],
|
|
1916
|
+
[16, ["Sierra", "10.12"]],
|
|
1917
|
+
[15, ["El Capitan", "10.11"]],
|
|
1918
|
+
[14, ["Yosemite", "10.10"]],
|
|
1919
|
+
[13, ["Mavericks", "10.9"]],
|
|
1920
|
+
[12, ["Mountain Lion", "10.8"]],
|
|
1921
|
+
[11, ["Lion", "10.7"]],
|
|
1922
|
+
[10, ["Snow Leopard", "10.6"]],
|
|
1923
|
+
[9, ["Leopard", "10.5"]],
|
|
1924
|
+
[8, ["Tiger", "10.4"]],
|
|
1925
|
+
[7, ["Panther", "10.3"]],
|
|
1926
|
+
[6, ["Jaguar", "10.2"]],
|
|
1927
|
+
[5, ["Puma", "10.1"]]
|
|
1928
|
+
]);
|
|
1929
|
+
const macosRelease = () => {
|
|
1930
|
+
const releaseN = Number(node_os.default.release().split(".")[0]);
|
|
1931
|
+
const [name, version] = macOSVersionMap.get(releaseN) || ["Unknown", ""];
|
|
1932
|
+
return {
|
|
1933
|
+
name,
|
|
1934
|
+
version
|
|
1935
|
+
};
|
|
1936
|
+
};
|
|
1937
|
+
const getOSVersion = () => {
|
|
1938
|
+
switch (getOS()) {
|
|
1939
|
+
case "macOS": return macosRelease().version;
|
|
1940
|
+
case "Windows": return node_os.default.release();
|
|
1941
|
+
case "Linux": return node_os.default.release();
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1944
|
+
const createUserAgentData = () => {
|
|
1945
|
+
const brands = [{
|
|
1946
|
+
brand: "Azot",
|
|
1947
|
+
version: package_default.version.split(".").slice(0, 2).join(".")
|
|
1948
|
+
}, {
|
|
1949
|
+
brand: "Node.js",
|
|
1950
|
+
version: process.version.replace("v", "").split(".").slice(0, 1).join(".")
|
|
1951
|
+
}];
|
|
1952
|
+
return {
|
|
1953
|
+
mobile: false,
|
|
1954
|
+
platform: getOS(),
|
|
1955
|
+
brands,
|
|
1956
|
+
getHighEntropyValues: async (hints) => {
|
|
1957
|
+
const values = {
|
|
1958
|
+
mobile: false,
|
|
1959
|
+
platform: getOS(),
|
|
1960
|
+
brands
|
|
1961
|
+
};
|
|
1962
|
+
if (hints.includes("architecture")) values.architecture = node_os.default.arch();
|
|
1963
|
+
if (hints.includes("platform")) values.platform = getOS();
|
|
1964
|
+
if (hints.includes("platformVersion")) values.platformVersion = getOSVersion();
|
|
1965
|
+
if (hints.includes("fullVersionList")) values.fullVersionList = [{
|
|
1966
|
+
brand: "Azot",
|
|
1967
|
+
version: package_default.version
|
|
1968
|
+
}, {
|
|
1969
|
+
brand: "Node.js",
|
|
1970
|
+
version: process.version
|
|
1971
|
+
}];
|
|
1972
|
+
return values;
|
|
1973
|
+
}
|
|
1974
|
+
};
|
|
1975
|
+
};
|
|
1976
|
+
const createContext = ({ name = "extension", dir = process.cwd(), title } = {}) => {
|
|
1977
|
+
const workDir = resolveDir((0, node_path.join)(dir, name));
|
|
1978
|
+
const localStorage = new FileStorage((0, node_path.join)(workDir, `storage.json`));
|
|
1979
|
+
const cookieStore = new CookieStore({ storagePath: (0, node_path.join)(workDir, `cookies.json`) });
|
|
1980
|
+
const http = new HttpClient({ cookieStore });
|
|
1981
|
+
const between = (text, from, to) => text.split(from)[1]?.split(to)[0]?.trim();
|
|
1982
|
+
const common = {
|
|
1983
|
+
sanitizeString,
|
|
1984
|
+
execUrlPatterns,
|
|
1985
|
+
extendEpisodes,
|
|
1986
|
+
between,
|
|
1987
|
+
getRandomElements
|
|
1988
|
+
};
|
|
1989
|
+
const defaultTitle = title ? capitalize(title) : void 0;
|
|
1990
|
+
const resolveTitle = (nextTitle) => nextTitle || defaultTitle;
|
|
1991
|
+
const requestPrompt = async (request) => {
|
|
1992
|
+
if (!request.title) request.title = defaultTitle;
|
|
1993
|
+
return await prompt.ask(request);
|
|
1994
|
+
};
|
|
1995
|
+
const notify = async (message, options = {}) => {
|
|
1996
|
+
const titleText = resolveTitle(options.title) ?? "Azot";
|
|
1997
|
+
const actions = [options.primaryAction ? {
|
|
1998
|
+
kind: "primary",
|
|
1999
|
+
action: options.primaryAction
|
|
2000
|
+
} : null, options.secondaryAction ? {
|
|
2001
|
+
kind: "secondary",
|
|
2002
|
+
action: options.secondaryAction
|
|
2003
|
+
} : null].filter(Boolean);
|
|
2004
|
+
if (isCLI) {
|
|
2005
|
+
if (!actions.length) return logger.info(message);
|
|
2006
|
+
const selected = await chooseActionWithSelect(message, actions);
|
|
2007
|
+
if (selected === "primary") await runAction(options.primaryAction);
|
|
2008
|
+
if (selected === "secondary") await runAction(options.secondaryAction);
|
|
2009
|
+
return;
|
|
2010
|
+
}
|
|
2011
|
+
const selected = (await feedback.ask({
|
|
2012
|
+
variant: "notify",
|
|
2013
|
+
title: titleText,
|
|
2014
|
+
message,
|
|
2015
|
+
style: options.style,
|
|
2016
|
+
primaryAction: options.primaryAction ? {
|
|
2017
|
+
title: options.primaryAction.title,
|
|
2018
|
+
style: options.primaryAction.style
|
|
2019
|
+
} : void 0,
|
|
2020
|
+
secondaryAction: options.secondaryAction ? {
|
|
2021
|
+
title: options.secondaryAction.title,
|
|
2022
|
+
style: options.secondaryAction.style
|
|
2023
|
+
} : void 0
|
|
2024
|
+
})).action ?? "dismiss";
|
|
2025
|
+
if (selected === "primary") await runAction(options.primaryAction);
|
|
2026
|
+
if (selected === "secondary") await runAction(options.secondaryAction);
|
|
2027
|
+
};
|
|
2028
|
+
const confirm = async (message, options = {}) => {
|
|
2029
|
+
const titleText = resolveTitle(options.title) ?? "Azot";
|
|
2030
|
+
const hasCustomActions = !!options.primaryAction || !!options.secondaryAction;
|
|
2031
|
+
const primaryAction = options.primaryAction ?? { title: "OK" };
|
|
2032
|
+
const secondaryAction = options.secondaryAction ?? {
|
|
2033
|
+
title: "Cancel",
|
|
2034
|
+
style: "cancel"
|
|
2035
|
+
};
|
|
2036
|
+
if (isCLI) {
|
|
2037
|
+
if (hasCustomActions) {
|
|
2038
|
+
const selected = await chooseActionWithSelect(message, [{
|
|
2039
|
+
kind: "primary",
|
|
2040
|
+
action: primaryAction
|
|
2041
|
+
}, {
|
|
2042
|
+
kind: "secondary",
|
|
2043
|
+
action: secondaryAction
|
|
2044
|
+
}]);
|
|
2045
|
+
if (selected === "primary") {
|
|
2046
|
+
await runAction(primaryAction);
|
|
2047
|
+
return true;
|
|
2048
|
+
}
|
|
2049
|
+
if (selected === "secondary") await runAction(secondaryAction);
|
|
2050
|
+
return false;
|
|
2051
|
+
}
|
|
2052
|
+
try {
|
|
2053
|
+
const accepted = await (0, _inquirer_prompts.confirm)({
|
|
2054
|
+
message,
|
|
2055
|
+
default: true
|
|
2056
|
+
});
|
|
2057
|
+
if (accepted) await runAction(options.primaryAction);
|
|
2058
|
+
else await runAction(options.secondaryAction);
|
|
2059
|
+
return accepted;
|
|
2060
|
+
} catch (error) {
|
|
2061
|
+
if (isPromptCancelError(error)) return false;
|
|
2062
|
+
throw error;
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
const result = await feedback.ask({
|
|
2066
|
+
variant: "confirm",
|
|
2067
|
+
title: titleText,
|
|
2068
|
+
message,
|
|
2069
|
+
style: options.style,
|
|
2070
|
+
primaryAction: {
|
|
2071
|
+
title: primaryAction.title,
|
|
2072
|
+
style: primaryAction.style
|
|
2073
|
+
},
|
|
2074
|
+
secondaryAction: {
|
|
2075
|
+
title: secondaryAction.title,
|
|
2076
|
+
style: secondaryAction.style
|
|
2077
|
+
}
|
|
2078
|
+
});
|
|
2079
|
+
const isPrimary = result.action === "primary";
|
|
2080
|
+
if (isPrimary) await runAction(primaryAction);
|
|
2081
|
+
else if (result.action === "secondary") await runAction(secondaryAction);
|
|
2082
|
+
return isPrimary;
|
|
2083
|
+
};
|
|
2084
|
+
const askFeedback = async (message, options) => {
|
|
2085
|
+
const emptyResult = createEmptyAskResult(options.form);
|
|
2086
|
+
const formEntries = Object.entries(options.form);
|
|
2087
|
+
const hasActions = !!options.primaryAction || !!options.secondaryAction;
|
|
2088
|
+
const primaryAction = options.primaryAction ?? { title: "Submit" };
|
|
2089
|
+
const secondaryAction = options.secondaryAction ?? {
|
|
2090
|
+
title: "Cancel",
|
|
2091
|
+
style: "cancel"
|
|
2092
|
+
};
|
|
2093
|
+
if (isCLI) {
|
|
2094
|
+
const values = {};
|
|
2095
|
+
try {
|
|
2096
|
+
for (const [name, field] of formEntries) {
|
|
2097
|
+
const fieldMessage = [field.title || name, field.description].filter(Boolean).join(" - ");
|
|
2098
|
+
if (field.type === "checkbox") {
|
|
2099
|
+
values[name] = await (0, _inquirer_prompts.confirm)({
|
|
2100
|
+
message: fieldMessage,
|
|
2101
|
+
default: parseBoolean(field.defaultValue, false)
|
|
2102
|
+
});
|
|
2103
|
+
continue;
|
|
2104
|
+
}
|
|
2105
|
+
if (field.type === "number") {
|
|
2106
|
+
const fallback = parseNumber(field.defaultValue, NaN);
|
|
2107
|
+
values[name] = await (0, _inquirer_prompts.number)({
|
|
2108
|
+
message: fieldMessage,
|
|
2109
|
+
default: Number.isFinite(fallback) ? fallback : void 0,
|
|
2110
|
+
validate: (value) => {
|
|
2111
|
+
if (value === void 0 || Number.isNaN(value)) return field.required ? "This field is required" : true;
|
|
2112
|
+
return true;
|
|
2113
|
+
}
|
|
2114
|
+
});
|
|
2115
|
+
continue;
|
|
2116
|
+
}
|
|
2117
|
+
if (field.type === "password") {
|
|
2118
|
+
values[name] = await (0, _inquirer_prompts.password)({
|
|
2119
|
+
message: fieldMessage,
|
|
2120
|
+
validate: field.required ? (value) => String(value ?? "").trim() ? true : "This field is required" : void 0
|
|
2121
|
+
});
|
|
2122
|
+
continue;
|
|
2123
|
+
}
|
|
2124
|
+
values[name] = await (0, _inquirer_prompts.input)({
|
|
2125
|
+
message: fieldMessage,
|
|
2126
|
+
default: field.defaultValue,
|
|
2127
|
+
validate: field.required ? (value) => String(value ?? "").trim() ? true : "This field is required" : void 0
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
} catch (error) {
|
|
2131
|
+
if (isPromptCancelError(error)) return emptyResult;
|
|
2132
|
+
throw error;
|
|
2133
|
+
}
|
|
2134
|
+
if (!hasActions) return coerceAskResult(options.form, values);
|
|
2135
|
+
const selectedAction = await chooseActionWithSelect(message, [{
|
|
2136
|
+
kind: "primary",
|
|
2137
|
+
action: primaryAction
|
|
2138
|
+
}, {
|
|
2139
|
+
kind: "secondary",
|
|
2140
|
+
action: secondaryAction
|
|
2141
|
+
}]);
|
|
2142
|
+
if (selectedAction === "primary") {
|
|
2143
|
+
await runAction(primaryAction);
|
|
2144
|
+
return coerceAskResult(options.form, values);
|
|
2145
|
+
}
|
|
2146
|
+
if (selectedAction === "secondary") await runAction(secondaryAction);
|
|
2147
|
+
return emptyResult;
|
|
2148
|
+
}
|
|
2149
|
+
const promptFields = Object.fromEntries(formEntries.map(([fieldName, field]) => [fieldName, {
|
|
2150
|
+
type: field.type,
|
|
2151
|
+
label: field.title || fieldName,
|
|
2152
|
+
description: field.description,
|
|
2153
|
+
placeholder: field.placeholder,
|
|
2154
|
+
defaultValue: field.defaultValue,
|
|
2155
|
+
value: field.defaultValue,
|
|
2156
|
+
required: field.required,
|
|
2157
|
+
autoFocus: field.autoFocus
|
|
2158
|
+
}]));
|
|
2159
|
+
const promptResponse = await requestPrompt({
|
|
2160
|
+
title: resolveTitle(options.title),
|
|
2161
|
+
description: message,
|
|
2162
|
+
fields: promptFields,
|
|
2163
|
+
actions: hasActions ? {
|
|
2164
|
+
primaryAction: {
|
|
2165
|
+
title: primaryAction.title,
|
|
2166
|
+
style: primaryAction.style
|
|
2167
|
+
},
|
|
2168
|
+
secondaryAction: {
|
|
2169
|
+
title: secondaryAction.title,
|
|
2170
|
+
style: secondaryAction.style
|
|
2171
|
+
}
|
|
2172
|
+
} : void 0
|
|
2173
|
+
});
|
|
2174
|
+
const action = promptResponse.__action ?? "primary";
|
|
2175
|
+
const values = { ...promptResponse };
|
|
2176
|
+
delete values.__action;
|
|
2177
|
+
if (action === "primary") {
|
|
2178
|
+
await runAction(options.primaryAction);
|
|
2179
|
+
return coerceAskResult(options.form, values);
|
|
2180
|
+
}
|
|
2181
|
+
if (action === "secondary") await runAction(options.secondaryAction);
|
|
2182
|
+
return emptyResult;
|
|
2183
|
+
};
|
|
2184
|
+
const Azot = {
|
|
2185
|
+
defineExtension: (extension) => extension,
|
|
2186
|
+
version: package_default.version,
|
|
2187
|
+
sleep: node_timers_promises.setTimeout,
|
|
2188
|
+
sanitizeString,
|
|
2189
|
+
execUrlPatterns,
|
|
2190
|
+
extendEpisodes,
|
|
2191
|
+
between,
|
|
2192
|
+
getRandomElements,
|
|
2193
|
+
utils: common,
|
|
2194
|
+
prompt: requestPrompt,
|
|
2195
|
+
input,
|
|
2196
|
+
notify,
|
|
2197
|
+
confirm,
|
|
2198
|
+
ask: askFeedback
|
|
2199
|
+
};
|
|
2200
|
+
class Document {
|
|
2201
|
+
get cookie() {
|
|
2202
|
+
return cookieStore.toString();
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
const window = {
|
|
2206
|
+
fetch: http.fetch.bind(http),
|
|
2207
|
+
Response,
|
|
2208
|
+
Request,
|
|
2209
|
+
Headers,
|
|
2210
|
+
AbortController,
|
|
2211
|
+
AbortSignal,
|
|
2212
|
+
URL,
|
|
2213
|
+
URLSearchParams,
|
|
2214
|
+
URLPattern,
|
|
2215
|
+
open: openWindow,
|
|
2216
|
+
Blob,
|
|
2217
|
+
structuredClone,
|
|
2218
|
+
btoa,
|
|
2219
|
+
atob,
|
|
2220
|
+
TextEncoder,
|
|
2221
|
+
TextDecoder,
|
|
2222
|
+
Uint8Array,
|
|
2223
|
+
crypto,
|
|
2224
|
+
console: {
|
|
2225
|
+
log: console.log,
|
|
2226
|
+
info: logger.info.bind(logger),
|
|
2227
|
+
warn: logger.warn.bind(logger),
|
|
2228
|
+
error: (...args) => {
|
|
2229
|
+
const message = String(args[0] ?? "Unknown error");
|
|
2230
|
+
errors.emit("error", { message });
|
|
2231
|
+
logger.error(message);
|
|
2232
|
+
},
|
|
2233
|
+
trace: logger.trace.bind(logger),
|
|
2234
|
+
debug: logger.debug.bind(logger)
|
|
2235
|
+
},
|
|
2236
|
+
Event,
|
|
2237
|
+
EventTarget,
|
|
2238
|
+
localStorage,
|
|
2239
|
+
cookieStore,
|
|
2240
|
+
document: new Document(),
|
|
2241
|
+
eval: (x) => create(x)?.exports,
|
|
2242
|
+
navigator: {
|
|
2243
|
+
appName: "Azot",
|
|
2244
|
+
appVersion: package_default.version,
|
|
2245
|
+
platform: process.platform,
|
|
2246
|
+
userAgent: `Azot/${package_default.version}`,
|
|
2247
|
+
userAgentData: createUserAgentData()
|
|
2248
|
+
}
|
|
2249
|
+
};
|
|
2250
|
+
return {
|
|
2251
|
+
http,
|
|
2252
|
+
question: prompt,
|
|
2253
|
+
common,
|
|
2254
|
+
Streamyx: Azot,
|
|
2255
|
+
Azot,
|
|
2256
|
+
window,
|
|
2257
|
+
...window
|
|
2258
|
+
};
|
|
2259
|
+
};
|
|
2260
|
+
|
|
2261
|
+
//#endregion
|
|
2262
|
+
Object.defineProperty(exports, 'createContext', {
|
|
2263
|
+
enumerable: true,
|
|
2264
|
+
get: function () {
|
|
2265
|
+
return createContext;
|
|
2266
|
+
}
|
|
2267
|
+
});
|