Skip to content

Instantly share code, notes, and snippets.

@cullylarson
Last active January 30, 2024 14:23
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save cullylarson/8f22f7cc2ce5bc7deefda5c93ac81291 to your computer and use it in GitHub Desktop.
Save cullylarson/8f22f7cc2ce5bc7deefda5c93ac81291 to your computer and use it in GitHub Desktop.
Example configuration file
const stages = ['production', 'staging', 'development', 'test'] as const;
type Stage = typeof stages[number];
function getStage(stages: Stage[]) {
if (!stages.length) return 'production';
for (const stage of stages) {
// if any of the provided stages is production, assume we are in production
if (stage === 'production') {
return stage;
}
}
return stages[0];
}
function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
return value !== null && value !== undefined;
}
function isStage(potentialStage: string): potentialStage is Stage {
return stages.includes(potentialStage as Stage);
}
const stage = getStage(
[process.env.NODE_ENV, process.env.APP_ENV].filter(notEmpty).filter(isStage)
);
function envToBool(value: string | undefined) {
if (!value) {
return false;
}
return ['true', 'TRUE', '1'].includes(value);
}
function envToStr(value: string | undefined, defaultValue = '') {
return value === undefined ? defaultValue : value;
}
function envToNumber(value: string | undefined, defaultValue: number): number {
const numValue = value === undefined || value === "" ? defaultValue : Number(value);
return isNaN(numValue) ? defaultValue : numValue;
}
const configSchema = z.object({
stage: z.enum(stages),
ci: z.object({
isPullRequest: z.boolean(),
}),
api: {
tokenLifetimeMs: z.number().min(1),
},
database: {
url: z.string().min(1),
shouldMigrate: z.boolean(),
},
sentry: {
enabled: z.boolean(),
dsn: z.string().optional(),
},
git: {
commit: z.string().optional(),
},
});
export const config = configSchema.parse({
stage,
ci: {
isPullRequest: envToBool(process.env.IS_PULL_REQUEST),
},
api: {
tokenLifetimeMs: envToNumber(process.env.API_TOKEN_LIFETIME_MS, 3600000), // 3600000ms = 1h
},
database: {
url: envToStr(process.env.DATABASE_URL),
shouldMigrate: envToBool(process.env.SHOULD_MIGRATE),
},
sentry: {
enabled: envToBool(process.env.SENTRY_ENABLED),
dsn: envToStr(process.env.NEXT_PUBLIC_SENTRY_DSN),
},
git: {
commit: envToStr(process.env.FC_GIT_COMMIT_SHA || process.env.RENDER_GIT_COMMIT),
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment