Test + Style

This commit is contained in:
Izuco 2021-10-28 19:32:34 +02:00
parent 255574df1b
commit 2c07f51f54
No known key found for this signature in database
GPG key ID: 41DFCB1835A5695E
14 changed files with 1560 additions and 1494 deletions

2
.eslintignore Normal file
View file

@ -0,0 +1,2 @@
lib
/videos/*.ts

View file

@ -1,23 +0,0 @@
name: eslint
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm i
- run: npx eslint .

33
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,33 @@
name: eslint
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 14
uses: actions/setup-node@v2
with:
node-version: 14
cache: 'npm'
- run: npm i
- run: npx eslint .
test:
needs: eslint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 14
uses: actions/setup-node@v2
with:
node-version: 14
cache: 'npm'
- run: npm i
- run: npm run test

39
@types/episode.d.ts vendored
View file

@ -59,20 +59,20 @@ export interface Value {
} }
export enum Label { export enum Label {
Rating = "Rating", Rating = 'Rating',
RatingSystem = "Rating System", RatingSystem = 'Rating System',
ReleaseDate = "Release Date", ReleaseDate = 'Release Date',
Synopsis = "Synopsis", Synopsis = 'Synopsis',
SynopsisType = "Synopsis Type", SynopsisType = 'Synopsis Type',
} }
export enum MetaType { export enum MetaType {
Rating = "rating", Rating = 'rating',
RatingSystemType = "RatingSystemType", RatingSystemType = 'RatingSystemType',
ReleaseDate = "release-date", ReleaseDate = 'release-date',
Synopsis = "synopsis", Synopsis = 'synopsis',
Synopsistype = "synopsistype", Synopsistype = 'synopsistype',
VideoRatingType = "VideoRatingType", VideoRatingType = 'VideoRatingType',
} }
export interface HistoricalSelections { export interface HistoricalSelections {
@ -87,8 +87,8 @@ export interface EpisodeDataIDS {
} }
export enum TitleElement { export enum TitleElement {
Empty = "", Empty = '',
English = "English", English = 'English',
} }
export interface Media { export interface Media {
@ -194,8 +194,7 @@ export interface AvailIDS {
externalAlphaId: string; externalAlphaId: string;
} }
export interface Next { export type Next = Record<string, unknown>
}
export interface LanguageClass { export interface LanguageClass {
code: string; code: string;
@ -299,7 +298,7 @@ export interface CatalogParent {
} }
export enum Source { export enum Source {
Dbb = "dbb", Dbb = 'dbb',
} }
export interface MetaItems { export interface MetaItems {
@ -313,10 +312,10 @@ export interface Filters {
} }
export interface Items { export interface Items {
"release-date": AnimationProductionStudio; 'release-date': AnimationProductionStudio;
rating: AnimationProductionStudio; rating: AnimationProductionStudio;
synopsis: AnimationProductionStudio; synopsis: AnimationProductionStudio;
"animation-production-studio": AnimationProductionStudio; 'animation-production-studio': AnimationProductionStudio;
} }
export interface AnimationProductionStudio { export interface AnimationProductionStudio {
@ -366,8 +365,8 @@ export interface PreviousSeasonEpisode {
} }
export enum Type { export enum Type {
Episode = "episode", Episode = 'episode',
Ova = "ova", Ova = 'ova',
} }
export interface Quality { export interface Quality {

View file

@ -2,7 +2,7 @@ declare module 'hls-download' {
export default class hlsDownload { export default class hlsDownload {
constructor(options: { constructor(options: {
m3u8json: { m3u8json: {
segments: {}[], segments: Record<string, unknown>[],
mediaSequence?: number, mediaSequence?: number,
}, },
output?: string, output?: string,

23
@types/items.d.ts vendored
View file

@ -39,8 +39,8 @@ export interface Item {
} }
export enum ContentType { export enum ContentType {
Episode = "episode", Episode = 'episode',
Ova = "ova", Ova = 'ova',
} }
export interface IDs { export interface IDs {
@ -110,19 +110,18 @@ export interface MostRecentAvodIDS {
} }
export enum Purchase { export enum Purchase {
AVOD = "A-VOD", AVOD = 'A-VOD',
Dfov = "DFOV", Dfov = 'DFOV',
Est = "EST", Est = 'EST',
Svod = "SVOD", Svod = 'SVOD',
} }
export enum Version { export enum Version {
Simulcast = "Simulcast", Simulcast = 'Simulcast',
Uncut = "Uncut", Uncut = 'Uncut',
} }
export interface MostRecentSvodJpnUs { export type MostRecentSvodJpnUs = Record<string, any>
}
export interface QualityClass { export interface QualityClass {
quality: QualityQuality; quality: QualityQuality;
@ -130,8 +129,8 @@ export interface QualityClass {
} }
export enum QualityQuality { export enum QualityQuality {
HD = "HD", HD = 'HD',
SD = "SD", SD = 'SD',
} }
export interface TitleImages { export interface TitleImages {

View file

@ -32,17 +32,17 @@ declare module 'm3u8-parsed' {
uri: string, uri: string,
timeline: number, timeline: number,
attributes: { attributes: {
"CLOSED-CAPTIONS": string, 'CLOSED-CAPTIONS': string,
"AUDIO": string, 'AUDIO': string,
"FRAME-RATE": number, 'FRAME-RATE': number,
"RESOLUTION": { 'RESOLUTION': {
width: number, width: number,
height: number height: number
}, },
"CODECS": string, 'CODECS': string,
"AVERAGE-BANDWIDTH": string, 'AVERAGE-BANDWIDTH': string,
"BANDWIDTH": number 'BANDWIDTH': number
} }
}[], }[],
} };
} }

1334
funi.ts

File diff suppressed because it is too large Load diff

View file

@ -5,69 +5,70 @@ import fs from 'fs-extra';
import pkg from '../package.json'; import pkg from '../package.json';
import modulesCleanup from 'removeNPMAbsolutePaths'; import modulesCleanup from 'removeNPMAbsolutePaths';
import { exec } from 'pkg'; import { exec } from 'pkg';
import { execSync } from 'child_process';
const buildsDir = './_builds'; const buildsDir = './_builds';
const nodeVer = 'node14-'; const nodeVer = 'node14-';
// main // main
(async function(){ (async function(){
const buildStr = `${pkg.name}-${pkg.version}`; const buildStr = `${pkg.name}-${pkg.version}`;
const acceptableBuilds = ['win64','linux64','macos64']; const acceptableBuilds = ['win64','linux64','macos64'];
const buildType = process.argv[2]; const buildType = process.argv[2];
if(!acceptableBuilds.includes(buildType)){ if(!acceptableBuilds.includes(buildType)){
console.error('[ERROR] unknown build type!'); console.error('[ERROR] unknown build type!');
process.exit(1); process.exit(1);
} }
await modulesCleanup('.'); await modulesCleanup('.');
if(!fs.existsSync(buildsDir)){ if(!fs.existsSync(buildsDir)){
fs.mkdirSync(buildsDir); fs.mkdirSync(buildsDir);
} }
const buildFull = `${buildStr}-${buildType}`; const buildFull = `${buildStr}-${buildType}`;
const buildDir = `${buildsDir}/${buildFull}`; const buildDir = `${buildsDir}/${buildFull}`;
if(fs.existsSync(buildDir)){ if(fs.existsSync(buildDir)){
fs.removeSync(buildDir); fs.removeSync(buildDir);
} }
fs.mkdirSync(buildDir); fs.mkdirSync(buildDir);
const buildConfig = [ const buildConfig = [
pkg.main, pkg.main,
'--target', nodeVer + getTarget(buildType), '--target', nodeVer + getTarget(buildType),
'--output', `${buildDir}/${pkg.short_name}`, '--output', `${buildDir}/${pkg.short_name}`,
]; ];
console.log(`[Build] Build configuration: ${buildFull}`); console.log(`[Build] Build configuration: ${buildFull}`);
try { try {
await exec(buildConfig); await exec(buildConfig);
} }
catch(e){ catch(e){
console.log(e); console.log(e);
process.exit(1); process.exit(1);
} }
fs.mkdirSync(`${buildDir}/bin`); fs.mkdirSync(`${buildDir}/bin`);
fs.mkdirSync(`${buildDir}/config`); fs.mkdirSync(`${buildDir}/config`);
fs.mkdirSync(`${buildDir}/videos`); fs.mkdirSync(`${buildDir}/videos`);
fs.copySync('./bin/', `${buildDir}/bin/`); fs.copySync('./bin/', `${buildDir}/bin/`);
fs.copySync('./config/bin-path.yml', `${buildDir}/config/bin-path.yml`); fs.copySync('./config/bin-path.yml', `${buildDir}/config/bin-path.yml`);
fs.copySync('./config/cli-defaults.yml', `${buildDir}/config/cli-defaults.yml`); fs.copySync('./config/cli-defaults.yml', `${buildDir}/config/cli-defaults.yml`);
fs.copySync('./config/dir-path.yml', `${buildDir}/config/dir-path.yml`); fs.copySync('./config/dir-path.yml', `${buildDir}/config/dir-path.yml`);
fs.copySync('./modules/cmd-here.bat', `${buildDir}/cmd-here.bat`); fs.copySync('./modules/cmd-here.bat', `${buildDir}/cmd-here.bat`);
fs.copySync('./modules/NotoSans-Regular.ttf', `${buildDir}/NotoSans-Regular.ttf`); fs.copySync('./modules/NotoSans-Regular.ttf', `${buildDir}/NotoSans-Regular.ttf`);
fs.copySync('./package.json', `${buildDir}/package.json`) fs.copySync('./package.json', `${buildDir}/package.json`);
fs.copySync('./docs/', `${buildDir}/docs/`); fs.copySync('./docs/', `${buildDir}/docs/`);
fs.copySync('./LICENSE.md', `${buildDir}/docs/LICENSE.md`); fs.copySync('./LICENSE.md', `${buildDir}/docs/LICENSE.md`);
if(fs.existsSync(`${buildsDir}/${buildFull}.7z`)){ if(fs.existsSync(`${buildsDir}/${buildFull}.7z`)){
fs.removeSync(`${buildsDir}/${buildFull}.7z`); fs.removeSync(`${buildsDir}/${buildFull}.7z`);
} }
require('child_process').execSync(`7z a -t7z "${buildsDir}/${buildFull}.7z" "${buildDir}"`,{stdio:[0,1,2]}); execSync(`7z a -t7z "${buildsDir}/${buildFull}.7z" "${buildDir}"`,{stdio:[0,1,2]});
}()); }());
function getTarget(bt: string) : string { function getTarget(bt: string) : string {
switch(bt){ switch(bt){
case 'win64': case 'win64':
return 'windows-x64'; return 'windows-x64';
case 'linux64': case 'linux64':
return 'linux-x64'; return 'linux-x64';
case 'macos64': case 'macos64':
return 'macos-x64'; return 'macos-x64';
default: default:
return 'windows-x64'; return 'windows-x64';
} }
} }

View file

@ -1,12 +1,12 @@
import yargs from 'yargs'; import yargs from 'yargs';
const availableFilenameVars = [ const availableFilenameVars = [
'title', 'title',
'episode', 'episode',
'showTitle', 'showTitle',
'season', 'season',
'width', 'width',
'height' 'height'
]; ];
export type possibleDubs = ( export type possibleDubs = (
@ -22,241 +22,241 @@ const dubLang: possibleDubs = ['enUS', 'esLA', 'ptBR', 'zhMN', 'jaJP'];
const appArgv = (cfg: { const appArgv = (cfg: {
[key: string]: unknown [key: string]: unknown
}) => { }) => {
// init // init
const parseDefault = <T = unknown>(key: string, _default: T) : T=> { const parseDefault = <T = unknown>(key: string, _default: T) : T=> {
if (Object.prototype.hasOwnProperty.call(cfg, key)) { if (Object.prototype.hasOwnProperty.call(cfg, key)) {
return cfg[key] as T; return cfg[key] as T;
} else } else
return _default; return _default;
}; };
const argv = yargs.parserConfiguration({ const argv = yargs.parserConfiguration({
'duplicate-arguments-array': true, 'duplicate-arguments-array': true,
'camel-case-expansion': false 'camel-case-expansion': false
})
// main
.wrap(Math.min(120)) // yargs.terminalWidth()
.help(false).version(false)
.usage('Usage: $0 [options]')
// auth
.option('auth', {
group: 'Authentication:',
describe: 'Enter authentication mode',
type: 'boolean',
}) })
// main // search
.wrap(Math.min(120)) // yargs.terminalWidth() .option('search', {
.help(false).version(false) alias: 'f',
.usage('Usage: $0 [options]') group: 'Search:',
// auth describe: 'Search show ids',
.option('auth', { type: 'string',
group: 'Authentication:', })
describe: 'Enter authentication mode', // select show and eps
type: 'boolean', .option('s', {
}) group: 'Downloading:',
// search describe: 'Sets the show id',
.option('search', { type: 'number',
alias: 'f', })
group: 'Search:', .option('e', {
describe: 'Search show ids', group: 'Downloading:',
type: 'string', describe: 'Select episode ids (comma-separated, hyphen-sequence)',
}) type: 'string',
// select show and eps })
.option('s', { .option('all', {
group: 'Downloading:', group: 'Downloading:',
describe: 'Sets the show id', describe: 'Used to download all episodes from the show',
type: 'number', type: 'boolean',
}) default: parseDefault<boolean>('all', false)
.option('e', { })
group: 'Downloading:', .option('partsize', {
describe: 'Select episode ids (comma-separated, hyphen-sequence)', group: 'Downloading:',
type: 'string', describe: 'The amount of parts that should be downloaded in paralell',
}) type: 'number',
.option('all', { default: parseDefault<number>('partsize', 10)
group: 'Downloading:', })
describe: 'Used to download all episodes from the show', // quality
type: 'boolean', .option('q', {
default: parseDefault<boolean>('all', false) group: 'Downloading:',
}) describe: 'Select video layer (0 is max)',
.option('partsize', { choices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
group: 'Downloading:', default: parseDefault<number>('videoLayer', 7),
describe: 'The amount of parts that should be downloaded in paralell', type: 'number',
type: 'number', })
default: parseDefault<number>('partsize', 10) // alt listing
}) .option('alt', {
// quality group: 'Downloading:',
.option('q', { describe: 'Alternative episode listing (if available)',
group: 'Downloading:', default: parseDefault<boolean>('altList', false),
describe: 'Select video layer (0 is max)', type: 'boolean',
choices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], })
default: parseDefault<number>('videoLayer', 7), // switch to subs
type: 'number', .option('dub', {
}) group: 'Downloading:',
// alt listing describe: 'Download non-Japanese Dub (English Dub mode by default)',
.option('alt', { choices: dubLang,
group: 'Downloading:', default: parseDefault<possibleDubs>('dub', ['enUS']),
describe: 'Alternative episode listing (if available)', type: 'array',
default: parseDefault<boolean>('altList', false), })
type: 'boolean', .option('subLang', {
}) group: 'Downloading:',
// switch to subs describe: 'Set the subtitle language (English is default and fallback)',
.option('dub', { default: parseDefault<possibleSubs>('subLang', ['enUS']),
group: 'Downloading:', choices: subLang,
describe: 'Download non-Japanese Dub (English Dub mode by default)', type: 'array'
choices: dubLang, })
default: parseDefault<possibleDubs>('dub', ['enUS']), .option('fontSize', {
type: 'array', group: 'Downloading:',
}) describe: 'Used to set the fontsize of the subtitles',
.option('subLang', { default: parseDefault<number>('fontSize', 55),
group: 'Downloading:', type: 'number'
describe: 'Set the subtitle language (English is default and fallback)', })
default: parseDefault<possibleSubs>('subLang', ['enUS']), .option('allSubs', {
choices: subLang, group: 'Downloading:',
type: 'array' describe: 'If set to true, all available subs will get downloaded',
}) default: false,
.option('fontSize', { type: 'boolean'
group: 'Downloading:', })
describe: 'Used to set the fontsize of the subtitles', .option('allDubs', {
default: parseDefault<number>('fontSize', 55), group: 'Downloading:',
type: 'number' describe: 'If set to true, all available dubs will get downloaded',
}) default: false,
.option('allSubs', { type: 'boolean'
group: 'Downloading:', })
describe: 'If set to true, all available subs will get downloaded', // simulcast
default: false, .option('simul', {
type: 'boolean' group: 'Downloading:',
}) describe: 'Force downloading simulcast ver. instead of uncut ver. (if uncut ver. available)',
.option('allDubs', { default: parseDefault<boolean>('forceSimul', false),
group: 'Downloading:', type: 'boolean',
describe: 'If set to true, all available dubs will get downloaded', })
default: false, // server number
type: 'boolean' .option('x', {
}) alias: 'server',
// simulcast group: 'Downloading:',
.option('simul', { describe: 'Select server',
group: 'Downloading:', choices: [1, 2, 3, 4],
describe: 'Force downloading simulcast ver. instead of uncut ver. (if uncut ver. available)', default: parseDefault<number>('nServer', 1),
default: parseDefault<boolean>('forceSimul', false), type: 'number',
type: 'boolean', })
}) // skip
// server number .option('noaudio', {
.option('x', { group: 'Downloading:',
alias: 'server', describe: 'Skip downloading audio',
group: 'Downloading:', type: 'boolean'
describe: 'Select server', })
choices: [1, 2, 3, 4], .option('novids', {
default: parseDefault<number>('nServer', 1), group: 'Downloading:',
type: 'number', alias: 'skipdl',
}) describe: 'Skip downloading video',
// skip type: 'boolean',
.option('noaudio', { })
group: 'Downloading:', .option('nosubs', {
describe: 'Skip downloading audio', group: 'Downloading:',
type: 'boolean' describe: 'Skip downloading subtitles for English Dub (if available)',
}) type: 'boolean',
.option('novids', { default: false
group: 'Downloading:', })
alias: 'skipdl', // proxy
describe: 'Skip downloading video', .option('proxy', {
type: 'boolean', group: 'Proxy:',
}) describe: 'Set http(s)/socks proxy WHATWG url',
.option('nosubs', { default: parseDefault<boolean>('proxy', false),
group: 'Downloading:', hidden: true,
describe: 'Skip downloading subtitles for English Dub (if available)', })
type: 'boolean', .option('proxy-auth', {
default: false group: 'Proxy:',
}) describe: 'Colon-separated username and password for proxy',
// proxy default: parseDefault<string|boolean>('proxy_auth', false),
.option('proxy', { hidden: true,
group: 'Proxy:', })
describe: 'Set http(s)/socks proxy WHATWG url', .option('ssp', {
default: parseDefault<boolean>('proxy', false), group: 'Proxy:',
hidden: true, describe: 'Don\'t use proxy for stream and subtitles downloading',
}) default: parseDefault<boolean>('proxy_ssp', false),
.option('proxy-auth', { hidden: true,
group: 'Proxy:', type: 'boolean',
describe: 'Colon-separated username and password for proxy', })
default: parseDefault<string|boolean>('proxy_auth', false), // muxing
hidden: true, .option('skipmux', {
}) group: 'Muxing:',
.option('ssp', { describe: 'Skip muxing video and subtitles',
group: 'Proxy:', type: 'boolean',
describe: 'Don\'t use proxy for stream and subtitles downloading', })
default: parseDefault<boolean>('proxy_ssp', false), .option('mp4', {
hidden: true, group: 'Muxing:',
type: 'boolean', describe: 'Mux into mp4',
}) default: parseDefault<boolean>('mp4mux', false),
// muxing type: 'boolean'
.option('skipmux', { })
group: 'Muxing:', // filenaming
describe: 'Skip muxing video and subtitles', .option('fileName', {
type: 'boolean', group: 'Filename Template:',
}) describe: `Set the filename template. Use \${variable_name} to insert variables.\nYou may use ${availableFilenameVars
.option('mp4', { .map(a => `'${a}'`).join(', ')} as variables.`,
group: 'Muxing:', type: 'string',
describe: 'Mux into mp4', default: parseDefault<string>('fileName', '[Funimation] ${showTitle} - ${episode} [${height}p]')
default: parseDefault<boolean>('mp4mux', false), })
type: 'boolean' .option('numbers', {
}) group: 'Filename Template:',
// filenaming describe: `Set how long a number in the title should be at least.\n${[[3, 5, '005'], [2, 1, '01'], [1, 20, '20']]
.option('fileName', { .map(val => `Set in config: ${val[0]}; Episode number: ${val[1]}; Output: ${val[2]}`).join('\n')}`,
group: 'Filename Template:', type: 'number',
describe: `Set the filename template. Use \${variable_name} to insert variables.\nYou may use ${availableFilenameVars default: parseDefault<number>('numbers', 2)
.map(a => `'${a}'`).join(', ')} as variables.`, })
type: 'string', // util
default: parseDefault<string>('fileName', '[Funimation] ${showTitle} - ${episode} [${height}p]') .option('nocleanup', {
}) group: 'Utilities:',
.option('numbers', { describe: 'Dont\'t delete the input files after muxing',
group: 'Filename Template:', default: parseDefault<boolean>('noCleanUp', false),
describe: `Set how long a number in the title should be at least.\n${[[3, 5, '005'], [2, 1, '01'], [1, 20, '20']] type: 'boolean'
.map(val => `Set in config: ${val[0]}; Episode number: ${val[1]}; Output: ${val[2]}`).join('\n')}`, })
type: 'number', .option('timeout', {
default: parseDefault<number>('numbers', 2) group: 'Downloading:',
}) describe: 'Set the timeout of all download reqests. Set in millisecods',
// util type: 'number',
.option('nocleanup', { default: parseDefault('timeout', 60 * 1000)
group: 'Utilities:', })
describe: 'Dont\'t delete the input files after muxing', .option('debug', {
default: parseDefault<boolean>('noCleanUp', false), group: 'Utilities:',
type: 'boolean' describe: 'Used to enter debug mode. Please use this flag when opening an issue to get more information'
})
.option('timeout', {
group: 'Downloading:',
describe: 'Set the timeout of all download reqests. Set in millisecods',
type: 'number',
default: parseDefault('timeout', 60 * 1000)
})
.option('debug', {
group: 'Utilities:',
describe: 'Used to enter debug mode. Please use this flag when opening an issue to get more information'
+ '\n!Be careful! - Your token might be exposed so make sure to delete it!', + '\n!Be careful! - Your token might be exposed so make sure to delete it!',
type: 'boolean', type: 'boolean',
default: false default: false
}) })
// help // help
.option('help', { .option('help', {
alias: 'h', alias: 'h',
group: 'Help:', group: 'Help:',
describe: 'Show this help', describe: 'Show this help',
type: 'boolean' type: 'boolean'
}) })
// usage // usage
.example([ .example([
['$0 --search "My Hero"', 'search "My Hero" in title'], ['$0 --search "My Hero"', 'search "My Hero" in title'],
['$0 -s 124389 -e 1,2,3', 'download episodes 1-3 from show with id 124389'], ['$0 -s 124389 -e 1,2,3', 'download episodes 1-3 from show with id 124389'],
['$0 -s 124389 -e 1-3,2-7,s1-2', 'download episodes 1-7 and "S"-episodes 1-2 from show with id 124389'], ['$0 -s 124389 -e 1-3,2-7,s1-2', 'download episodes 1-7 and "S"-episodes 1-2 from show with id 124389'],
]) ])
// -- // --
.parseSync(); .parseSync();
// Resolve unwanted arrays // Resolve unwanted arrays
if (argv.allDubs) if (argv.allDubs)
argv.dub = dubLang; argv.dub = dubLang;
if (argv.allSubs) if (argv.allSubs)
argv.subLang = subLang; argv.subLang = subLang;
for (let key in argv) { for (const key in argv) {
if (argv[key] instanceof Array && !(key === 'subLang' || key === 'dub')) { if (argv[key] instanceof Array && !(key === 'subLang' || key === 'dub')) {
argv[key] = (argv[key] as Array<unknown>).pop(); argv[key] = (argv[key] as Array<unknown>).pop();
}
} }
return argv; }
return argv;
}; };
const showHelp = yargs.showHelp; const showHelp = yargs.showHelp;
export { export {
appArgv, appArgv,
showHelp, showHelp,
availableFilenameVars, availableFilenameVars,
dubLang, dubLang,
subLang subLang
}; };

View file

@ -185,16 +185,16 @@ class Merger {
MKVmerge: undefined|string|false, MKVmerge: undefined|string|false,
FFmpeg: undefined|string|false FFmpeg: undefined|string|false
} = { } = {
MKVmerge: bin.mkvmerge, MKVmerge: bin.mkvmerge,
FFmpeg: bin.ffmpeg, FFmpeg: bin.ffmpeg,
}; };
if( !useMP4format && !merger.MKVmerge ){ if( !useMP4format && !merger.MKVmerge ){
console.log('[WARN] MKVMerge not found, skip using this...'); console.log('[WARN] MKVMerge not found, skip using this...');
merger.MKVmerge = false; merger.MKVmerge = false;
} }
if( !merger.MKVmerge && !merger.FFmpeg || useMP4format && !merger.FFmpeg ){ if( !merger.MKVmerge && !merger.FFmpeg || useMP4format && !merger.FFmpeg ){
console.log('[WARN] FFmpeg not found, skip using this...'); console.log('[WARN] FFmpeg not found, skip using this...');
merger.FFmpeg = false; merger.FFmpeg = false;
} }
return merger; return merger;

953
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{ {
"name": "funimation-downloader-nx", "name": "funimation-downloader-nx",
"short_name": "funi", "short_name": "funi",
"version": "4.12.5", "version": "5.0.0",
"description": "Download videos from Funimation via cli.", "description": "Download videos from Funimation via cli.",
"keywords": [ "keywords": [
"download", "download",
@ -57,6 +57,8 @@
"build-macos64": "cd lib && node modules/build macos64", "build-macos64": "cd lib && node modules/build macos64",
"eslint": "eslint *.js modules", "eslint": "eslint *.js modules",
"eslint-fix": "eslint *.js modules --fix", "eslint-fix": "eslint *.js modules --fix",
"test": "echo \"Error: no test specified\" && exit 1" "pretest": "npm run tsc",
"test": "cd lib && node modules/build win64 && node modules/build linux64 && node modules/build macos64"
} }
} }

32
tsc.ts
View file

@ -1,7 +1,7 @@
import { exec } from "child_process"; import { exec } from 'child_process';
import fs from "fs"; import fs from 'fs';
import path from "path"; import path from 'path';
import { removeSync, copyFileSync } from "fs-extra"; import { removeSync, copyFileSync } from 'fs-extra';
const ignore = [ const ignore = [
'.git', '.git',
@ -13,29 +13,29 @@ const ignore = [
(async () => { (async () => {
removeSync('lib'); removeSync('lib');
const tsc = exec('npx tsc'); const tsc = exec('npx tsc');
tsc.stdout?.on("data", console.log); tsc.stdout?.on('data', console.log);
tsc.stderr?.on("data", console.log); tsc.stderr?.on('data', console.log);
tsc.on("close", () => { tsc.on('close', () => {
const files = readDir(__dirname); const files = readDir(__dirname);
const filtered = files.filter(a => { const filtered = files.filter(a => {
if (a.stats.isFile()) { if (a.stats.isFile()) {
return a.path.split('.').pop() !== 'ts'; return a.path.split('.').pop() !== 'ts';
} else { } else {
return true return true;
} }
}) });
filtered.forEach(item => { filtered.forEach(item => {
const itemPath = path.join(__dirname, 'lib', item.path.replace(__dirname, '')); const itemPath = path.join(__dirname, 'lib', item.path.replace(__dirname, ''));
if (item.stats.isDirectory()) { if (item.stats.isDirectory()) {
if (!fs.existsSync(itemPath)) if (!fs.existsSync(itemPath))
fs.mkdirSync(itemPath) fs.mkdirSync(itemPath);
} else { } else {
copyFileSync(item.path, itemPath) copyFileSync(item.path, itemPath);
} }
}) });
}) });
})() })();
const readDir = (dir: string) : { const readDir = (dir: string) : {
path: string, path: string,
@ -56,8 +56,8 @@ const readDir = (dir: string) : {
stats stats
}); });
if (stats.isDirectory()) { if (stats.isDirectory()) {
items.push(...readDir(itemPath)) items.push(...readDir(itemPath));
} }
} }
return items; return items;
} };