Make local DEV work out of the box

This commit is contained in:
MartinBraquet
2025-09-20 23:51:28 +02:00
parent d7c95e2ae0
commit 84a437772d
22 changed files with 138 additions and 121 deletions

View File

@@ -1,4 +1,4 @@
import { ENV_CONFIG } from 'common/envs/constants'
import {BACKEND_DOMAIN} from 'common/envs/constants'
type ErrorCode =
| 400 // your input is bad (like zod is mad)
@@ -11,6 +11,7 @@ type ErrorCode =
export class APIError extends Error {
code: ErrorCode
details?: unknown
constructor(code: ErrorCode, message: string, details?: unknown) {
super(message)
this.code = code
@@ -19,20 +20,19 @@ export class APIError extends Error {
}
}
const prefix = 'v0'
export function pathWithPrefix(path: string) {
return `/v0${path}`
return `/${prefix}${path}`
}
export function getWebsocketUrl() {
const endpoint = process.env.NEXT_PUBLIC_API_URL ?? ENV_CONFIG.apiEndpoint
const protocol = endpoint.startsWith('localhost') ? 'ws' : 'wss'
const protocol = BACKEND_DOMAIN.startsWith('localhost') ? 'ws' : 'wss'
return `${protocol}://${endpoint}/ws`
return `${protocol}://${BACKEND_DOMAIN}/ws`
}
export function getApiUrl(path: string) {
const endpoint = process.env.NEXT_PUBLIC_API_URL ?? ENV_CONFIG.apiEndpoint
const protocol = endpoint.startsWith('localhost') ? 'http' : 'https'
const prefix = 'v0'
return `${protocol}://${endpoint}/${prefix}/${path}`
const protocol = BACKEND_DOMAIN.startsWith('localhost') ? 'http' : 'https'
return `${protocol}://${BACKEND_DOMAIN}/${prefix}/${path}`
}

View File

@@ -15,7 +15,13 @@ export function isModId(id: string) {
return MOD_IDS.includes(id)
}
export const DOMAIN = ENV_CONFIG.domain
export const LOCAL_WEB_DOMAIN = 'localhost:3000';
export const LOCAL_BACKEND_DOMAIN = 'localhost:8088';
export const IS_LOCAL = !process.env.VERCEL && !process.env.K_SERVICE;
console.log(IS_LOCAL ? 'Running in local mode' : 'Running in deployed mode', isProd() ? '(prod)' : '(dev)');
export const DOMAIN = IS_LOCAL ? LOCAL_WEB_DOMAIN : ENV_CONFIG.domain
export const BACKEND_DOMAIN = IS_LOCAL ? LOCAL_BACKEND_DOMAIN : ENV_CONFIG.backendDomain
export const FIREBASE_CONFIG = ENV_CONFIG.firebaseConfig
export const PROJECT_ID = ENV_CONFIG.firebaseConfig.projectId
@@ -98,7 +104,4 @@ export const RESERVED_PATHS = [
'users',
'web',
'welcome',
]
export const LOCAL_WEB_URL = 'http://localhost:3000';
export const LOCAL_DEV = process.env.GOOGLE_CLOUD_PROJECT == null
]

View File

@@ -2,9 +2,12 @@ import { EnvConfig, PROD_CONFIG } from './prod'
export const DEV_CONFIG: EnvConfig = {
...PROD_CONFIG,
domain: 'dev.compassmeet.com',
backendDomain: 'api.dev.compassmeet.com',
supabaseInstanceId: 'zbspxezubpzxmuxciurg',
supabaseServiceRoleKey: '09wATRREfAzyL5pc', // For database write access (dev). A 16-character password with digits and letters.
supabasePwd: 'FO3y0G7chzdq6aE7', // For database write access (dev). A 16-character password with digits and letters.
supabaseAnonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inpic3B4ZXp1YnB6eG11eGNpdXJnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTc2ODM0MTMsImV4cCI6MjA3MzI1OTQxM30.ZkM7zlawP8Nke0T3KJrqpOQ4DzqPaXTaJXLC2WU8Y7c',
googleApplicationCredentials: 'googleApplicationCredentials-dev.json',
firebaseConfig: {
apiKey: "AIzaSyBspL9glBXWbMsjmtt36dgb2yU0YGGhzKo",
authDomain: "compass-57c3c.firebaseapp.com",
@@ -15,5 +18,5 @@ export const DEV_CONFIG: EnvConfig = {
appId: "1:297460199314:web:c45678c54285910e255b4b",
measurementId: "G-N6LZ64EMJ2",
region: 'us-west1',
}
},
}

