mirror of
https://github.com/anidl/multi-downloader-nx.git
synced 2026-01-11 20:10:20 +00:00
added proxy support
This commit is contained in:
parent
6b3fd97f56
commit
debc2876d6
12 changed files with 250 additions and 242 deletions
11
adn.ts
11
adn.ts
|
|
@ -35,6 +35,7 @@ import { ADNVideo, ADNVideos } from './@types/adnVideos';
|
|||
import { ADNPlayerConfig } from './@types/adnPlayerConfig';
|
||||
import { ADNStreams } from './@types/adnStreams';
|
||||
import { ADNSubtitles } from './@types/adnSubtitles';
|
||||
import { FetchParams } from './modules/module.fetch';
|
||||
|
||||
export default class AnimationDigitalNetwork implements ServiceClass {
|
||||
public cfg: yamlCfg.ConfigObject;
|
||||
|
|
@ -58,7 +59,7 @@ export default class AnimationDigitalNetwork implements ServiceClass {
|
|||
constructor(private debug = false) {
|
||||
this.cfg = yamlCfg.loadCfg();
|
||||
this.token = yamlCfg.loadADNToken();
|
||||
this.req = new reqModule.Req(domain, debug, false, 'adn');
|
||||
this.req = new reqModule.Req();
|
||||
this.locale = 'fr';
|
||||
}
|
||||
|
||||
|
|
@ -184,13 +185,14 @@ export default class AnimationDigitalNetwork implements ServiceClass {
|
|||
password: data.password,
|
||||
source: 'Web'
|
||||
});
|
||||
const authReqOpts: reqModule.Params = {
|
||||
const authReqOpts: FetchParams = {
|
||||
method: 'POST',
|
||||
body: authData,
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'x-target-distribution': this.locale
|
||||
}
|
||||
},
|
||||
useProxy: true
|
||||
};
|
||||
const authReq = await this.req.getData('https://gw.api.animationdigitalnetwork.com/authentication/login', authReqOpts);
|
||||
if (!authReq.ok || !authReq.res) {
|
||||
|
|
@ -212,7 +214,8 @@ export default class AnimationDigitalNetwork implements ServiceClass {
|
|||
'content-type': 'application/json',
|
||||
'x-target-distribution': this.locale
|
||||
},
|
||||
body: JSON.stringify({ refreshToken: this.token.refreshToken })
|
||||
body: JSON.stringify({ refreshToken: this.token.refreshToken }),
|
||||
useProxy: true
|
||||
});
|
||||
if (!authReq.ok || !authReq.res) {
|
||||
console.error('Token refresh failed!');
|
||||
|
|
|
|||
67
crunchy.ts
67
crunchy.ts
|
|
@ -41,6 +41,7 @@ import vtt2ass from './modules/module.vtt2ass';
|
|||
import { CrunchyPlayStream } from './@types/crunchyPlayStreams';
|
||||
import { CrunchyVideoPlayStreams, CrunchyAudioPlayStreams } from './@types/enums';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { FetchParams } from './modules/module.fetch';
|
||||
|
||||
export type sxItem = {
|
||||
language: langsData.LanguageItem;
|
||||
|
|
@ -64,7 +65,7 @@ export default class Crunchy implements ServiceClass {
|
|||
constructor(private debug = false) {
|
||||
this.cfg = yamlCfg.loadCfg();
|
||||
this.token = yamlCfg.loadCRToken();
|
||||
this.req = new reqModule.Req(domain, debug, false, 'cr');
|
||||
this.req = new reqModule.Req();
|
||||
this.locale = 'en-US';
|
||||
}
|
||||
|
||||
|
|
@ -193,8 +194,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
// seasons list
|
||||
const seriesSeasonListReq = await this.req.getData(
|
||||
|
|
@ -224,8 +224,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
// seasons list
|
||||
let episodeList = { total: 0, data: [], meta: {} } as CrunchyEpisodeList;
|
||||
|
|
@ -277,8 +276,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
|
||||
const allShows: any[] = [];
|
||||
|
|
@ -402,10 +400,11 @@ export default class Crunchy implements ServiceClass {
|
|||
device_name: 'iPhone',
|
||||
device_type: 'iPhone 13'
|
||||
}).toString();
|
||||
const authReqOpts: reqModule.Params = {
|
||||
const authReqOpts: FetchParams = {
|
||||
method: 'POST',
|
||||
headers: { ...api.crunchyAuthHeader, 'ETP-Anonymous-ID': uuid },
|
||||
body: authData
|
||||
body: authData,
|
||||
useProxy: true
|
||||
};
|
||||
const authReq = await this.req.getData(api.auth, authReqOpts);
|
||||
if (!authReq.ok || !authReq.res) {
|
||||
|
|
@ -441,10 +440,11 @@ export default class Crunchy implements ServiceClass {
|
|||
device_name: 'iPhone',
|
||||
device_type: 'iPhone 13'
|
||||
}).toString();
|
||||
const authReqOpts: reqModule.Params = {
|
||||
const authReqOpts: FetchParams = {
|
||||
method: 'POST',
|
||||
headers: { ...api.crunchyAuthHeader, 'ETP-Anonymous-ID': uuid },
|
||||
body: authData
|
||||
body: authData,
|
||||
useProxy: true
|
||||
};
|
||||
const authReq = await this.req.getData(api.auth, authReqOpts);
|
||||
if (!authReq.ok || !authReq.res) {
|
||||
|
|
@ -477,8 +477,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
...api.crunchyDefHeader,
|
||||
Authorization: `Bearer ${this.token.access_token}`
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
const profileReq = await this.req.getData(api.profile, profileReqOptions);
|
||||
if (!profileReq.ok || !profileReq.res) {
|
||||
|
|
@ -509,10 +508,11 @@ export default class Crunchy implements ServiceClass {
|
|||
device_name: 'iPhone',
|
||||
device_type: 'iPhone 13'
|
||||
}).toString();
|
||||
const authReqOpts: reqModule.Params = {
|
||||
const authReqOpts: FetchParams = {
|
||||
method: 'POST',
|
||||
headers: { ...api.crunchyAuthHeader, 'ETP-Anonymous-ID': uuid, Cookie: `etp_rt=${refreshToken}` },
|
||||
body: authData
|
||||
body: authData,
|
||||
useProxy: true
|
||||
};
|
||||
const authReq = await this.req.getData(api.auth, authReqOpts);
|
||||
if (!authReq.ok || !authReq.res) {
|
||||
|
|
@ -560,10 +560,11 @@ export default class Crunchy implements ServiceClass {
|
|||
device_name: 'iPhone',
|
||||
device_type: 'iPhone 13'
|
||||
}).toString();
|
||||
const authReqOpts: reqModule.Params = {
|
||||
const authReqOpts: FetchParams = {
|
||||
method: 'POST',
|
||||
headers: { ...api.crunchyAuthHeader, 'ETP-Anonymous-ID': uuid },
|
||||
body: authData
|
||||
body: authData,
|
||||
useProxy: true
|
||||
};
|
||||
const authReq = await this.req.getData(api.auth, authReqOpts);
|
||||
if (!authReq.ok || !authReq.res) {
|
||||
|
|
@ -613,8 +614,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
const cmsTokenReq = await this.req.getData(api.cms_auth, cmsTokenReqOpts);
|
||||
if (!cmsTokenReq.ok || !cmsTokenReq.res) {
|
||||
|
|
@ -666,8 +666,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
const searchStart = data.page ? (data.page - 1) * 5 : 0;
|
||||
const searchParams = new URLSearchParams({
|
||||
|
|
@ -929,8 +928,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
// reqs
|
||||
if (!hideSeriesTitle) {
|
||||
|
|
@ -974,8 +972,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
|
||||
//Movie Listing
|
||||
|
|
@ -1017,8 +1014,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
const newlyAddedParams = new URLSearchParams({
|
||||
sort_by: 'newly_added',
|
||||
|
|
@ -1070,8 +1066,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
|
||||
//get show info
|
||||
|
|
@ -1303,8 +1298,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
|
||||
// reqs
|
||||
|
|
@ -1317,8 +1311,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
|
||||
const mvInfoReq = await this.req.getData(
|
||||
|
|
@ -1545,7 +1538,7 @@ export default class Crunchy implements ServiceClass {
|
|||
await this.refreshToken(true, true);
|
||||
let currentVersion;
|
||||
let isPrimary = mMeta.isSubbed;
|
||||
const AuthHeaders: RequestInit = {
|
||||
const AuthHeaders: FetchParams = {
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
|
|
@ -3302,8 +3295,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
|
||||
// seasons list
|
||||
|
|
@ -3334,8 +3326,7 @@ export default class Crunchy implements ServiceClass {
|
|||
headers: {
|
||||
Authorization: `Bearer ${this.token.access_token}`,
|
||||
...api.crunchyDefHeader
|
||||
},
|
||||
useProxy: true
|
||||
}
|
||||
};
|
||||
|
||||
//get show info
|
||||
|
|
|
|||
12
hidive.ts
12
hidive.ts
|
|
@ -37,6 +37,7 @@ import { NewHidivePlayback, Subtitle } from './@types/newHidivePlayback';
|
|||
import { MPDParsed, parse } from './modules/module.transform-mpd';
|
||||
import { canDecrypt, getKeysWVD, cdm, getKeysPRD } from './modules/cdm';
|
||||
import { KeyContainer } from './modules/widevine/license';
|
||||
import { FetchParams } from './modules/module.fetch';
|
||||
|
||||
export default class Hidive implements ServiceClass {
|
||||
public cfg: yamlCfg.ConfigObject;
|
||||
|
|
@ -46,7 +47,7 @@ export default class Hidive implements ServiceClass {
|
|||
constructor(private debug = false) {
|
||||
this.cfg = yamlCfg.loadCfg();
|
||||
this.token = yamlCfg.loadNewHDToken();
|
||||
this.req = new reqModule.Req(domain, debug, false, 'hd');
|
||||
this.req = new reqModule.Req();
|
||||
}
|
||||
|
||||
public async cli() {
|
||||
|
|
@ -127,7 +128,7 @@ export default class Hidive implements ServiceClass {
|
|||
method: method as 'GET' | 'POST',
|
||||
url: (api.hd_new_api + endpoint) as string,
|
||||
body: body,
|
||||
useProxy: true
|
||||
useProxy: false
|
||||
};
|
||||
// get request type
|
||||
const isGet = method == 'GET';
|
||||
|
|
@ -139,8 +140,10 @@ export default class Hidive implements ServiceClass {
|
|||
options.headers['Authorization'] = authHeader;
|
||||
} else if (authType == 'auth') {
|
||||
options.headers['Authorization'] = `Bearer ${this.token.authorisationToken}`;
|
||||
options.useProxy = true;
|
||||
} else if (authType == 'refresh') {
|
||||
options.headers['Authorization'] = `Bearer ${this.token.refreshToken}`;
|
||||
options.useProxy = true;
|
||||
} else if (authType == 'both') {
|
||||
options.headers['Authorization'] = `Mixed ${this.token.authorisationToken} ${this.token.refreshToken}`;
|
||||
}
|
||||
|
|
@ -148,10 +151,11 @@ export default class Hidive implements ServiceClass {
|
|||
console.debug('[DEBUG] Request params:');
|
||||
console.debug(options);
|
||||
}
|
||||
const apiReqOpts: reqModule.Params = {
|
||||
const apiReqOpts: FetchParams = {
|
||||
method: options.method,
|
||||
headers: options.headers as Record<string, string>,
|
||||
body: options.body as string
|
||||
body: options.body as string,
|
||||
useProxy: options.useProxy
|
||||
};
|
||||
let apiReq = await this.req.getData(options.url, apiReqOpts);
|
||||
if (!apiReq.ok || !apiReq.res) {
|
||||
|
|
|
|||
103
modules/cdm.ts
103
modules/cdm.ts
|
|
@ -6,7 +6,9 @@ import { Device } from './playready/device';
|
|||
import Cdm from './playready/cdm';
|
||||
import { PSSH } from './playready/pssh';
|
||||
import { KeyContainer, Session } from './widevine/license';
|
||||
import { ofetch } from 'ofetch';
|
||||
import * as reqModule from './module.fetch';
|
||||
|
||||
const req = new reqModule.Req();
|
||||
|
||||
//read cdm files located in the same directory
|
||||
let privateKey: Buffer = Buffer.from([]),
|
||||
|
|
@ -97,45 +99,26 @@ export async function getKeysWVD(pssh: string | undefined, licenseServer: string
|
|||
//Create a new widevine session
|
||||
const session = new Session({ privateKey, identifierBlob }, psshBuffer);
|
||||
|
||||
//Generate license
|
||||
const data = await ofetch(licenseServer, {
|
||||
// Request License
|
||||
const licReq = await req.getData(licenseServer, {
|
||||
method: 'POST',
|
||||
body: session.createLicenseRequest(),
|
||||
headers: authData,
|
||||
responseType: 'arrayBuffer'
|
||||
}).catch((error) => {
|
||||
if (error.status && error.statusText) {
|
||||
console.error(`${error.name} ${error.status}: ${error.statusText}`);
|
||||
} else {
|
||||
console.error(`${error.name}: ${error.message}`);
|
||||
}
|
||||
|
||||
if (!error.data) return;
|
||||
const data = error.data instanceof ArrayBuffer ? new TextDecoder().decode(error.data) : error.data;
|
||||
if (data) {
|
||||
const docTitle = data.match(/<title>(.*)<\/title>/);
|
||||
if (docTitle) {
|
||||
console.error(docTitle[1]);
|
||||
}
|
||||
if (error.status && error.status != 404 && error.status != 403) {
|
||||
console.error('Body:', data);
|
||||
}
|
||||
}
|
||||
headers: authData
|
||||
});
|
||||
|
||||
if (data) {
|
||||
//Parse License and return keys
|
||||
const text = new TextDecoder().decode(data);
|
||||
try {
|
||||
const json = JSON.parse(text);
|
||||
return session.parseLicense(Buffer.from(json['license'], 'base64')) as KeyContainer[];
|
||||
} catch {
|
||||
return session.parseLicense(Buffer.from(new Uint8Array(data))) as KeyContainer[];
|
||||
}
|
||||
} else {
|
||||
console.error('License request failed');
|
||||
if (!licReq.ok || !licReq.res) {
|
||||
console.error('License fetch Failed!');
|
||||
return [];
|
||||
}
|
||||
|
||||
const lic = await licReq.res.arrayBuffer();
|
||||
const lictext = new TextDecoder().decode(lic);
|
||||
try {
|
||||
const json = JSON.parse(lictext);
|
||||
return session.parseLicense(Buffer.from(json['license'], 'base64')) as KeyContainer[];
|
||||
} catch {
|
||||
return session.parseLicense(Buffer.from(new Uint8Array(lic))) as KeyContainer[];
|
||||
}
|
||||
}
|
||||
|
||||
export async function getKeysPRD(pssh: string | undefined, licenseServer: string, authData: Record<string, string>): Promise<KeyContainer[]> {
|
||||
|
|
@ -146,45 +129,29 @@ export async function getKeysPRD(pssh: string | undefined, licenseServer: string
|
|||
const session = prd_cdm.getLicenseChallenge(pssh_parsed.get_wrm_headers(true)[0]);
|
||||
|
||||
//Generate license
|
||||
const data = await ofetch(licenseServer, {
|
||||
const licReq = await req.getData(licenseServer, {
|
||||
method: 'POST',
|
||||
body: session,
|
||||
headers: authData,
|
||||
responseType: 'text'
|
||||
}).catch((error) => {
|
||||
if (error && error.status && error.statusText) {
|
||||
console.error(`${error.name} ${error.status}: ${error.statusText}`);
|
||||
} else {
|
||||
console.error(`${error.name}: ${error.message}`);
|
||||
}
|
||||
|
||||
if (!error.data) return;
|
||||
const docTitle = error.data.match(/<title>(.*)<\/title>/);
|
||||
if (docTitle) {
|
||||
console.error(docTitle[1]);
|
||||
}
|
||||
if (error.status && error.status != 404 && error.status != 403) {
|
||||
console.error('Body:', error.data);
|
||||
}
|
||||
headers: authData
|
||||
});
|
||||
|
||||
if (data) {
|
||||
//Parse License and return keys
|
||||
try {
|
||||
const keys = prd_cdm.parseLicense(data);
|
||||
if (!licReq.ok || !licReq.res) {
|
||||
console.error('License fetch Failed!');
|
||||
return [];
|
||||
}
|
||||
|
||||
return keys.map((k) => {
|
||||
return {
|
||||
kid: k.key_id,
|
||||
key: k.key
|
||||
};
|
||||
});
|
||||
} catch {
|
||||
console.error('License parsing failed');
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
console.error('License request failed');
|
||||
//Parse License and return keys
|
||||
try {
|
||||
const keys = prd_cdm.parseLicense(await licReq.res.text());
|
||||
|
||||
return keys.map((k) => {
|
||||
return {
|
||||
kid: k.key_id,
|
||||
key: k.key
|
||||
};
|
||||
});
|
||||
} catch {
|
||||
console.error('License parsing failed');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ import url from 'url';
|
|||
|
||||
import { console } from './log';
|
||||
import { ProgressData } from '../@types/messageHandler';
|
||||
import { ofetch } from 'ofetch';
|
||||
import Helper from './module.helper';
|
||||
import * as reqModule from './module.fetch';
|
||||
|
||||
const req = new reqModule.Req();
|
||||
|
||||
export type HLSCallback = (data: ProgressData) => unknown;
|
||||
|
||||
|
|
@ -343,6 +345,7 @@ class hlsDownload {
|
|||
segOffset,
|
||||
false
|
||||
);
|
||||
if (!part) throw Error();
|
||||
// if (this.data.checkPartLength) {
|
||||
// this.data.checkPartLength = false;
|
||||
// console.warn(`Part ${segIndex + segOffset + 1}: can't check parts size!`);
|
||||
|
|
@ -419,18 +422,20 @@ const extFn = {
|
|||
const buffer = await fs.readFile(url.fileURLToPath(uri));
|
||||
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
||||
}
|
||||
// do request
|
||||
return await ofetch(uri, {
|
||||
|
||||
const partReq = await req.getData(uri, {
|
||||
method: 'GET',
|
||||
headers: headers,
|
||||
responseType: 'arrayBuffer',
|
||||
retry: 0,
|
||||
async onRequestError({ error }) {
|
||||
const partType = isKey ? 'Key' : 'Part';
|
||||
const partIndx = partIndex + 1 + segOffset;
|
||||
console.warn(`%s %s: ${error.message}`, partType, partIndx);
|
||||
}
|
||||
headers: headers
|
||||
});
|
||||
|
||||
if (!partReq.res || !partReq.ok) {
|
||||
const partType = isKey ? 'Key' : 'Part';
|
||||
const partIndx = partIndex + 1 + segOffset;
|
||||
console.warn(`%s %s: ${partReq.error?.res?.statusText}`, partType, partIndx);
|
||||
return;
|
||||
}
|
||||
|
||||
return await partReq.res.arrayBuffer();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { console } from './log';
|
|||
import { CrunchyVideoPlayStreams, CrunchyAudioPlayStreams } from '../@types/enums';
|
||||
import pj from '../package.json';
|
||||
|
||||
let argvC: {
|
||||
export let argvC: {
|
||||
[x: string]: unknown;
|
||||
ccTag: string;
|
||||
defaultAudio: LanguageItem;
|
||||
|
|
@ -96,6 +96,9 @@ let argvC: {
|
|||
scaledBorderAndShadowFix: boolean;
|
||||
scaledBorderAndShadow: 'yes' | 'no';
|
||||
originalScriptFix: boolean;
|
||||
// Proxy
|
||||
proxy: string;
|
||||
proxyAll: boolean;
|
||||
};
|
||||
|
||||
export type ArgvType = typeof argvC;
|
||||
|
|
|
|||
|
|
@ -1002,6 +1002,30 @@ const args: TAppArg<boolean | number | string | unknown[]>[] = [
|
|||
default: {
|
||||
default: 'cc'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'proxy',
|
||||
describe: 'Uses Proxy on geo-restricted or geo-defining endpoints (e.g. socks5://127.0.0.1:1080 or http://127.0.0.1:1080)',
|
||||
docDescribe: true,
|
||||
group: 'util',
|
||||
service: ['all'],
|
||||
type: 'string',
|
||||
usage: '${proxy_url}',
|
||||
default: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'proxyAll',
|
||||
describe: 'Proxies everything, not recommended. Proxy needs to be defined.',
|
||||
docDescribe: true,
|
||||
group: 'util',
|
||||
service: ['all'],
|
||||
type: 'boolean',
|
||||
usage: '',
|
||||
default: {
|
||||
default: false
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import * as yamlCfg from './module.cfg-loader';
|
||||
import * as yargs from './module.app-args';
|
||||
import { console } from './log';
|
||||
import { connect } from 'puppeteer-real-browser';
|
||||
import { argvC } from './module.app-args';
|
||||
import { ProxyAgent, fetch, RequestInit } from 'undici';
|
||||
|
||||
export type FetchParams = Partial<RequestInit & CustomParams>;
|
||||
|
||||
export type Params = {
|
||||
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
||||
|
|
@ -10,6 +15,10 @@ export type Params = {
|
|||
followRedirect?: 'follow' | 'error' | 'manual';
|
||||
};
|
||||
|
||||
type CustomParams = {
|
||||
useProxy: boolean;
|
||||
};
|
||||
|
||||
type GetDataResponse = {
|
||||
ok: boolean;
|
||||
res?: Response;
|
||||
|
|
@ -31,39 +40,19 @@ function hasDisplay(): boolean {
|
|||
|
||||
// req
|
||||
export class Req {
|
||||
private sessCfg: string;
|
||||
private service: 'cr' | 'hd' | 'adn';
|
||||
private session: Record<
|
||||
string,
|
||||
{
|
||||
value: string;
|
||||
expires: Date;
|
||||
path: string;
|
||||
domain: string;
|
||||
secure: boolean;
|
||||
'Max-Age'?: string;
|
||||
}
|
||||
> = {};
|
||||
private cfgDir = yamlCfg.cfgDir;
|
||||
private curl: boolean | string = false;
|
||||
private debug: boolean;
|
||||
public argv: typeof argvC;
|
||||
|
||||
constructor(
|
||||
private domain: Record<string, unknown>,
|
||||
private debug: boolean,
|
||||
private nosess = false,
|
||||
private type: 'cr' | 'hd' | 'adn'
|
||||
) {
|
||||
this.sessCfg = yamlCfg.sessCfgFile[type];
|
||||
this.service = type;
|
||||
constructor() {
|
||||
const cfg = yamlCfg.loadCfg();
|
||||
this.argv = yargs.appArgv(cfg.cli, process.env.isGUI ? true : false);
|
||||
this.debug = this.argv.debug ?? false;
|
||||
}
|
||||
|
||||
async getData(durl: string, params?: RequestInit): Promise<GetDataResponse> {
|
||||
params = params || {};
|
||||
// options
|
||||
async getData(durl: string, params: Partial<RequestInit & CustomParams> = {}): Promise<GetDataResponse> {
|
||||
const options: RequestInit = {
|
||||
method: params.method ? params.method : 'GET'
|
||||
};
|
||||
// additional params
|
||||
if (params.headers) {
|
||||
options.headers = params.headers;
|
||||
}
|
||||
|
|
@ -73,14 +62,24 @@ export class Req {
|
|||
if (typeof params.redirect == 'string') {
|
||||
options.redirect = params.redirect;
|
||||
}
|
||||
// debug
|
||||
|
||||
// Proxy Handler
|
||||
let dispatcher: ProxyAgent | undefined;
|
||||
const validProxy = this.argv.proxy ? this.isValidProxyUrl(this.argv.proxy) : false;
|
||||
if ((params.useProxy || this.argv.proxyAll) && this.argv.proxy && validProxy) {
|
||||
dispatcher = new ProxyAgent(this.argv.proxy);
|
||||
} else if ((params.useProxy || this.argv.proxyAll) && this.argv.proxy && !validProxy) {
|
||||
console.warn('[Fetch] Provided invalid Proxy URL, not proxying traffic.');
|
||||
}
|
||||
|
||||
// Debug
|
||||
if (this.debug) {
|
||||
console.debug('[DEBUG] FETCH OPTIONS:');
|
||||
console.debug(options);
|
||||
}
|
||||
// try do request
|
||||
|
||||
try {
|
||||
const res = await fetch(durl, options);
|
||||
const res = await fetch(durl, { ...options, dispatcher: dispatcher });
|
||||
if (!res.ok) {
|
||||
console.error(`${res.status}: ${res.statusText}`);
|
||||
const body = await res.text();
|
||||
|
|
@ -122,7 +121,7 @@ export class Req {
|
|||
}
|
||||
return {
|
||||
ok: res.ok,
|
||||
res,
|
||||
res: res as any,
|
||||
headers: params.headers as Record<string, string>
|
||||
};
|
||||
} catch (_error) {
|
||||
|
|
@ -149,33 +148,28 @@ export class Req {
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function buildProxy(proxyBaseUrl: string, proxyAuth: string) {
|
||||
if (!proxyBaseUrl.match(/^(https?|socks4|socks5):/)) {
|
||||
proxyBaseUrl = 'http://' + proxyBaseUrl;
|
||||
}
|
||||
|
||||
const proxyCfg = new URL(proxyBaseUrl);
|
||||
let proxyStr = `${proxyCfg.protocol}//`;
|
||||
|
||||
if (typeof proxyCfg.hostname != 'string' || proxyCfg.hostname == '') {
|
||||
throw new Error('[ERROR] Hostname and port required for proxy!');
|
||||
}
|
||||
|
||||
if (proxyAuth && typeof proxyAuth == 'string' && proxyAuth.match(':')) {
|
||||
proxyCfg.username = proxyAuth.split(':')[0];
|
||||
proxyCfg.password = proxyAuth.split(':')[1];
|
||||
proxyStr += `${proxyCfg.username}:${proxyCfg.password}@`;
|
||||
}
|
||||
|
||||
proxyStr += proxyCfg.hostname;
|
||||
|
||||
if (!proxyCfg.port && proxyCfg.protocol == 'http:') {
|
||||
proxyStr += ':80';
|
||||
} else if (!proxyCfg.port && proxyCfg.protocol == 'https:') {
|
||||
proxyStr += ':443';
|
||||
}
|
||||
|
||||
return proxyStr;
|
||||
|
||||
private isValidProxyUrl(proxyUrl: string): boolean {
|
||||
try {
|
||||
if (!proxyUrl.match(/^(https?|socks4|socks5):\/\//)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const url = new URL(proxyUrl);
|
||||
|
||||
if (!url.hostname) return false;
|
||||
|
||||
if (!['http:', 'https:', 'socks4:', 'socks5:'].includes(url.protocol)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.port && (!/^\d+$/.test(url.port) || Number(url.port) < 1 || Number(url.port) > 65535)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { parse as mpdParse } from 'mpd-parser';
|
||||
import { LanguageItem, findLang, languages } from './module.langsData';
|
||||
import { console } from './log';
|
||||
import * as reqModule from './module.fetch';
|
||||
import { FetchParams } from './module.fetch';
|
||||
|
||||
const req = new reqModule.Req();
|
||||
|
||||
type Segment = {
|
||||
uri: string;
|
||||
|
|
@ -77,13 +81,15 @@ export async function parse(manifest: string, language?: LanguageItem, url?: str
|
|||
if (!Object.prototype.hasOwnProperty.call(ret, host)) ret[host] = { audio: [], video: [] };
|
||||
|
||||
if (playlist.sidx && playlist.segments.length == 0) {
|
||||
const options: RequestInit = {
|
||||
const options: FetchParams = {
|
||||
method: 'head'
|
||||
};
|
||||
const item = await fetch(playlist.sidx.uri, options);
|
||||
if (!item.ok)
|
||||
console.warn(`${item.status}: ${item.statusText}, Unable to fetch byteLength for audio stream ${Math.round(playlist.attributes.BANDWIDTH / 1024)}KiB/s`);
|
||||
const byteLength = parseInt(item.headers.get('content-length') as string);
|
||||
const itemReq = await req.getData(playlist.sidx.uri, options);
|
||||
if (!itemReq.res || !itemReq.ok)
|
||||
console.warn(
|
||||
`${itemReq.error?.res?.status}: ${itemReq.error?.res?.statusText}, Unable to fetch byteLength for audio stream ${Math.round(playlist.attributes.BANDWIDTH / 1024)}KiB/s`
|
||||
);
|
||||
const byteLength = parseInt(itemReq.res?.headers?.get('content-length') as string);
|
||||
let currentByte = playlist.sidx.map.byterange.length;
|
||||
while (currentByte <= byteLength) {
|
||||
playlist.segments.push({
|
||||
|
|
@ -156,15 +162,15 @@ export async function parse(manifest: string, language?: LanguageItem, url?: str
|
|||
if (!Object.prototype.hasOwnProperty.call(ret, host)) ret[host] = { audio: [], video: [] };
|
||||
|
||||
if (playlist.sidx && playlist.segments.length == 0) {
|
||||
const options: RequestInit = {
|
||||
const options: FetchParams = {
|
||||
method: 'head'
|
||||
};
|
||||
const item = await fetch(playlist.sidx.uri, options);
|
||||
if (!item.ok)
|
||||
const itemReq = await req.getData(playlist.sidx.uri, options);
|
||||
if (!itemReq.res || !itemReq.ok)
|
||||
console.warn(
|
||||
`${item.status}: ${item.statusText}, Unable to fetch byteLength for video stream ${playlist.attributes.RESOLUTION?.height}x${playlist.attributes.RESOLUTION?.width}@${Math.round(playlist.attributes.BANDWIDTH / 1024)}KiB/s`
|
||||
`${itemReq.error?.res?.status}: ${itemReq.error?.res?.statusText}, Unable to fetch byteLength for video stream ${playlist.attributes.RESOLUTION?.height}x${playlist.attributes.RESOLUTION?.width}@${Math.round(playlist.attributes.BANDWIDTH / 1024)}KiB/s`
|
||||
);
|
||||
const byteLength = parseInt(item.headers.get('content-length') as string);
|
||||
const byteLength = parseInt(itemReq.res?.headers?.get('content-length') as string);
|
||||
let currentByte = playlist.sidx.map.byterange.length;
|
||||
while (currentByte <= byteLength) {
|
||||
playlist.segments.push({
|
||||
|
|
|
|||
|
|
@ -9,8 +9,11 @@ import fsextra from 'fs-extra';
|
|||
import { workingDir } from './module.cfg-loader';
|
||||
import { console } from './log';
|
||||
import Helper from './module.helper';
|
||||
import * as reqModule from './module.fetch';
|
||||
const updateFilePlace = path.join(workingDir, 'config', 'updates.json');
|
||||
|
||||
const req = new reqModule.Req();
|
||||
|
||||
const updateIgnore = [
|
||||
'*.d.ts',
|
||||
'.git',
|
||||
|
|
@ -58,8 +61,13 @@ export default async (force = false) => {
|
|||
}
|
||||
}
|
||||
console.info('Checking for updates...');
|
||||
const tagRequest = await fetch('https://api.github.com/repos/anidl/multi-downloader-nx/tags');
|
||||
const tags = JSON.parse(await tagRequest.text()) as GithubTag[];
|
||||
const tagRequest = await req.getData('https://api.github.com/repos/anidl/multi-downloader-nx/tags');
|
||||
if (!tagRequest.res || !tagRequest.ok) {
|
||||
console.info('No new tags found');
|
||||
return done();
|
||||
}
|
||||
|
||||
const tags = JSON.parse((await tagRequest.res.text()) as string) as GithubTag[];
|
||||
|
||||
if (tags.length > 0) {
|
||||
const newer = tags.filter((a) => {
|
||||
|
|
@ -72,9 +80,13 @@ export default async (force = false) => {
|
|||
return done();
|
||||
}
|
||||
const newest = newer.sort((a, b) => (a.name < b.name ? 1 : a.name > b.name ? -1 : 0))[0];
|
||||
const compareRequest = await fetch(`https://api.github.com/repos/anidl/multi-downloader-nx/compare/${packageJson.version}...${newest.name}`);
|
||||
const compareRequest = await req.getData(`https://api.github.com/repos/anidl/multi-downloader-nx/compare/${packageJson.version}...${newest.name}`);
|
||||
if (!compareRequest.res || !compareRequest.ok) {
|
||||
console.info('No new tags found');
|
||||
return done();
|
||||
}
|
||||
|
||||
const compareJSON = JSON.parse(await compareRequest.text()) as TagCompare;
|
||||
const compareJSON = JSON.parse(await compareRequest.res.text()) as TagCompare;
|
||||
|
||||
console.info(`You are behind by ${compareJSON.ahead_by} releases!`);
|
||||
const changedFiles = compareJSON.files
|
||||
|
|
@ -109,7 +121,7 @@ export default async (force = false) => {
|
|||
const isTSX = a.filename.endsWith('tsx');
|
||||
const ret = {
|
||||
path: a.filename.slice(0, isTSX ? -3 : -2) + `js${isTSX ? 'x' : ''}`,
|
||||
content: transpileModule(await (await fetch(a.raw_url)).text(), {
|
||||
content: transpileModule((await (await req.getData(a.raw_url)).res?.text()) ?? '', {
|
||||
compilerOptions: tsConfig.compilerOptions as unknown as CompilerOptions
|
||||
}).outputText,
|
||||
type: a.status === 'modified' ? ApplyType.UPDATE : a.status === 'added' ? ApplyType.ADD : ApplyType.DELETE
|
||||
|
|
@ -119,7 +131,7 @@ export default async (force = false) => {
|
|||
} else {
|
||||
const ret = {
|
||||
path: a.filename,
|
||||
content: await (await fetch(a.raw_url)).text(),
|
||||
content: (await (await req.getData(a.raw_url)).res?.text()) ?? '',
|
||||
type: a.status === 'modified' ? ApplyType.UPDATE : a.status === 'added' ? ApplyType.ADD : ApplyType.DELETE
|
||||
};
|
||||
console.info('✓ Got %s', ret.path);
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@
|
|||
"m3u8-parsed": "^2.0.0",
|
||||
"mpd-parser": "^1.3.1",
|
||||
"node-forge": "^1.3.1",
|
||||
"ofetch": "^1.4.1",
|
||||
"open": "^8.4.2",
|
||||
"protobufjs": "^7.5.4",
|
||||
"puppeteer-real-browser": "^1.4.4",
|
||||
"undici": "^7.16.0",
|
||||
"ws": "^8.18.3",
|
||||
"yaml": "^2.8.1",
|
||||
"yargs": "17.7.2"
|
||||
|
|
|
|||
|
|
@ -65,9 +65,6 @@ importers:
|
|||
node-forge:
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1
|
||||
ofetch:
|
||||
specifier: ^1.4.1
|
||||
version: 1.4.1
|
||||
open:
|
||||
specifier: ^8.4.2
|
||||
version: 8.4.2
|
||||
|
|
@ -77,6 +74,9 @@ importers:
|
|||
puppeteer-real-browser:
|
||||
specifier: ^1.4.4
|
||||
version: 1.4.4
|
||||
undici:
|
||||
specifier: ^7.16.0
|
||||
version: 7.16.0
|
||||
ws:
|
||||
specifier: ^8.18.3
|
||||
version: 8.18.3
|
||||
|
|
@ -774,11 +774,16 @@ packages:
|
|||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
bare-events@2.7.0:
|
||||
resolution: {integrity: sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==}
|
||||
bare-events@2.8.0:
|
||||
resolution: {integrity: sha512-AOhh6Bg5QmFIXdViHbMc2tLDsBIRxdkIaIddPslJF9Z5De3APBScuqGP2uThXnIpqFrgoxMNC6km7uXNIMLHXA==}
|
||||
peerDependencies:
|
||||
bare-abort-controller: '*'
|
||||
peerDependenciesMeta:
|
||||
bare-abort-controller:
|
||||
optional: true
|
||||
|
||||
bare-fs@4.4.7:
|
||||
resolution: {integrity: sha512-huJQxUWc2d1T+6dxnC/FoYpBgEHzJp33mYZqFtQqTTPPyP9xPvmjC16VpR4wTte4ZKd5VxkFAcfDYi51iwWMcg==}
|
||||
bare-fs@4.4.9:
|
||||
resolution: {integrity: sha512-sh8UV8OvXBZa3Yg5rhF1LNH3U4DfHniexdqyUXelC1thQUxO9TCF37yvd1/7Ir+cgeSg/6YrXyH67xvRr7yaOg==}
|
||||
engines: {bare: '>=1.16.0'}
|
||||
peerDependencies:
|
||||
bare-buffer: '*'
|
||||
|
|
@ -991,9 +996,6 @@ packages:
|
|||
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
destr@2.0.5:
|
||||
resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
@ -1570,9 +1572,6 @@ packages:
|
|||
resolution: {integrity: sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
node-fetch-native@1.6.7:
|
||||
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
|
||||
|
||||
node-fetch@2.7.0:
|
||||
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
|
|
@ -1597,9 +1596,6 @@ packages:
|
|||
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
ofetch@1.4.1:
|
||||
resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
|
||||
|
||||
on-finished@2.4.1:
|
||||
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
|
@ -2020,15 +2016,16 @@ packages:
|
|||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
ufo@1.6.1:
|
||||
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
|
||||
|
||||
unbzip2-stream@1.4.3:
|
||||
resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==}
|
||||
|
||||
undici-types@7.14.0:
|
||||
resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==}
|
||||
|
||||
undici@7.16.0:
|
||||
resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==}
|
||||
engines: {node: '>=20.18.1'}
|
||||
|
||||
universalify@0.1.2:
|
||||
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
|
|
@ -2425,6 +2422,7 @@ snapshots:
|
|||
unbzip2-stream: 1.4.3
|
||||
yargs: 17.7.2
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- react-native-b4a
|
||||
- supports-color
|
||||
|
|
@ -2665,6 +2663,7 @@ snapshots:
|
|||
tar-fs: 3.1.1
|
||||
yargs: 16.2.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- encoding
|
||||
- react-native-b4a
|
||||
|
|
@ -2688,6 +2687,7 @@ snapshots:
|
|||
tinyglobby: 0.2.15
|
||||
unzipper: 0.12.3
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- encoding
|
||||
- react-native-b4a
|
||||
|
|
@ -2746,16 +2746,17 @@ snapshots:
|
|||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
bare-events@2.7.0: {}
|
||||
bare-events@2.8.0: {}
|
||||
|
||||
bare-fs@4.4.7:
|
||||
bare-fs@4.4.9:
|
||||
dependencies:
|
||||
bare-events: 2.7.0
|
||||
bare-events: 2.8.0
|
||||
bare-path: 3.0.0
|
||||
bare-stream: 2.7.0(bare-events@2.7.0)
|
||||
bare-stream: 2.7.0(bare-events@2.8.0)
|
||||
bare-url: 2.2.2
|
||||
fast-fifo: 1.3.2
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
optional: true
|
||||
|
||||
|
|
@ -2767,12 +2768,13 @@ snapshots:
|
|||
bare-os: 3.6.2
|
||||
optional: true
|
||||
|
||||
bare-stream@2.7.0(bare-events@2.7.0):
|
||||
bare-stream@2.7.0(bare-events@2.8.0):
|
||||
dependencies:
|
||||
streamx: 2.23.0
|
||||
optionalDependencies:
|
||||
bare-events: 2.7.0
|
||||
bare-events: 2.8.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
optional: true
|
||||
|
||||
|
|
@ -2957,8 +2959,6 @@ snapshots:
|
|||
|
||||
depd@2.0.0: {}
|
||||
|
||||
destr@2.0.5: {}
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
devtools-protocol@0.0.1367902: {}
|
||||
|
|
@ -3125,7 +3125,9 @@ snapshots:
|
|||
|
||||
events-universal@1.0.1:
|
||||
dependencies:
|
||||
bare-events: 2.7.0
|
||||
bare-events: 2.8.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
|
||||
expand-template@2.0.3: {}
|
||||
|
||||
|
|
@ -3596,8 +3598,6 @@ snapshots:
|
|||
dependencies:
|
||||
semver: 7.7.3
|
||||
|
||||
node-fetch-native@1.6.7: {}
|
||||
|
||||
node-fetch@2.7.0:
|
||||
dependencies:
|
||||
whatwg-url: 5.0.0
|
||||
|
|
@ -3610,12 +3610,6 @@ snapshots:
|
|||
|
||||
object-inspect@1.13.4: {}
|
||||
|
||||
ofetch@1.4.1:
|
||||
dependencies:
|
||||
destr: 2.0.5
|
||||
node-fetch-native: 1.6.7
|
||||
ufo: 1.6.1
|
||||
|
||||
on-finished@2.4.1:
|
||||
dependencies:
|
||||
ee-first: 1.1.1
|
||||
|
|
@ -3774,6 +3768,7 @@ snapshots:
|
|||
xvfb: 0.4.0
|
||||
transitivePeerDependencies:
|
||||
- '@types/puppeteer'
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- bufferutil
|
||||
- puppeteer
|
||||
|
|
@ -3829,6 +3824,7 @@ snapshots:
|
|||
typed-query-selector: 2.12.0
|
||||
ws: 8.18.3
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- bufferutil
|
||||
- react-native-b4a
|
||||
|
|
@ -3987,6 +3983,7 @@ snapshots:
|
|||
fast-fifo: 1.3.2
|
||||
text-decoder: 1.2.3
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
string-width@4.2.3:
|
||||
|
|
@ -4031,9 +4028,10 @@ snapshots:
|
|||
pump: 3.0.3
|
||||
tar-stream: 3.1.7
|
||||
optionalDependencies:
|
||||
bare-fs: 4.4.7
|
||||
bare-fs: 4.4.9
|
||||
bare-path: 3.0.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- react-native-b4a
|
||||
|
||||
|
|
@ -4051,6 +4049,7 @@ snapshots:
|
|||
fast-fifo: 1.3.2
|
||||
streamx: 2.23.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
tar@7.5.1:
|
||||
|
|
@ -4139,8 +4138,6 @@ snapshots:
|
|||
|
||||
typescript@5.9.3: {}
|
||||
|
||||
ufo@1.6.1: {}
|
||||
|
||||
unbzip2-stream@1.4.3:
|
||||
dependencies:
|
||||
buffer: 5.7.1
|
||||
|
|
@ -4148,6 +4145,8 @@ snapshots:
|
|||
|
||||
undici-types@7.14.0: {}
|
||||
|
||||
undici@7.16.0: {}
|
||||
|
||||
universalify@0.1.2: {}
|
||||
|
||||
universalify@2.0.1: {}
|
||||
|
|
|
|||
Loading…
Reference in a new issue