1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
import { ZodIssueCode, z } from 'zod'
const interpretEnvVarAsBool = (val: unknown): boolean => {
if (typeof val !== 'string') return false
return ['true', 'yes', '1', 'on'].includes(val.toLowerCase())
}
const envSchema = z
.object({
POSTGRES_URL_NON_POOLING: z.string().url(),
POSTGRES_PRISMA_URL: z.string().url(),
NEXT_PUBLIC_BASE_URL: z
.string()
.optional()
.default(
process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: 'http://localhost:3000',
),
NEXT_PUBLIC_ENABLE_EXPENSE_DOCUMENTS: z.preprocess(
interpretEnvVarAsBool,
z.boolean().default(false),
),
S3_UPLOAD_KEY: z.string().optional(),
S3_UPLOAD_SECRET: z.string().optional(),
S3_UPLOAD_BUCKET: z.string().optional(),
S3_UPLOAD_REGION: z.string().optional(),
S3_UPLOAD_ENDPOINT: z.string().optional(),
NEXT_PUBLIC_ENABLE_RECEIPT_EXTRACT: z.preprocess(
interpretEnvVarAsBool,
z.boolean().default(false),
),
NEXT_PUBLIC_ENABLE_CATEGORY_EXTRACT: z.preprocess(
interpretEnvVarAsBool,
z.boolean().default(false),
),
OPENAI_API_KEY: z.string().optional(),
})
.superRefine((env, ctx) => {
if (
env.NEXT_PUBLIC_ENABLE_EXPENSE_DOCUMENTS &&
// S3_UPLOAD_ENDPOINT is fully optional as it will only be used for providers other than AWS
(!env.S3_UPLOAD_BUCKET ||
!env.S3_UPLOAD_KEY ||
!env.S3_UPLOAD_REGION ||
!env.S3_UPLOAD_SECRET)
) {
ctx.addIssue({
code: ZodIssueCode.custom,
message:
'If NEXT_PUBLIC_ENABLE_EXPENSE_DOCUMENTS is specified, then S3_* must be specified too',
})
}
if (
(env.NEXT_PUBLIC_ENABLE_RECEIPT_EXTRACT ||
env.NEXT_PUBLIC_ENABLE_CATEGORY_EXTRACT) &&
!env.OPENAI_API_KEY
) {
ctx.addIssue({
code: ZodIssueCode.custom,
message:
'If NEXT_PUBLIC_ENABLE_RECEIPT_EXTRACT or NEXT_PUBLIC_ENABLE_CATEGORY_EXTRACT is specified, then OPENAI_API_KEY must be specified too',
})
}
})
export const env = envSchema.parse(process.env)
|