Skip to main content
Glama

Convex MCP server

Official
by get-convex
url.ts21.2 kB
/* eslint-disable no-self-assign */ import { query } from "../_generated/server"; import { assert } from "chai"; import { wrapInTests } from "./testHelpers"; /** * The goal of this test is to run our V8 implementation of URL and URLSearchParams * 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: * - setting username/password in a URL is unsupported (CX-3088) * - setting the host is unsupported (CX-3090) */ function urlParsing() { const url = new URL("https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat"); assert.strictEqual(url.hash, "#qat"); assert.strictEqual(url.host, "baz.qat:8000"); assert.strictEqual(url.hostname, "baz.qat"); assert.strictEqual( url.href, "https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat", ); assert.strictEqual(url.origin, "https://baz.qat:8000"); assert.strictEqual(url.pathname, "/qux/quux"); assert.strictEqual(url.port, "8000"); assert.strictEqual(url.protocol, "https:"); assert.strictEqual(url.search, "?foo=bar&baz=12"); assert.deepEqual(url.searchParams.getAll("foo"), ["bar"]); assert.deepEqual(url.searchParams.getAll("baz"), ["12"]); assert.strictEqual( String(url), "https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat", ); } function urlProtocolParsing() { assert.strictEqual(new URL("http://foo").protocol, "http:"); assert.strictEqual(new URL("https://foo").protocol, "https:"); assert.throws(() => new URL("1://foo"), TypeError, "Invalid URL: '1://foo'"); assert.throws(() => new URL("+://foo"), TypeError, "Invalid URL: '+://foo'"); assert.throws(() => new URL("-://foo"), TypeError, "Invalid URL: '-://foo'"); assert.throws(() => new URL(".://foo"), TypeError, "Invalid URL: '.://foo'"); assert.throws(() => new URL("_://foo"), TypeError, "Invalid URL: '_://foo'"); assert.throws(() => new URL("=://foo"), TypeError, "Invalid URL: '=://foo'"); assert.throws(() => new URL("!://foo"), TypeError, "Invalid URL: '!://foo'"); assert.throws(() => new URL(`"://foo`), TypeError, `Invalid URL: '"://foo'`); assert.throws(() => new URL("$://foo"), TypeError, "Invalid URL: '$://foo'"); assert.throws(() => new URL("%://foo"), TypeError, "Invalid URL: '%://foo'"); assert.throws(() => new URL("^://foo"), TypeError, "Invalid URL: '^://foo'"); assert.throws(() => new URL("*://foo"), TypeError, "Invalid URL: '*://foo'"); assert.throws(() => new URL("*://foo"), TypeError, "Invalid URL: '*://foo'"); } function urlAuthenticationParsing() { const specialUrl = new URL("http://foo:bar@baz"); assert.strictEqual(specialUrl.username, "foo"); assert.strictEqual(specialUrl.password, "bar"); assert.strictEqual(specialUrl.hostname, "baz"); assert.throws(() => new URL("file://foo:bar@baz"), TypeError, "Invalid URL"); const nonSpecialUrl = new URL("abcd://foo:bar@baz"); assert.strictEqual(nonSpecialUrl.username, "foo"); assert.strictEqual(nonSpecialUrl.password, "bar"); assert.strictEqual(nonSpecialUrl.hostname, "baz"); } function urlHostnameParsing() { // IPv6. assert.strictEqual(new URL("http://[::1]").hostname, "[::1]"); assert.strictEqual(new URL("file://[::1]").hostname, "[::1]"); assert.strictEqual(new URL("abcd://[::1]").hostname, "[::1]"); assert.strictEqual( new URL("http://[0:f:0:0:f:f:0:0]").hostname, "[0:f::f:f:0:0]", ); // Forbidden host code point. assert.throws(() => new URL("http:// a"), TypeError, "Invalid URL"); assert.throws(() => new URL("file:// a"), TypeError, "Invalid URL"); assert.throws(() => new URL("abcd:// a"), TypeError, "Invalid URL"); assert.throws(() => new URL("http://%"), TypeError, "Invalid URL"); assert.throws(() => new URL("file://%"), TypeError, "Invalid URL"); assert.strictEqual(new URL("abcd://%").hostname, "%"); // Percent-decode. assert.strictEqual(new URL("http://%21").hostname, "!"); assert.strictEqual(new URL("file://%21").hostname, "!"); assert.strictEqual(new URL("abcd://%21").hostname, "%21"); // IPv4 parsing. assert.strictEqual(new URL("http://260").hostname, "0.0.1.4"); assert.strictEqual(new URL("file://260").hostname, "0.0.1.4"); assert.strictEqual(new URL("abcd://260").hostname, "260"); assert.strictEqual(new URL("http://255.0.0.0").hostname, "255.0.0.0"); assert.throws(() => new URL("http://256.0.0.0"), TypeError, "Invalid URL"); assert.strictEqual(new URL("http://0.255.0.0").hostname, "0.255.0.0"); assert.throws(() => new URL("http://0.256.0.0"), TypeError, "Invalid URL"); assert.strictEqual(new URL("http://0.0.255.0").hostname, "0.0.255.0"); assert.throws(() => new URL("http://0.0.256.0"), TypeError, "Invalid URL"); assert.strictEqual(new URL("http://0.0.0.255").hostname, "0.0.0.255"); assert.throws(() => new URL("http://0.0.0.256"), TypeError, "Invalid URL"); assert.strictEqual(new URL("http://0.0.65535").hostname, "0.0.255.255"); assert.throws(() => new URL("http://0.0.65536"), TypeError, "Invalid URL"); assert.strictEqual(new URL("http://0.16777215").hostname, "0.255.255.255"); assert.throws(() => new URL("http://0.16777216"), TypeError, "Invalid URL"); assert.strictEqual(new URL("http://4294967295").hostname, "255.255.255.255"); assert.throws(() => new URL("http://4294967296"), TypeError, "Invalid URL"); } function urlPortParsing() { const specialUrl = new URL("http://foo:8000"); assert.strictEqual(specialUrl.hostname, "foo"); assert.strictEqual(specialUrl.port, "8000"); assert.throws(() => new URL("file://foo:8000"), TypeError, "Invalid URL"); const nonSpecialUrl = new URL("abcd://foo:8000"); assert.strictEqual(nonSpecialUrl.hostname, "foo"); assert.strictEqual(nonSpecialUrl.port, "8000"); } function urlModifications() { const url = new URL("https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat"); url.hash = ""; assert.strictEqual(url.href, "https://baz.qat:8000/qux/quux?foo=bar&baz=12"); // Set host not implemented // url.host = "qat.baz:8080"; // assert.strictEqual(url.href, "https://qat.baz:8080/qux/quux?foo=bar&baz=12"); url.hostname = "foo.bar"; assert.strictEqual(url.href, "https://foo.bar:8000/qux/quux?foo=bar&baz=12"); // setting password / username unsupported // url.password = "qux"; // assert.strictEqual( // url.href, // "https://foo:qux@foo.bar:8080/qux/quux?foo=bar&baz=12" // ); url.pathname = "/foo/bar%qat"; assert.strictEqual( url.href, "https://foo.bar:8000/foo/bar%qat?foo=bar&baz=12", ); url.port = ""; assert.strictEqual(url.href, "https://foo.bar/foo/bar%qat?foo=bar&baz=12"); url.protocol = "http:"; assert.strictEqual(url.href, "http://foo.bar/foo/bar%qat?foo=bar&baz=12"); url.search = "?foo=bar&foo=baz"; assert.strictEqual(url.href, "http://foo.bar/foo/bar%qat?foo=bar&foo=baz"); assert.deepEqual(url.searchParams.getAll("foo"), ["bar", "baz"]); // setting password / username unsupported // url.username = "foo@bar"; // assert.strictEqual( // url.href, // "http://foo%40bar:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz" // ); url.searchParams.set("bar", "qat"); assert.strictEqual( url.href, "http://foo.bar/foo/bar%qat?foo=bar&foo=baz&bar=qat", ); url.searchParams.delete("foo"); assert.strictEqual(url.href, "http://foo.bar/foo/bar%qat?bar=qat"); url.searchParams.append("foo", "bar"); assert.strictEqual(url.href, "http://foo.bar/foo/bar%qat?bar=qat&foo=bar"); } function urlModifyHref() { const url = new URL("http://example.com/"); url.href = "https://foo:bar@example.com:8080/baz/qat#qux"; assert.strictEqual(url.protocol, "https:"); assert.strictEqual(url.username, "foo"); assert.strictEqual(url.password, "bar"); assert.strictEqual(url.host, "example.com:8080"); assert.strictEqual(url.hostname, "example.com"); assert.strictEqual(url.pathname, "/baz/qat"); assert.strictEqual(url.hash, "#qux"); } function urlModifyHrefErroring() { const url = new URL("http://example.com/"); assert.throws( () => (url.href = "foo"), /^Could not parse URL: http:\/\/example.com\/$/, ); } function urlNormalize() { const url = new URL("http://example.com"); assert.strictEqual(url.pathname, "/"); assert.strictEqual(url.href, "http://example.com/"); } function urlModifyPathname() { const url = new URL("http://foo.bar/baz%qat/qux%quux"); assert.strictEqual(url.pathname, "/baz%qat/qux%quux"); // Self-assignment is to invoke the setter. url.pathname = url.pathname; assert.strictEqual(url.pathname, "/baz%qat/qux%quux"); url.pathname = "baz#qat qux"; assert.strictEqual(url.pathname, "/baz%23qat%20qux"); url.pathname = url.pathname; assert.strictEqual(url.pathname, "/baz%23qat%20qux"); url.pathname = "\\a\\b\\c"; assert.strictEqual(url.pathname, "/a/b/c"); } function urlModifyHash() { const url = new URL("http://foo.bar"); url.hash = "%foo bar/qat%qux#bar"; assert.strictEqual(url.hash, "#%foo%20bar/qat%qux#bar"); url.hash = url.hash; assert.strictEqual(url.hash, "#%foo%20bar/qat%qux#bar"); } function urlSearchParamsReuse() { const url = new URL("https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat"); const sp = url.searchParams; url.hostname = "baz.qat"; if (sp !== url.searchParams) { throw new Error("Search params should be reused."); } } function urlBackSlashes() { const url = new URL("https:\\\\baz.qat:8000\\qux\\quux?foo=bar&baz=12#qat"); assert.strictEqual( url.href, "https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat", ); } function urlProtocolSlashes() { assert.strictEqual(new URL("http:foo").href, "http://foo/"); assert.strictEqual(new URL("http://foo").href, "http://foo/"); assert.strictEqual(new URL("file:foo").href, "file:///foo"); assert.strictEqual(new URL("file://foo").href, "file://foo/"); assert.strictEqual(new URL("abcd:foo").href, "abcd:foo"); assert.strictEqual(new URL("abcd://foo").href, "abcd://foo"); } function urlRequireHost() { assert.strictEqual(new URL("file:///").href, "file:///"); assert.throws(() => new URL("ftp:///"), TypeError, "Invalid URL"); assert.throws(() => new URL("http:///"), TypeError, "Invalid URL"); assert.throws(() => new URL("https:///"), TypeError, "Invalid URL"); assert.throws(() => new URL("ws:///"), TypeError, "Invalid URL"); assert.throws(() => new URL("wss:///"), TypeError, "Invalid URL"); } function urlDriveLetter() { assert.strictEqual(new URL("file:///C:").href, "file:///C:"); assert.strictEqual(new URL("file:///C:/").href, "file:///C:/"); assert.strictEqual(new URL("file:///C:/..").href, "file:///C:/"); // Don't recognise drive letters with extra leading slashes. // FIXME(nayeemrmn): This is true according to // https://jsdom.github.io/whatwg-url/#url=ZmlsZTovLy8vQzovLi4=&base=ZmlsZTovLy8= // but not the behavior of rust-url. // assert.strictEqual(new URL("file:////C:/..").href, "file:///"); // Drop the hostname if a drive letter is parsed. assert.strictEqual(new URL("file://foo/C:").href, "file:///C:"); // Don't recognise drive letters in non-file protocols. // FIXME(nayeemrmn): This is true according to // https://jsdom.github.io/whatwg-url/#url=YWJjZDovL2Zvby9DOi8uLg==&base=ZmlsZTovLy8= // but not the behavior of rust-url. // assert.strictEqual(new URL("http://foo/C:/..").href, "http://foo/"); // assert.strictEqual(new URL("abcd://foo/C:/..").href, "abcd://foo/"); } function urlHostnameUpperCase() { assert.strictEqual(new URL("http://EXAMPLE.COM").href, "http://example.com/"); assert.strictEqual(new URL("abcd://EXAMPLE.COM").href, "abcd://EXAMPLE.COM"); } function urlEmptyPath() { assert.strictEqual(new URL("http://foo").pathname, "/"); assert.strictEqual(new URL("file://foo").pathname, "/"); assert.strictEqual(new URL("abcd://foo").pathname, ""); } function urlPathRepeatedSlashes() { assert.strictEqual(new URL("http://foo//bar//").pathname, "//bar//"); assert.strictEqual(new URL("file://foo///bar//").pathname, "/bar//"); assert.strictEqual(new URL("abcd://foo//bar//").pathname, "//bar//"); } function urlTrim() { assert.strictEqual( new URL(" http://example.com ").href, "http://example.com/", ); } function urlEncoding() { assert.strictEqual( new URL("http://a !$&*()=,;+'\"@example.com").username, "a%20!$&*()%3D,%3B+'%22", ); assert.strictEqual( new URL("http://:a !$&*()=,;+'\"@example.com").password, "a%20!$&*()%3D,%3B+'%22", ); // https://url.spec.whatwg.org/#idna assert.strictEqual(new URL("http://mañana/c?d#e").hostname, "xn--maana-pta"); assert.strictEqual(new URL("abcd://mañana/c?d#e").hostname, "ma%C3%B1ana"); assert.strictEqual( new URL("http://example.com/a ~!@$&*()=:/,;+'\"\\").pathname, "/a%20~!@$&*()=:/,;+'%22/", ); assert.strictEqual( new URL("http://example.com?a ~!@$&*()=:/,;?+'\"\\").search, "?a%20~!@$&*()=:/,;?+%27%22\\", ); assert.strictEqual( new URL("abcd://example.com?a ~!@$&*()=:/,;?+'\"\\").search, "?a%20~!@$&*()=:/,;?+'%22\\", ); assert.strictEqual( new URL("http://example.com#a ~!@#$&*()=:/,;?+'\"\\").hash, "#a%20~!@#$&*()=:/,;?+'%22\\", ); } function urlBase() { assert.strictEqual( new URL("d", new URL("http://foo/a?b#c")).href, "http://foo/d", ); assert.strictEqual( new URL("", "http://foo/a/b?c#d").href, "http://foo/a/b?c", ); assert.strictEqual( new URL("", "file://foo/a/b?c#d").href, "file://foo/a/b?c", ); assert.strictEqual( new URL("", "abcd://foo/a/b?c#d").href, "abcd://foo/a/b?c", ); assert.strictEqual( new URL("#e", "http://foo/a/b?c#d").href, "http://foo/a/b?c#e", ); assert.strictEqual( new URL("#e", "file://foo/a/b?c#d").href, "file://foo/a/b?c#e", ); assert.strictEqual( new URL("#e", "abcd://foo/a/b?c#d").href, "abcd://foo/a/b?c#e", ); assert.strictEqual( new URL("?e", "http://foo/a/b?c#d").href, "http://foo/a/b?e", ); assert.strictEqual( new URL("?e", "file://foo/a/b?c#d").href, "file://foo/a/b?e", ); assert.strictEqual( new URL("?e", "abcd://foo/a/b?c#d").href, "abcd://foo/a/b?e", ); assert.strictEqual(new URL("e", "http://foo/a/b?c#d").href, "http://foo/a/e"); assert.strictEqual(new URL("e", "file://foo/a/b?c#d").href, "file://foo/a/e"); assert.strictEqual(new URL("e", "abcd://foo/a/b?c#d").href, "abcd://foo/a/e"); assert.strictEqual(new URL(".", "http://foo/a/b?c#d").href, "http://foo/a/"); assert.strictEqual(new URL(".", "file://foo/a/b?c#d").href, "file://foo/a/"); assert.strictEqual(new URL(".", "abcd://foo/a/b?c#d").href, "abcd://foo/a/"); assert.strictEqual(new URL("..", "http://foo/a/b?c#d").href, "http://foo/"); assert.strictEqual(new URL("..", "file://foo/a/b?c#d").href, "file://foo/"); assert.strictEqual(new URL("..", "abcd://foo/a/b?c#d").href, "abcd://foo/"); assert.strictEqual(new URL("/e", "http://foo/a/b?c#d").href, "http://foo/e"); assert.strictEqual(new URL("/e", "file://foo/a/b?c#d").href, "file://foo/e"); assert.strictEqual(new URL("/e", "abcd://foo/a/b?c#d").href, "abcd://foo/e"); assert.strictEqual( new URL("//bar", "http://foo/a/b?c#d").href, "http://bar/", ); assert.strictEqual( new URL("//bar", "file://foo/a/b?c#d").href, "file://bar/", ); assert.strictEqual(new URL("//bar", "abcd://foo/a/b?c#d").href, "abcd://bar"); assert.strictEqual(new URL("efgh:", "http://foo/a/b?c#d").href, "efgh:"); assert.strictEqual(new URL("efgh:", "file://foo/a/b?c#d").href, "efgh:"); assert.strictEqual(new URL("efgh:", "abcd://foo/a/b?c#d").href, "efgh:"); assert.strictEqual(new URL("/foo", "abcd:/").href, "abcd:/foo"); } function urlDriveLetterBase() { assert.strictEqual(new URL("/b", "file:///C:/a/b").href, "file:///C:/b"); assert.strictEqual(new URL("/D:", "file:///C:/a/b").href, "file:///D:"); } function urlSameProtocolBase() { assert.strictEqual(new URL("http:", "http://foo/a").href, "http://foo/a"); assert.strictEqual(new URL("file:", "file://foo/a").href, "file://foo/a"); assert.strictEqual(new URL("abcd:", "abcd://foo/a").href, "abcd:"); assert.strictEqual(new URL("http:b", "http://foo/a").href, "http://foo/b"); assert.strictEqual(new URL("file:b", "file://foo/a").href, "file://foo/b"); assert.strictEqual(new URL("abcd:b", "abcd://foo/a").href, "abcd:b"); } function deletingAllParamsRemovesQuestionMarkFromURL() { const url = new URL("http://example.com/?param1&param2"); url.searchParams.delete("param1"); url.searchParams.delete("param2"); assert.strictEqual(url.href, "http://example.com/"); assert.strictEqual(url.search, ""); } function removingNonExistentParamRemovesQuestionMarkFromURL() { const url = new URL("http://example.com/?"); assert.strictEqual(url.href, "http://example.com/?"); url.searchParams.delete("param1"); assert.strictEqual(url.href, "http://example.com/"); assert.strictEqual(url.search, ""); } function sortingNonExistentParamRemovesQuestionMarkFromURL() { const url = new URL("http://example.com/?"); assert.strictEqual(url.href, "http://example.com/?"); url.searchParams.sort(); assert.strictEqual(url.href, "http://example.com/"); assert.strictEqual(url.search, ""); } function protocolNotHttpOrFile() { const url = new URL("about:blank"); assert.strictEqual(url.href, "about:blank"); assert.strictEqual(url.protocol, "about:"); assert.strictEqual(url.origin, "null"); } function throwForInvalidPortConstructor() { const urls = [ // If port is greater than 2^16 − 1, validation error, return failure. `https://baz.qat:${2 ** 16}`, "https://baz.qat:-32", "https://baz.qat:deno", "https://baz.qat:9land", "https://baz.qat:10.5", ]; for (const url of urls) { assert.throws(() => new URL(url), TypeError, "Invalid URL"); } // Do not throw for 0 & 65535 new URL("https://baz.qat:65535"); new URL("https://baz.qat:0"); } function doNotOverridePortIfInvalid() { const initialPort = "3000"; const url = new URL(`https://deno.land:${initialPort}`); // If port is greater than 2^16 − 1, validation error, return failure. url.port = `${2 ** 16}`; assert.strictEqual(url.port, initialPort); } function emptyPortForSchemeDefaultPort() { const nonDefaultPort = "3500"; const url = new URL("ftp://baz.qat:21"); assert.strictEqual(url.port, ""); url.port = nonDefaultPort; assert.strictEqual(url.port, nonDefaultPort); url.port = "21"; assert.strictEqual(url.port, ""); url.protocol = "http"; assert.strictEqual(url.port, ""); const url2 = new URL("https://baz.qat:443"); assert.strictEqual(url2.port, ""); url2.port = nonDefaultPort; assert.strictEqual(url2.port, nonDefaultPort); url2.port = "443"; assert.strictEqual(url2.port, ""); url2.protocol = "http"; assert.strictEqual(url2.port, ""); } function assigningPortPropertyAffectsReceiverOnly() { // Setting `.port` should update only the receiver. const u1 = new URL("http://google.com/"); const u2 = new URL(u1 as any); u2.port = "123"; assert.strictEqual(u1.port, ""); assert.strictEqual(u2.port, "123"); } function urlSearchParamsIdentityPreserved() { // URLSearchParams identity should not be lost when URL is updated. const u = new URL("http://foo.com/"); const sp1 = u.searchParams; u.href = "http://bar.com/?baz=42"; const sp2 = u.searchParams; if (sp1 !== sp2) { throw new Error("Search params should be reused."); } } function urlTakeURLObjectAsParameter() { const url = new URL( new URL("https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat"), ); assert.strictEqual( url.href, "https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat", ); } function urlConsoleLog() { console.log(new URL("https://baz.qat:8000/qux/quux?foo=bar&baz=123#qat")); } export default query(async () => { return await wrapInTests({ urlParsing, urlProtocolParsing, protocolNotHttpOrFile, urlAuthenticationParsing, urlHostnameParsing, urlPortParsing, urlModifications, urlModifyHref, urlModifyHrefErroring, urlNormalize, urlModifyPathname, urlModifyHash, urlSearchParamsReuse, urlBackSlashes, urlProtocolSlashes, urlRequireHost, urlDriveLetter, urlHostnameUpperCase, urlEmptyPath, urlPathRepeatedSlashes, urlTrim, urlEncoding, urlBase, urlDriveLetterBase, urlSameProtocolBase, deletingAllParamsRemovesQuestionMarkFromURL, removingNonExistentParamRemovesQuestionMarkFromURL, sortingNonExistentParamRemovesQuestionMarkFromURL, throwForInvalidPortConstructor, doNotOverridePortIfInvalid, emptyPortForSchemeDefaultPort, assigningPortPropertyAffectsReceiverOnly, urlTakeURLObjectAsParameter, urlSearchParamsIdentityPreserved, urlConsoleLog, }); }); export const setHostUnimplemented = query(() => { const url = new URL("https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat"); url.host = "qat.baz:8080"; });

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