feat: add support for app url variables (#915)
* feat: add support for app url variables * fix: test not working * fix: format issue
This commit is contained in:
23
packages/common/src/app-url/base.ts
Normal file
23
packages/common/src/app-url/base.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import * as tldts from "tldts";
|
||||
|
||||
const safeParseTldts = (url: string) => {
|
||||
try {
|
||||
return tldts.parse(url);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const parseAppHrefWithVariables = <TInput extends string | null>(url: TInput, currentHref: string): TInput => {
|
||||
if (!url || url.length === 0) return url;
|
||||
|
||||
const tldtsResult = safeParseTldts(currentHref);
|
||||
|
||||
const urlObject = new URL(currentHref);
|
||||
|
||||
return url
|
||||
.replaceAll("[homarr_base]", `${urlObject.protocol}//${urlObject.hostname}`)
|
||||
.replaceAll("[homarr_hostname]", tldtsResult?.hostname ?? "")
|
||||
.replaceAll("[homarr_domain]", tldtsResult?.domain ?? "")
|
||||
.replaceAll("[homarr_protocol]", urlObject.protocol.replace(":", "")) as TInput;
|
||||
};
|
||||
5
packages/common/src/app-url/client.ts
Normal file
5
packages/common/src/app-url/client.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { parseAppHrefWithVariables } from "./base";
|
||||
|
||||
export const parseAppHrefWithVariablesClient = <TInput extends string | null>(url: TInput): TInput => {
|
||||
return parseAppHrefWithVariables(url, window.location.href);
|
||||
};
|
||||
8
packages/common/src/app-url/server.ts
Normal file
8
packages/common/src/app-url/server.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { headers } from "next/headers";
|
||||
|
||||
import { extractBaseUrlFromHeaders } from "../url";
|
||||
import { parseAppHrefWithVariables } from "./base";
|
||||
|
||||
export const parseAppHrefWithVariablesServer = <TInput extends string | null>(url: TInput): TInput => {
|
||||
return parseAppHrefWithVariables(url, extractBaseUrlFromHeaders(headers()));
|
||||
};
|
||||
1
packages/common/src/client.ts
Normal file
1
packages/common/src/client.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./app-url/client";
|
||||
@@ -1 +1,2 @@
|
||||
export * from "./app-url/server";
|
||||
export * from "./security";
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { ReadonlyHeaders } from "next/dist/server/web/spec-extension/adapters/headers";
|
||||
|
||||
export const appendPath = (url: URL | string, path: string) => {
|
||||
const newUrl = new URL(url);
|
||||
newUrl.pathname = removeTrailingSlash(newUrl.pathname) + path;
|
||||
@@ -7,3 +9,16 @@ export const appendPath = (url: URL | string, path: string) => {
|
||||
const removeTrailingSlash = (path: string) => {
|
||||
return path.at(-1) === "/" ? path.substring(0, path.length - 1) : path;
|
||||
};
|
||||
|
||||
export const extractBaseUrlFromHeaders = (headers: ReadonlyHeaders): `${string}://${string}` => {
|
||||
let protocol = headers.get("x-forwarded-proto") ?? "http";
|
||||
|
||||
// @see https://support.glitch.com/t/x-forwarded-proto-contains-multiple-protocols/17219
|
||||
if (protocol.includes(",")) {
|
||||
protocol = protocol.includes("https") ? "https" : "http";
|
||||
}
|
||||
|
||||
const host = headers.get("x-forwarded-host") ?? headers.get("host");
|
||||
|
||||
return `${protocol}://${host}`;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user