1 line
14 KiB
JSON
1 line
14 KiB
JSON
|
{"ast":null,"code":"// URI parser based on RFC 3986\n// We can't use the standard `URL` object, because we want to support relative `file:` URLs like\n// `file:relative/path/database.db`, which are not correct according to RFC 8089, which standardizes the\n// `file` scheme.\nimport { LibsqlError } from \"./api.js\";\nexport function parseUri(text) {\n const match = URI_RE.exec(text);\n if (match === null) {\n throw new LibsqlError(`The URL '${text}' is not in a valid format`, \"URL_INVALID\");\n }\n const groups = match.groups;\n const scheme = groups[\"scheme\"];\n const authority = groups[\"authority\"] !== undefined ? parseAuthority(groups[\"authority\"]) : undefined;\n const path = percentDecode(groups[\"path\"]);\n const query = groups[\"query\"] !== undefined ? parseQuery(groups[\"query\"]) : undefined;\n const fragment = groups[\"fragment\"] !== undefined ? percentDecode(groups[\"fragment\"]) : undefined;\n return {\n scheme,\n authority,\n path,\n query,\n fragment\n };\n}\nconst URI_RE = (() => {\n const SCHEME = \"(?<scheme>[A-Za-z][A-Za-z.+-]*)\";\n const AUTHORITY = \"(?<authority>[^/?#]*)\";\n const PATH = \"(?<path>[^?#]*)\";\n const QUERY = \"(?<query>[^#]*)\";\n const FRAGMENT = \"(?<fragment>.*)\";\n return new RegExp(`^${SCHEME}:(//${AUTHORITY})?${PATH}(\\\\?${QUERY})?(#${FRAGMENT})?$`, \"su\");\n})();\nfunction parseAuthority(text) {\n const match = AUTHORITY_RE.exec(text);\n if (match === null) {\n throw new LibsqlError(\"The authority part of the URL is not in a valid format\", \"URL_INVALID\");\n }\n const groups = match.groups;\n const host = percentDecode(groups[\"host_br\"] ?? groups[\"host\"]);\n const port = groups[\"port\"] ? parseInt(groups[\"port\"], 10) : undefined;\n const userinfo = groups[\"username\"] !== undefined ? {\n username: percentDecode(groups[\"username\"]),\n password: groups[\"password\"] !== undefined ? percentDecode(groups[\"password\"]) : undefined\n } : undefined;\n return {\n host,\n port,\n userinfo\n };\n}\nconst AUTHORITY_RE = (() => {\n return new RegExp(`^((?<username>[^:]*)(:(?<password>.*))?@)?((?<host>[^:\\\\[\\\\]]*)|(\\\\[(?<host_br>[^\\\\[\\\\]]*)\\\\]))(:(?<port>[0-9]*))?$`, \"su\");\n})();\n// Query string is parsed as application/x-www-form-urlencoded according to the Web URL standard:\n// https://url.spec.whatwg.org/#urlencoded-parsing\nfunction parseQuery(text) {\n const sequences = text.split(\"&\");\n const pairs = [];\n for (const sequence of sequences) {\n if (sequence === \"\") {\n continue;\n }\n let key;\n let value;\n const splitIdx = sequence.indexOf(\"=\");\n if (splitIdx < 0) {\n key = sequence;\n value = \"\";\n } else {\n key = sequence.substring(0, splitIdx);\n value = sequence.substring(splitIdx + 1);\n }\n pairs.push({\n key: percentDecode(key.replaceAll(\"+\", \" \")),\n value: percentDecode(value.replaceAll(\"+\", \" \"))\n });\n }\n return {\n pairs\n };\n}\nfunction percentDecode(text) {\n try {\n return decodeURIComponent(text);\n } catch (e) {\n if (e instanceof URIError) {\n throw new LibsqlError(`URL component has invalid percent encoding: ${e}`, \"URL_INVALID\", undefined, e);\n }\n throw e;\n }\n}\nexport function encodeBaseUrl(scheme, authority, path) {\n if (authority === undefined) {\n throw new LibsqlError(`URL with scheme ${JSON.stringify(scheme + \":\")} requires authority (the \"//\" part)`, \"URL_INVALID\");\n }\n const schemeText = `${scheme}:`;\n const hostText = encodeHost(authority.host);\n const portText = encodePort(authority.port);\n const userinfoText = encodeUserinfo(authority.userinfo);\n const authorityText = `//${userinfoText}${hostText}${portText}`;\n let pathText = path.split(\"/\").map(encodeURIComponent).join(\"/\");\n if (pathText !== \"\" && !pathText.startsWith(\"/\")) {\n pathText = \"/\" + pathText;\n }\n return new URL(`${schemeText}${authorityText}${pathText}`);\n}\nfunction encodeHost(host) {\n return host.includes(\":\") ?
|