pubnub
Version:
Publish & Subscribe Real-time Messaging with PubNub
140 lines (108 loc) • 3.45 kB
JavaScript
/** @flow */
import { Readable, PassThrough } from 'stream';
import { ReadStream } from 'fs';
import { basename } from 'path';
import { IFile, FileClass } from '../';
type PubNubFileNodeConstructor = {|
stream?: Readable,
data?: string | Buffer,
encoding?: string,
name?: string,
mimeType?: string,
|};
type PubNubFileNodeSupportedInputType = Readable | Buffer | string;
const PubNubFile: FileClass = class PubNubFile implements IFile {
static supportsBlob = false;
static supportsFile = false;
static supportsBuffer = typeof Buffer !== 'undefined';
static supportsStream = true;
static supportsString = true;
static supportsArrayBuffer = false;
static supportsEncryptFile = true;
static supportsFileUri = false;
data: PubNubFileNodeSupportedInputType;
name: string;
mimeType: string;
static create(config: PubNubFileNodeConstructor) {
return new this(config);
}
constructor({ stream, data, encoding, name, mimeType }: PubNubFileNodeConstructor) {
if (stream instanceof Readable) {
this.data = stream;
if (stream instanceof ReadStream) {
// $FlowFixMe: incomplete flow node definitions
this.name = basename(stream.path);
}
} else if (data instanceof Buffer) {
this.data = Buffer.from(data);
} else if (typeof data === 'string') {
// $FlowFixMe: incomplete flow node definitions
this.data = Buffer.from(data, encoding ?? 'utf8');
}
if (name) {
this.name = basename(name);
}
if (mimeType) {
this.mimeType = mimeType;
}
if (this.data === undefined) {
throw new Error("Couldn't construct a file out of supplied options.");
}
if (this.name === undefined) {
throw new Error("Couldn't guess filename out of the options. Please provide one.");
}
}
toBuffer(): Promise<Buffer> {
if (this.data instanceof Buffer) {
return Promise.resolve(Buffer.from(this.data));
}
if (this.data instanceof Readable) {
const stream = this.data;
return new Promise((resolve, reject) => {
const chunks = [];
stream.on('data', (chunk) => chunks.push(chunk));
stream.once('error', reject);
stream.once('end', () => {
resolve(Buffer.concat(chunks));
});
});
}
if (typeof this.data === 'string') {
return Promise.resolve(Buffer.from(this.data));
}
throw new Error("Can't cast to 'buffer'.");
}
async toArrayBuffer() {
throw new Error('This feature is only supported in browser environments.');
}
async toString(encoding: buffer$NonBufferEncoding = 'utf8') {
const buffer = await this.toBuffer();
return buffer.toString(encoding);
}
async toStream() {
if (!(this.data instanceof Readable)) {
const input = this.data;
return new Readable({
read() {
this.push(Buffer.from(input));
this.push(null);
},
});
}
const stream = new PassThrough();
if (this.data instanceof Readable) {
this.data.pipe(stream);
}
return stream;
}
async toFile() {
throw new Error('This feature is only supported in browser environments.');
}
async toFileUri() {
throw new Error('This feature is only supported in react native environments.');
}
async toBlob() {
throw new Error('This feature is only supported in browser environments.');
}
};
export default PubNubFile;