xhr.ts 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { fetchAdvanced, type Stringifiable } from "@sv443-network/userutils";
  2. import type { ResourceKey } from "src/types";
  3. import { getResourceUrl } from "./misc";
  4. import { error } from "./logging";
  5. /**
  6. * Constructs a URL from a base URL and a record of query parameters.
  7. * If a value is null, the parameter will be valueless. If a value is undefined, the parameter will be omitted.
  8. * All values will be stringified using their `toString()` method and then URI-encoded.
  9. * @returns Returns a string instead of a URL object
  10. */
  11. export function constructUrlString(baseUrl: string, params: Record<string, Stringifiable | null>) {
  12. return `${baseUrl}?${
  13. Object.entries(params)
  14. .filter(([, v]) => v !== undefined)
  15. .map(([key, val]) => `${key}${val === null ? "" : `=${encodeURIComponent(String(val))}`}`)
  16. .join("&")
  17. }`;
  18. }
  19. /**
  20. * Constructs a URL object from a base URL and a record of query parameters.
  21. * If a value is null, the parameter will be valueless. If a value is undefined, the parameter will be omitted.
  22. * All values will be URI-encoded.
  23. * @returns Returns a URL object instead of a string
  24. */
  25. export function constructUrl(base: string, params: Record<string, Stringifiable | null>) {
  26. return new URL(constructUrlString(base, params));
  27. }
  28. /**
  29. * Sends a request with the specified parameters and returns the response as a Promise.
  30. * Ignores the CORS policy, contrary to fetch and fetchAdvanced.
  31. */
  32. export function sendRequest<T = any>(details: GM.Request<T>) {
  33. return new Promise<GM.Response<T>>((resolve, reject) => {
  34. GM.xmlHttpRequest({
  35. timeout: 10_000,
  36. ...details,
  37. onload: resolve,
  38. onerror: reject,
  39. ontimeout: reject,
  40. onabort: reject,
  41. });
  42. });
  43. }
  44. /** Fetches a CSS file from the specified resource with a key starting with `css-` */
  45. export async function fetchCss(key: ResourceKey & `css-${string}`) {
  46. try {
  47. const css = await (await fetchAdvanced(await getResourceUrl(key))).text();
  48. return css ?? undefined;
  49. }
  50. catch(err) {
  51. error("Couldn't fetch CSS due to an error:", err);
  52. return undefined;
  53. }
  54. }