cleanup for the docker setup

Signed-off-by: ngn <ngn@ngn.tf>
This commit is contained in:
ngn
2025-01-18 03:31:37 +03:00
parent ecaa6fb68f
commit fa2f3acb35
34 changed files with 433 additions and 319 deletions

View File

@ -1,4 +1,4 @@
node_modules
.svelte-kit
build
public
build

View File

@ -1,22 +1,39 @@
FROM node:23.5.0 as build
# build the application with node
FROM node:23.5.0 AS build
ARG WEBSITE_REPORT_URL
ARG WEBSITE_SOURCE_URL
ARG WEBSITE_APP_URL
ARG WEBSITE_API_URL
ARG WEBSITE_DOC_URL
ENV WEBSITE_REPORT_URL=$WEBSITE_REPORT_URL
ENV WEBSITE_SOURCE_URL=$WEBSITE_SOURCE_URL
ENV WEBSITE_APP_URL=$WEBSITE_APP_URL
ENV WEBSITE_API_URL=$WEBSITE_API_URL
ENV WEBSITE_DOC_URL=$WEBSITE_DOC_URL
WORKDIR /app
COPY . /app
ARG API_URL
ENV VITE_API_URL_DEV $API_URL
RUN npm install && npm run build
FROM oven/bun:1.1.20 as main
# run it with bun (a lot faster)
FROM oven/bun:latest AS main
WORKDIR /app
COPY --from=build /app/build ./build
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/build ./build
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/package-lock.json ./package-lock.json
EXPOSE 7001
RUN useradd runner -r -u 1001 -d /app
RUN chown -R runner:runner /app
USER runner
RUN bun install
EXPOSE 7001
ENV PORT=7001
CMD ["bun", "build/index.js"]

View File

