fp/packages/utils/index.ts

65 lines
1.7 KiB
TypeScript

import * as slugify from 'slugify';
import { basename, join } from 'path';
import os from 'node:os';
import fs from 'node:fs';
import { createId } from '@paralleldrive/cuid2';
import { ua0 } from 'scout/ua.js';
import { Readable } from 'stream';
import { finished } from 'stream/promises';
import pRetry from 'p-retry';
export function fpSlugify(str: string): string {
return slugify(str, {
lower: true,
strict: true,
locale: 'en',
trim: true,
});
}
export function getTmpFile(str: string): string {
return join(os.tmpdir(), `${createId()}_${basename(str)}`);
}
/**
*
* @param {String} url
* @returns {String} filePath
*
* greetz https://stackoverflow.com/a/74722818/1004931
*/
export async function download({ url, filePath }: { url: string; filePath?: string }): Promise<string | null> {
if (!url) throw new Error(`second arg passed to download() must be a {string} url`);
const fileBaseName = basename(url);
filePath = filePath || join(os.tmpdir(), `${createId()}_${fileBaseName}`);
const stream = fs.createWriteStream(filePath);
const requestData = async () => {
const response = await fetch(url, {
headers: {
'user-agent': ua0,
},
});
const { body } = response;
await finished(Readable.fromWeb(body).pipe(stream));
// Abort retrying if the resource doesn't exist
if (response.status === 404) {
throw new AbortError(response.statusText);
}
return;
};
try {
await pRetry(requestData, { retries: 3 });
} catch (e) {
console.error(`utils.download failed to download ${url}`);
console.error(e);
return null;
}
return filePath;
}
export const tmpFileRegex = /^\/tmp\/.*\.jpg$/;