+
{loadingLabel} {config.label}…
)}
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index 3604773..8b61eff 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -92,7 +92,7 @@ services:
- .env.docker.dev
environment:
FILE_STORAGE_ROOT: /var/lib/rentaldrivego/storage
- command: ["npm", "run", "dev", "--workspace", "@rentaldrivego/api"]
+ command: ["sh", "-c", "npm run build --workspace @rentaldrivego/types && cd /app/apps/api && exec /app/node_modules/.bin/ts-node-dev --respawn --transpile-only src/index.ts"]
ports:
- "4000:4000"
volumes:
diff --git a/scripts/run-with-env-file.cjs b/scripts/run-with-env-file.cjs
new file mode 100644
index 0000000..e068d2d
--- /dev/null
+++ b/scripts/run-with-env-file.cjs
@@ -0,0 +1,78 @@
+#!/usr/bin/env node
+
+const fs = require('node:fs')
+const path = require('node:path')
+const { spawn } = require('node:child_process')
+
+function parseEnvFile(content) {
+ const env = {}
+
+ for (const rawLine of content.split(/\r?\n/)) {
+ const line = rawLine.trim()
+ if (!line || line.startsWith('#')) continue
+
+ const normalized = line.startsWith('export ') ? line.slice(7).trim() : line
+ const separatorIndex = normalized.indexOf('=')
+ if (separatorIndex === -1) continue
+
+ const key = normalized.slice(0, separatorIndex).trim()
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue
+
+ let value = normalized.slice(separatorIndex + 1)
+
+ if (
+ (value.startsWith('"') && value.endsWith('"')) ||
+ (value.startsWith("'") && value.endsWith("'"))
+ ) {
+ const quote = value[0]
+ value = value.slice(1, -1)
+
+ if (quote === '"') {
+ value = value
+ .replace(/\\n/g, '\n')
+ .replace(/\\r/g, '\r')
+ .replace(/\\t/g, '\t')
+ .replace(/\\"/g, '"')
+ .replace(/\\\\/g, '\\')
+ }
+ }
+
+ env[key] = value
+ }
+
+ return env
+}
+
+const [, , envFileArg, commandArg, ...commandArgs] = process.argv
+
+if (!envFileArg || !commandArg) {
+ console.error('Usage: node run-with-env-file.cjs
[args...]')
+ process.exit(1)
+}
+
+const envFilePath = path.resolve(process.cwd(), envFileArg)
+const commandPath = path.resolve(process.cwd(), commandArg)
+const fileContent = fs.readFileSync(envFilePath, 'utf8')
+const parsedEnv = parseEnvFile(fileContent)
+
+const child = spawn(commandPath, commandArgs, {
+ stdio: 'inherit',
+ env: {
+ ...process.env,
+ ...parsedEnv,
+ },
+})
+
+child.on('exit', (code, signal) => {
+ if (signal) {
+ process.kill(process.pid, signal)
+ return
+ }
+
+ process.exit(code ?? 0)
+})
+
+child.on('error', (error) => {
+ console.error(error.message)
+ process.exit(1)
+})