UNPKG

rstify-ask

Version:

Restify is a comprehensive npm package that streamlines and enhances the handling of HTTP requests in JavaScript applications.

388 lines (327 loc) 13 kB
class Cancel { constructor(message) { this.message = message; } } class CancelToken { constructor(executor) { let cancel; this.promise = new Promise((resolve, reject) => { cancel = () => { reject(new Cancel('Operation canceled by the user.')); }; executor(cancel); }); this.throwIfRequested = () => { if (this.reason) { throw this.reason; } }; } static source() { let cancel; const token = new CancelToken((c) => { cancel = c; }); return { token, cancel }; } } class CanceledError extends Error { constructor(message) { super(message); this.name = 'CanceledError'; } } class RestifyError extends Error { constructor(message, config, code, request, response) { super(message); this.name = 'RestifyError'; this.config = config; this.code = code; this.request = request; this.response = response; } } class HttpStatusCode { static OK = 200; static CREATED = 201; static ACCEPTED = 202; static NO_CONTENT = 204; static MOVED_PERMANENTLY = 301; static FOUND = 302; static SEE_OTHER = 303; static NOT_MODIFIED = 304; static TEMPORARY_REDIRECT = 307; static PERMANENT_REDIRECT = 308; static BAD_REQUEST = 400; static UNAUTHORIZED = 401; static FORBIDDEN = 403; static NOT_FOUND = 404; static METHOD_NOT_ALLOWED = 405; static CONFLICT = 409; static GONE = 410; static PRECONDITION_FAILED = 412; static UNPROCESSABLE_ENTITY = 422; static INTERNAL_SERVER_ERROR = 500; static NOT_IMPLEMENTED = 501; static BAD_GATEWAY = 502; static SERVICE_UNAVAILABLE = 503; static GATEWAY_TIMEOUT = 504; } class RestifyHeaders { // Common headers static ACCEPT = 'Accept'; static ACCEPT_CHARSET = 'Accept-Charset'; static ACCEPT_ENCODING = 'Accept-Encoding'; static ACCEPT_LANGUAGE = 'Accept-Language'; static AUTHORIZATION = 'Authorization'; static CACHE_CONTROL = 'Cache-Control'; static CONTENT_TYPE = 'Content-Type'; static USER_AGENT = 'User-Agent'; // Content type headers static CONTENT_TYPE_JSON = 'application/json'; static CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded'; static CONTENT_TYPE_XML = 'application/xml'; static CONTENT_TYPE_TEXT = 'text/plain'; static CONTENT_TYPE_HTML = 'text/html'; static CONTENT_TYPE_MULTIPART = 'multipart/form-data'; // Caching headers static ETAG = 'ETag'; static IF_MATCH = 'If-Match'; static IF_NONE_MATCH = 'If-None-Match'; static IF_MODIFIED_SINCE = 'If-Modified-Since'; static IF_UNMODIFIED_SINCE = 'If-Unmodified-Since'; // Authentication headers static WWW_AUTHENTICATE = 'WWW-Authenticate'; // CORS headers static ACCESS_CONTROL_ALLOW_ORIGIN = 'Access-Control-Allow-Origin'; static ACCESS_CONTROL_ALLOW_METHODS = 'Access-Control-Allow-Methods'; static ACCESS_CONTROL_ALLOW_HEADERS = 'Access-Control-Allow-Headers'; static ACCESS_CONTROL_MAX_AGE = 'Access-Control-Max-Age'; static ACCESS_CONTROL_EXPOSE_HEADERS = 'Access-Control-Expose-Headers'; static ACCESS_CONTROL_ALLOW_CREDENTIALS = 'Access-Control-Allow-Credentials'; // Security headers static STRICT_TRANSPORT_SECURITY = 'Strict-Transport-Security'; static CONTENT_SECURITY_POLICY = 'Content-Security-Policy'; static X_CONTENT_TYPE_OPTIONS = 'X-Content-Type-Options'; static X_FRAME_OPTIONS = 'X-Frame-Options'; static X_XSS_PROTECTION = 'X-XSS-Protection'; // Cookies and session headers static SET_COOKIE = 'Set-Cookie'; static COOKIE = 'Cookie'; // Compression headers static CONTENT_ENCODING = 'Content-Encoding'; static CONTENT_DECODING = 'Content-Decoding'; // Custom headers static X_CUSTOM_HEADER = 'X-Custom-Header'; } function isCancel(value) { try { return value instanceof Cancel; } catch (error) { console.log(error) } } function isRestifyError(value) { try { return value instanceof RestifyError; } catch (error) { console.log(error) } } function spread(callback) { try { return function wrap(arr) { return callback.apply(null, arr); }; } catch (error) { console.log(error) } } function toFormData(obj) { try { const formData = new FormData(); for (const key in obj) { if (obj.hasOwnProperty(key)) { formData.append(key, obj[key]); } } return formData; } catch (error) { console.log(error) } } function formToJSON(formData) { try { const jsonObject = {}; formData?.forEach((value, key) => { // Check if the key already exists in the object if (jsonObject.hasOwnProperty(key)) { // If it's an array, push the new value if (!Array.isArray(jsonObject[key])) { jsonObject[key] = [jsonObject[key]]; } jsonObject[key].push(value); } else { // If the key doesn't exist, create a new key-value pair jsonObject[key] = value; } }); return JSON.stringify(jsonObject); } catch (error) { console.log(error); } } function getAdapter(config) { try { // If running in a browser environment if (typeof window !== 'undefined' && window.fetch) { return (resolve, reject) => { const { method, url, headers, data, cancelToken } = config; const options = { method, headers: { ...headers, 'Content-Type': 'application/json', }, body: JSON.stringify(data), }; if (cancelToken) { cancelToken.promise.then((reason) => { reject(reason); }); } fetch(url, options) .then((response) => { // Check if the response has a JSON content type const contentType = response.headers.get('content-type'); const isJsonResponse = contentType && contentType.includes('application/json'); return isJsonResponse ? response.json() // Parse JSON response : response.text(); // Otherwise, treat as text }) .then((responseData) => { // Resolve with parsed data resolve({ status: responseData.status || 200, data: responseData, }); }) .catch((error) => { // Enhance error logging console.error('Fetch error:', error); reject(error); }); }; } // If the environment is not recognized throw new Error('Restify does not support the current environment'); } catch (error) { console.log(error); } } function mergeConfig(config1, config2) { // Create a new object to hold the merged configuration const mergedConfig = Object.assign({}, config1); // Iterate through config2 and add or overwrite properties in mergedConfig for (const key in config2) { if (config2.hasOwnProperty(key)) { // Special handling for headers, merging them instead of overwriting if (key === 'headers' && config1.headers && typeof config1.headers === 'object') { mergedConfig.headers = Object.assign({}, config1.headers, config2.headers); } else if (key === 'params' && config1.params && typeof config1.params === 'object') { // Merge params instead of overwriting mergedConfig.params = Object.assign({}, config1.params, config2.params); } else { mergedConfig[key] = config2[key]; } } } return mergedConfig; } function restify(config) { try { return new Promise((resolve, reject) => { const adapter = getAdapter(config); const cancelToken = config.cancelToken; if (cancelToken) { cancelToken.promise.then((reason) => { reject(reason); }); } adapter(resolve, reject); }); } catch (error) { console.log(error) } } class Restify { static request(config) { return restify(config); } static get(url, config) { return restify(mergeConfig(config, { method: 'GET', url })); } static delete(url, config) { return restify(mergeConfig(config, { method: 'DELETE', url })); } static head(url, config) { return restify(mergeConfig(config, { method: 'HEAD', url })); } static options(url, config) { return restify(mergeConfig(config, { method: 'OPTIONS', url })); } static post(url, data, config) { return restify(mergeConfig(config, { method: 'POST', url, data })); } static put(url, data, config) { return restify(mergeConfig(config, { method: 'PUT', url, data })); } static patch(url, data, config) { return restify(mergeConfig(config, { method: 'PATCH', url, data })); } static postForm(url, data, config) { const formData = toFormData(data); return restify(mergeConfig(config, { method: 'POST', url, data: formData })); } static putForm(url, data, config) { const formData = toFormData(data); return restify(mergeConfig(config, { method: 'PUT', url, data: formData })); } static patchForm(url, data, config) { const formData = toFormData(data); return restify(mergeConfig(config, { method: 'PATCH', url, data: formData })); } // Added a new method to handle dynamic authorization static withAuthorization(authorizationToken) { return { get: (url, config = {}) => Restify.get(url, mergeConfig(config, { headers: { Authorization: authorizationToken } })), delete: (url, config = {}) => Restify.delete(url, mergeConfig(config, { headers: { Authorization: authorizationToken } })), head: (url, config = {}) => Restify.head(url, mergeConfig(config, { headers: { Authorization: authorizationToken } })), options: (url, config = {}) => Restify.options(url, mergeConfig(config, { headers: { Authorization: authorizationToken } })), post: (url, data, config = {}) => Restify.post(url, data, mergeConfig(config, { headers: { Authorization: authorizationToken } })), put: (url, data, config = {}) => Restify.put(url, data, mergeConfig(config, { headers: { Authorization: authorizationToken } })), patch: (url, data, config = {}) => Restify.patch(url, data, mergeConfig(config, { headers: { Authorization: authorizationToken } })), postForm: (url, data, config = {}) => Restify.postForm(url, data, mergeConfig(config, { headers: { Authorization: authorizationToken } })), putForm: (url, data, config = {}) => Restify.putForm(url, data, mergeConfig(config, { headers: { Authorization: authorizationToken } })), patchForm: (url, data, config = {}) => Restify.patchForm(url, data, mergeConfig(config, { headers: { Authorization: authorizationToken } })), }; } } // Exporting individual components restify.Cancel = Cancel; restify.CancelToken = CancelToken; restify.CanceledError = CanceledError; restify.RestifyError = RestifyError; restify.HttpStatusCode = HttpStatusCode; restify.RestifyHeaders = RestifyHeaders; restify.isCancel = isCancel; restify.isRestifyError = isRestifyError; restify.spread = spread; restify.toFormData = toFormData; restify.formToJSON = formToJSON; restify.getAdapter = getAdapter; restify.mergeConfig = mergeConfig; // Exporting individual components export default Restify; export { Cancel, CancelToken, CanceledError, RestifyError, HttpStatusCode, RestifyHeaders, isCancel, isRestifyError, spread, toFormData, getAdapter, mergeConfig, formToJSON };