Skip to main content
Glama
request.js10.2 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; import { each, find } from './utils'; import Config from './config'; import { Compression } from './types'; import { formDataToQuery } from './utils/request-utils'; import { logger } from './utils/logger'; import { AbortController, fetch, navigator, XMLHttpRequest } from './utils/globals'; import { gzipSync, strToU8 } from 'fflate'; import { _base64Encode } from './utils/encode-utils'; // eslint-disable-next-line compat/compat export var SUPPORTS_REQUEST = !!XMLHttpRequest || !!fetch; var CONTENT_TYPE_PLAIN = 'text/plain'; var CONTENT_TYPE_JSON = 'application/json'; var CONTENT_TYPE_FORM = 'application/x-www-form-urlencoded'; var SIXTY_FOUR_KILOBYTES = 64 * 1024; /* fetch will fail if we request keepalive with a body greater than 64kb sets the threshold lower than that so that any overhead doesn't push over the threshold after checking here */ var KEEP_ALIVE_THRESHOLD = SIXTY_FOUR_KILOBYTES * 0.8; export var extendURLParams = function (url, params) { var _a = __read(url.split('?'), 2), baseUrl = _a[0], search = _a[1]; var newParams = __assign({}, params); search === null || search === void 0 ? void 0 : search.split('&').forEach(function (pair) { var _a = __read(pair.split('='), 1), key = _a[0]; delete newParams[key]; }); var newSearch = formDataToQuery(newParams); newSearch = newSearch ? (search ? search + '&' : '') + newSearch : search; return "".concat(baseUrl, "?").concat(newSearch); }; export var jsonStringify = function (data, space) { // With plain JSON.stringify, we get an exception when a property is a BigInt. This has caused problems for some users, // see https://github.com/PostHog/posthog-js/issues/1440 // To work around this, we convert BigInts to strings before stringifying the data. This is not ideal, as we lose // information that this was originally a number, but given ClickHouse doesn't support BigInts, the customer // would not be able to operate on these numerically anyway. return JSON.stringify(data, function (_, value) { return (typeof value === 'bigint' ? value.toString() : value); }, space); }; var encodeToDataString = function (data) { return 'data=' + encodeURIComponent(typeof data === 'string' ? data : jsonStringify(data)); }; var encodePostData = function (_a) { var data = _a.data, compression = _a.compression; if (!data) { return; } if (compression === Compression.GZipJS) { var gzipData = gzipSync(strToU8(jsonStringify(data)), { mtime: 0 }); var blob = new Blob([gzipData], { type: CONTENT_TYPE_PLAIN }); return { contentType: CONTENT_TYPE_PLAIN, body: blob, estimatedSize: blob.size, }; } if (compression === Compression.Base64) { var b64data = _base64Encode(jsonStringify(data)); var encodedBody = encodeToDataString(b64data); return { contentType: CONTENT_TYPE_FORM, body: encodedBody, estimatedSize: new Blob([encodedBody]).size, }; } var jsonBody = jsonStringify(data); return { contentType: CONTENT_TYPE_JSON, body: jsonBody, estimatedSize: new Blob([jsonBody]).size, }; }; var xhr = function (options) { var _a; var req = new XMLHttpRequest(); req.open(options.method || 'GET', options.url, true); var _b = (_a = encodePostData(options)) !== null && _a !== void 0 ? _a : {}, contentType = _b.contentType, body = _b.body; each(options.headers, function (headerValue, headerName) { req.setRequestHeader(headerName, headerValue); }); if (contentType) { req.setRequestHeader('Content-Type', contentType); } if (options.timeout) { req.timeout = options.timeout; } // send the ph_optout cookie // withCredentials cannot be modified until after calling .open on Android and Mobile Safari req.withCredentials = true; req.onreadystatechange = function () { var _a; // XMLHttpRequest.DONE == 4, except in safari 4 if (req.readyState === 4) { var response = { statusCode: req.status, text: req.responseText, }; if (req.status === 200) { try { response.json = JSON.parse(req.responseText); } catch (_b) { // logger.error(e) } } (_a = options.callback) === null || _a === void 0 ? void 0 : _a.call(options, response); } }; req.send(body); }; var _fetch = function (options) { var _a; var _b = (_a = encodePostData(options)) !== null && _a !== void 0 ? _a : {}, contentType = _b.contentType, body = _b.body, estimatedSize = _b.estimatedSize; // eslint-disable-next-line compat/compat var headers = new Headers(); each(options.headers, function (headerValue, headerName) { headers.append(headerName, headerValue); }); if (contentType) { headers.append('Content-Type', contentType); } var url = options.url; var aborter = null; if (AbortController) { var controller_1 = new AbortController(); aborter = { signal: controller_1.signal, timeout: setTimeout(function () { return controller_1.abort(); }, options.timeout), }; } fetch(url, __assign({ method: (options === null || options === void 0 ? void 0 : options.method) || 'GET', headers: headers, // if body is greater than 64kb, then fetch with keepalive will error // see 8:10:5 at https://fetch.spec.whatwg.org/#http-network-or-cache-fetch, // but we do want to set keepalive sometimes as it can help with success // when e.g. a page is being closed // so let's get the best of both worlds and only set keepalive for POST requests // where the body is less than 64kb // NB this is fetch keepalive and not http keepalive keepalive: options.method === 'POST' && (estimatedSize || 0) < KEEP_ALIVE_THRESHOLD, body: body, signal: aborter === null || aborter === void 0 ? void 0 : aborter.signal }, options.fetchOptions)) .then(function (response) { return response.text().then(function (responseText) { var _a; var res = { statusCode: response.status, text: responseText, }; if (response.status === 200) { try { res.json = JSON.parse(responseText); } catch (e) { logger.error(e); } } (_a = options.callback) === null || _a === void 0 ? void 0 : _a.call(options, res); }); }) .catch(function (error) { var _a; logger.error(error); (_a = options.callback) === null || _a === void 0 ? void 0 : _a.call(options, { statusCode: 0, text: error }); }) .finally(function () { return (aborter ? clearTimeout(aborter.timeout) : null); }); return; }; var _sendBeacon = function (options) { // beacon documentation https://w3c.github.io/beacon/ // beacons format the message and use the type property var _a; var url = extendURLParams(options.url, { beacon: '1', }); try { var _b = (_a = encodePostData(options)) !== null && _a !== void 0 ? _a : {}, contentType = _b.contentType, body = _b.body; // sendBeacon requires a blob so we convert it var sendBeaconBody = typeof body === 'string' ? new Blob([body], { type: contentType }) : body; navigator.sendBeacon(url, sendBeaconBody); } catch (_c) { // send beacon is a best-effort, fire-and-forget mechanism on page unload, // we don't want to throw errors here } }; var AVAILABLE_TRANSPORTS = []; // We add the transports in order of preference if (fetch) { AVAILABLE_TRANSPORTS.push({ transport: 'fetch', method: _fetch, }); } if (XMLHttpRequest) { AVAILABLE_TRANSPORTS.push({ transport: 'XHR', method: xhr, }); } if (navigator === null || navigator === void 0 ? void 0 : navigator.sendBeacon) { AVAILABLE_TRANSPORTS.push({ transport: 'sendBeacon', method: _sendBeacon, }); } // This is the entrypoint. It takes care of sanitizing the options and then calls the appropriate request method. export var request = function (_options) { var _a, _b, _c; // Clone the options so we don't modify the original object var options = __assign({}, _options); options.timeout = options.timeout || 60000; options.url = extendURLParams(options.url, { _: new Date().getTime().toString(), ver: Config.LIB_VERSION, compression: options.compression, }); var transport = (_a = options.transport) !== null && _a !== void 0 ? _a : 'fetch'; var transportMethod = (_c = (_b = find(AVAILABLE_TRANSPORTS, function (t) { return t.transport === transport; })) === null || _b === void 0 ? void 0 : _b.method) !== null && _c !== void 0 ? _c : AVAILABLE_TRANSPORTS[0].method; if (!transportMethod) { throw new Error('No available transport method'); } transportMethod(options); }; //# sourceMappingURL=request.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sadiuysal/mem0-mcp-server-ts'

If you have feedback or need assistance with the MCP directory API, please join our Discord server