fluent-file 0.2.0 → 0.2.1
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 +16 -7
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { createReadStream, createWriteStream } from "node:fs";
|
|
2
2
|
import { inspect } from "node:util";
|
|
3
|
-
import * as
|
|
3
|
+
import * as fluent_command0$1 from "fluent-command";
|
|
4
4
|
import * as fluent_command0 from "fluent-command";
|
|
5
5
|
import { WriteFileOptions } from "fs-extra/esm";
|
|
6
6
|
import * as neverthrow0$1 from "neverthrow";
|
|
7
7
|
import * as neverthrow0 from "neverthrow";
|
|
8
8
|
import { ResultAsync } from "neverthrow";
|
|
9
9
|
import sharpLib, { AvifOptions, ResizeOptions, SharpOptions } from "sharp";
|
|
10
|
-
import * as zerde5 from "zerde";
|
|
11
10
|
import * as zerde0 from "zerde";
|
|
11
|
+
import * as zerde1 from "zerde";
|
|
12
12
|
import { ParseOptions, Prettify, StringifyOptions } from "zerde";
|
|
13
13
|
import * as zod0 from "zod";
|
|
14
14
|
import z from "zod";
|
|
@@ -226,7 +226,7 @@ declare function getVideoMetaData(path: string): neverthrow0$1.ResultAsync<{
|
|
|
226
226
|
nb_frames: number;
|
|
227
227
|
bit_rate: number;
|
|
228
228
|
}[];
|
|
229
|
-
},
|
|
229
|
+
}, fluent_command0$1.FluentCommandError | zerde0.ParseError | zerde0.ValidationError>;
|
|
230
230
|
type ExtractFrameOptions = FileOutputOptions & {
|
|
231
231
|
time?: number;
|
|
232
232
|
unit?: "s" | "ms" | "us";
|
|
@@ -297,11 +297,11 @@ declare class FluentFile<Content = string, ParsedContent = Content> {
|
|
|
297
297
|
remove: () => ResultAsync<void, FileRemoveError>;
|
|
298
298
|
readText: (options?: FileReadOptions | undefined) => ResultAsync<string, FileReadError>;
|
|
299
299
|
readBuffer: (options?: Pick<FileReadOptions, "flag" | "signal"> | undefined) => ResultAsync<Buffer<ArrayBufferLike>, FileReadError>;
|
|
300
|
-
read: (options?: FileReadOptions) => ResultAsync<ParsedContent, FileReadError |
|
|
300
|
+
read: (options?: FileReadOptions) => ResultAsync<ParsedContent, FileReadError | zerde1.ParseError | zerde1.ValidationError>;
|
|
301
301
|
createReadStream: (readStreamOptions?: Parameters<typeof createReadStream>[1]) => fs0.ReadStream;
|
|
302
302
|
writeText: (textContent: string, writeOptions?: WriteFileOptions | undefined) => ResultAsync<void, FileWriteError>;
|
|
303
303
|
writeBuffer: (bufferContent: Buffer<ArrayBufferLike>, writeOptions?: WriteFileOptions | undefined) => ResultAsync<void, FileWriteError>;
|
|
304
|
-
write: (content: Content, options?: FileWriteOptions) => ResultAsync<void, FileWriteError |
|
|
304
|
+
write: (content: Content, options?: FileWriteOptions) => ResultAsync<void, FileWriteError | zerde1.ValidationError | zerde1.StringifyError>;
|
|
305
305
|
createWriteStream: (writeStreamOptions?: Parameters<typeof createWriteStream>[1]) => fs0.WriteStream;
|
|
306
306
|
append: (data: string | Buffer<ArrayBufferLike>, writeOptions?: WriteFileOptions | undefined) => ResultAsync<void, FileAppendError>;
|
|
307
307
|
image: (sharpOptions?: SharpOptions) => {
|
|
@@ -471,7 +471,7 @@ declare class FluentFile<Content = string, ParsedContent = Content> {
|
|
|
471
471
|
nb_frames: number;
|
|
472
472
|
bit_rate: number;
|
|
473
473
|
}[];
|
|
474
|
-
},
|
|
474
|
+
}, fluent_command0.FluentCommandError | zerde1.ParseError | zerde1.ValidationError>;
|
|
475
475
|
extractFrame: (extractFrameOptions?: ExtractFrameOptions) => Promise<neverthrow0.Result<FluentFile<string, string>, fluent_command0.FluentCommandError>>;
|
|
476
476
|
};
|
|
477
477
|
download: (url: string, downloadOptions?: DownloadFileOptions) => ResultAsync<"ALREADY_EXISTS" | "SUCCESS", FileDownloadError>;
|
|
@@ -491,4 +491,13 @@ type FileWriteOptions = StringifyOptions & Partial<{
|
|
|
491
491
|
declare function ffile(file: PathPieces[number], ...extraPathPieces: PathPieces): FluentFile<string, string>;
|
|
492
492
|
declare function homeFile(file: PathPieces[number], ...extraPathPieces: PathPieces): FluentFile<string, string>;
|
|
493
493
|
//#endregion
|
|
494
|
-
|
|
494
|
+
//#region src/folder/xdg.d.ts
|
|
495
|
+
declare function cacheFolder(...pathPieces: PathPieces): FluentFolder;
|
|
496
|
+
declare function configFolder(...pathPieces: PathPieces): FluentFolder;
|
|
497
|
+
declare function dataFolder(...pathPieces: PathPieces): FluentFolder;
|
|
498
|
+
declare function logsFolder(...pathPieces: PathPieces): FluentFolder;
|
|
499
|
+
declare function homeFolder(...pathPieces: PathPieces): FluentFolder;
|
|
500
|
+
declare function tempFolder(...pathPieces: PathPieces): FluentFolder;
|
|
501
|
+
declare function currentFolder(): FluentFolder;
|
|
502
|
+
//#endregion
|
|
503
|
+
export { DEFAULT_PHASH_THRESHOLD, DESTINATION_FALLBACK, ExtractFrameOptions, FileAppendError, FileChmodError, FileCopyError, FileDownloadError, FileImageConvertError, FileImageMetadataError, FileImagePhashError, FileImageResizeError, FileLinkError, FileMoveError, FileOperation, FileReadError, FileReadOptions, FileRemoveError, FileStatError, FileSymLinkError, FileWriteError, FileWriteOptions, FindFilesGlobOptions, FindFoldersGlobOptions, FluentFile, FluentFolder, FsFlag, FsFlags, IMAGE_EXTENSIONS, ImageResizeOptions, MAX_DIFFERENCES, PhashSimilarity, PhashSimilarityInfo, PhashString, PhashThreshold, ToAVIFOptions, VIDEO_EXTENSIONS, binaryStringRegex, cacheFolder, comparePhashes, configFolder, currentFolder, dataFolder, ffile, folder, getVideoMetaData, homeFile, homeFolder, logsFolder, phashStringSchema, phashThresholdSchema, phashesMatch, tempFolder };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{constants as e,createReadStream as t,createWriteStream as n}from"node:fs";import{chmod as r,copyFile as i,opendir as a,readFile as o,stat as s}from"node:fs/promises";import{homedir as c,platform as l}from"node:os";import{inspect as u}from"node:util";import{fcmd as d}from"fluent-command";import{appendFile as f}from"fs-extra";import{emptyDir as ee,ensureDir as te,ensureFile as ne,ensureLink as re,ensureSymlink as ie,move as ae,outputFile as p,remove as m}from"fs-extra/esm";import{ResultAsync as h}from"neverthrow";import g,{basename as oe}from"pathe";import se from"sharp";import ce from"sharp-phash";import{parseString as le,zparse as _,zstringify as ue}from"zerde";import v from"zod";import y from"picomatch";import{pipeline as b}from"node:stream/promises";const de={Append:`a`,AppendOrFail:`ax`,AppendAndRead:`a+`,AppendAndReadOrFail:`ax+`,Read:`r`,ReadAndWrite:`r+`,Write:`w`,WriteOrFailIfExists:`wx`};function x(...e){let t=e.map((e,t)=>{if(typeof e==`number`)return e.toString();if(t===0&&e===`~`)return c();if(e.toUpperCase()!==e)return e;let n=``;if(e.startsWith(`$`)&&(n=e.slice(1)),l()===`win32`&&e.startsWith(`%`)&&e.endsWith(`%`)&&(n=e.slice(1,-1)),n!==``){let t=process.env[n];if(!t)throw Error(`Missing Environment variable ${e}`);return t}return e});return g.resolve(...t)}function S(e){let t=e.lastIndexOf(`.`);return t<0?e:e.slice(t+1)}function fe(e){return S(g.extname(e))}const pe=4,me=-5;var C=class extends Error{operation;path;constructor(e,t){super(),this.path=e,this.operation=this.constructor.name.slice(pe,me),this.message=`Error trying to ${this.operation} file: ${e}`,this.cause=t,this.name=this.constructor.name}},w=class extends C{url;constructor(e,t,n){super(e,n),this.url=t,this.message=`Error trying to download url: ${t} to file: ${e}`}},he=class extends C{},ge=class extends C{},T=class extends C{},E=class extends C{},D=class extends C{},O=class extends C{},k=class extends C{},A=class extends C{},j=class extends C{},M=class extends C{};const N=`DESTINATION_FALLBACK`;var P=class extends C{destinationPath;constructor(e,t,n){super(e,n),this.destinationPath=t??N}},F=class extends P{},I=class extends P{},L=class extends P{},R=class extends P{};const _e=6,ve=[`avif`,`gif`,`jpeg`,`jpg`,`png`,`svg`,`tiff`,`webp`],z=64,ye=16,B=/^[01]+$/,V=v.codec(v.string().regex(B).length(z),v.hex().brand(`PhashString`),{decode:e=>BigInt(`0b${e}`).toString(ye),encode:e=>BigInt(`0x${e}`).toString(2).padStart(z,`0`)}),H=v.int().nonnegative().max(z).brand(`PhashThreshold`),be=6,U=H.parse(be);function xe(e,t,n=U){if(e===t)return Object.freeze({level:`SAME`,diff:0});let r=V.encode(e),i=V.encode(t),a=0,o=z;for(;o--;)r[o]!==i[o]&&a++;let s=a<n?`SIMILAR`:`DIFFERENT`;return Object.freeze({level:s,diff:a})}function Se(e,t,n=U){if(e===t)return!0;let r=V.encode(e),i=V.encode(t),a=0,o=z;for(;o--;)if(r[o]!==i[o]&&a++,a>=n)return!1;return!0}const Ce=v.coerce.number().positive(),W=v.coerce.number().int(),we=W.nonnegative(),G=W.positive(),K=v.object({duration:Ce,bit_rate:G}),Te=1e3;function q(e){let t=Math.round(e*Te),n=Math.trunc(e%60),r=Math.trunc(e/60%60),i=Math.trunc(e/60/60%60),a=[i,r,n].filter((e,t)=>t>0||e>0).map((e,t)=>{let n=e.toString();return t>0&&(n=n.padStart(2,`0`)),n}).join(`:`);return{millis:t,seconds:n,minutes:r,hours:i,hms:a}}const J=v.object({...K.shape,codec_name:v.string(),codec_long_name:v.string(),codec_tag_string:v.string(),nb_frames:G}),Ee=v.object({...J.shape,codec_type:v.literal(`audio`),channels:G,channel_layout:v.string()}),De=v.object({...J.shape,codec_type:v.literal(`video`),height:G,width:G}),Oe=v.object({...K.shape,nb_streams:G,format_name:v.string(),format_long_name:v.string(),size:G}),ke=v.object({format:Oe,streams:v.array(v.union([Ee,De])).min(2)}).transform(({format:{duration:e,...t},streams:n},{addIssue:r})=>{let i=n.filter(e=>e.codec_type===`video`).map(({duration:e,...t})=>({...t,...q(e)})).at(0);if(!i)return r({code:`custom`,message:`Video was missing video stream`}),v.NEVER;let a=n.filter(e=>e.codec_type===`audio`).map(({duration:e,...t})=>({...t,...q(e)}));return a.length===0?(r({code:`custom`,message:`Video was missing audio stream`}),v.NEVER):{videoStream:i,audioStreams:a,...t,...q(e)}}),Ae=[`avi`,`flv`,`mkv`,`mov`,`mp4`,`mpeg`,`mpg`,`rm`,`rmvb`,`webm`,`wmv`];function Y(e){return d(`ffprobe`).opt(`hide_banner`).opt(`show_format`).opt(`show_streams`).opt({v:`error`,print_format:`json`}).args(e).read().andThen(e=>_(e.stdout,ke,`json`))}var X=class extends Error{operation;path;constructor(e,t,n){let r=`Error trying to ${e} folder: ${t}`;super(r,{cause:n}),this.path=t,this.operation=e,this.name=this.constructor.name}},je=class extends X{constructor(e,t){super(`glob`,e,t)}};function Me(){return Q(process.cwd())}var Z=class{path;name;constructor(...e){this.path=x(...e),this.name=oe(this.path),this.name||=this.path}get info(){return{path:this.path,name:this.name}}folder=(...e)=>Q(this.path,...e);file=(e,...t)=>$(this.path,e,...t);relativePath=(e=Me())=>{let t=this.path;return t.startsWith(e.path)&&(t=t.slice(e.path.length),t.startsWith(`/`))?t.slice(1):t};toString=()=>this.path;toJSON=()=>({FluentFolder:this.info});[u.custom]=()=>this.toJSON();stats=h.fromThrowable(async()=>{let e=await s(this.path);if(!e.isDirectory())throw new X(`stat`,this.path,`FolderWasNotFolder`);return e},e=>e instanceof X?e:new X(`stat`,this.path,e));exists=async()=>(await this.stats()).isOk();ensureExists=()=>te(this.path);ensureEmpty=()=>ee(this.path);remove=()=>m(this.path);findFolders=h.fromThrowable(async(e={})=>{let t=e.glob?y(e.glob,{cwd:this.path}):null,n=await a(this.path,{recursive:e.recursive??!0}),r=[];for await(let e of n){if(!e.isDirectory())continue;let n=g.resolve(e.parentPath,e.name);if(t&&!t(n))continue;r.push(n)}return r.sort().map(e=>Q(e))},e=>new je(this.path,e));findFiles=h.fromThrowable(async(e={})=>{let t=e.glob?y(e.glob,{cwd:this.path}):null,n=await a(this.path,{recursive:e.recursive??!0}),r=[],i=(e.exts??[]).map(S);for await(let e of n){if(!e.isFile())continue;let n=g.resolve(e.parentPath,e.name);if(i.length>0){let t=fe(e.name);if(!i.includes(t))continue}if(t&&!t(n))continue;r.push(n)}return r.sort().map(e=>$(e))},e=>new je(this.path,e))};function Q(...e){return new Z(...e)}const Ne=h.fromThrowable(async(e,t,n={})=>{try{let{overwrite:r=!1,progressThrottle:i=100,onProgress:a}=n;if(!r&&await t.exists())return`ALREADY_EXISTS`;await t.folder().ensureExists();let o=await fetch(e);if(!o.ok){let{status:t,statusText:n,redirected:r,type:i}=o,a={};throw o.headers.forEach((e,t)=>{a[t]=e}),Error(`Got ${o.status} ${o.statusText} for url: ${e}`,{cause:{status:t,statusText:n,headers:a,redirected:r,type:i}})}let s=G.parse(o.headers.get(`content-length`));if(!o.body)throw Error(`Request body was null for url: ${e}`,{cause:o});let c=o.body,l=t.createWriteStream();if(!a)return await b(c,l),`SUCCESS`;let u=0,d=null,f=e=>{u+=e,!d&&(a({downloadedBytes:u,totalBytes:s}),d=setTimeout(()=>{d=null},i))};return await b(c,async function*(e){for await(let t of e)f(t.length)},l),`SUCCESS`}catch(n){throw new w(t.path(),e,n)}},e=>e);var Pe=class a{#path;#folderPath;#name;#basename;#ext;#schema;#info;#ensureDestination=async e=>{let t=e instanceof a?e:e.file(this.#name);return await t.folder().ensureExists(),await t.remove(),t.path()};#prepareTarget=async e=>{let{newFolder:t=this.folder(),newBaseName:n=this.#basename,newExt:r=this.#ext}=e,i=t.file(`${n}.${r}`);return await i.remove(),await t.ensureExists(),i};constructor(e,t,...n){this.#path=x(t,...n),this.#schema=e;let r=Fe(this.#path);this.#folderPath=r.folderPath,this.#name=r.name,this.#basename=r.basename,this.#ext=r.ext,this.#info=r}toString=()=>this.#path;toJSON=()=>({FluentFile:this.info});[u.custom]=()=>this.toJSON();path=()=>this.#path;folderPath=()=>this.#folderPath;name(e){return e===void 0?this.#name:(this.#name=e,this.#path=`${this.#folderPath}/${e}`,this)}basename(e){return e===void 0?this.#basename:(this.#basename=e,this.#name=e+this.#ext,this.#path=`${this.#folderPath}/${this.#name}`,this)}ext(e){return e===void 0?this.#ext:(this.#ext=e,this.#name=this.#basename+e,this.#path=`${this.#folderPath}/${this.#name}`,this)}schema=e=>new a(e,this.#path);get info(){return this.#info}relativePath=(e=Me())=>{let t=this.#path;return t.startsWith(e.path)&&(t=t.slice(e.path.length),t.startsWith(`/`))?t.slice(1):t};file=(e,...t)=>new a(this.#schema,this.#folderPath,e,...t);folder=(...e)=>new Z(this.#folderPath,...e);stats=h.fromThrowable(async()=>{let e=await s(this.#path);if(!e.isFile())throw new j(this.#path,`FileWasNotFile`);return e},e=>e instanceof j?e:new j(this.#path,e));exists=async()=>(await this.stats()).isOk();ensureExists=()=>ne(this.#path);chmod=h.fromThrowable(async e=>{await r(this.#path,e)},e=>new ge(this.#path,e));copyTo=h.fromThrowable(async t=>{let n=null;try{n=await this.#ensureDestination(t),await i(this.#path,n,e.COPYFILE_FICLONE)}catch(e){throw new F(this.#path,n,e)}},e=>e);moveTo=h.fromThrowable(async(e,t)=>{let n=null;try{n=await this.#ensureDestination(e),await ae(this.#path,n,{overwrite:!0,dereference:t})}catch(e){throw new I(this.#path,n,e)}},e=>e);linkTo=h.fromThrowable(async e=>{let t=null;try{t=await this.#ensureDestination(e),await re(this.#path,t)}catch(e){throw new L(this.#path,t,e)}},e=>e);symlinkTo=h.fromThrowable(async e=>{let t=null;try{t=await this.#ensureDestination(e),await ie(this.#path,t)}catch(e){throw new R(this.#path,t,e)}},e=>e);remove=h.fromThrowable(()=>m(this.#path),e=>new A(this.#path,e));readText=h.fromThrowable((e={})=>o(this.#path,{encoding:`utf8`,...e}),e=>new k(this.#path,e));readBuffer=h.fromThrowable((e={})=>o(this.#path,e),e=>new k(this.#path,e));read=(e={})=>this.readText(e).andThen(t=>_(t,this.#schema,{format:this.#path,...e}));createReadStream=e=>t(this.#path,e);writeText=h.fromThrowable((e,t={})=>p(this.#path,e,t),e=>new M(this.#path,e));writeBuffer=h.fromThrowable((e,t={})=>p(this.#path,e,t),e=>new M(this.#path,e));write=(e,t={})=>ue(e,this.#schema,t).andThen(e=>this.writeText(e,t));createWriteStream=e=>n(this.#path,e);append=h.fromThrowable((e,t={})=>f(this.#path,e,t),e=>new he(this.#path,e));image=(e={})=>{let t=se(this.#path,e),n=h.fromThrowable(()=>t.metadata(),e=>new E(this.#path,e)),r=h.fromThrowable(async e=>{let n=await this.#prepareTarget(e);return await t.resize(e).toFile(n.path()),n},e=>new O(this.#path,e)),i=h.fromThrowable(async(e={})=>{let n=await this.#prepareTarget({...e,newExt:`avif`});return await t.resize(e).avif(e).toFile(n.path()),n},e=>new T(this.#path,e)),a=h.fromThrowable(async()=>{let t=await ce(this.#path,e);return V.decode(t)},e=>new D(this.#path,e));return{...t,metadata:n,resize:r,toAVIF:i,phash:a}};video=()=>({metadata:()=>Y(this.#path),extractFrame:async(e={})=>{let{time:t=1,unit:n=`s`,ext:r=`png`,...i}=e,a=n===`s`?t:`${t}${n}`,o=await this.#prepareTarget({newExt:r,...i});return d(`ffmpeg`).opt(`hide_banner`).opt({ss:a,i:this.#path,"frames:v":1,y:``}).args(o.path()).read().map(()=>o)}});download=(e,t={})=>Ne(e,this,t)};function Fe(e){let t=g.basename(e),n=g.dirname(e),r=``,i=``,a=t.lastIndexOf(`.`);return a<=0?(r=t,i=``):(r=t.slice(0,a),i=t.slice(a+1)),{absolutePath:e,folderPath:n,name:t,basename:r,ext:i}}function $(e,...t){return new Pe(le(),e,...t)}function Ie(e,...t){return $(c(),e,...t)}export{U as DEFAULT_PHASH_THRESHOLD,N as DESTINATION_FALLBACK,he as FileAppendError,ge as FileChmodError,F as FileCopyError,w as FileDownloadError,T as FileImageConvertError,E as FileImageMetadataError,D as FileImagePhashError,O as FileImageResizeError,L as FileLinkError,I as FileMoveError,k as FileReadError,A as FileRemoveError,j as FileStatError,R as FileSymLinkError,M as FileWriteError,Pe as FluentFile,Z as FluentFolder,de as FsFlags,ve as IMAGE_EXTENSIONS,_e as MAX_DIFFERENCES,Ae as VIDEO_EXTENSIONS,B as binaryStringRegex,xe as comparePhashes,$ as ffile,Q as folder,Y as getVideoMetaData,Ie as homeFile,V as phashStringSchema,H as phashThresholdSchema,Se as phashesMatch};
|
|
1
|
+
import{constants as e,createReadStream as t,createWriteStream as n}from"node:fs";import{chmod as r,copyFile as i,opendir as a,readFile as o,stat as s}from"node:fs/promises";import{homedir as c,platform as l,tmpdir as u}from"node:os";import{inspect as d}from"node:util";import{fcmd as f}from"fluent-command";import{appendFile as ee}from"fs-extra";import{emptyDir as te,ensureDir as ne,ensureFile as re,ensureLink as ie,ensureSymlink as ae,move as oe,outputFile as p,remove as m}from"fs-extra/esm";import{ResultAsync as h}from"neverthrow";import g,{basename as se}from"pathe";import ce from"sharp";import le from"sharp-phash";import{parseString as ue,zparse as de,zstringify as fe}from"zerde";import _ from"zod";import pe from"picomatch";import{pipeline as me}from"node:stream/promises";const he={Append:`a`,AppendOrFail:`ax`,AppendAndRead:`a+`,AppendAndReadOrFail:`ax+`,Read:`r`,ReadAndWrite:`r+`,Write:`w`,WriteOrFailIfExists:`wx`};function v(...e){let t=e.map((e,t)=>{if(typeof e==`number`)return e.toString();if(t===0&&e===`~`)return c();if(e.toUpperCase()!==e)return e;let n=``;if(e.startsWith(`$`)&&(n=e.slice(1)),l()===`win32`&&e.startsWith(`%`)&&e.endsWith(`%`)&&(n=e.slice(1,-1)),n!==``){let t=process.env[n];if(!t)throw Error(`Missing Environment variable ${e}`);return t}return e});return g.resolve(...t)}function y(e){let t=e.lastIndexOf(`.`);return t<0?e:e.slice(t+1)}function ge(e){return y(g.extname(e))}const _e=4,ve=-5;var b=class extends Error{operation;path;constructor(e,t){super(),this.path=e,this.operation=this.constructor.name.slice(_e,ve),this.message=`Error trying to ${this.operation} file: ${e}`,this.cause=t,this.name=this.constructor.name}},x=class extends b{url;constructor(e,t,n){super(e,n),this.url=t,this.message=`Error trying to download url: ${t} to file: ${e}`}},S=class extends b{},C=class extends b{},w=class extends b{},T=class extends b{},E=class extends b{},D=class extends b{},O=class extends b{},k=class extends b{},A=class extends b{},j=class extends b{};const M=`DESTINATION_FALLBACK`;var N=class extends b{destinationPath;constructor(e,t,n){super(e,n),this.destinationPath=t??M}},P=class extends N{},F=class extends N{},I=class extends N{},L=class extends N{};const ye=6,be=[`avif`,`gif`,`jpeg`,`jpg`,`png`,`svg`,`tiff`,`webp`],R=64,xe=16,z=/^[01]+$/,B=_.codec(_.string().regex(z).length(R),_.hex().brand(`PhashString`),{decode:e=>BigInt(`0b${e}`).toString(xe),encode:e=>BigInt(`0x${e}`).toString(2).padStart(R,`0`)}),V=_.int().nonnegative().max(R).brand(`PhashThreshold`),Se=6,H=V.parse(Se);function Ce(e,t,n=H){if(e===t)return Object.freeze({level:`SAME`,diff:0});let r=B.encode(e),i=B.encode(t),a=0,o=R;for(;o--;)r[o]!==i[o]&&a++;let s=a<n?`SIMILAR`:`DIFFERENT`;return Object.freeze({level:s,diff:a})}function we(e,t,n=H){if(e===t)return!0;let r=B.encode(e),i=B.encode(t),a=0,o=R;for(;o--;)if(r[o]!==i[o]&&a++,a>=n)return!1;return!0}const Te=_.coerce.number().positive(),U=_.coerce.number().int(),Ee=U.nonnegative(),W=U.positive(),G=_.object({duration:Te,bit_rate:W}),De=1e3;function K(e){let t=Math.round(e*De),n=Math.trunc(e%60),r=Math.trunc(e/60%60),i=Math.trunc(e/60/60%60),a=[i,r,n].filter((e,t)=>t>0||e>0).map((e,t)=>{let n=e.toString();return t>0&&(n=n.padStart(2,`0`)),n}).join(`:`);return{millis:t,seconds:n,minutes:r,hours:i,hms:a}}const q=_.object({...G.shape,codec_name:_.string(),codec_long_name:_.string(),codec_tag_string:_.string(),nb_frames:W}),Oe=_.object({...q.shape,codec_type:_.literal(`audio`),channels:W,channel_layout:_.string()}),ke=_.object({...q.shape,codec_type:_.literal(`video`),height:W,width:W}),Ae=_.object({...G.shape,nb_streams:W,format_name:_.string(),format_long_name:_.string(),size:W}),je=_.object({format:Ae,streams:_.array(_.union([Oe,ke])).min(2)}).transform(({format:{duration:e,...t},streams:n},{addIssue:r})=>{let i=n.filter(e=>e.codec_type===`video`).map(({duration:e,...t})=>({...t,...K(e)})).at(0);if(!i)return r({code:`custom`,message:`Video was missing video stream`}),_.NEVER;let a=n.filter(e=>e.codec_type===`audio`).map(({duration:e,...t})=>({...t,...K(e)}));return a.length===0?(r({code:`custom`,message:`Video was missing audio stream`}),_.NEVER):{videoStream:i,audioStreams:a,...t,...K(e)}}),Me=[`avi`,`flv`,`mkv`,`mov`,`mp4`,`mpeg`,`mpg`,`rm`,`rmvb`,`webm`,`wmv`];function Ne(e){return f(`ffprobe`).opt(`hide_banner`).opt(`show_format`).opt(`show_streams`).opt({v:`error`,print_format:`json`}).args(e).read().andThen(e=>de(e.stdout,je,`json`))}var J=class extends Error{operation;path;constructor(e,t,n){let r=`Error trying to ${e} folder: ${t}`;super(r,{cause:n}),this.path=t,this.operation=e,this.name=this.constructor.name}},Pe=class extends J{constructor(e,t){super(`glob`,e,t)}};const Fe={CACHE:{darwin:[`~`,`Library`,`Caches`],linux:[`~`,`.cache`],win32:[`$LOCALAPPDATA`]},CONFIG:{darwin:[`~`,`Library`,`Preferences`],linux:[`~`,`.config`],win32:[`$APPDATA`]},DATA:{darwin:[`~`,`Library`,`Application Support`],linux:[`~`,`.local`,`share`],win32:[`$LOCALAPPDATA`]},STATE:{darwin:[`~`,`Library`,`Logs`],linux:[`~`,`.local`,`state`],win32:[`$LOCALAPPDATA`]}};function Y(e){let t=l();if(t===`win32`||t===`darwin`)return Fe[e][t];let n=process.env[`XDG_${e}_HOME`];return n?[n]:Fe[e].linux}function Ie(...e){return Q(...Y(`CACHE`),...e)}function Le(...e){return Q(...Y(`CONFIG`),...e)}function Re(...e){return Q(...Y(`DATA`),...e)}function ze(...e){return Q(...Y(`STATE`),...e)}function Be(...e){return Q(c(),...e)}function Ve(...e){return Q(u(),...e)}function X(){return Q(process.cwd())}var Z=class{path;name;constructor(...e){this.path=v(...e),this.name=se(this.path),this.name||=this.path}get info(){return{path:this.path,name:this.name}}folder=(...e)=>Q(this.path,...e);file=(e,...t)=>$(this.path,e,...t);relativePath=(e=X())=>{let t=this.path;return t.startsWith(e.path)&&(t=t.slice(e.path.length),t.startsWith(`/`))?t.slice(1):t};toString=()=>this.path;toJSON=()=>({FluentFolder:this.info});[d.custom]=()=>this.toJSON();stats=h.fromThrowable(async()=>{let e=await s(this.path);if(!e.isDirectory())throw new J(`stat`,this.path,`FolderWasNotFolder`);return e},e=>e instanceof J?e:new J(`stat`,this.path,e));exists=async()=>(await this.stats()).isOk();ensureExists=()=>ne(this.path);ensureEmpty=()=>te(this.path);remove=()=>m(this.path);findFolders=h.fromThrowable(async(e={})=>{let t=e.glob?pe(e.glob,{cwd:this.path}):null,n=await a(this.path,{recursive:e.recursive??!0}),r=[];for await(let e of n){if(!e.isDirectory())continue;let n=g.resolve(e.parentPath,e.name);if(t&&!t(n))continue;r.push(n)}return r.sort().map(e=>Q(e))},e=>new Pe(this.path,e));findFiles=h.fromThrowable(async(e={})=>{let t=e.glob?pe(e.glob,{cwd:this.path}):null,n=await a(this.path,{recursive:e.recursive??!0}),r=[],i=(e.exts??[]).map(y);for await(let e of n){if(!e.isFile())continue;let n=g.resolve(e.parentPath,e.name);if(i.length>0){let t=ge(e.name);if(!i.includes(t))continue}if(t&&!t(n))continue;r.push(n)}return r.sort().map(e=>$(e))},e=>new Pe(this.path,e))};function Q(...e){return new Z(...e)}const He=h.fromThrowable(async(e,t,n={})=>{try{let{overwrite:r=!1,progressThrottle:i=100,onProgress:a}=n;if(!r&&await t.exists())return`ALREADY_EXISTS`;await t.folder().ensureExists();let o=await fetch(e);if(!o.ok){let{status:t,statusText:n,redirected:r,type:i}=o,a={};throw o.headers.forEach((e,t)=>{a[t]=e}),Error(`Got ${o.status} ${o.statusText} for url: ${e}`,{cause:{status:t,statusText:n,headers:a,redirected:r,type:i}})}let s=W.parse(o.headers.get(`content-length`));if(!o.body)throw Error(`Request body was null for url: ${e}`,{cause:o});let c=o.body,l=t.createWriteStream();if(!a)return await me(c,l),`SUCCESS`;let u=0,d=null,f=e=>{u+=e,!d&&(a({downloadedBytes:u,totalBytes:s}),d=setTimeout(()=>{d=null},i))};return await me(c,async function*(e){for await(let t of e)f(t.length)},l),`SUCCESS`}catch(n){throw new x(t.path(),e,n)}},e=>e);var Ue=class a{#path;#folderPath;#name;#basename;#ext;#schema;#info;#ensureDestination=async e=>{let t=e instanceof a?e:e.file(this.#name);return await t.folder().ensureExists(),await t.remove(),t.path()};#prepareTarget=async e=>{let{newFolder:t=this.folder(),newBaseName:n=this.#basename,newExt:r=this.#ext}=e,i=t.file(`${n}.${r}`);return await i.remove(),await t.ensureExists(),i};constructor(e,t,...n){this.#path=v(t,...n),this.#schema=e;let r=We(this.#path);this.#folderPath=r.folderPath,this.#name=r.name,this.#basename=r.basename,this.#ext=r.ext,this.#info=r}toString=()=>this.#path;toJSON=()=>({FluentFile:this.info});[d.custom]=()=>this.toJSON();path=()=>this.#path;folderPath=()=>this.#folderPath;name(e){return e===void 0?this.#name:(this.#name=e,this.#path=`${this.#folderPath}/${e}`,this)}basename(e){return e===void 0?this.#basename:(this.#basename=e,this.#name=e+this.#ext,this.#path=`${this.#folderPath}/${this.#name}`,this)}ext(e){return e===void 0?this.#ext:(this.#ext=e,this.#name=this.#basename+e,this.#path=`${this.#folderPath}/${this.#name}`,this)}schema=e=>new a(e,this.#path);get info(){return this.#info}relativePath=(e=X())=>{let t=this.#path;return t.startsWith(e.path)&&(t=t.slice(e.path.length),t.startsWith(`/`))?t.slice(1):t};file=(e,...t)=>new a(this.#schema,this.#folderPath,e,...t);folder=(...e)=>new Z(this.#folderPath,...e);stats=h.fromThrowable(async()=>{let e=await s(this.#path);if(!e.isFile())throw new A(this.#path,`FileWasNotFile`);return e},e=>e instanceof A?e:new A(this.#path,e));exists=async()=>(await this.stats()).isOk();ensureExists=()=>re(this.#path);chmod=h.fromThrowable(async e=>{await r(this.#path,e)},e=>new C(this.#path,e));copyTo=h.fromThrowable(async t=>{let n=null;try{n=await this.#ensureDestination(t),await i(this.#path,n,e.COPYFILE_FICLONE)}catch(e){throw new P(this.#path,n,e)}},e=>e);moveTo=h.fromThrowable(async(e,t)=>{let n=null;try{n=await this.#ensureDestination(e),await oe(this.#path,n,{overwrite:!0,dereference:t})}catch(e){throw new F(this.#path,n,e)}},e=>e);linkTo=h.fromThrowable(async e=>{let t=null;try{t=await this.#ensureDestination(e),await ie(this.#path,t)}catch(e){throw new I(this.#path,t,e)}},e=>e);symlinkTo=h.fromThrowable(async e=>{let t=null;try{t=await this.#ensureDestination(e),await ae(this.#path,t)}catch(e){throw new L(this.#path,t,e)}},e=>e);remove=h.fromThrowable(()=>m(this.#path),e=>new k(this.#path,e));readText=h.fromThrowable((e={})=>o(this.#path,{encoding:`utf8`,...e}),e=>new O(this.#path,e));readBuffer=h.fromThrowable((e={})=>o(this.#path,e),e=>new O(this.#path,e));read=(e={})=>this.readText(e).andThen(t=>de(t,this.#schema,{format:this.#path,...e}));createReadStream=e=>t(this.#path,e);writeText=h.fromThrowable((e,t={})=>p(this.#path,e,t),e=>new j(this.#path,e));writeBuffer=h.fromThrowable((e,t={})=>p(this.#path,e,t),e=>new j(this.#path,e));write=(e,t={})=>fe(e,this.#schema,t).andThen(e=>this.writeText(e,t));createWriteStream=e=>n(this.#path,e);append=h.fromThrowable((e,t={})=>ee(this.#path,e,t),e=>new S(this.#path,e));image=(e={})=>{let t=ce(this.#path,e),n=h.fromThrowable(()=>t.metadata(),e=>new T(this.#path,e)),r=h.fromThrowable(async e=>{let n=await this.#prepareTarget(e);return await t.resize(e).toFile(n.path()),n},e=>new D(this.#path,e)),i=h.fromThrowable(async(e={})=>{let n=await this.#prepareTarget({...e,newExt:`avif`});return await t.resize(e).avif(e).toFile(n.path()),n},e=>new w(this.#path,e)),a=h.fromThrowable(async()=>{let t=await le(this.#path,e);return B.decode(t)},e=>new E(this.#path,e));return{...t,metadata:n,resize:r,toAVIF:i,phash:a}};video=()=>({metadata:()=>Ne(this.#path),extractFrame:async(e={})=>{let{time:t=1,unit:n=`s`,ext:r=`png`,...i}=e,a=n===`s`?t:`${t}${n}`,o=await this.#prepareTarget({newExt:r,...i});return f(`ffmpeg`).opt(`hide_banner`).opt({ss:a,i:this.#path,"frames:v":1,y:``}).args(o.path()).read().map(()=>o)}});download=(e,t={})=>He(e,this,t)};function We(e){let t=g.basename(e),n=g.dirname(e),r=``,i=``,a=t.lastIndexOf(`.`);return a<=0?(r=t,i=``):(r=t.slice(0,a),i=t.slice(a+1)),{absolutePath:e,folderPath:n,name:t,basename:r,ext:i}}function $(e,...t){return new Ue(ue(),e,...t)}function Ge(e,...t){return $(c(),e,...t)}export{H as DEFAULT_PHASH_THRESHOLD,M as DESTINATION_FALLBACK,S as FileAppendError,C as FileChmodError,P as FileCopyError,x as FileDownloadError,w as FileImageConvertError,T as FileImageMetadataError,E as FileImagePhashError,D as FileImageResizeError,I as FileLinkError,F as FileMoveError,O as FileReadError,k as FileRemoveError,A as FileStatError,L as FileSymLinkError,j as FileWriteError,Ue as FluentFile,Z as FluentFolder,he as FsFlags,be as IMAGE_EXTENSIONS,ye as MAX_DIFFERENCES,Me as VIDEO_EXTENSIONS,z as binaryStringRegex,Ie as cacheFolder,Ce as comparePhashes,Le as configFolder,X as currentFolder,Re as dataFolder,$ as ffile,Q as folder,Ne as getVideoMetaData,Ge as homeFile,Be as homeFolder,ze as logsFolder,B as phashStringSchema,V as phashThresholdSchema,we as phashesMatch,Ve as tempFolder};
|