Comparing version 1.1.0 to 1.2.0
@@ -8,3 +8,4 @@ #!/usr/bin/env node | ||
import { truncateText } from "../utils/truncate-text.js"; | ||
import findDownloadDir from "./utils/find-download-dir.js"; | ||
import { FastDownload } from "../index.js"; | ||
import findDownloadDir, { downloadToDirectory } from "./utils/find-download-dir.js"; | ||
import { setCommand } from "./commands/set.js"; | ||
@@ -16,5 +17,6 @@ const pullCommand = new Command(); | ||
.argument("[files...]", "Files to pull/copy") | ||
.option("-s --save [path]", "Save directory") | ||
.option("-s --save [path]", "Save location (directory/file)") | ||
.option("-f --full-name", "Show full name of the file while downloading, even if it long") | ||
.action(async (files = [], { save, fullName }) => { | ||
let specificFileName = null; | ||
if (files.length === 0) { | ||
@@ -24,5 +26,15 @@ pullCommand.outputHelp(); | ||
} | ||
if (save && !await downloadToDirectory(save)) { | ||
specificFileName = path.basename(save); | ||
save = path.dirname(save); | ||
} | ||
const pullLogs = []; | ||
for (const file of files) { | ||
const fileName = path.basename(file); | ||
for (const [index, file] of Object.entries(files)) { | ||
let fileName = path.basename(file); | ||
if (specificFileName) { | ||
fileName = files.length > 1 ? specificFileName + index : specificFileName; | ||
} | ||
else if (file.startsWith("http")) { | ||
fileName = await FastDownload.fetchFilename(file); | ||
} | ||
const downloadTag = fullName ? fileName : truncateText(fileName); | ||
@@ -29,0 +41,0 @@ const downloadPath = path.join(save || await findDownloadDir(fileName), fileName); |
export default function findDownloadDir(fileName: string): Promise<string>; | ||
export declare function downloadToDirectory(path: string): Promise<boolean>; |
import path from "path"; | ||
import fs from "fs-extra"; | ||
import { getWithDefault } from "../../settings/settings.js"; | ||
@@ -9,2 +10,11 @@ const DEFAULT_DOWNLOAD_DIR = process.cwd(); | ||
} | ||
export async function downloadToDirectory(path) { | ||
try { | ||
const stats = await fs.lstat(path); | ||
return stats.isDirectory(); | ||
} | ||
catch { | ||
return false; | ||
} | ||
} | ||
//# sourceMappingURL=find-download-dir.js.map |
@@ -11,5 +11,10 @@ import TurboDownloader from "turbo-downloader"; | ||
init(): Promise<void>; | ||
private _getRedirectedURL; | ||
private _fetchFileInfo; | ||
progress(callback: (progressBytes: number, totalBytes: number) => void): Promise<void>; | ||
private static get _TurboDownloaderClass(); | ||
/** | ||
* Fetches filename from `content-disposition` header. If it's not present, extract it from the `pathname` of the url | ||
* @param {string} url | ||
*/ | ||
static fetchFilename(url: string): Promise<string>; | ||
} |
import TurboDownloader from "turbo-downloader"; | ||
import wretch from "wretch"; | ||
import fs from "fs-extra"; | ||
import contentDisposition from "content-disposition"; | ||
const DEFAULT_FILE_NAME = "file"; | ||
export default class FastDownload { | ||
@@ -16,5 +18,6 @@ _url; | ||
async init() { | ||
await this._fetchFileInfo(); | ||
await fs.ensureFile(this._savePath); | ||
this._downloader = new FastDownload._TurboDownloaderClass({ | ||
url: await this._getRedirectedURL(), | ||
url: this._redirectedURL, | ||
destFile: this._savePath, | ||
@@ -27,3 +30,3 @@ chunkSize: 50 * 1024 * 1024, | ||
} | ||
async _getRedirectedURL() { | ||
async _fetchFileInfo() { | ||
const { url } = await wretch(this._url) | ||
@@ -35,3 +38,3 @@ .head() | ||
}); | ||
return this._redirectedURL = url; | ||
this._redirectedURL = url; | ||
} | ||
@@ -48,3 +51,21 @@ async progress(callback) { | ||
} | ||
/** | ||
* Fetches filename from `content-disposition` header. If it's not present, extract it from the `pathname` of the url | ||
* @param {string} url | ||
*/ | ||
static async fetchFilename(url) { | ||
const contentDispositionHeader = await wretch(url) | ||
.head() | ||
.res(response => response.headers.get("content-disposition")) | ||
.catch(error => { | ||
throw new Error(`Error while getting file head: ${error.status}`); | ||
}); | ||
const parsed = new URL(url); | ||
const defaultFilename = decodeURIComponent(parsed.pathname.split("/").pop() ?? DEFAULT_FILE_NAME); | ||
if (!contentDispositionHeader) | ||
return defaultFilename; | ||
const { parameters } = contentDisposition.parse(contentDispositionHeader); | ||
return parameters.filename ?? defaultFilename; | ||
} | ||
} | ||
//# sourceMappingURL=fast-download.js.map |
{ | ||
"name": "ipull", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "Super fast cli file downloader", | ||
@@ -63,2 +63,3 @@ "main": "dist/index.js", | ||
"@types/cli-progress": "^3.11.0", | ||
"@types/content-disposition": "^0.5.8", | ||
"@types/fs-extra": "^11.0.1", | ||
@@ -84,2 +85,3 @@ "@types/node": "^20.4.9", | ||
"commander": "^10.0.0", | ||
"content-disposition": "^0.5.4", | ||
"execa": "^7.2.0", | ||
@@ -86,0 +88,0 @@ "fs-extra": "^11.1.1", |
@@ -40,3 +40,3 @@ <div align="center"> | ||
-V, --version output the version number | ||
-s --save [path] Save directory | ||
-s --save [path] Save location (directory/file) | ||
-f --full-name Show full name of the file while downloading, even if it long | ||
@@ -86,9 +86,9 @@ -h, --help display help for command | ||
class FastDownload implements IStreamProgress { | ||
constructor(url: string, savePath: string, options?: TurboDownloaderOptions) { | ||
} | ||
constructor(url: string, savePath: string, options?: TurboDownloaderOptions); | ||
static async fetchFilename(url: string); | ||
} | ||
class CopyProgress implements IStreamProgress { | ||
constructor(fromPath: string, toPath: string) { | ||
} | ||
constructor(fromPath: string, toPath: string); | ||
} | ||
@@ -95,0 +95,0 @@ ``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
38557
443
12
20
4
+ Addedcontent-disposition@^0.5.4
+ Added@types/node@22.9.1(transitive)
+ Addedcontent-disposition@0.5.4(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedundici-types@6.19.8(transitive)
- Removed@types/node@22.10.0(transitive)
- Removedundici-types@6.20.0(transitive)