UNPKG

getstream

Version:

The official low-level GetStream.io client for Node.js and the browser.

121 lines (98 loc) 3 kB
import FormData from 'form-data'; import { FeedError } from './errors'; const validFeedSlugRe = /^[\w]+$/; const validUserIdRe = /^[\w-]+$/; /* * Validate that the feedSlug matches \w */ function validateFeedSlug(feedSlug: string) { if (!validFeedSlugRe.test(feedSlug)) { throw new FeedError(`Invalid feedSlug, please use letters, numbers or _: ${feedSlug}`); } return feedSlug; } /* * Validate the userId matches \w */ function validateUserId(userId: string) { if (!validUserIdRe.test(userId)) { throw new FeedError(`Invalid userId, please use letters, numbers, - or _: ${userId}`); } return userId; } function rfc3986(str: string) { return str.replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`); } function isReadableStream(obj: unknown): obj is NodeJS.ReadStream { return ( obj !== null && typeof obj === 'object' && ((obj as NodeJS.ReadStream).readable || typeof (obj as NodeJS.ReadStream)._read === 'function') ); } function isBuffer(obj: unknown): obj is Buffer { return ( obj != null && (obj as Buffer).constructor != null && // @ts-expect-error typeof obj.constructor.isBuffer === 'function' && // @ts-expect-error obj.constructor.isBuffer(obj) ); } function isFileWebAPI(uri: unknown): uri is File { return typeof window !== 'undefined' && 'File' in window && uri instanceof File; } /* * Validate that the feedId matches the spec user:1 */ function validateFeedId(feedId: string) { const parts = feedId.split(':'); if (parts.length !== 2) { throw new FeedError(`Invalid feedId, expected something like user:1 got ${feedId}`); } const [feedSlug, userId] = parts; validateFeedSlug(feedSlug); validateUserId(userId); return feedId; } function addFileToFormData(uri: string | File | Buffer | NodeJS.ReadStream, name?: string, contentType?: string) { const data = new FormData(); if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri)) { if (name) data.append('file', uri, name); else data.append('file', uri); } else { data.append('file', { uri, name: name || (uri as string).split('/').reverse()[0], type: contentType || undefined, contentType: contentType || undefined, }); } return data; } // TODO: refactor and add proper types function replaceStreamObjects<T, V>(obj: T): V { // @ts-expect-error if (Array.isArray(obj)) return obj.map((v) => replaceStreamObjects(v)); // @ts-expect-error if (Object.prototype.toString.call(obj) !== '[object Object]') return obj; // @ts-expect-error if (typeof obj.ref === 'function') return obj.ref(); const cloned = {}; Object.getOwnPropertyNames(obj).forEach((k) => { // @ts-expect-error cloned[k] = replaceStreamObjects(obj[k]); }); // @ts-expect-error return cloned; } export default { validateFeedId, validateFeedSlug, validateUserId, rfc3986, isReadableStream, addFileToFormData, replaceStreamObjects, };