| 478 | ); |
| 479 | return new Map(groupedResults.flat()); |
| 480 | } |
| 481 | |
| 482 | function resolveSecretStoreSource( |
| 483 | secretName: string, |
| 484 | envLocal: Map<string, string>, |
| 485 | localSecretSources: Map<string, { sourceKey: string; value: string }> |
| 486 | ): { sourceKey: string; value: string } | undefined { |
| 487 | const baseKey = secretName.replace(/_(PROD|DEV)$/, ''); |
| 488 | const exactLocalSource = localSecretSources.get(secretName); |
| 489 | if (exactLocalSource) { |
| 490 | return exactLocalSource; |
| 491 | } |
| 492 | |
| 493 | const exactEnvLocalValue = envLocal.get(secretName); |
| 494 | if (exactEnvLocalValue) { |
| 495 | return { sourceKey: secretName, value: exactEnvLocalValue }; |
| 496 | } |
| 497 | |
| 498 | const baseEnvLocalValue = envLocal.get(baseKey); |
| 499 | if (baseEnvLocalValue) { |
| 500 | return { sourceKey: baseKey, value: baseEnvLocalValue }; |
| 501 | } |
| 502 | |
| 503 | return localSecretSources.get(baseKey); |
| 504 | } |
| 505 | |
| 506 | function collectLocalSecretSources( |
| 507 | repoRoot: string, |
| 508 | workerDirs: string[], |
| 509 | envLocal: Map<string, string>, |
| 510 | lanIp: string | undefined, |
| 511 | dirUsesLanIp: Map<string, boolean> |
| 512 | ): Map<string, { sourceKey: string; value: string }> { |
| 513 | const sources = new Map<string, { sourceKey: string; value: string }>(); |
| 514 | |
| 515 | for (const workerDir of workerDirs) { |
| 516 | const devVarsPath = path.join(repoRoot, workerDir, '.dev.vars'); |
| 517 | const localVars = readEnvFile(devVarsPath); |
| 518 | for (const [key, value] of localVars) { |
| 519 | if (value) { |
| 520 | sources.set(key, { |
| 521 | sourceKey: `${workerDir}/.dev.vars:${key}`, |
| 522 | value, |
| 523 | }); |
| 524 | } |
| 525 | } |
| 526 | |
| 527 | const examplePath = path.join(repoRoot, workerDir, '.dev.vars.example'); |
| 528 | const serviceUsesLanIp = dirUsesLanIp.get(workerDir) ?? false; |
| 529 | if (fs.existsSync(examplePath)) { |
| 530 | const entries = parseExampleFile(fs.readFileSync(examplePath, 'utf-8')); |
| 531 | for (const entry of entries) { |
| 532 | if (entry.annotation.type === 'exec') { |
| 533 | continue; |
| 534 | } |
| 535 | const { value } = resolveAnnotatedValue( |
| 536 | entry.key, |
| 537 | entry, |