-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvite.config.ts
More file actions
123 lines (107 loc) · 3.44 KB
/
vite.config.ts
File metadata and controls
123 lines (107 loc) · 3.44 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import react from "@vitejs/plugin-react";
import "dotenv/config";
import path from "node:path";
import { defineConfig, splitVendorChunkPlugin } from "vite";
import injectHTML from "vite-plugin-html-inject";
import tsConfigPaths from "vite-tsconfig-paths";
type Extension = {
name: string;
version: string;
config: Record<string, unknown>;
};
enum ExtensionName {
FIREBASE_AUTH = "firebase-auth",
STACK_AUTH = "stack-auth"
}
const listExtensions = (): Extension[] => {
if (process.env.DATABUTTON_EXTENSIONS) {
try {
return JSON.parse(process.env.DATABUTTON_EXTENSIONS) as Extension[];
} catch (err: unknown) {
console.error("Error parsing DATABUTTON_EXTENSIONS", err);
console.error(process.env.DATABUTTON_EXTENSIONS);
return [];
}
}
return [];
};
const extensions = listExtensions();
const getExtensionConfig = (name: string): Record<string, unknown> | undefined => {
const extension = extensions.find((it) => it.name === name);
if (!extension) {
console.warn(`Extension ${name} not found`);
return undefined;
}
return extension.config;
};
/**
* Validates that Firebase config has all required keys.
* Returns true only if apiKey, projectId, and appId are present and non-empty.
* Implements "Atomic Config or Nothing" principle - config must be complete or not used.
*/
const isFirebaseConfigComplete = (
config: Record<string, unknown> | undefined,
): boolean => {
if (!config) return false;
const requiredKeys = ["apiKey", "projectId", "appId"];
return requiredKeys.every((key) => {
const value = config[key];
return typeof value === "string" && value.trim().length > 0;
});
};
const buildVariables = () => {
const appId = process.env.DATABUTTON_PROJECT_ID;
const defines: Record<string, string> = {
__APP_ID__: JSON.stringify(appId),
__API_PATH__: JSON.stringify(""),
__API_HOST__: JSON.stringify(""),
__API_PREFIX_PATH__: JSON.stringify(""),
__API_URL__: JSON.stringify("http://localhost:8000"),
__WS_API_URL__: JSON.stringify("ws://localhost:8000"),
__APP_BASE_PATH__: JSON.stringify("/"),
__APP_TITLE__: JSON.stringify("Databutton"),
__APP_FAVICON_LIGHT__: JSON.stringify("/favicon-light.svg"),
__APP_FAVICON_DARK__: JSON.stringify("/favicon-dark.svg"),
__APP_DEPLOY_USERNAME__: JSON.stringify(""),
__APP_DEPLOY_APPNAME__: JSON.stringify(""),
__APP_DEPLOY_CUSTOM_DOMAIN__: JSON.stringify(""),
__STACK_AUTH_CONFIG__: JSON.stringify(
JSON.stringify(getExtensionConfig(ExtensionName.STACK_AUTH)),
),
};
// Only inject Firebase config if it's complete with all required keys
// Implements "Atomic Config or Nothing" to prevent auth/invalid-api-key errors
const firebaseConfig = getExtensionConfig(ExtensionName.FIREBASE_AUTH);
if (isFirebaseConfigComplete(firebaseConfig)) {
defines.__FIREBASE_CONFIG__ = JSON.stringify(JSON.stringify(firebaseConfig));
console.log("Firebase config validated and injected successfully");
} else {
console.warn(
"Firebase config is incomplete (missing apiKey, projectId, or appId). " +
"Skipping injection to prevent auth errors in Preview.",
);
}
return defines;
};
// https://vite.dev/config/
export default defineConfig({
define: buildVariables(),
plugins: [react(), splitVendorChunkPlugin(), tsConfigPaths(), injectHTML()],
server: {
proxy: {
"/routes": {
target: "http://127.0.0.1:8000",
changeOrigin: true,
},
},
},
resolve: {
alias: {
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
},
},
});