Domain degisikligi: fristy.net -> fristy.dev #4
No files matched your search
@@ -11,7 +11,7 @@ concurrency:
|
||||
|
||||
env:
|
||||
REGISTRY: git.fristy.net
|
||||
IMAGE_NAME: fristy/fristynet
|
||||
IMAGE_NAME: fristy/fristydev
|
||||
|
||||
jobs:
|
||||
image:
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# fristy.net
|
||||
# fristy.dev
|
||||
|
||||

|
||||
|
||||
My personal corner of the internet — projects, live Discord status, and ways to reach me.
|
||||
|
||||
**Live:** https://fristy.net
|
||||
**Live:** https://fristy.dev
|
||||
|
||||
## What's inside
|
||||
|
||||
@@ -48,15 +48,15 @@ docker run --rm -p 3000:3000 fristynet
|
||||
No need to build it yourself though — CI publishes every `main` push:
|
||||
|
||||
```bash
|
||||
docker pull git.fristy.net/fristy/fristynet:latest
|
||||
docker pull git.fristy.net/fristy/fristydev:latest
|
||||
```
|
||||
|
||||
## CI/CD
|
||||
|
||||
Pushes to `main` (and `<sha>` tags) run format check, lint and build first. If those pass, the Docker image is built and pushed to the Gitea registry:
|
||||
|
||||
- `git.fristy.net/fristy/fristynet:latest` on every `main` push
|
||||
- `git.fristy.net/fristy/fristynet:<sha>` for every pushed commit
|
||||
- `git.fristy.net/fristy/fristydev:latest` on every `main` push
|
||||
- `git.fristy.net/fristy/fristydev:<sha>` for every pushed commit
|
||||
|
||||
Pull requests only run the checks — nothing is pushed.
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ function contextWith(id: string) {
|
||||
describe("GET /api/discord-app/[id]", () => {
|
||||
it("returns 400 for non-numeric ids", async () => {
|
||||
const response = await GET(
|
||||
new Request("https://fristy.net/api/discord-app/abc"),
|
||||
new Request("https://fristy.dev/api/discord-app/abc"),
|
||||
contextWith("abc"),
|
||||
);
|
||||
expect(response.status).toBe(400);
|
||||
@@ -25,7 +25,7 @@ describe("GET /api/discord-app/[id]", () => {
|
||||
vi.fn(async () => ({ ok: false, status: 404 })),
|
||||
);
|
||||
const response = await GET(
|
||||
new Request("https://fristy.net/api/discord-app/123"),
|
||||
new Request("https://fristy.dev/api/discord-app/123"),
|
||||
contextWith("123"),
|
||||
);
|
||||
expect(response.status).toBe(404);
|
||||
@@ -39,7 +39,7 @@ describe("GET /api/discord-app/[id]", () => {
|
||||
}),
|
||||
);
|
||||
const response = await GET(
|
||||
new Request("https://fristy.net/api/discord-app/123"),
|
||||
new Request("https://fristy.dev/api/discord-app/123"),
|
||||
contextWith("123"),
|
||||
);
|
||||
expect(response.status).toBe(502);
|
||||
|
||||
@@ -17,11 +17,11 @@ function requestWith(url: string) {
|
||||
describe("GET /api/game/[id]", () => {
|
||||
it("returns 400 for non-numeric ids", async () => {
|
||||
const response = await GET(
|
||||
requestWith("https://fristy.net/api/game/abc"),
|
||||
requestWith("https://fristy.dev/api/game/abc"),
|
||||
contextWith("abc"),
|
||||
);
|
||||
expect(response.status).toBe(400);
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
});
|
||||
|
||||
it("returns 404 when no profile resolves", async () => {
|
||||
@@ -30,7 +30,7 @@ describe("GET /api/game/[id]", () => {
|
||||
vi.fn(async () => ({ ok: false, status: 404 })),
|
||||
);
|
||||
const response = await GET(
|
||||
requestWith("https://fristy.net/api/game/123"),
|
||||
requestWith("https://fristy.dev/api/game/123"),
|
||||
contextWith("123"),
|
||||
);
|
||||
expect(response.status).toBe(404);
|
||||
@@ -44,10 +44,10 @@ describe("GET /api/game/[id]", () => {
|
||||
}),
|
||||
);
|
||||
const response = await GET(
|
||||
requestWith("https://fristy.net/api/game/123"),
|
||||
requestWith("https://fristy.dev/api/game/123"),
|
||||
contextWith("123"),
|
||||
);
|
||||
expect(response.status).toBe(502);
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
});
|
||||
});
|
||||
+1
-1
@@ -17,7 +17,7 @@ export async function generateMetadata(): Promise<Metadata> {
|
||||
metadataBase: new URL(SITE_URL),
|
||||
title: {
|
||||
default: dict.meta.title,
|
||||
template: "%s · fristy.net",
|
||||
template: "%s · fristy.dev",
|
||||
},
|
||||
description: dict.meta.description,
|
||||
openGraph: {
|
||||
|
||||
@@ -7,7 +7,7 @@ describe("SiteFooter", () => {
|
||||
it("renders brand, rights, and source links", () => {
|
||||
const dict = getDictionary("en");
|
||||
const { container } = render(<SiteFooter dict={dict.footer} />);
|
||||
expect(container.querySelector('a[href="https://fristy.net"]')).not.toBeNull();
|
||||
expect(container.querySelector('a[href="https://fristy.dev"]')).not.toBeNull();
|
||||
expect(container.textContent).toContain(dict.footer.rights);
|
||||
const links = screen.getAllByRole("link");
|
||||
expect(links.length).toBeGreaterThanOrEqual(3);
|
||||
|
||||
@@ -28,7 +28,7 @@ export function SiteFooter({ dict }: { dict: Dictionary["footer"] }) {
|
||||
<p>
|
||||
© {year}{" "}
|
||||
<a href={SITE_URL} className="transition-colors hover:text-white">
|
||||
fristy.net
|
||||
fristy.dev
|
||||
</a>{" "}
|
||||
· {dict.rights}
|
||||
</p>
|
||||
|
||||
@@ -7,7 +7,7 @@ export function SiteHeader({ dict, locale }: { dict: Dictionary["nav"]; locale:
|
||||
<header className="sticky top-0 z-50 border-b border-white/5 bg-void/80 backdrop-blur">
|
||||
<div className="mx-auto flex h-16 w-full max-w-4xl items-center justify-between px-5">
|
||||
<a href="#top" className="font-mono text-lg font-bold tracking-tight">
|
||||
fristy<span className="text-blurple">.net</span>
|
||||
fristy<span className="text-blurple">.dev</span>
|
||||
</a>
|
||||
<nav className="hidden items-center gap-6 text-sm text-zinc-400 sm:flex">
|
||||
<a href="#discord" className="transition-colors hover:text-white">
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
web:
|
||||
image: git.fristy.net/fristy/fristynet:latest
|
||||
image: git.fristy.net/fristy/fristydev:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
TWITCH_CLIENT_ID: ${TWITCH_CLIENT_ID}
|
||||
|
||||
@@ -29,7 +29,7 @@ describe("jsonErrorWithCors", () => {
|
||||
const response = jsonErrorWithCors({ error: "Nope" }, 404);
|
||||
expect(response.status).toBe(404);
|
||||
expect(response.headers.get("Cache-Control")).toContain("s-maxage=60");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
await expect(response.json()).resolves.toEqual({ error: "Nope" });
|
||||
});
|
||||
});
|
||||
@@ -37,7 +37,7 @@ describe("jsonWithCors", () => {
|
||||
it("sets cache and CORS headers", async () => {
|
||||
const response = jsonWithCors({ ok: true }, 3600);
|
||||
expect(response.headers.get("Cache-Control")).toContain("s-maxage=3600");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
await expect(response.json()).resolves.toEqual({ ok: true });
|
||||
});
|
||||
|
||||
@@ -48,6 +48,6 @@ describe("jsonWithCors", () => {
|
||||
|
||||
it("falls back to production for untrusted origins", async () => {
|
||||
const response = jsonWithCors({ ok: true }, 3600, "https://evil.example");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
});
|
||||
});
|
||||
@@ -57,7 +57,7 @@ export async function getDiscordAppInfo(applicationId: string): Promise<DiscordA
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetch(`https://discord.com/api/v10/applications/${applicationId}/rpc`, {
|
||||
headers: { "User-Agent": "fristy.net (personal site)" },
|
||||
headers: { "User-Agent": "fristy.dev (personal site)" },
|
||||
next: { revalidate: 86_400 },
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
+4
-1
@@ -5,6 +5,8 @@ const GITEA_USER = "fristy";
|
||||
|
||||
const EXCLUDED_REPOS = new Set([".profile"]);
|
||||
|
||||
const MAX_REPOS = 8;
|
||||
|
||||
export interface GiteaRepo {
|
||||
id: number;
|
||||
name: string;
|
||||
@@ -56,7 +58,8 @@ export async function getRepos(): Promise<GiteaRepo[]> {
|
||||
forks: repo.forks_count,
|
||||
updatedAt: repo.updated_at,
|
||||
}))
|
||||
.sort((a, b) => +new Date(b.updatedAt) - +new Date(a.updatedAt));
|
||||
.sort((a, b) => +new Date(b.updatedAt) - +new Date(a.updatedAt))
|
||||
.slice(0, MAX_REPOS);
|
||||
} catch {
|
||||
warnDev("cannot fetch gitea repos");
|
||||
return [];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "fristy.net — fristy love you",
|
||||
"title": "fristy.dev — fristy love you",
|
||||
"description": "Fristys persönliche Ecke: Projekte, Live-Discord-Status und Kontakt."
|
||||
},
|
||||
"nav": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "fristy.net — fristy love you",
|
||||
"title": "fristy.dev — fristy love you",
|
||||
"description": "Fristy's personal corner: projects, live Discord status and contact."
|
||||
},
|
||||
"nav": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "fristy.net - fristy love you",
|
||||
"title": "fristy.dev - fristy love you",
|
||||
"description": "Fristy'nin kişisel köşesi: projeler, canlı Discord durumu ve iletişim."
|
||||
},
|
||||
"nav": {
|
||||
@@ -71,7 +71,7 @@
|
||||
},
|
||||
"projects": {
|
||||
"title": "Projeler",
|
||||
"subtitle": "Açık kaynak projelerim git.fristy.net üzerinde. Liste otomatik güncelleniyor.",
|
||||
"subtitle": "Açık kaynak projelerim git.fristy.net adresinde barınıyor. Liste her saat otomatik güncelleniyor.",
|
||||
"updated": "Güncellendi",
|
||||
"stars": "Yıldız",
|
||||
"forks": "Çatal",
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
export const SITE_URL = "https://fristy.net";
|
||||
export const CONTACT_EMAIL = "iletisim@fristy.net";
|
||||
export const SITE_URL = "https://fristy.dev";
|
||||
export const CONTACT_EMAIL = "iletisim@fristy.dev";
|
||||
export const GITEA_PROFILE_URL = "https://git.fristy.net/fristy";
|
||||
export const SOURCE_URL = "https://git.fristy.net/fristy/fristynet";
|
||||
export const SOURCE_URL = "https://git.fristy.net/fristy/fristydev";
|
||||
export const GITHUB_URL = "https://github.com/fristyxd";
|
||||
export const DISCORD_SERVER_URL = "https://discord.gg/fristy";
|
||||
export const SPOTIFY_URL = "https://open.spotify.com/user/gayiw5j9i0rtvyra6gfzhpfwf";
|
||||
|
||||
+6
-6
@@ -9,9 +9,9 @@ afterEach(() => {
|
||||
function apiRequest(path: string, init?: { method?: string; origin?: string | null }): NextRequest {
|
||||
const headers = new Headers();
|
||||
if (init?.origin !== null) {
|
||||
headers.set("origin", init?.origin ?? "https://fristy.net");
|
||||
headers.set("origin", init?.origin ?? "https://fristy.dev");
|
||||
}
|
||||
return new NextRequest(`https://fristy.net${path}`, {
|
||||
return new NextRequest(`https://fristy.dev${path}`, {
|
||||
method: init?.method ?? "GET",
|
||||
headers,
|
||||
});
|
||||
@@ -21,19 +21,19 @@ describe("proxy /api/*", () => {
|
||||
it("answers OPTIONS preflight with CORS headers", () => {
|
||||
const response = proxy(apiRequest("/api/game/1", { method: "OPTIONS" }));
|
||||
expect(response.status).toBe(204);
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
expect(response.headers.get("Access-Control-Allow-Methods")).toBe("GET, OPTIONS");
|
||||
});
|
||||
|
||||
it("rejects foreign origins", () => {
|
||||
const response = proxy(apiRequest("/api/game/1", { origin: "https://evil.test" }));
|
||||
expect(response.status).toBe(403);
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
});
|
||||
|
||||
it("passes same-origin API requests with CORS headers", () => {
|
||||
const response = proxy(apiRequest("/api/game/1"));
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(response.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -57,7 +57,7 @@ describe("proxy rate limit", () => {
|
||||
const limited = proxy(ipRequest("10.0.0.2"));
|
||||
expect(limited.status).toBe(429);
|
||||
expect(limited.headers.get("Retry-After")).toBe("60");
|
||||
expect(limited.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.net");
|
||||
expect(limited.headers.get("Access-Control-Allow-Origin")).toBe("https://fristy.dev");
|
||||
await expect(limited.json()).resolves.toEqual({ error: "Too many requests" });
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user