View File

@@ -3,9 +3,10 @@ export type EnvConfig = {
firebaseConfig: FirebaseConfig
supabaseInstanceId: string
supabaseAnonKey: string
supabaseServiceRoleKey?: string
supabasePwd?: string
posthogKey: string
apiEndpoint: string
backendDomain: string
googleApplicationCredentials: string
// IDs for v2 cloud functions -- find these by deploying a cloud function and
// examining the URL, https://[name]-[cloudRunId]-[cloudRunRegion].a.run.app
@@ -33,6 +34,11 @@ type FirebaseConfig = {
export const PROD_CONFIG: EnvConfig = {
posthogKey: 'phc_tFvQzHiMVdaAIgE38xqYomMN8q8SB5K45fqmkKNjfBU',
domain: 'compassmeet.com',
backendDomain: 'api.compassmeet.com',
supabaseInstanceId: 'ltzepxnhhnrnvovqblfr',
supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_KEY || '',
supabasePwd: process.env.SUPABASE_DB_PASSWORD || '',
googleApplicationCredentials: process.env.GOOGLE_APPLICATION_CREDENTIALS || '',
firebaseConfig: {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',
authDomain: "compass-130ba.firebaseapp.com",
@@ -46,12 +52,8 @@ export const PROD_CONFIG: EnvConfig = {
},
cloudRunId: 'w3txbmd3ba',
cloudRunRegion: 'uc',
supabaseInstanceId: 'ltzepxnhhnrnvovqblfr',
supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_KEY || '',
apiEndpoint: 'api.compassmeet.com',
adminIds: [
'0vaZsIJk9zLVOWY4gb61gTrRIU73', // Martin
],
faviconPath: '/favicon.ico',
}

View File

@@ -1,6 +1,6 @@
import { readFileSync } from 'fs'
import { SecretManagerServiceClient } from '@google-cloud/secret-manager'
import { zip } from 'lodash'
import {SecretManagerServiceClient} from '@google-cloud/secret-manager'
import {zip} from 'lodash'
import {IS_LOCAL} from "common/envs/constants";
// List of secrets that are available to backend (api, functions, scripts, etc.)
// Edit them at:
@@ -27,6 +27,9 @@ type SecretId = (typeof secrets)[number]
// For deployed google cloud service, no credential is needed.
// For local and Vercel deployments: requires credentials json object.
export const getSecrets = async (credentials?: any, ...ids: SecretId[]) => {
if (!ids.length && IS_LOCAL) return {}
console.log('Fetching secrets...')
let client: SecretManagerServiceClient
if (credentials) {
const projectId = credentials['project_id']
@@ -71,29 +74,3 @@ export const loadSecretsToEnv = async (credentials?: any) => {
}
}
// Get service account credentials from Vercel environment variable or local file.
export const getServiceAccountCredentials = (env: 'PROD' | 'DEV') => {
// Vercel environment variable for service credential.
const value =
env === 'PROD'
? process.env.PROD_FIREBASE_SERVICE_ACCOUNT_KEY
: process.env.DEV_FIREBASE_SERVICE_ACCOUNT_KEY
if (value && !process.env.LOCAL) {
return JSON.parse(value)
}
// Local environment variable for service credential.
const envVar = `GOOGLE_APPLICATION_CREDENTIALS_${env}`
const keyPath = process.env[envVar]
if (keyPath == null) {
throw new Error(
`Please set the ${envVar} environment variable to contain the path to your ${env} environment key file.`
)
}
try {
return JSON.parse(readFileSync(keyPath, { encoding: 'utf8' }))
} catch (e) {
throw new Error(`Failed to load service account key from ${keyPath}.`)
}
}

View File

@@ -1,4 +1,4 @@
import {DOMAIN, LOCAL_DEV, LOCAL_WEB_URL} from 'common/envs/constants'
import {DOMAIN} from 'common/envs/constants'
// opengraph functions that run in static props or client-side, but not in the edge (in image creation)
@@ -10,5 +10,5 @@ export function buildOgUrl<P extends Record<string, string>>(
const generateUrlParams = (params: P) =>
new URLSearchParams(params).toString()
return `https://${domain ?? LOCAL_DEV ? LOCAL_WEB_URL : DOMAIN}/api/og/${endpoint}?` + generateUrlParams(props)
return `https://${domain ?? DOMAIN}/api/og/${endpoint}?` + generateUrlParams(props)
}