netbird-gitops/src/config.ts
2026-03-06 13:21:08 +02:00

72 lines
2.2 KiB
TypeScript

import { z } from "zod";
/**
* Base fields required regardless of Gitea integration mode.
*/
const BaseSchema = z.object({
netbirdApiUrl: z.string().url(),
netbirdApiToken: z.string().min(1),
giteaEnabled: z.string().default("true").transform((v) => v === "true"),
reconcilerToken: z.string().min(1),
pollIntervalSeconds: z.coerce.number().int().positive().default(30),
port: z.coerce.number().int().positive().default(8080),
dataDir: z.string().default("/data"),
});
const GiteaFieldsSchema = z.object({
giteaUrl: z.string().url(),
giteaToken: z.string().min(1),
giteaRepo: z.string().regex(/^[^/]+\/[^/]+$/), // owner/repo
});
/**
* When giteaEnabled=true, Gitea fields are validated and required.
* When giteaEnabled=false, Gitea fields are ignored.
*
* The output type always includes the optional Gitea fields so
* downstream code can check `config.giteaEnabled` and narrow.
*/
const ConfigSchema = BaseSchema.merge(GiteaFieldsSchema.partial())
.superRefine((data, ctx) => {
if (!data.giteaEnabled) return;
if (!data.giteaUrl) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "GITEA_URL is required when GITEA_ENABLED=true",
path: ["giteaUrl"],
});
}
if (!data.giteaToken) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "GITEA_TOKEN is required when GITEA_ENABLED=true",
path: ["giteaToken"],
});
}
if (!data.giteaRepo) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "GITEA_REPO is required when GITEA_ENABLED=true",
path: ["giteaRepo"],
});
}
});
export type Config = z.infer<typeof ConfigSchema>;
export function loadConfig(): Config {
return ConfigSchema.parse({
netbirdApiUrl: Deno.env.get("NETBIRD_API_URL"),
netbirdApiToken: Deno.env.get("NETBIRD_API_TOKEN"),
giteaEnabled: Deno.env.get("GITEA_ENABLED"),
giteaUrl: Deno.env.get("GITEA_URL"),
giteaToken: Deno.env.get("GITEA_TOKEN"),
giteaRepo: Deno.env.get("GITEA_REPO"),
reconcilerToken: Deno.env.get("RECONCILER_TOKEN"),
pollIntervalSeconds: Deno.env.get("POLL_INTERVAL_SECONDS"),
port: Deno.env.get("PORT"),
dataDir: Deno.env.get("DATA_DIR"),
});
}