diff --git a/package-lock.json b/package-lock.json
index 9c10e63..62f0466 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,8 @@
"pocketbase": "^0.26.2",
"svelte-katex": "^0.1.2",
"svelte-media-queries": "^1.6.2",
- "theme-change": "^2.5.0"
+ "theme-change": "^2.5.0",
+ "zod": "^4.1.11"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0",
@@ -3808,6 +3809,15 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz",
"integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="
+ },
+ "node_modules/zod": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.11.tgz",
+ "integrity": "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
}
}
}
diff --git a/package.json b/package.json
index e77804c..5c60990 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
"pocketbase": "^0.26.2",
"svelte-katex": "^0.1.2",
"svelte-media-queries": "^1.6.2",
- "theme-change": "^2.5.0"
+ "theme-change": "^2.5.0",
+ "zod": "^4.1.11"
}
}
diff --git a/src/env.d.ts b/src/env.d.ts
new file mode 100644
index 0000000..6104d1e
--- /dev/null
+++ b/src/env.d.ts
@@ -0,0 +1,10 @@
+///
+
+interface ImportMetaEnv {
+ readonly PUBLIC_URL_BASE: string;
+ readonly PUBLIC_POCKET_URL: string;
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv;
+}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 0e65b81..21b6322 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -4,6 +4,7 @@
import fly from "@e/fly";
import MediaQuery from "svelte-media-queries";
import Dices from "@lucide/svelte/icons/dices";
+ import { re } from "@ts/Redaction/Redactor";
let hideOnPrint: boolean = $state(false);
let { children } = $props();
@@ -26,7 +27,9 @@
afterNavigate(() => {
const params = new URLSearchParams(window.location.search);
hideOnPrint = params.get("hideOnPrint") === "1";
- // console.log(hideOnPrint);
+ if (!!params.get("key")) {
+ localStorage.setItem("key", params.get("key")!);
+ }
});
import onMount from "@e/onMount";
@@ -37,6 +40,7 @@
const lock = document.createElement("meta");
lock.name = "darkreader-lock";
document.head.appendChild(lock);
+ re.TryGetUnredacter();
});
function nextTheme() {
diff --git a/src/ts/Redaction/Profile.ts b/src/ts/Redaction/Profile.ts
new file mode 100644
index 0000000..5dfa942
--- /dev/null
+++ b/src/ts/Redaction/Profile.ts
@@ -0,0 +1,50 @@
+// npm i zod
+import { z } from "zod";
+
+const Link = z.object({
+ text: z.string().min(1),
+ link: z.string().url(),
+});
+
+const Experience = z.object({
+ imageId: z.string().min(1),
+ name: z.string().min(1),
+ date: z.string().min(1),
+});
+
+const EducationLoose = z.object({
+ imageId: z.string().min(1).optional(),
+ name: z.string().min(1).optional(),
+});
+
+const ProfileSchema = z.object({
+ name: z.string().min(1),
+ shortProfileHiddenContent: z.array(z.string()),
+ email: z.string().email(),
+ phone: z.string().min(1),
+ linkedIn: Link,
+ itch: Link,
+ experience: z.array(Experience),
+ education: z
+ .array(EducationLoose)
+ .transform((arr) =>
+ arr.filter(
+ (e): e is { imageId: string; name: string } => !!e.imageId && !!e.name,
+ ),
+ ),
+});
+
+export type LinkT = z.infer;
+export type ExperienceT = z.infer;
+export type EducationT = { imageId: string; name: string };
+export type Profile = Omit, "education"> & {
+ education: EducationT[];
+};
+
+export function parseProfile(json: unknown): Profile {
+ return ProfileSchema.parse(json);
+}
+
+// --- usage ---
+// const raw = JSON.parse(yourJsonString);
+// const profile = parseProfile(raw);
diff --git a/src/ts/Redaction/Redactor.ts b/src/ts/Redaction/Redactor.ts
new file mode 100644
index 0000000..a51b495
--- /dev/null
+++ b/src/ts/Redaction/Redactor.ts
@@ -0,0 +1,25 @@
+import PocketBase from "pocketbase";
+import { parseProfile, type Profile } from "./Profile";
+import { PUBLIC_POCKET_URL } from "$env/static/public";
+
+let pb = new PocketBase(PUBLIC_POCKET_URL);
+
+class Redactor {
+ async TryGetUnredacter(): Promise {
+ const url =
+ 'https://pocket.deprived.dev/api/collections/redacted_content/records?page=1&perPage=1&filter=plain_id="redacted_json"&skipTotal=1';
+ const res = await fetch(url, {
+ body: localStorage.getItem("key"),
+ method: "GET",
+ });
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
+ console.log(res);
+ const data = await res.json();
+ console.log(data);
+ const item = data?.items?.[0];
+ const raw = JSON.parse(item.file);
+ return parseProfile(raw);
+ }
+}
+
+export let re = new Redactor();
diff --git a/src/ts/api/api.ts b/src/ts/api/api.ts
index 1cab772..dedc9d7 100644
--- a/src/ts/api/api.ts
+++ b/src/ts/api/api.ts
@@ -3,8 +3,7 @@
import PocketBase from "pocketbase";
import ShopItem from "./classes/ShopItem";
-import { env } from "$env/dynamic/public";
-export const PUBLIC_URL_BASE = env.PUBLIC_URL_BASE ?? "";
+import { PUBLIC_POCKET_URL } from "$env/static/public";
export let pb = new PocketBase(PUBLIC_POCKET_URL);