@xbrowser/cli 0.14.0 → 0.14.2

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.
@@ -1,100 +0,0 @@
1
- // src/config.ts
2
- import { existsSync, mkdirSync, writeFileSync as writeFileSync2 } from "fs";
3
- import { join } from "path";
4
- import { homedir, tmpdir } from "os";
5
-
6
- // src/utils/json-file.ts
7
- import { readFileSync, writeFileSync } from "fs";
8
- function readJsonFile(filePath, defaultValue) {
9
- try {
10
- const content = readFileSync(filePath, "utf-8");
11
- return JSON.parse(content);
12
- } catch {
13
- return defaultValue;
14
- }
15
- }
16
-
17
- // src/config.ts
18
- function getConfigFile() {
19
- return join(homedir() || tmpdir(), ".xbrowser", "config.json");
20
- }
21
- function loadConfig() {
22
- const configFile = getConfigFile();
23
- if (!existsSync(configFile)) return {};
24
- return readJsonFile(configFile, {});
25
- }
26
- function saveConfig(config) {
27
- const dir = join(homedir() || tmpdir(), ".xbrowser");
28
- const configFile = getConfigFile();
29
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
30
- writeFileSync2(configFile, JSON.stringify(config, null, 2), "utf-8");
31
- }
32
- function getConfigValue(key) {
33
- return loadConfig()[key];
34
- }
35
- function setConfigValue(key, value) {
36
- const config = loadConfig();
37
- config[key] = value;
38
- saveConfig(config);
39
- }
40
- var DEFAULT_MARKETPLACE_URL = "https://marketplace.xbrowser.dev";
41
- var DEFAULT_REGISTRY_URL = "https://xbrowser.dev";
42
- var NPM_REGISTRY_URL = "https://registry.npmjs.org";
43
- var NPM_SCOPE = "@xbrowser/";
44
- function getMarketplaceUrl() {
45
- return process.env.XBROWSER_MARKETPLACE_URL || getConfigValue("marketplaceUrl") || DEFAULT_MARKETPLACE_URL;
46
- }
47
- function getRegistryUrl(options = {}, fallbackRegistry) {
48
- return options["registry"] || process.env.XBROWSER_REGISTRY || fallbackRegistry || DEFAULT_REGISTRY_URL;
49
- }
50
- function resolveNpmPackageName(name) {
51
- if (name.startsWith("@")) return name;
52
- return `${NPM_SCOPE}${name}`;
53
- }
54
- var NPM_NAME_ALIASES = {
55
- "1688": "alibaba-1688"
56
- };
57
- function generateNpmCandidates(name) {
58
- if (name.startsWith("@")) return [name];
59
- const resolved = NPM_NAME_ALIASES[name] ?? name;
60
- return [
61
- `${NPM_SCOPE}xbrowser-plugin-${resolved}`,
62
- `${NPM_SCOPE}${resolved}`,
63
- `xbrowser-plugin-${resolved}`
64
- ];
65
- }
66
- async function resolveNpmPackageWithFallback(name) {
67
- const candidates = generateNpmCandidates(name);
68
- for (const candidate of candidates) {
69
- try {
70
- const encoded = encodeURIComponent(candidate);
71
- const res = await fetch(`${NPM_REGISTRY_URL}/${encoded}`);
72
- if (res.ok) return candidate;
73
- } catch {
74
- continue;
75
- }
76
- }
77
- return resolveNpmPackageName(name);
78
- }
79
- function getCaptchaConfig() {
80
- const config = loadConfig();
81
- return {
82
- notifyUrl: process.env.XBROWSER_NOTIFY_URL || config.captcha?.notifyUrl,
83
- autoOpen: process.env.XBROWSER_AUTO_OPEN === "true" || config.captcha?.autoOpen === true,
84
- timeout: parseInt(process.env.XBROWSER_CAPTCHA_TIMEOUT || "") || config.captcha?.timeout || 120,
85
- previewPort: parseInt(process.env.XBROWSER_PREVIEW_PORT || "") || config.preview?.port || 9223
86
- };
87
- }
88
-
89
- export {
90
- readJsonFile,
91
- loadConfig,
92
- getConfigValue,
93
- setConfigValue,
94
- NPM_REGISTRY_URL,
95
- NPM_SCOPE,
96
- getMarketplaceUrl,
97
- getRegistryUrl,
98
- resolveNpmPackageWithFallback,
99
- getCaptchaConfig
100
- };
@@ -1,29 +0,0 @@
1
- import {
2
- readJsonFile
3
- } from "./chunk-FF5WHQHN.js";
4
-
5
- // src/plugin/builtins/shared.ts
6
- import { existsSync, writeFileSync, mkdirSync } from "fs";
7
- import { resolve } from "path";
8
- import { homedir } from "os";
9
- function getAuthDir() {
10
- return resolve(homedir(), ".xbrowser");
11
- }
12
- function getAuthFile() {
13
- return resolve(getAuthDir(), "auth.json");
14
- }
15
- function loadAuth() {
16
- const authFile = getAuthFile();
17
- if (!existsSync(authFile)) return null;
18
- return readJsonFile(authFile, null);
19
- }
20
- function saveAuth(config) {
21
- const dir = getAuthDir();
22
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
23
- writeFileSync(getAuthFile(), JSON.stringify(config, null, 2), "utf-8");
24
- }
25
-
26
- export {
27
- loadAuth,
28
- saveAuth
29
- };
@@ -1,438 +0,0 @@
1
- import {
2
- ensureProxyFetch
3
- } from "./chunk-VEKPHQBR.js";
4
- import {
5
- NPM_REGISTRY_URL,
6
- readJsonFile
7
- } from "./chunk-M7CMBPCA.js";
8
-
9
- // src/plugin/publisher.ts
10
- import { existsSync as existsSync2, readdirSync, readFileSync } from "fs";
11
- import { resolve as resolve2, relative, basename, posix } from "path";
12
- import { createHash } from "crypto";
13
- import { gzipSync } from "zlib";
14
-
15
- // src/plugin/metadata-parser.ts
16
- import { existsSync } from "fs";
17
- import { resolve } from "path";
18
- var PluginMetadataParser = class {
19
- static XBROWSER_KEYWORDS = ["xbrowser", "xbrowser-plugin"];
20
- static parseFromPackageJson(pluginPath) {
21
- const packageJsonPath = resolve(pluginPath, "package.json");
22
- if (!existsSync(packageJsonPath)) {
23
- return null;
24
- }
25
- const packageJson = readJsonFile(packageJsonPath, null);
26
- if (!packageJson) return null;
27
- if (!packageJson.xbrowser) {
28
- return null;
29
- }
30
- const xbrowser = packageJson.xbrowser;
31
- const metadata = {
32
- id: xbrowser.id || packageJson.name,
33
- name: xbrowser.name || packageJson.name,
34
- description: xbrowser.description || packageJson.description || "",
35
- version: xbrowser.version || packageJson.version || "1.0.0",
36
- author: xbrowser.author || this.extractAuthor(packageJson.author),
37
- homepage: xbrowser.homepage || packageJson.homepage,
38
- commands: xbrowser.commands,
39
- sites: xbrowser.sites,
40
- tags: xbrowser.tags,
41
- screenshot: xbrowser.screenshot,
42
- license: xbrowser.license || packageJson.license
43
- };
44
- return metadata;
45
- }
46
- static isXBrowserPlugin(packageJson) {
47
- if (packageJson.xbrowser) {
48
- return true;
49
- }
50
- const keywords = packageJson.keywords;
51
- if (!keywords) return false;
52
- return this.XBROWSER_KEYWORDS.some((kw) => keywords.includes(kw));
53
- }
54
- static fromNPMResult(result) {
55
- const author = typeof result.author === "string" ? result.author : result.author?.name || "Unknown";
56
- return {
57
- id: result.name,
58
- name: result.name.replace(/^xbrowser-plugin-/, "").replace(/^@[^/]+\//, ""),
59
- description: result.description || "",
60
- version: result.version,
61
- author,
62
- homepage: result.homepage || result.links?.homepage,
63
- tags: result.keywords,
64
- license: ""
65
- };
66
- }
67
- static extractAuthor(author) {
68
- if (typeof author === "string") return author;
69
- if (typeof author === "object" && author !== null) {
70
- const authorObj = author;
71
- return authorObj.name || "Unknown";
72
- }
73
- return "Unknown";
74
- }
75
- static validateMetadata(metadata) {
76
- const errors = [];
77
- if (!metadata.id) errors.push("id is required");
78
- if (!metadata.name) errors.push("name is required");
79
- if (!metadata.description) errors.push("description is required");
80
- if (!metadata.version) errors.push("version is required");
81
- return errors;
82
- }
83
- };
84
-
85
- // src/plugin/publisher.ts
86
- var IGNORE_PATTERNS = [
87
- "node_modules",
88
- ".git",
89
- ".DS_Store",
90
- "dist",
91
- ".env",
92
- ".env.local",
93
- "*.log"
94
- ];
95
- function shouldIgnore(name) {
96
- return IGNORE_PATTERNS.some((pattern) => {
97
- if (pattern.startsWith("*")) return name.endsWith(pattern.slice(1));
98
- return name === pattern;
99
- });
100
- }
101
- function collectFiles(dir, base = dir) {
102
- const files = [];
103
- if (!existsSync2(dir)) return files;
104
- const entries = readdirSync(dir, { withFileTypes: true });
105
- for (const entry of entries) {
106
- if (shouldIgnore(entry.name)) continue;
107
- const fullPath = resolve2(dir, entry.name);
108
- if (entry.isDirectory()) {
109
- files.push(...collectFiles(fullPath, base));
110
- } else if (entry.isFile()) {
111
- const relPath = relative(base, fullPath).split("/").join(posix.sep);
112
- files.push({ path: relPath, content: readFileSync(fullPath) });
113
- }
114
- }
115
- return files;
116
- }
117
- function extractCommandDocsFromCode(code) {
118
- const docs = [];
119
- const commandStartRegex = /\b\w+\s*\.\s*command\s*\(\s*['"`]([^'"`]+)['"`]\s*,\s*\{/g;
120
- let startMatch;
121
- while ((startMatch = commandStartRegex.exec(code)) !== null) {
122
- const cmdName = startMatch[1];
123
- const startPos = startMatch.index + startMatch[0].length;
124
- const header = extractCommandHeader(code, startPos);
125
- const descMatch = header.match(/description\s*:\s*['"`]([\s\S]*?)['"`]/);
126
- const description = descMatch ? descMatch[1].trim() : "";
127
- const parameters = extractParameters(header);
128
- const examples = extractExamples(header);
129
- docs.push({
130
- name: cmdName,
131
- description,
132
- parameters,
133
- examples: examples.length > 0 ? examples : void 0
134
- });
135
- }
136
- return docs;
137
- }
138
- function extractCommandHeader(code, startPos) {
139
- let depth = 1;
140
- let i = startPos;
141
- while (i < code.length && depth > 0) {
142
- const ch = code[i];
143
- if (ch === "{") depth++;
144
- else if (ch === "}") {
145
- depth--;
146
- if (depth === 0) break;
147
- }
148
- i++;
149
- }
150
- const fullBlock = code.slice(startPos, i);
151
- const handlerIdx = fullBlock.search(/\bhandler\s*:/);
152
- if (handlerIdx !== -1) {
153
- return fullBlock.slice(0, handlerIdx);
154
- }
155
- return fullBlock;
156
- }
157
- function extractParameters(block) {
158
- const params = [];
159
- const zodObjectRegex = /z\.object\s*\(\s*\{([\s\S]*?)\}\s*\)/;
160
- const objMatch = block.match(zodObjectRegex);
161
- if (!objMatch) return params;
162
- const objBody = objMatch[1];
163
- const normalized = objBody.replace(/\n\s*/g, " ").replace(/\s+/g, " ").replace(/z\s*\.\s*/g, "z.");
164
- const fieldRegex = /(\w+)\s*:\s*z\.(\w+)([^(]*)/g;
165
- let fieldMatch;
166
- while ((fieldMatch = fieldRegex.exec(normalized)) !== null) {
167
- const pName = fieldMatch[1];
168
- const zType = fieldMatch[2];
169
- const restStart = fieldMatch.index + fieldMatch[0].length;
170
- let rest = "";
171
- let depth = 0;
172
- let j = restStart;
173
- while (j < normalized.length) {
174
- if (normalized[j] === "(") depth++;
175
- else if (normalized[j] === ")") {
176
- if (depth === 0) break;
177
- depth--;
178
- } else if (depth === 0 && (normalized[j] === "," || normalized[j] === "}")) {
179
- break;
180
- }
181
- rest += normalized[j];
182
- j++;
183
- }
184
- const isOptional = rest.includes(".optional()");
185
- const defaultMatch = rest.match(/\.default\s*\(\s*([^)]+)\s*\)/);
186
- let defaultValue = void 0;
187
- if (defaultMatch) {
188
- const raw = defaultMatch[1].trim();
189
- if (raw === "true") defaultValue = true;
190
- else if (raw === "false") defaultValue = false;
191
- else if (raw.startsWith("'") || raw.startsWith('"')) defaultValue = raw.slice(1, -1);
192
- else if (!isNaN(Number(raw))) defaultValue = Number(raw);
193
- else defaultValue = raw;
194
- }
195
- const descMatch = rest.match(/\.describe\s*\(\s*['"`]([\s\S]*?)['"`]\s*\)/);
196
- const pDesc = descMatch ? descMatch[1].trim() : "";
197
- let pType = zType;
198
- const enumMatch = rest.match(/\.enum\s*\(\s*\[([^\]]+)\]\s*\)/);
199
- if (enumMatch) {
200
- pType = `enum: ${enumMatch[1].trim()}`;
201
- }
202
- params.push({
203
- name: pName,
204
- type: pType,
205
- description: pDesc,
206
- required: !isOptional,
207
- ...defaultValue !== void 0 ? { default: defaultValue } : {}
208
- });
209
- }
210
- return params;
211
- }
212
- function extractExamples(block) {
213
- const examples = [];
214
- const examplesRegex = /examples\s*:\s*\[([\s\S]*?)\]\s*,?\s*(?:result|handler|\}\s*\)|$)/;
215
- const exMatch = block.match(examplesRegex);
216
- if (!exMatch) {
217
- const fallbackRegex = /examples\s*:\s*\[([\s\S]*?)\]\s*[,}\n]/;
218
- const fbMatch = block.match(fallbackRegex);
219
- if (!fbMatch) return examples;
220
- const exBody = fbMatch[1];
221
- const objRegex2 = /\{\s*cmd\s*:\s*'([^']+)'\s*,\s*description\s*:\s*'([^']+)'\s*\}/g;
222
- let objMatch2;
223
- while ((objMatch2 = objRegex2.exec(exBody)) !== null) {
224
- examples.push({ cmd: objMatch2[1], description: objMatch2[2].trim() });
225
- }
226
- if (examples.length === 0) {
227
- const objRegex22 = /\{\s*cmd\s*:\s*"([^"]+)"\s*,\s*description\s*:\s*"([^"]+)"\s*\}/g;
228
- let objMatch22;
229
- while ((objMatch22 = objRegex22.exec(exBody)) !== null) {
230
- examples.push({ cmd: objMatch22[1], description: objMatch22[2].trim() });
231
- }
232
- }
233
- return examples;
234
- }
235
- const exBody2 = exMatch[1];
236
- const objRegex = /\{\s*cmd\s*:\s*'([^']+)'\s*,\s*description\s*:\s*'([^']+)'\s*\}/g;
237
- let objMatch;
238
- while ((objMatch = objRegex.exec(exBody2)) !== null) {
239
- examples.push({ cmd: objMatch[1], description: objMatch[2].trim() });
240
- }
241
- if (examples.length === 0) {
242
- const objRegex2 = /\{\s*cmd\s*:\s*"([^"]+)"\s*,\s*description\s*:\s*"([^"]+)"\s*\}/g;
243
- let objMatch2;
244
- while ((objMatch2 = objRegex2.exec(exBody2)) !== null) {
245
- examples.push({ cmd: objMatch2[1], description: objMatch2[2].trim() });
246
- }
247
- }
248
- return examples;
249
- }
250
- function readReadme(pluginDir) {
251
- const candidates = ["README.md", "readme.md", "Readme.md"];
252
- for (const name of candidates) {
253
- const path = resolve2(pluginDir, name);
254
- if (existsSync2(path)) {
255
- return readFileSync(path, "utf-8");
256
- }
257
- }
258
- return null;
259
- }
260
- var SITE_TAG_MAP = {
261
- "baidu.com": ["baidu", "search-engine"],
262
- "google.com": ["google", "search-engine"],
263
- "bing.com": ["bing", "search-engine"],
264
- "douyin.com": ["douyin", "social-media", "video"],
265
- "tiktok.com": ["tiktok", "social-media", "video"],
266
- "instagram.com": ["instagram", "social-media", "photo"],
267
- "twitter.com": ["twitter", "social-media"],
268
- "x.com": ["twitter", "social-media"],
269
- "facebook.com": ["facebook", "social-media"],
270
- "weibo.com": ["weibo", "social-media"],
271
- "zhihu.com": ["zhihu", "q&a", "knowledge"],
272
- "xiaohongshu.com": ["xiaohongshu", "social-media", "lifestyle"],
273
- "csdn.net": ["csdn", "developer", "knowledge"],
274
- "juejin.cn": ["juejin", "developer"],
275
- "github.com": ["github", "developer", "code"],
276
- "reddit.com": ["reddit", "social-media", "forum"],
277
- "medium.com": ["medium", "blog", "knowledge"],
278
- "taobao.com": ["taobao", "e-commerce"],
279
- "jd.com": ["jd", "e-commerce"],
280
- "pinterest.com": ["pinterest", "social-media", "photo"],
281
- "youtube.com": ["youtube", "video", "social-media"],
282
- "bilibili.com": ["bilibili", "video", "social-media"]
283
- };
284
- function extractTagsFromCode(code, existingTags) {
285
- const tags = new Set(existingTags);
286
- const urlMatch = code.match(/url\s*:\s*['"`](https?:\/\/[^'"`]+)['"`]/);
287
- if (urlMatch) {
288
- try {
289
- const hostname = new URL(urlMatch[1]).hostname.replace(/^www\./, "");
290
- const mapped = SITE_TAG_MAP[hostname];
291
- if (mapped) {
292
- for (const tag of mapped) tags.add(tag);
293
- } else {
294
- const domain = hostname.split(".")[0];
295
- tags.add(domain);
296
- }
297
- } catch {
298
- }
299
- }
300
- const nameMatch = code.match(/name\s*:\s*['"`]([^'"`]+)['"`]/);
301
- if (nameMatch && !tags.has(nameMatch[1])) {
302
- tags.add(nameMatch[1]);
303
- }
304
- return Array.from(tags);
305
- }
306
- function extractSitesFromCode(code, existingSites) {
307
- const sites = new Set(existingSites);
308
- const urlMatch = code.match(/url\s*:\s*['"`](https?:\/\/[^'"`]+)['"`]/);
309
- if (urlMatch) {
310
- try {
311
- const hostname = new URL(urlMatch[1]).hostname.replace(/^www\./, "");
312
- sites.add(hostname);
313
- } catch {
314
- }
315
- }
316
- return Array.from(sites);
317
- }
318
- function slugify(name) {
319
- return name.toLowerCase().replace(/^@[^/]+\//, "").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
320
- }
321
- async function validateNpmPackageExists(packageName, version) {
322
- await ensureProxyFetch();
323
- const encodedName = encodeURIComponent(packageName);
324
- const res = await fetch(`${NPM_REGISTRY_URL}/${encodedName}/${version}`);
325
- if (!res.ok) {
326
- throw new Error(
327
- `Package ${packageName}@${version} not found on npm. Publish to npm first, or use --storage r2 to upload directly.`
328
- );
329
- }
330
- }
331
- async function createTarball(pluginDir, options) {
332
- const indexPath = resolve2(pluginDir, "index.ts");
333
- const pkgPath = resolve2(pluginDir, "package.json");
334
- if (!existsSync2(indexPath)) {
335
- throw new Error("No index.ts found. A plugin must have an index.ts entry file.");
336
- }
337
- let packageJson = {};
338
- if (existsSync2(pkgPath)) {
339
- packageJson = readJsonFile(pkgPath, {});
340
- }
341
- const xbrowserMeta = packageJson.xbrowser || {};
342
- const name = xbrowserMeta.name || packageJson.name || basename(pluginDir);
343
- const version = xbrowserMeta.version || packageJson.version || "1.0.0";
344
- const description = xbrowserMeta.description || packageJson.description || "";
345
- const author = PluginMetadataParser.extractAuthor(packageJson.author);
346
- const slug = slugify(xbrowserMeta.slug || name);
347
- if (!description) {
348
- throw new Error('Plugin must have a description. Add "description" to package.json or xbrowser metadata.');
349
- }
350
- const indexCode = readFileSync(indexPath, "utf-8");
351
- const commandsDocs = extractCommandDocsFromCode(indexCode);
352
- const detectedCommands = commandsDocs.map((d) => d.name);
353
- const commands = xbrowserMeta.commands || detectedCommands.length > 0 ? xbrowserMeta.commands || detectedCommands : detectedCommands;
354
- const readme = readReadme(pluginDir);
355
- const tags = extractTagsFromCode(indexCode, xbrowserMeta.tags || []);
356
- const sites = extractSitesFromCode(indexCode, xbrowserMeta.sites || []);
357
- const storage = options.storage || "r2";
358
- if (storage === "npm") {
359
- const packageName = packageJson.name || name;
360
- await validateNpmPackageExists(packageName, version);
361
- }
362
- const formData = new FormData();
363
- const metadata = {
364
- name,
365
- slug,
366
- version,
367
- description,
368
- author,
369
- commands,
370
- commandsDocs,
371
- readme,
372
- tags,
373
- sites,
374
- license: xbrowserMeta.license || packageJson.license || "MIT",
375
- homepageUrl: xbrowserMeta.homepage || packageJson.homepage || null,
376
- repositoryUrl: xbrowserMeta.repository || packageJson.repository?.url || null,
377
- npmPackage: packageJson.name || null,
378
- storageType: storage
379
- };
380
- const metadataBlob = new Blob([JSON.stringify(metadata)], { type: "application/json" });
381
- formData.append("metadata", metadataBlob, "metadata.json");
382
- let totalSize = 0;
383
- let checksum = "";
384
- if (storage === "r2") {
385
- const files = collectFiles(pluginDir);
386
- const manifest = files.map((f) => ({
387
- path: f.path,
388
- content: f.content.toString("base64")
389
- }));
390
- const manifestJson = JSON.stringify(manifest);
391
- const gzipped = gzipSync(Buffer.from(manifestJson));
392
- totalSize = gzipped.length;
393
- const hash = createHash("sha256");
394
- hash.update(gzipped);
395
- checksum = `sha256-${hash.digest("hex").slice(0, 16)}`;
396
- const blob = new Blob([new Uint8Array(gzipped)]);
397
- formData.append("files", blob, `${slug}-${version}.tar.gz`);
398
- formData.append("checksum", checksum);
399
- return {
400
- name,
401
- version,
402
- slug,
403
- description,
404
- author,
405
- commands,
406
- commandsDocs,
407
- readme,
408
- tags,
409
- sites,
410
- fileCount: files.length,
411
- size: totalSize,
412
- checksum,
413
- formData
414
- };
415
- }
416
- formData.append("checksum", "npm-managed");
417
- return {
418
- name,
419
- version,
420
- slug,
421
- description,
422
- author,
423
- commands,
424
- commandsDocs,
425
- readme,
426
- tags,
427
- sites,
428
- fileCount: 0,
429
- size: 0,
430
- checksum: "npm-managed",
431
- formData
432
- };
433
- }
434
-
435
- export {
436
- PluginMetadataParser,
437
- createTarball
438
- };
@@ -1,47 +0,0 @@
1
- // src/utils/proxy-fetch.ts
2
- var patched = false;
3
- async function ensureProxyFetch() {
4
- if (patched) return;
5
- patched = true;
6
- if (process.env.https_proxy && !process.env.HTTPS_PROXY) {
7
- process.env.HTTPS_PROXY = process.env.https_proxy;
8
- }
9
- if (process.env.http_proxy && !process.env.HTTP_PROXY) {
10
- process.env.HTTP_PROXY = process.env.http_proxy;
11
- }
12
- if (process.env.all_proxy && !process.env.ALL_PROXY) {
13
- process.env.ALL_PROXY = process.env.all_proxy;
14
- }
15
- const proxyUrl = process.env.https_proxy || process.env.HTTPS_PROXY || process.env.http_proxy || process.env.HTTP_PROXY || process.env.all_proxy || process.env.ALL_PROXY;
16
- if (!proxyUrl) return;
17
- try {
18
- const undici = await import("undici");
19
- const EnvHttpProxyAgent = undici.EnvHttpProxyAgent;
20
- const uFetch = undici.fetch;
21
- const UFormData = undici.FormData;
22
- if (EnvHttpProxyAgent && uFetch && UFormData) {
23
- const agent = new EnvHttpProxyAgent();
24
- globalThis.fetch = ((input, init) => {
25
- const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
26
- const body = init?.body;
27
- if (body instanceof globalThis.FormData && !(body instanceof UFormData)) {
28
- const ufd = new UFormData();
29
- body.forEach((value, key) => {
30
- if (value instanceof Blob) {
31
- ufd.append(key, value, value.name || "file");
32
- } else {
33
- ufd.append(key, value);
34
- }
35
- });
36
- return uFetch(url, { ...init, body: ufd, dispatcher: agent });
37
- }
38
- return uFetch(url, { ...init, dispatcher: agent });
39
- });
40
- }
41
- } catch {
42
- }
43
- }
44
-
45
- export {
46
- ensureProxyFetch
47
- };
@@ -1,14 +0,0 @@
1
- // src/utils/json-file.ts
2
- import { readFileSync, writeFileSync } from "fs";
3
- function readJsonFile(filePath, defaultValue) {
4
- try {
5
- const content = readFileSync(filePath, "utf-8");
6
- return JSON.parse(content);
7
- } catch {
8
- return defaultValue;
9
- }
10
- }
11
-
12
- export {
13
- readJsonFile
14
- };