@yt-kit/core 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -43,10 +43,17 @@ export interface DownloadOptions {
43
43
  formatId: string | number;
44
44
  outputDir?: string;
45
45
  filename?: string;
46
+ simulate?: boolean;
46
47
  }
47
48
  export interface DownloadResult {
49
+ type: string;
50
+ status: string;
48
51
  path: string;
49
- duration: number;
52
+ id: string;
53
+ ext: string;
54
+ title: string;
55
+ size: number;
56
+ alreadyDownloaded: boolean | string;
50
57
  }
51
58
  export declare function downloadVideo(ytId: string, options: DownloadOptions): Promise<DownloadResult | undefined>;
52
59
  export declare function downloadAudio(ytId: string, options: DownloadOptions): Promise<DownloadResult | undefined>;
@@ -67,18 +74,18 @@ declare const PATTERNS: {
67
74
  };
68
75
  export type Height = typeof STANDARD_RESOLUTIONS[number];
69
76
  export type Resolution = `${Height}p`;
70
- export type FormatsToFind = Resolution | "best-video" | "worst-video" | "best-audio" | "worst-audio";
71
- export type MediaType = "audio" | "video";
77
+ export type FormatsToFind = Resolution | "best-video" | "worst-video" | "best-audio" | "worst-audio" | "best-storyboard" | "worst-storyboard";
78
+ export type MediaType = "audio" | "video" | "sb";
72
79
  export declare function findFormatId(ytId: string, formatToFind: FormatsToFind): Promise<{
73
80
  foundSpecific: string | boolean;
74
81
  formatId: string | undefined;
75
82
  }>;
