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