mirror of
https://github.com/Xevion/bus-reminder.git
synced 2025-12-17 00:11:22 -06:00
Essential environment variable parsing ^& validation
This commit is contained in:
18
src/env/schema.mjs
vendored
Normal file
18
src/env/schema.mjs
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// @ts-check
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify your server-side environment variables schema here.
|
||||||
|
* This way you can ensure the app isn't built with invalid env vars.
|
||||||
|
*/
|
||||||
|
export const serverSchema = z.object({
|
||||||
|
API_KEY: z.string(),
|
||||||
|
CRONITOR_ACCOUNT_ID: z.string(),
|
||||||
|
CRONITOR_JOB_ID: z.string(),
|
||||||
|
LIFE360_USERNAME: z.string(),
|
||||||
|
LIFE360_PASSWORD: z.string(),
|
||||||
|
LIFE360_MEMBER_ID: z.string(),
|
||||||
|
MAX_DISTANCE: z.coerce.number().positive(),
|
||||||
|
CENTER_LATITUDE: z.coerce.number().min(-90).max(90),
|
||||||
|
CENTER_LONGITUDE: z.coerce.number().min(-180).max(180),
|
||||||
|
});
|
||||||
40
src/env/server.mjs
vendored
Normal file
40
src/env/server.mjs
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* This file is included in `/next.config.mjs` which ensures the app isn't built with invalid env vars.
|
||||||
|
* It has to be a `.mjs`-file to be imported there.
|
||||||
|
*/
|
||||||
|
import { serverSchema } from "./schema.mjs";
|
||||||
|
import { formatErrors } from "./util.mjs";
|
||||||
|
|
||||||
|
const _serverEnv = serverSchema.safeParse({
|
||||||
|
API_KEY: process.env.API_KEY,
|
||||||
|
CRONITOR_ACCOUNT_ID: process.env.CRONITOR_ACCOUNT_ID,
|
||||||
|
CRONITOR_JOB_ID: process.env.CRONITOR_JOB_ID,
|
||||||
|
LIFE360_USERNAME: process.env.LIFE360_USERNAME,
|
||||||
|
LIFE360_PASSWORD: process.env.LIFE360_PASSWORD,
|
||||||
|
LIFE360_MEMBER_ID: process.env.LIFE360_MEMBER_ID,
|
||||||
|
MAX_DISTANCE: process.env.MAX_DISTANCE,
|
||||||
|
CENTER_LATITUDE: process.env.CENTER_LATITUDE,
|
||||||
|
CENTER_LONGITUDE: process.env.CENTER_LONGITUDE,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_serverEnv.success === false) {
|
||||||
|
console.error(
|
||||||
|
"❌ Invalid environment variables:\n",
|
||||||
|
...formatErrors(_serverEnv.error.format())
|
||||||
|
);
|
||||||
|
throw new Error("Invalid environment variables");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that server-side environment variables are not exposed to the client.
|
||||||
|
*/
|
||||||
|
for (let key of Object.keys(_serverEnv.data)) {
|
||||||
|
if (key.startsWith("NEXT_PUBLIC_")) {
|
||||||
|
console.warn("❌ You are exposing a server-side env-variable:", key);
|
||||||
|
|
||||||
|
throw new Error("You are exposing a server-side env-variable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const env = { ..._serverEnv.data };
|
||||||
10
src/env/util.mjs
vendored
Normal file
10
src/env/util.mjs
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export const formatErrors = (
|
||||||
|
/** @type {import('zod').ZodFormattedError<Map<string,string>,string>} */
|
||||||
|
errors,
|
||||||
|
) =>
|
||||||
|
Object.entries(errors)
|
||||||
|
.map(([name, value]) => {
|
||||||
|
if (value && "_errors" in value)
|
||||||
|
return `${name}: ${value._errors.join(", ")}\n`;
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
Reference in New Issue
Block a user