76
- export type YtDlpFormat = {
83
+ export interface YtDlpFormat {
77
84
  format_id: string;
78
85
  format_note: string;
79
- ext: EXT;
80
- protocol: Protocol;
81
- acodec: Acodec;
86
+ ext: "mhtml" | "m4a" | "webm" | "mp4";
87
+ protocol: "mhtml" | "https";
88
+ acodec: "none" | "mp4a.40.5" | "opus" | "mp4a.40.2";
82
89
  vcodec: string;
83
90
  url: string;
84
91
  width: number | null;
@@ -86,16 +93,24 @@ export type YtDlpFormat = {
86
93
  fps: number | null;
87
94
  rows?: number;
88
95
  columns?: number;
89
- fragments?: Fragment[];
90
- audio_ext: AudioEXT;
91
- video_ext: VideoEXT;
96
+ fragments?: {
97
+ url: string;
98
+ duration: number;
99
+ }[];
100
+ audio_ext: "none" | "m4a" | "webm";
101
+ video_ext: "none" | "mp4" | "webm";
92
102
  vbr: number | null;
93
103
  abr: number | null;
94
104
  tbr: number | null;
95
105
  resolution: string;
96
106
  aspect_ratio: number | null;
97
107
  filesize_approx: number | null;
98
- http_headers: HTTPHeaders;
108
+ http_headers: {
109
+ "User-Agent": string;
110
+ Accept: "text/html,application/xhtml+xml,application/xmlq=0.9,*/*q=0.8";
111
+ "Accept-Language": "en-us,enq=0.5";
112
+ "Sec-Fetch-Mode": "navigate";
113
+ };
99
114
  format: string;
100
115
  asr?: number | null;
101
116
  filesize?: number | null;
@@ -106,34 +121,13 @@ export type YtDlpFormat = {
106
121
  language?: null | string;
107
122
  language_preference?: number;
108
123
  preference?: null;
109
- dynamic_range?: DynamicRange | null;
110
- container?: Container;
124
+ dynamic_range?: "SDR" | null;
125
+ container?: "m4a_dash" | "webm_dash" | "mp4_dash";
111
126
  available_at?: number;
112
- downloader_options?: DownloaderOptions;
113
- };
114
- export type Acodec = "none" | "mp4a.40.5" | "opus" | "mp4a.40.2";
115
- export type AudioEXT = "none" | "m4a" | "webm";
116
- export type Container = "m4a_dash" | "webm_dash" | "mp4_dash";
117
- export type DownloaderOptions = {
118
- http_chunk_size: number;
119
- };
120
- export type DynamicRange = "SDR";
121
- export type EXT = "mhtml" | "m4a" | "webm" | "mp4";
122
- export type Fragment = {
123
- url: string;
124
- duration: number;
125
- };
126
- export type HTTPHeaders = {
127
- "User-Agent": string;
128
- Accept: Accept;
129
- "Accept-Language": AcceptLanguage;
130
- "Sec-Fetch-Mode": SECFetchMode;
131
- };
132
- export type Accept = "text/html,application/xhtml+xml,application/xmlq=0.9,*/*q=0.8";
133
- export type AcceptLanguage = "en-us,enq=0.5";
134
- export type SECFetchMode = "navigate";
135
- export type Protocol = "mhtml" | "https";
136
- export type VideoEXT = "none" | "mp4" | "webm";
127
+ downloader_options?: {
128
+ http_chunk_size: number;
129
+ };
130
+ }
137
131
  export declare function getAllFormats(ytId: string): Promise<YtDlpFormat[]>;
138
132
  export declare function getFromDisk(key: CacheKey): Promise<CachedData | undefined>;
139
133
  export declare function saveInDisk(key: CacheKey, value: CachedData): Promise<void>;
@@ -142,7 +136,7 @@ export interface CompareOptions {
142
136
  compareResolution: boolean;
143
137
  }
144
138
  export declare function getBetterFormat(a: YtDlpFormat | undefined, b: YtDlpFormat | undefined, { type, compareResolution }: CompareOptions): YtDlpFormat | undefined;
145
- export declare function getWorstFormat(a: YtDlpFormat | undefined, b: YtDlpFormat | undefined, { type, compareResolution }: CompareOptions): YtDlpFormat | undefined;
139
+ export declare function getWorseFormat(a: YtDlpFormat | undefined, b: YtDlpFormat | undefined, { type, compareResolution }: CompareOptions): YtDlpFormat | undefined;
146
140
  export interface ResolverProps {
147
141
  filename: string;
148
142
  id: string;
@@ -153,5 +147,20 @@ export type Pattern = typeof PATTERNS[keyof typeof PATTERNS];
153
147
  export type PatternData = string;
154
148
  export declare function expandPattern(pattern: string, patternMap: Map<Pattern, PatternData>): string;
155
149
  export declare function resolvePath(input: string): string;
150
+ export type TimeUnit = "day" | "hour" | "minute" | "second" | "nano";
151
+ /**
152
+ * Recibe una cantidad de tiempo (`amount`) en una unidad (`unit`), y devuelve ese tiempo convertido en milisegundos.
153
+ *
154
+ * Si `unit` no es válido, devuelve `amount`.
155
+ *
156
+ * ```js
157
+ * convertTime(7, 'second') // 7000ms
158
+ * convertTime(4, 'lemon') // 4ms
159
+ * ```
160
+ *
161
+ * @returns Devuelve en milisegundos la cantidad (`amount`) de unidad (`unit`) especificada
162
+ */
163
+ export declare function timeToMs(amount: number, unit: TimeUnit): number;
164
+ export declare function msToTime(ms: number, unit: TimeUnit): number;
156
165
 
157
166
  export {};
package/dist/index.js CHANGED
@@ -1 +1,3 @@
1
- var N={day:86400000,hrs:3600000,min:60000,sec:1000,nano:0.001};function y(e,t){if(!N[t])return e;return e*N[t]}var P={cacheLocation:void 0,ignoreTTL:void 0,method:"memory",ttlInMs:y(10,"day")},$={"yt-dlp":"yt-dlp"},V=new Map([["cache",P],["commands",$]]);class K{store=new Map(V);get(e){let t=this.store.get(e);if(!t)return null;return t}add(e,t){let r=this.store.get(e)??{};this.store.set(e,{...r,...t})}replace(e,t){this.store.set(e,t)}delete(e){this.store.delete(e)}}var m=new K;function D(e){if(typeof e!=="string")return!1;return!0}import{readFile as U}from"node:fs/promises";import{homedir as z}from"node:os";import{join as B,resolve as W,sep as J}from"node:path";function h(e){if(!e)return"";if(e.match(/~[^/]+/))throw Error("Ruta inválida. Ten más cuidado usando '~'");if(e.includes(" "))throw Error("La ruta no puede tener espacios");if(e==="."||e==="..")throw Error(`'${e}' No es una ruta válida. Tal vez faltó agregar '/'?`);let t=e;if(e.startsWith("~"))t=B(z(),J,e.slice(1));return W(t)}import{join as Q}from"node:path";function l(e){let t=m.get("cache")?.cacheLocation;if(!t)throw Error("Es necesario configurar cacheLocation para buscar en el almacenamiento.");let r=h(t);if(e.includes("formats:")){let o=e.split(":")[1];if(!o)throw Error(`Falta especificar ytId en ${e}`);if(o==="${ytId}")throw Error("${ytId} no es un ID válido. Eso debes evaluarlo como `${ytId}`");r=Q(h(t),"formats",o)}return r}async function C(e){let t=l(e);if(!t)return;let r;try{r=await U(t,"utf8")}catch{}if(r)try{r=JSON.parse(r)}catch(o){console.error(`Error convirtiendo la caché de ${e} a JSON:`,o)}if(!r)return;return r}import{rm as G}from"node:fs/promises";async function S(e){let t=l(e);if(!t)return;try{await G(t)}catch(r){console.error(`Error borrando la caché de ${e} en el almacenamiento:`,r)}}import{mkdir as H,writeFile as X}from"node:fs/promises";import{dirname as Z}from"node:path";async function T(e,t){let r=l(e);if(!r)return;let o=Z(r);try{H(o,{recursive:!0})}catch{console.error(`Error creando la carpeta para guardar ${e}`)}try{await X(r,JSON.stringify(t,null,2),"utf8")}catch{console.error(`Error cacheando "${e}" en el almacenamiento`)}}class v{store=new Map;ttl=m.get("cache")?.ttlInMs??y(10,"day");async get(e){if(!D(e))throw Error("CacheKey inválida",{cause:e});let t=m.get("cache")?.method??"memory",r=null;if(t==="memory")r=this.store.get(e);if(t==="disk")r=await C(e);if(t==="hybrid"){if(r=this.store.get(e),!r)r=await C(e)}if(!r)return null;let o=m.get("cache")?.ignoreTTL??"never";if(o==="always")return r;if(o==="next")return m.add("cache",{ignoreTTL:"never"}),r;if(Date.now()-r.timestamp>this.ttl)return await this.delete(e),null;return r}async set(e,t){if(!D(e))throw Error("CacheKey inválida",{cause:e});let r=m.get("cache")?.method??"memory",o={...t,timestamp:Date.now()};if(r==="memory")this.store.set(e,o);if(r==="disk")await T(e,o);if(r==="hybrid")this.store.set(e,o),await T(e,o)}async delete(e){let t=m.get("cache")?.method;if(t==="memory")this.store.delete(e);if(t==="disk")await S(e);if(t==="hybrid")this.store.delete(e),await S(e)}}var u=new v;var j=[18,144,240,360,480,720,1080,1440,2160],q="%(ytId)s.%(ext)s",R={ID:"%(id)s",YT_ID:"%(ytId)s"};import{spawn as k}from"node:child_process";import{stdout as b,stderr as I}from"node:process";function A(e,t){(e==="data"?b:I).write(t)}function w(e,t,r){let s=m.get("commands")?.[e];if(!s)throw Error(`No se encontró un comando configurado para ${e}`);return new Promise((i,f)=>{let p=k(s,t),c="",a="";p.stdout.on("data",(n)=>{c+=n;let d=n.toString();if(r)A("data",d)}),p.stderr.on("data",(n)=>{a+=n;let d=n.toString();if(r)A("err",d)}),p.on("close",(n)=>{if(n===0)i(c.toString());else f(Error(a.toString()))}),p.on("error",(n)=>{f(n)})})}function Y(e,t){let r=e;for(let[o,s]of t)r=r.replaceAll(o,s);return r}function L(e){return e.replaceAll("/","⁄")}function E({filename:e,id:t,ytId:r}){let o=new Map([[R.ID,t],[R.YT_ID,r]]),s=Y(e,o);return L(s)}class x{async download(e,t){let r=this.buildYtDlpArgs(e,t);return await w("yt-dlp",r,!0),{duration:-1,path:"unknown"}}buildYtDlpArgs(e,t){let{id:r,type:o}=t,s=o==="video",i=t.outputDir,f=E({filename:t.filename,id:t.id,ytId:e}),p="aac";return["-f",r,...s?[]:["-x","--audio-format","aac"],"-o",f,"-P",i,e]}}async function ee(e,t){if(!e||!t.formatId)return;let r=O("video",t);return new x().download(e,r)}async function te(e,t){if(!e||!t.formatId)return;let r=O("audio",t);return new x().download(e,r)}function O(e,t){return{id:`${t.formatId}`,type:e,outputDir:t.outputDir??".",filename:t.filename??q}}function _({a:e,b:t,compareResolution:r,type:o}){let s=o==="video"&&r&&e.quality!==null&&t.quality!==null,i=o==="video"&&r&&e.height!==null&&t.height!==null,f=o==="video"&&e.fps!==null&&t.fps!==null,p=o==="audio"&&e.asr!==null&&t.asr!==null,c=e.tbr!==null&&t.tbr!==null,a=0,n=0;if(s){if((e.quality??0)>(t.quality??0))a+=3;else if((e.quality??0)<(t.quality??0))n+=3}if(i){if((e.height??0)>(t.height??0))a+=3;else if((e.height??0)<(t.height??0))n+=3}if(f){if((e.fps??0)>(t.fps??0))a+=2;else if((e.fps??0)<(t.fps??0))n+=2}if(p){if((e.asr??0)>(t.asr??0))a+=2;else if((e.asr??0)<(t.asr??0))n+=2}if(c){if((e.tbr??0)>(t.tbr??0))a+=1;else if((e.tbr??0)<(t.tbr??0))n+=1}return{aScore:a,bScore:n}}function g(e,t,{type:r,compareResolution:o}){if(!e||!t)return;let{aScore:s,bScore:i}=_({a:e,b:t,type:r,compareResolution:o});return s>i?e:t}function F(e,t,{type:r,compareResolution:o}){if(!e||!t)return;let{aScore:s,bScore:i}=_({a:e,b:t,type:r,compareResolution:o});return s>i?t:e}async function M(e){let t=["--print","%(formats)j",e],o=(await u.get(`formats:${e}`))?.content??"";if(!o){let i;try{i=await w("yt-dlp",t)}catch(f){throw console.error("Error consiguiendo el ID del formato"),f}if(typeof i!=="string")throw Error("La salida del proceso es de tipo inválido (se esperaba string)");o=i,u.set(`formats:${e}`,{content:o})}let s=[];try{s=JSON.parse(o)}catch(i){throw console.error("Error convirtiendo la salida de yt-dlp a JSON"),i}if(!Array.isArray(s))throw Error("Se esperaba que los formatos fuesen un array. Puede que el contenido cacheado esté corrupto o sea inválido.");return s}async function re(e,t){let r=Boolean(t.match(/\d/)),o=r?!1:"N/A",s=await M(e),i=void 0,f=void 0,p=void 0,c=void 0,a=void 0;for(let n of s){let d=n.resolution==="audio only";if(r&&n.format_note===t){o=!0,a=g(a,n,{compareResolution:!1,type:"video"})??n;continue}if(d)p=g(p,n,{compareResolution:!1,type:"audio"})??n,c=F(c,n,{compareResolution:!1,type:"audio"})??n;else i=g(i,n,{compareResolution:!0,type:"video"})??n,f=F(f,n,{compareResolution:!0,type:"video"})??n}if(!r)a={"best-video":i,"worst-video":f,"best-audio":p,"worst-audio":c}[t];return{foundSpecific:o,formatId:a?.format_id}}export{T as saveInDisk,h as resolvePath,E as resolveFilenamePattern,F as getWorstFormat,C as getFromDisk,g as getBetterFormat,M as getAllFormats,re as findFormatId,Y as expandPattern,ee as downloadVideo,te as downloadAudio,m as config,u as cache,j as STANDARD_RESOLUTIONS,K as Configuration,v as CacheManager};
1
+ var C={day:86400000,hour:3600000,minute:60000,second:1000,nano:0.001};function g(e,t){if(!C[t])return e;return e*C[t]}function B(e,t){if(!C[t])return e;return e/C[t]}var j={cacheLocation:void 0,ignoreTTL:void 0,method:"memory",ttlInMs:g(10,"day")},U={"yt-dlp":"yt-dlp"},_=new Map([["cache",j],["commands",U]]);class O{store=new Map(_);get(e){let t=this.store.get(e);if(!t)return null;return t}add(e,t){let r=this.store.get(e)??{};this.store.set(e,{...r,...t})}replace(e,t){this.store.set(e,t)}delete(e){this.store.delete(e)}}var p=new O;function K(e){if(typeof e!=="string")return!1;return!0}import{readFile as I}from"node:fs/promises";import{homedir as Q}from"node:os";import{join as G,resolve as H,sep as X}from"node:path";function T(e){if(!e)return"";if(e.match(/~[^/]+/))throw Error("Ruta inválida. Ten más cuidado usando '~'");if(e.includes(" "))throw Error("La ruta no puede tener espacios");if(e==="."||e==="..")throw Error(`'${e}' No es una ruta válida. Tal vez faltó agregar '/'?`);let t=e;if(e.startsWith("~"))t=G(Q(),X,e.slice(1));return H(t)}import{join as Z}from"node:path";function w(e){let t=p.get("cache")?.cacheLocation;if(!t)throw Error("Es necesario configurar cacheLocation para buscar en el almacenamiento.");let r=T(t);if(e.includes("formats:")){let o=e.split(":")[1];if(!o)throw Error(`Falta especificar ytId en ${e}`);if(o==="${ytId}")throw Error("${ytId} no es un ID válido. Eso debes evaluarlo como `${ytId}`");r=Z(T(t),"formats",o)}return r}async function S(e){let t=w(e);if(!t)return;let r;try{r=await I(t,"utf8")}catch{}if(r)try{r=JSON.parse(r)}catch(o){console.error(`Error convirtiendo la caché de ${e} a JSON:`,o)}if(!r)return;return r}import{rm as k}from"node:fs/promises";async function N(e){let t=w(e);if(!t)return;try{await k(t)}catch(r){console.error(`Error borrando la caché de ${e} en el almacenamiento:`,r)}}import{mkdir as ee,writeFile as te}from"node:fs/promises";import{dirname as re}from"node:path";async function x(e,t){let r=w(e);if(!r)return;let o=re(r);try{ee(o,{recursive:!0})}catch{console.error(`Error creando la carpeta para guardar ${e}`)}try{await te(r,JSON.stringify(t,null,2),"utf8")}catch{console.error(`Error cacheando "${e}" en el almacenamiento`)}}class v{store=new Map;ttl=p.get("cache")?.ttlInMs??g(10,"day");async get(e){if(!K(e))throw Error("CacheKey inválida",{cause:e});let t=p.get("cache")?.method??"memory",r=null;if(t==="memory")r=this.store.get(e);if(t==="disk")r=await S(e);if(t==="hybrid"){if(r=this.store.get(e),!r)r=await S(e)}if(!r)return null;let o=p.get("cache")?.ignoreTTL??"never";if(o==="always")return r;if(o==="next")return p.add("cache",{ignoreTTL:"never"}),r;if(Date.now()-r.timestamp>this.ttl)return await this.delete(e),null;return r}async set(e,t){if(!K(e))throw Error("CacheKey inválida",{cause:e});let r=p.get("cache")?.method??"memory",o={...t,timestamp:Date.now()};if(r==="memory")this.store.set(e,o);if(r==="disk")await x(e,o);if(r==="hybrid")this.store.set(e,o),await x(e,o)}async delete(e){let t=p.get("cache")?.method;if(t==="memory")this.store.delete(e);if(t==="disk")await N(e);if(t==="hybrid")this.store.delete(e),await N(e)}}var h=new v;var oe=[18,144,240,360,480,720,1080,1440,2160],P="%(ytId)s.%(ext)s",E={ID:"%(id)s",YT_ID:"%(ytId)s"},F={startMarker:"%$#>RESULT>:",endMarker:":<RESULT%$#|"};import{spawn as ae}from"node:child_process";import{stdout as se,stderr as ne}from"node:process";function M(e,t){(e==="data"?se:ne).write(t)}var ie={showOutput:!1};function A(e,t,r){let o={...ie,...r},{showOutput:n}=o,l=p.get("commands")?.[e];if(!l)throw Error(`No se encontró un comando configurado para ${e}`);return new Promise((m,d)=>{let i=ae(l,t),f="",c="";i.stdout.on("data",(s)=>{f+=s;let u=s.toString();if(n)M("data",u)}),i.stderr.on("data",(s)=>{c+=s;let u=s.toString();if(n)M("err",u)}),i.on("close",(s)=>{if(s===0)m(f.toString());else d(Error(c.toString()))}),i.on("error",(s)=>{d(s)})})}function Y(e,t){let r=e;for(let[o,n]of t)r=r.replaceAll(o,n);return r}function V(e){return e.replaceAll("/","⁄")}function L({filename:e,id:t,ytId:r}){let o=new Map([[E.ID,t],[E.YT_ID,r]]),n=Y(e,o);return V(n)}var{endMarker:le,startMarker:q}=F;function $(e,t){let n=String(e).split(`
2
+ `).find((m)=>m.includes(q))?.split(q)[1].split(le)[0];if(!n)throw console.error("Salida completa recibida:",e),Error("No se encontró el JSON de resultado en la salida de la descarga");let a;try{a=JSON.parse(n)}catch{throw Error("Error convirtiendo la salida de la descarga a JSON")}let l=fe(e);return{...a,alreadyDownloaded:t?"NA (simulated)":l}}function fe(e){return String(e).split(`
3
+ `).some((r)=>r.includes("has already been downloaded"))}var{endMarker:pe,startMarker:me}=F;class R{async download(e,t){let r=this.buildYtDlpArgs(e,t),o;try{o=await A("yt-dlp",r,{showOutput:!0})}catch{console.error("Error en la descarga")}if(!o)return{ext:"NA",id:e,path:"NA",size:-1,status:"failed",title:"NA",type:"download:result",alreadyDownloaded:"NA"};return $(o,t.simulate)}buildYtDlpArgs(e,t){let{id:r,type:o,simulate:n}=t,a=o==="video",l=n?"video":"after_move",m=t.simulate?"--simulate":"--no-simulate",d=t.outputDir,i=L({filename:t.filename,id:t.id,ytId:e}),f="aac",c=a?[]:["-x","--audio-format","aac"],s=["--newline","--progress","--no-quiet","--print",`${l}:${me}{"type":"download:result","status":"success","path":"%(filepath)s","id":%(id)j,"ext":%(ext)j,"title":%(title)j,"size":%(filesize_approx)s}${pe}`];return["-f",r,m,...s,...c,"-o",i,"-P",d,e]}}async function de(e,t){if(!e||!t.formatId)return;let r=z("video",t);return new R().download(e,r)}async function ce(e,t){if(!e||!t.formatId)return;let r=z("audio",t);return new R().download(e,r)}function z(e,t){return{id:`${t.formatId}`,type:e,outputDir:t.outputDir??".",filename:t.filename??P,simulate:t.simulate??!1}}function W({a:e,b:t,compareResolution:r,type:o}){let n=o==="video"&&r&&e.quality!==null&&t.quality!==null,a=o!=="audio"&&r&&e.height!==null&&t.height!==null,l=o==="video"&&e.fps!==null&&t.fps!==null,m=o==="audio"&&e.asr!==null&&t.asr!==null,d=e.tbr!==null&&t.tbr!==null,i=0,f=0;if(n){if((e.quality??0)>(t.quality??0))i+=3;else if((e.quality??0)<(t.quality??0))f+=3}if(a){if((e.height??0)>(t.height??0))i+=3;else if((e.height??0)<(t.height??0))f+=3}if(l){if((e.fps??0)>(t.fps??0))i+=2;else if((e.fps??0)<(t.fps??0))f+=2}if(m){if((e.asr??0)>(t.asr??0))i+=2;else if((e.asr??0)<(t.asr??0))f+=2}if(d){if((e.tbr??0)>(t.tbr??0))i+=1;else if((e.tbr??0)<(t.tbr??0))f+=1}return{aScore:i,bScore:f}}function y(e,t,{type:r,compareResolution:o}){if(!e||!t)return;let{aScore:n,bScore:a}=W({a:e,b:t,type:r,compareResolution:o});return n>a?e:t}function D(e,t,{type:r,compareResolution:o}){if(!e||!t)return;let{aScore:n,bScore:a}=W({a:e,b:t,type:r,compareResolution:o});return n>a?t:e}async function b(e){let t=["--print","%(formats)j",e],o=(await h.get(`formats:${e}`))?.content??"";if(!o){let a;try{a=await A("yt-dlp",t)}catch(l){throw console.error("Error consiguiendo el ID del formato"),l}if(typeof a!=="string")throw Error("La salida del proceso es de tipo inválido (se esperaba string)");o=a,h.set(`formats:${e}`,{content:o})}let n=[];try{n=JSON.parse(o)}catch(a){throw console.error("Error convirtiendo la salida de yt-dlp a JSON"),a}if(!Array.isArray(n))throw Error("Se esperaba que los formatos fuesen un array. Puede que el contenido cacheado esté corrupto o sea inválido.");return n}async function ue(e,t){let r=Boolean(t.match(/\d/)),o=r?!1:"N/A",n=await b(e),a=void 0,l=void 0,m=void 0,d=void 0,i=void 0,f=void 0,c=void 0;for(let s of n){let u=s.resolution==="audio only",J=s.format_note==="storyboard";if(r&&s.format_note===t){o=!0,c=y(c,s,{compareResolution:!1,type:"video"})??s;continue}if(u)m=y(m,s,{compareResolution:!1,type:"audio"})??s,d=D(d,s,{compareResolution:!1,type:"audio"})??s;else if(J)i=y(i,s,{compareResolution:!1,type:"sb"})??s,f=D(f,s,{compareResolution:!1,type:"sb"})??s;else a=y(a,s,{compareResolution:!0,type:"video"})??s,l=D(l,s,{compareResolution:!0,type:"video"})??s}if(!r)c={"best-video":a,"worst-video":l,"best-audio":m,"worst-audio":d,"best-storyboard":i,"worst-storyboard":f}[t];return{foundSpecific:o,formatId:c?.format_id}}export{g as timeToMs,x as saveInDisk,T as resolvePath,L as resolveFilenamePattern,B as msToTime,D as getWorseFormat,S as getFromDisk,y as getBetterFormat,b as getAllFormats,ue as findFormatId,Y as expandPattern,de as downloadVideo,ce as downloadAudio,p as config,h as cache,oe as STANDARD_RESOLUTIONS,O as Configuration,v as CacheManager};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yt-kit/core",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -21,6 +21,7 @@
21
21
  "homepage": "https://github.com/ubiufboeuf/yt-kit#readme",
22
22
  "scripts": {
23
23
  "start": "bun pruebas.ts",
24
+ "dev": "bun --watch pruebas.ts",
24
25
  "build": "bun build.ts && dts-bundle-generator --no-check -o dist/index.d.ts src/index.ts",
25
26
  "build:debug": "tsc -p tsconfig.build.json",
26
27
  "prepublishOnly": "bun run build"