@huggingface/transformers
Version:
State-of-the-art Machine Learning for the web. Run 🤗 Transformers directly in your browser, with no need for a server!
122 lines (109 loc) • 4.28 kB
JavaScript
import fs from 'node:fs';
/**
* Mapping from file extensions to MIME types.
*/
const CONTENT_TYPE_MAP = {
txt: 'text/plain',
html: 'text/html',
css: 'text/css',
js: 'text/javascript',
json: 'application/json',
png: 'image/png',
jpg: 'image/jpeg',
jpeg: 'image/jpeg',
gif: 'image/gif',
};
export class FileResponse {
/**
* Creates a new `FileResponse` object.
* @param {string} filePath
*/
constructor(filePath) {
this.filePath = filePath;
this.headers = new Headers();
this.exists = fs.existsSync(filePath);
if (this.exists) {
this.status = 200;
this.statusText = 'OK';
let stats = fs.statSync(filePath);
this.headers.set('content-length', stats.size.toString());
this.updateContentType();
const stream = fs.createReadStream(filePath);
this.body = new ReadableStream({
start(controller) {
stream.on('data', (chunk) => controller.enqueue(chunk));
stream.on('end', () => controller.close());
stream.on('error', (err) => controller.error(err));
},
cancel() {
stream.destroy();
},
});
} else {
this.status = 404;
this.statusText = 'Not Found';
this.body = null;
}
}
/**
* Updates the 'content-type' header property of the response based on the extension of
* the file specified by the filePath property of the current object.
* @returns {void}
*/
updateContentType() {
// Set content-type header based on file extension
const extension = this.filePath.toString().split('.').pop().toLowerCase();
this.headers.set('content-type', CONTENT_TYPE_MAP[extension] ?? 'application/octet-stream');
}
/**
* Clone the current FileResponse object.
* @returns {FileResponse} A new FileResponse object with the same properties as the current object.
*/
clone() {
let response = new FileResponse(this.filePath);
response.exists = this.exists;
response.status = this.status;
response.statusText = this.statusText;
response.headers = new Headers(this.headers);
return response;
}
/**
* Reads the contents of the file specified by the filePath property and returns a Promise that
* resolves with an ArrayBuffer containing the file's contents.
* @returns {Promise<ArrayBuffer>} A Promise that resolves with an ArrayBuffer containing the file's contents.
* @throws {Error} If the file cannot be read.
*/
async arrayBuffer() {
const data = await fs.promises.readFile(this.filePath);
return /** @type {ArrayBuffer} */ (data.buffer);
}
/**
* Reads the contents of the file specified by the filePath property and returns a Promise that
* resolves with a Blob containing the file's contents.
* @returns {Promise<Blob>} A Promise that resolves with a Blob containing the file's contents.
* @throws {Error} If the file cannot be read.
*/
async blob() {
const data = await fs.promises.readFile(this.filePath);
return new Blob([/** @type {any} */ (data)], { type: this.headers.get('content-type') });
}
/**
* Reads the contents of the file specified by the filePath property and returns a Promise that
* resolves with a string containing the file's contents.
* @returns {Promise<string>} A Promise that resolves with a string containing the file's contents.
* @throws {Error} If the file cannot be read.
*/
async text() {
return await fs.promises.readFile(this.filePath, 'utf8');
}
/**
* Reads the contents of the file specified by the filePath property and returns a Promise that
* resolves with a parsed JavaScript object containing the file's contents.
*
* @returns {Promise<Object>} A Promise that resolves with a parsed JavaScript object containing the file's contents.
* @throws {Error} If the file cannot be read.
*/
async json() {
return JSON.parse(await this.text());
}
}