MCPcopy
hub / github.com/opactorai/Claudable / syncEnvFileToDb

Function syncEnvFileToDb

lib/services/env.ts:219–287  ·  view source on GitHub ↗
(projectId: string)

Source from the content-addressed store, hash-verified

217}
218
219export async function syncEnvFileToDb(projectId: string): Promise<number> {
220 const project = await ensureProject(projectId);
221 const repoEnvPath = envFilePath(project);
222
223 let fileContents = '';
224 try {
225 fileContents = await fs.readFile(repoEnvPath, 'utf8');
226 } catch (error) {
227 if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
228 return 0;
229 }
230 throw error;
231 }
232
233 const fileVars = parseEnvFile(fileContents);
234 const existingVars = await prisma.envVar.findMany({
235 where: { projectId },
236 });
237
238 const existingMap = new Map(existingVars.map((envVar) => [envVar.key, envVar]));
239 const fileKeys = new Set(Object.keys(fileVars));
240 let changes = 0;
241
242 for (const [key, value] of Object.entries(fileVars)) {
243 const current = existingMap.get(key);
244 if (current) {
245 let currentValue: string | null = null;
246 try {
247 currentValue = decrypt(current.valueEncrypted);
248 } catch (error) {
249 console.warn(`[EnvService] Failed to decrypt env var ${current.key}:`, error);
250 }
251 if (currentValue !== value) {
252 await prisma.envVar.update({
253 where: {
254 projectId_key: { projectId, key },
255 },
256 data: { valueEncrypted: encrypt(value) },
257 });
258 changes += 1;
259 }
260 } else {
261 await prisma.envVar.create({
262 data: {
263 projectId,
264 key,
265 valueEncrypted: encrypt(value),
266 scope: 'runtime',
267 varType: 'string',
268 isSecret: true,
269 },
270 });
271 changes += 1;
272 }
273 }
274
275 for (const envVar of existingVars) {
276 if (!fileKeys.has(envVar.key)) {

Callers 1

POSTFunction · 0.90

Calls 5

decryptFunction · 0.90
encryptFunction · 0.90
ensureProjectFunction · 0.85
envFilePathFunction · 0.85
parseEnvFileFunction · 0.85

Tested by

no test coverage detected