Skip to content

Commit 588ad6d

Browse files
committed
fix: improve error handling in datasource URL parsing
1 parent 1e2afd5 commit 588ad6d

File tree

2 files changed

+31
-28
lines changed

2 files changed

+31
-28
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/proxy",
3-
"version": "0.2.2",
3+
"version": "0.2.3",
44
"description": "A CLI tool to run an Express server that proxies CRUD requests to a ZenStack backend",
55
"main": "index.js",
66
"publishConfig": {

src/zmodel-parser.ts

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,9 @@ function loadPrismaConfig(schemaDir: string): string | null {
7171

7272
// Use Function constructor to safely evaluate the object literal
7373
// This is safer than eval as it doesn't have access to the local scope
74-
try {
75-
const configFn = new Function('env', `return ${configObjectStr}`)
76-
const config = configFn(env)
77-
78-
return config?.datasource?.url || null
79-
} catch (evalError) {
80-
console.warn(`Warning: Could not evaluate config object: ${evalError}`)
81-
return null
82-
}
74+
const configFn = new Function('env', `return ${configObjectStr}`)
75+
const config = configFn(env)
76+
return config?.datasource?.url
8377
} catch (error) {
8478
if (error instanceof Error && error.message.includes('Environment variable')) {
8579
throw error
@@ -117,34 +111,43 @@ function parseDatasource(
117111
return { provider, url: datasourceUrlOverride }
118112
}
119113

120-
// Extract url from schema
121-
let urlMatch = datasourceBlock.match(/url\s*=\s*['"]([^'"]+)['"]/)
114+
// Extract url value using single regex (could be string literal, env() call, or expression)
115+
const urlMatch = datasourceBlock.match(/url\s*=\s*([^\n]+)/)
122116
let url: string | null = null
123117

124118
if (urlMatch) {
125-
url = urlMatch[1]
126-
} else {
127-
// Try to match env("xxx")
128-
const envMatch = datasourceBlock.match(/url\s*=\s*env\(\s*['"]([^'"]+)['"]\s*\)/)
129-
if (envMatch) {
130-
const envVar = envMatch[1]
131-
const envValue = process.env[envVar]
132-
if (envValue) {
133-
url = envValue
119+
const urlValueStr = urlMatch[1].trim()
120+
121+
// Create env helper function
122+
const env = (varName: string) => {
123+
const value = process.env[varName]
124+
if (!value) {
125+
throw new CliError(`Environment variable ${varName} is not set`)
134126
}
127+
return value
135128
}
136-
}
137129

138-
// If no URL found in schema, try prisma.config.ts (Prisma 7)
139-
if (!url) {
130+
try {
131+
// Use Function constructor to evaluate the url value
132+
const urlFn = new Function('env', `return ${urlValueStr}`)
133+
url = urlFn(env)
134+
} catch (evalError) {
135+
throw new CliError(
136+
'Could not evaluate datasource url from schema, you could provide it via -d option.'
137+
)
138+
}
139+
} else {
140140
url = loadPrismaConfig(schemaDir)
141+
// If still no URL found, throw error
142+
if (url == null) {
143+
throw new CliError(
144+
'No datasource URL found. For Prisma 7, ensure prisma.config.ts exists with datasource configuration, or provide the URL via -d option.'
145+
)
146+
}
141147
}
142148

143-
// If still no URL found, throw error
144149
if (!url) {
145-
throw new CliError(
146-
'No datasource URL found. For Prisma 7, ensure prisma.config.ts exists with datasource configuration, or provide the URL via --datasource-url option.'
147-
)
150+
throw new CliError('datasource url has no value, you could provide it via -d option.')
148151
}
149152

150153
return { provider, url }

0 commit comments

Comments
 (0)