Skip to main content
Glama

Convex MCP server

Official
by get-convex
headers.ts9.42 kB
import { query } from "../_generated/server.js"; import { assert } from "chai"; import { wrapInTests } from "./testHelpers"; /** * The goal of this test is to run our V8 implementation of Headers * and assert that it behaves as expected. * * The test cases were pulled from Deno and the goal is to either pass the test * case or throw an error with an appropriate error message for the things * we're intentionally skipping implementing. * https://github.com/denoland/deno/blob/10e4b2e14046b74469f7310c599579a6611513fe/cli/tests/unit/url_test.ts * * Known limitations: * - We are not validating header values * - We are not handling header guards (https://fetch.spec.whatwg.org/#headers-class) * - We are not properly throwing TypeError when given an incorrect number or arguments * - We are not guaranteed that `Headers.name` === "Headers" */ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // function headersHasCorrectNameProp() { // assertEquals(Headers.name, "Headers"); // } // Logic heavily copied from web-platform-tests, make // sure pass mostly header basic test // ref: https://github.com/web-platform-tests/wpt/blob/7c50c216081d6ea3c9afe553ee7b64534020a1b2/fetch/api/headers/headers-basic.html function newHeaderTest() { new Headers(); new Headers(undefined); new Headers({}); try { new Headers(null as any); } catch (e) { assert(e instanceof TypeError, "e instanceof TypeError"); } } const headerDict: Record<string, string> = { name1: "value1", name2: "value2", name3: "value3", name4: undefined as any, "Content-Type": "value4", }; const headerSeq: any[] = []; for (const name in headerDict) { headerSeq.push([name, headerDict[name]]); } function newHeaderWithSequence() { const headers = new Headers(headerSeq); for (const name in headerDict) { assert.strictEqual(headers.get(name), String(headerDict[name])); } assert.strictEqual(headers.get("length"), null); } function newHeaderWithRecord() { const headers = new Headers(headerDict); for (const name in headerDict) { assert.strictEqual(headers.get(name), String(headerDict[name])); } } function newHeaderWithHeadersInstance() { const headers = new Headers(headerDict); const headers2 = new Headers(headers); for (const name in headerDict) { assert.strictEqual(headers2.get(name), String(headerDict[name])); } } function headerAppendSuccess() { const headers = new Headers(); for (const name in headerDict) { headers.append(name, headerDict[name]); assert.strictEqual(headers.get(name), String(headerDict[name])); } } function headerSetSuccess() { const headers = new Headers(); for (const name in headerDict) { headers.set(name, headerDict[name]); assert.strictEqual(headers.get(name), String(headerDict[name])); } } function headerHasSuccess() { const headers = new Headers(headerDict); for (const name in headerDict) { assert(headers.has(name), "headers has name " + name); assert( !headers.has("nameNotInHeaders"), "headers do not have header: nameNotInHeaders", ); } } function headerDeleteSuccess() { const headers = new Headers(headerDict); for (const name in headerDict) { assert(headers.has(name), "headers have a header: " + name); headers.delete(name); assert(!headers.has(name), "headers do not have anymore a header: " + name); } } function headerGetSuccess() { const headers = new Headers(headerDict); for (const name in headerDict) { assert.strictEqual(headers.get(name), String(headerDict[name])); assert.strictEqual(headers.get("nameNotInHeaders"), null); } } function headerEntriesSuccess() { const headers = new Headers(headerDict); // @ts-expect-error lib.dom typings disagree with headers being iterable const iterators = headers.entries(); for (const it of iterators) { const key = it[0]; const value = it[1]; assert(headers.has(key), "headers.has(key)"); assert.strictEqual(value, headers.get(key)); } } function headerKeysSuccess() { const headers = new Headers(headerDict); // @ts-expect-error lib.dom typings disagree with headers being iterable const iterators = headers.keys(); for (const it of iterators) { assert(headers.has(it), "headers.has(it))"); } } function headerValuesSuccess() { const headers = new Headers(headerDict); // @ts-expect-error lib.dom typings disagree with headers being iterable const iterators = headers.values(); // @ts-expect-error lib.dom typings disagree with headers being iterable const entries = headers.entries(); const values = []; for (const pair of entries) { values.push(pair[1]); } for (const it of iterators) { assert.include(values, it); } } function headerForEachSuccess() { const headerEntriesDict: Record<string, string> = { name1: "value1", Name2: "value2", name: "value3", "content-Type": "value4", "Content-Typ": "value5", "Content-Types": "value6", }; const headers = new Headers(headerEntriesDict); const keys = Object.keys(headerEntriesDict); keys.forEach((key) => { const value = headerEntriesDict[key]; const newkey = key.toLowerCase(); headerEntriesDict[newkey] = value; }); let callNum = 0; headers.forEach((value, key, container) => { assert.strictEqual(headers, container); assert.strictEqual(value, headerEntriesDict[key]); callNum++; }); assert(callNum === keys.length, "callNum === keys.length"); } function headerSymbolIteratorSuccess() { const headerEntriesDict: Record<string, string> = { name1: "value1", Name2: "value2", name: "value3", "content-Type": "value4", "Content-Typ": "value5", "Content-Types": "value6", }; assert( Symbol.iterator in Headers.prototype, "Symbol.iterator in Headers.prototype", ); const headers = new Headers(headerEntriesDict); // @ts-expect-error lib.dom typings disagree with headers being iterable for (const header of headers) { const key = header[0]; const value = header[1]; assert(headers.has(key), "headers.has(key)"); assert.strictEqual(value, headers.get(key)); } } function headerTypesAvailable() { function newHeaders(): Headers { return new Headers(); } const headers = newHeaders(); assert(headers instanceof Headers, "headers instanceof Headers"); } // Modified from https://github.com/bitinn/node-fetch/blob/7d3293200a91ad52b5ca7962f9d6fd1c04983edb/test/test.js#L2001-L2014 // Copyright (c) 2016 David Frank. MIT License. function headerIllegalReject() { assert.throws(() => new Headers({ "He y": "ok" })); assert.throws(() => new Headers({ "Hé-y": "ok" })); // TODO: validate header values // try { // new Headers({ "He-y": "ăk" }); // } catch (_e) { // errorCount++; // } const headers = new Headers(); assert.throws(() => headers.append("Hé-y", "ok")); assert.throws(() => headers.delete("Hé-y")); assert.throws(() => headers.get("Hé-y")); assert.throws(() => headers.has("Hé-y")); assert.throws(() => headers.set("Hé-y", "ok")); assert.throws(() => headers.set("", "ok")); // 'o k' is valid value but invalid name assert.doesNotThrow(() => new Headers({ "He-y": "o k" })); } // If pair does not contain exactly two items,then throw a TypeError. function headerParamsShouldThrowTypeError() { assert.throws(() => new Headers([["1"]] as any), TypeError); } function toStringShouldBeWebCompatibility() { const headers = new Headers(); assert.strictEqual(headers.toString(), "[object Headers]"); } function headerGetSetCookieSuccess() { const headers = new Headers(); // @ts-expect-error lib.dom typings disagree with headers being iterable (bc our typescript is old) assert.deepEqual(headers.getSetCookie(), []); headers.append("set-cookie", "name1=value1"); // @ts-expect-error lib.dom typings disagree with headers being iterable (bc our typescript is old) assert.deepEqual(headers.getSetCookie(), ["name1=value1"]); headers.append("set-cookie", "name2=value2"); // @ts-expect-error lib.dom typings disagree with headers being iterable (bc our typescript is old) assert.deepEqual(headers.getSetCookie(), ["name1=value1", "name2=value2"]); } // function invalidHeadersFlaky() { // assertThrows( // () => new Headers([["x", "\u0000x"]]), // TypeError, // "Header value is not valid." // ); // assertThrows( // () => new Headers([["x", "\u0000x"]]), // TypeError, // "Header value is not valid." // ); // } export default query(async () => { return await wrapInTests({ newHeaderTest, newHeaderWithSequence, newHeaderWithRecord, newHeaderWithHeadersInstance, headerAppendSuccess, headerSetSuccess, headerHasSuccess, headerDeleteSuccess, headerGetSuccess, headerEntriesSuccess, headerKeysSuccess, headerValuesSuccess, headerForEachSuccess, headerSymbolIteratorSuccess, headerTypesAvailable, headerIllegalReject, headerParamsShouldThrowTypeError, // TODO: argument length validation // headerParamsArgumentsCheck, toStringShouldBeWebCompatibility, headerGetSetCookieSuccess, // TODO: our bundler sometimes changes the class name, which we could // configure differently // headersHasCorrectNameProp, // TODO: validate header values // invalidHeadersFlaky, }); });

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/get-convex/convex-backend'

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