@ -3,9 +3,9 @@
"version": "6.0",
"private": true,
"scripts": {
"dev": "vite --port 7002 dev",
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview --host",
"preview": "vite preview",
"lint": "prettier --check .",
"format": "prettier --write ."
},
@ -21,7 +21,6 @@
},
"type": "module",
"dependencies": {
"@types/dompurify": "^3.2.0",
"dompurify": "^3.2.3",
"marked": "^15.0.6",
"svelte-i18n": "^4.0.1"

View File

@ -1,7 +1,7 @@
import { urljoin } from "$lib/util.js";
const api_version = "v1";
const api_url = urljoin(import.meta.env.APP_API_URL, api_version);
const api_url = urljoin(import.meta.env.WEBSITE_API_URL, api_version);
function api_urljoin(path = null, query = {}) {
return urljoin(api_url, path, query);

View File

@ -1,7 +1,7 @@
import { urljoin } from "$lib/util.js";
function doc_urljoin(path = null, query = {}) {
return urljoin(import.meta.env.APP_DOC_URL, path, query);
return urljoin(import.meta.env.WEBSITE_DOC_URL, path, query);
}
function doc_check_err(json) {

View File

@ -15,7 +15,7 @@
{error}
{/if}
</code>
<Link link={import.meta.env.APP_REPORT_URL}>
<Link link={import.meta.env.WEBSITE_REPORT_URL}>
{$_("error.report")}
</Link>
<img src="/profile/sad.png" alt="" />

View File

@ -17,17 +17,17 @@
<div class="info">
<div class="links">
<span>
<Link link={import.meta.env.APP_SOURCE_URL} bold={true}>{$_("footer.source")}</Link>
<Link link={import.meta.env.WEBSITE_SOURCE_URL} bold={true}>{$_("footer.source")}</Link>
</span>
<span>/</span>
<span>
<Link link={urljoin(import.meta.env.APP_URL, "doc/license")} bold={true}
<Link link={urljoin(import.meta.env.WEBSITE_APP_URL, "doc/license")} bold={true}
>{$_("footer.license")}</Link
>
</span>
<span>/</span>
<span>
<Link link={urljoin(import.meta.env.APP_URL, "doc/privacy")} bold={true}
<Link link={urljoin(import.meta.env.WEBSITE_APP_URL, "doc/privacy")} bold={true}
>{$_("footer.privacy")}</Link
>
</span>

View File

@ -1,6 +1,6 @@
<script>
import { frontend_url } from "$lib/util.js";
import { api_urljoin } from "$lib/api.js";
import { app_url } from "$lib/util.js";
export let desc, title;
</script>
@ -10,7 +10,7 @@
<meta content="[ngn.tf] | {title}" property="og:title" />
<meta content={desc} property="og:description" />
<meta content={frontend_url()} property="og:url" />
<meta content={app_url()} property="og:url" />
<meta content="#000000" data-react-helmet="true" name="theme-color" />
<link

View File

@ -1,4 +0,0 @@
export default [
{ code: "en", name: "English", icon: "🇬🇧", path: "../locales/en.json" },
{ code: "tr", name: "Turkish", icon: "🇹🇷", path: "../locales/tr.json" },
];

View File

@ -21,11 +21,11 @@
<Icon {icon} />
{/if}
{#if highlight}
<a {style} href={link}>
<a data-sveltekit-preload-data {style} href={link}>
<slot></slot>
</a>
{:else}
<a {style} class="no-highlight" href={link}>
<a data-sveltekit-preload-data {style} class="no-highlight" href={link}>
<slot></slot>
</a>
{/if}

66
app/src/lib/locale.js Normal file
View File

@ -0,0 +1,66 @@
import { init, locale, register, waitLocale } from "svelte-i18n";
import { browser } from "$app/environment";
import { get, writable } from "svelte/store";
const locale_default = "en";
let locale_index = writable(0);
let locale_list = [];
function locale_setup() {
// english
register("en", () => import("../locales/en.json"));
locale_list.push({ code: "en", name: "English", icon: "🇬🇧" });
// turkish
register("tr", () => import("../locales/tr.json"));
locale_list.push({ code: "tr", name: "Turkish", icon: "🇹🇷" });
init({
fallbackLocale: locale_default,
initialLocale: get(locale),
});
}
function locale_from_browser() {
if (browser) return window.navigator.language.slice(0, 2).toLowerCase();
else return locale_default;
}
function locale_select(l = null) {
if (l === null) {
if (browser && null !== (l = localStorage.getItem("locale"))) locale_select(l);
else locale_select(locale_from_browser());
return;
}
l = l.slice(0, 2);
for (let i = 0; i < locale_list.length; i++) {
if (l !== locale_list[i].code) continue;
if (browser) localStorage.setItem("locale", l);
locale.set(l);
locale_index.set(i);
return;
}
locale.set(locale_default);
locale_index.set(0);
}
async function locale_wait() {
await waitLocale();
}
export {
locale,
locale_list,
locale_index,
locale_default,
locale_setup,
locale_wait,
locale_select,
locale_from_browser,
};

View File

@ -1,38 +1,24 @@
<script>
import { language, set_lang } from "$lib/util.js";
import languages from "$lib/lang.js";
import { locale_list, locale_select, locale_index } from "$lib/locale.js";
let icon = null,
indx = 0,
len = languages.length;
let len = locale_list.length;
function next_indx() {
if (indx + 1 >= len) return 0;
return indx + 1;
}
function get_next(indx) {
let new_indx = 0;
function next_lang(inc) {
let new_indx = next_indx();
if (inc) indx = new_indx;
return languages[new_indx];
if (indx + 1 >= len) indx = 0;
else new_indx = indx + 1;
return locale_list[new_indx];
}
function next() {
set_lang(next_lang(true).code);
icon = next_lang(false).icon;
}
for (indx = 0; indx < len; indx++) {
if (languages[indx].code == $language) {
set_lang(languages[indx].code);
icon = next_lang(false).icon;
break;
}
locale_select(get_next($locale_index).code);
}
</script>
<button on:click={next}>
{icon}
{get_next($locale_index).icon}
</button>
<style>

View File

@ -2,8 +2,8 @@
import Icon from "$lib/icon.svelte";
import Link from "$lib/link.svelte";
import { color, time_from_ts, language } from "$lib/util.js";
import { _ } from "svelte-i18n";
import { color, time_from_ts } from "$lib/util.js";
import { locale, _ } from "svelte-i18n";
export let service = {};
</script>
@ -12,7 +12,7 @@
<div class="info">
<div class="title">
<h1>{service.name}</h1>
<p>{service.desc[$language]}</p>
<p>{service.desc[$locale]}</p>
</div>
<div class="links">
<Link highlight={false} link={service.clear}><Icon icon="nf-oct-link" /></Link>

View File

@ -1,9 +1,5 @@
import { browser } from "$app/environment";
import { locale } from "svelte-i18n";
import languages from "$lib/lang.js";
import { writable, get } from "svelte/store";
import { locale_from_browser } from "$lib/locale.js";
const default_language = languages[0].code;
const colors = [
"yellow",
"cyan",
@ -13,54 +9,8 @@ const colors = [
// "blue" (looks kinda ass)
];
let language = writable(default_language);
let colors_pos = -1;
function browser_lang() {
if (browser) return window.navigator.language.slice(0, 2).toLowerCase();
else return get(language);
}
function set_lang(lang) {
language.set(default_language);
locale.set(default_language);
if (lang === null || lang === undefined) {
if (browser && null !== (lang = localStorage.getItem("language"))) set_lang(lang);
else if (browser) set_lang(browser_lang());
return;
}
lang = lang.slice(0, 2);
for (let i = 0; i < languages.length; i++) {
if (lang !== languages[i].code) continue;
language.set(lang);
locale.set(lang);
if (browser) localStorage.setItem("language", lang);
}
}
function urljoin(url, path = null, query = {}) {
let url_len = url.length;
if (url[url_len - 1] != "/") url += "/";
if (null === path || "" === path) url = new URL(url);
else if (path[0] === "/") url = new URL(path.slice(1), url);
else url = new URL(path, url);
for (let k in query) url.searchParams.append(k, query[k]);
return url.href;
}
function frontend_url(path = null, query = {}) {
return urljoin(import.meta.env.APP_URL, path, query);
}
function color() {
if (colors_pos < 0) colors_pos = Math.floor(Math.random() * colors.length);
else if (colors_pos >= colors.length) colors_pos = 0;
@ -73,6 +23,26 @@ function click() {
audio.play();
}
function urljoin(url, path = null, query = {}) {
if (undefined === url || null === url) return;
let url_len = url.length;
if (url[url_len - 1] != "/") url += "/";
if (null === path || "" === path) url = new URL(url);
else if (path[0] === "/") url = new URL(path.slice(1), url);
else url = new URL(path, url);
for (let k in query) url.searchParams.append(k, query[k]);
return url.href;
}
function app_url(path = null, query = {}) {
return urljoin(import.meta.env.WEBSITE_APP_URL, path, query);
}
function time_from_ts(ts) {
if (ts === 0 || ts === undefined) return;
@ -80,7 +50,7 @@ function time_from_ts(ts) {
let ts_zone = ts_date.toString().match(/([A-Z]+[\+-][0-9]+)/)[1];
return (
new Intl.DateTimeFormat(browser_lang(), {
new Intl.DateTimeFormat(locale_from_browser(), {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
@ -91,22 +61,11 @@ function time_from_ts(ts) {
function date_from_ts(ts) {
if (ts === 0 || ts === undefined) return;
return new Intl.DateTimeFormat(browser_lang(), {
return new Intl.DateTimeFormat(locale_from_browser(), {
month: "2-digit",
year: "2-digit",
day: "2-digit",
}).format(new Date(ts * 1000));
}
export {
default_language,
browser_lang,
language,
set_lang,
urljoin,
frontend_url,
click,
color,
time_from_ts,
date_from_ts,
};
export { color, click, urljoin, app_url, time_from_ts, date_from_ts };

View File

@ -1,37 +1,6 @@
import { default_language, language, set_lang } from "$lib/util.js";
import { api_get_services, api_get_projects } from "$lib/api.js";
import { doc_get_list } from "$lib/doc.js";
import languages from "$lib/lang.js";
import { locale_setup, locale_wait } from "$lib/locale.js";
import { init, register, waitLocale } from "svelte-i18n";
import { get } from "svelte/store";
// setup the locale
for (let i = 0; i < languages.length; i++)
register(languages[i].code, () => import(/* @vite-ignore */ languages[i].path));
// set the language
set_lang();
init({
fallbackLocale: default_language,
initialLocale: get(language),
});
// load locales & load data from the API
export async function load({ fetch }) {
await waitLocale();
try {
return {
services: await api_get_services(fetch),
projects: await api_get_projects(fetch),
docs: await doc_get_list(fetch),
error: null,
};
} catch (err) {
return {
error: err.toString(),
};
}
export async function load() {
locale_setup();
await locale_wait();
}

View File

@ -1,25 +1,27 @@
<script>
import Navbar from "$lib/navbar.svelte";
import Footer from "$lib/footer.svelte";
import Error from "$lib/error.svelte";
let { data, children } = $props();
import { locale_select } from "$lib/locale.js";
import { onMount } from "svelte";
let { children } = $props();
onMount(() => {
locale_select();
});
</script>
<main>
{#if data.error === null}
<Navbar />
<div class="content">
{@render children()}
</div>
<Footer />
{:else}
<Error error={data.error} />>
{/if}
<Navbar />
<div class="content">
{@render children()}
</div>
<Footer />
</main>
<style>
@import "../../static/global.css";
@import "/global.css";
main {
display: flex;

14
app/src/routes/+page.js Normal file
View File

@ -0,0 +1,14 @@
import { api_get_projects } from "$lib/api.js";
export async function load({ fetch }) {
try {
let projects = await api_get_projects(fetch)
return {
projects: null === projects ? [] : projects,
};
} catch (err) {
return {
error: err.toString(),
};
}
}

View File

@ -1,97 +1,106 @@
<script>
import Header from "$lib/header.svelte";
import Error from "$lib/error.svelte";
import Head from "$lib/head.svelte";
import Card from "$lib/card.svelte";
import Link from "$lib/link.svelte";
import { color, language } from "$lib/util.js";
import { _ } from "svelte-i18n";
import { _, locale } from "svelte-i18n";
import { color } from "$lib/util.js";
const { data } = $props();
let projects = $state(data.projects);
let { data } = $props();
</script>
<Head title="home" desc="home page of my personal website" />
<Header picture="tired" title={$_("home.title")} />
<main>
<Card title={$_("home.welcome.title")}>
<span> 👋 {$_("home.welcome.desc")}</span>
<ul>
<li>🇹🇷 {$_("home.welcome.whoami")}</li>
<li>🖥️ {$_("home.welcome.interest")}</li>
<li>❤️ {$_("home.welcome.support")}</li>
</ul>
</Card>
<Card title={$_("home.work.title")}>
<span>{$_("home.work.desc")}</span>
<ul>
<li>⌨️ {$_("home.work.build")}</li>
<li>🤦 {$_("home.work.fix")}</li>
<li>🚩 {$_("home.work.ctf")}</li>
<li>👥 {$_("home.work.contribute")}</li>
<li>📑 {$_("home.work.wiki")}</li>
</ul>
</Card>
<Card title={$_("home.links.title")}>
<span>{$_("home.links.desc")}:</span>
<ul>
<li>
<Link icon="nf-fa-key" link="https://keyoxide.org/F9E70878C2FB389AEC2BA34CA3654DF5AD9F641D">
PGP
</Link>
</li>
<li>
<Link icon="nf-md-email" link="mailto:ngn@ngn.tf">Email</Link>
</li>
<li>
<Link icon="nf-md-mastodon" link="https://defcon.social/@ngn">Mastodon</Link>
</li>
</ul>
<span>
{$_("home.links.prefer")}
</span>
</Card>
<Card title={$_("home.services.title")}>
<span>
{$_("home.services.desc")}:
</span>
<ul>
<li>
<i style="color: var(--{color()});" class="nf nf-md-speedometer_slow"></i>
{$_("home.services.speed")}
</li>
<li>
<i style="color: var(--{color()});" class="nf nf-fa-lock"></i>
{$_("home.services.security")}
</li>
<li>
<i style="color: var(--{color()});" class="nf nf-fa-network_wired"></i>
{$_("home.services.privacy")}
</li>
<li>
<i style="color: var(--{color()});" class="nf nf-md-eye_off"></i>
{$_("home.services.bullshit")}
</li>
</ul>
<Link linK="/services">{$_("home.services.link")}</Link>
</Card>
<Card title={$_("home.projects.title")}>
<span>
{$_("home.projects.desc")}:
</span>
<ul>
{#each projects.filter((p) => {
return p.desc[$language] !== "" && p.desc[$language] !== null && p.desc[$language] !== undefined;
}) as project}
{#if data.error !== undefined}
<Error error={data.error} />
{:else}
<main>
<Card title={$_("home.welcome.title")}>
<span> 👋 {$_("home.welcome.desc")}</span>
<ul>
<li>🇹🇷 {$_("home.welcome.whoami")}</li>
<li>🖥️ {$_("home.welcome.interest")}</li>
<li>❤️ {$_("home.welcome.support")}</li>
</ul>
</Card>
<Card title={$_("home.work.title")}>
<span>{$_("home.work.desc")}</span>
<ul>
<li>⌨️ {$_("home.work.build")}</li>
<li>🤦 {$_("home.work.fix")}</li>
<li>🚩 {$_("home.work.ctf")}</li>
<li>👥 {$_("home.work.contribute")}</li>
<li>📑 {$_("home.work.wiki")}</li>
</ul>
</Card>
<Card title={$_("home.links.title")}>
<span>{$_("home.links.desc")}:</span>
<ul>
<li>
<Link active={true} link={project.url}>{project.name}</Link>:
{project.desc[$language]}
<Link
icon="nf-fa-key"
link="https://keyoxide.org/F9E70878C2FB389AEC2BA34CA3654DF5AD9F641D"
>
PGP
</Link>
</li>
{/each}
</ul>
</Card>
</main>
<li>
<Link icon="nf-md-email" link="mailto:ngn@ngn.tf">Email</Link>
</li>
<li>
<Link icon="nf-md-mastodon" link="https://defcon.social/@ngn">Mastodon</Link>
</li>
</ul>
<span>
{$_("home.links.prefer")}
</span>
</Card>
<Card title={$_("home.services.title")}>
<span>
{$_("home.services.desc")}:
</span>
<ul>
<li>
<i style="color: var(--{color()});" class="nf nf-md-speedometer_slow"></i>
{$_("home.services.speed")}
</li>
<li>
<i style="color: var(--{color()});" class="nf nf-fa-lock"></i>
{$_("home.services.security")}
</li>
<li>
<i style="color: var(--{color()});" class="nf nf-fa-network_wired"></i>
{$_("home.services.privacy")}
</li>
<li>
<i style="color: var(--{color()});" class="nf nf-md-eye_off"></i>
{$_("home.services.bullshit")}
</li>
</ul>
<Link link="/services">{$_("home.services.link")}</Link>
</Card>
<Card title={$_("home.projects.title")}>
<span>
{$_("home.projects.desc")}:
</span>
{#if data.error === undefined}
<ul>
{#each data.projects.filter((p) => {
return p.desc[$locale] !== "" && p.desc[$locale] !== null && p.desc[$locale] !== undefined;
}) as project}
<li>
<Link active={true} link={project.url}>{project.name}</Link>:
{project.desc[$locale]}
</li>
{/each}
</ul>
{/if}
</Card>
</main>
{/if}
<style>
main {

View File

@ -1,8 +1,11 @@
import { doc_get } from "$lib/doc";
import { doc_get_list, doc_get } from "$lib/doc";
export async function load({ fetch, params }) {
try {
return { doc: await doc_get(fetch, params.name) };
return {
docs: await doc_get_list(fetch),
doc: await doc_get(fetch, params.name),
};
} catch (err) {
return { error: err.toString() };
}

View File

@ -1,20 +1,18 @@
<script>
import Header from "$lib/header.svelte";
import Error from "$lib/error.svelte";
import Head from "$lib/head.svelte";
import { language, color } from "$lib/util.js";
import { goto } from "$app/navigation";
import { locale, _ } from "svelte-i18n";
import { color } from "$lib/util.js";
import DOMPurify from "dompurify";
import { onMount } from "svelte";
import { marked } from "marked";
import { _ } from "svelte-i18n";
let { data } = $props();
marked.use({ breaks: true });
onMount(async () => {
if (data.error !== null) return await goto("/");
for (let key in data.doc)
data.doc[key]["content"] = DOMPurify.sanitize(data.doc[key]["content"]);
});
@ -23,28 +21,32 @@
<Head title="documentation" desc="website and API documentation" />
<Header picture="reader" title={$_("doc.title")} />
<main>
{#if data.doc !== undefined}
<div class="markdown-body" style="--link-color: var(--{color()})">
{@html marked.parse(data.doc[$language].content)}
</div>
<div class="docs">
{#each data.docs[$language] as doc}
{#if doc.title == data.doc[$language].title}
<a href="/doc/{doc.name}" style="border-color: var(--{color()})">
<h1>{doc.title}</h1>
<h3>{doc.desc}</h3>
</a>
{:else}
<a href="/doc/{doc.name}" style="border-color: var(--white-3)">
<h1>{doc.title}</h1>
<h3>{doc.desc}</h3>
</a>
{/if}
{/each}
</div>
{/if}
</main>
{#if data.error !== undefined}
<Error error={data.error} />
{:else}
<main>
{#if data.doc !== undefined}
<div class="markdown-body" style="--link-color: var(--{color()})">
{@html marked.parse(data.doc[$locale].content)}
</div>
<div class="docs">
{#each data.docs[$locale] as doc}
{#if doc.title == data.doc[$locale].title}
<a href="/doc/{doc.name}" style="border-color: var(--{color()})">
<h1>{doc.title}</h1>
<h3>{doc.desc}</h3>
</a>
{:else}
<a href="/doc/{doc.name}" style="border-color: var(--white-3)">
<h1>{doc.title}</h1>
<h3>{doc.desc}</h3>
</a>
{/if}
{/each}
</div>
{/if}
</main>
{/if}
<style>
@import "/markdown.css";

View File

@ -0,0 +1,14 @@
import { api_get_services } from "$lib/api.js";
export async function load({ fetch }) {
try {
let services = await api_get_services(fetch)
return {
services: null === services ? [] : services,
};
} catch (err) {
return {
error: err.toString(),
};
}
}

View File

@ -1,12 +1,12 @@
<script>
import Service from "$lib/service.svelte";
import Header from "$lib/header.svelte";
import Error from "$lib/error.svelte";
import Link from "$lib/link.svelte";
import Head from "$lib/head.svelte";
import { api_urljoin } from "$lib/api.js";
import { language } from "$lib/util.js";
import { _ } from "svelte-i18n";
import { locale, _ } from "svelte-i18n";
let { data } = $props();
let services = $state(data.services);
@ -22,15 +22,13 @@
data.services.forEach((s) => {
if (s.name.toLowerCase().includes(value)) services.push(s);
else if (s.desc[$language].toLowerCase().includes(value)) services.push(s);
else if (s.desc[$locale].toLowerCase().includes(value)) services.push(s);
});
}
function get_services() {
return services.filter((s) => {
return (
s.desc[$language] !== "" && s.desc[$language] !== null && s.desc[$language] !== undefined
);
return s.desc[$locale] !== "" && s.desc[$locale] !== null && s.desc[$locale] !== undefined;
});
}
</script>
@ -38,23 +36,27 @@
<Head title="services" desc="my self-hosted services and projects" />
<Header picture="cool" title={$_("services.title")} />
<main>
<div class="title">
<input oninput={change} type="text" placeholder={$_("services.search")} />
<div>
<Link icon="nf-fa-feed" link={api_urljoin("/news/" + $language)}>{$_("services.feed")}</Link>
{#if data.error !== undefined}
<Error error={data.error} />
{:else}
<main>
<div class="title">
<input oninput={change} type="text" placeholder={$_("services.search")} />
<div>
<Link icon="nf-fa-feed" link={api_urljoin("/news/" + $locale)}>{$_("services.feed")}</Link>
</div>
</div>
</div>
<div class="services">
{#if get_services().length == 0}
<h3 class="none">{$_("services.none")}</h3>
{:else}
{#each get_services() as service}
<Service {service} />
{/each}
{/if}
</div>
</main>
<div class="services">
{#if get_services().length == 0}
<h3 class="none">{$_("services.none")}</h3>
{:else}
{#each get_services() as service}
<Service {service} />
{/each}
{/if}
</div>
</main>
{/if}
<style>
main {

View File

@ -6,8 +6,8 @@ import { readFileSync } from "fs";
const default_env = {
REPORT_URL: "https://github.com/ngn13/website/issues",
SOURCE_URL: "https://github.com/ngn13/website",
API_URL: "http://localhost:7001",
URL: "http://localhost:7002",
APP_URL: "http://localhost:7001",
API_URL: "http://localhost:7002",
DOC_URL: "http://localhost:7003",
};
@ -16,12 +16,20 @@ const json = readFileSync(file, "utf8");
const pkg = JSON.parse(json);
for (let env in default_env) {
if (process.env["APP_" + env] === undefined) process.env["APP_" + env] = default_env[env];
if (process.env["WEBSITE_" + env] === undefined) process.env["WEBSITE_" + env] = default_env[env];
}
export default defineConfig({
plugins: [sveltekit()],
envPrefix: "APP",
envPrefix: "WEBSITE",
preview: {
port: 7001,
strictPort: true,
},
server: {
port: 7001,
strictPort: true,
},
define: {
pkg: pkg,
},