|
| 1 | +import { type BuildOptions } from "@opennextjs/aws/build/helper.js"; |
1 | 2 | import { getPlatformProxy, type GetPlatformProxyOptions } from "wrangler"; |
2 | 3 |
|
| 4 | +import { extractProjectEnvVars } from "../build/utils/extract-project-env-vars.js"; |
| 5 | + |
3 | 6 | export type WorkerEnvVar = Record<keyof CloudflareEnv, string | undefined>; |
4 | 7 |
|
5 | 8 | /** |
6 | | - * Return the string env vars from the worker. |
| 9 | + * Returns the env vars to use by the CLI. |
| 10 | + * |
| 11 | + * The environments variables are returned from a combination of `process.env`, wrangler config, and `.env*` files. |
| 12 | + * |
| 13 | + * Recommended usage on CI: |
| 14 | + * |
| 15 | + * - Add you secrets to `process.env` (i.e. `CF_ACCOUNT_ID`) |
| 16 | + * - Add public values to the wrangler config `wrangler.jsonc` (i.e. `R2_CACHE_PREFIX_ENV_NAME`) |
| 17 | + * |
| 18 | + * Note: `.dev.vars*` and `.env*` should not be checked in. |
| 19 | + * |
| 20 | + * Recommended usage for local dev: |
| 21 | + * |
| 22 | + * - Add you secrets to either a `.dev.vars*` or `.env*` file (i.e. `CF_ACCOUNT_ID`) |
| 23 | + * - Add public values to the wrangler config `wrangler.jsonc` (i.e. `R2_CACHE_PREFIX_ENV_NAME`) |
| 24 | + * |
| 25 | + * Note: `.env*` files are also used by `next dev` while `.dev.var*` files are only loaded by `wrangler`. |
| 26 | + * |
| 27 | + * Loading details: |
| 28 | + * |
| 29 | + * 1. The variables are first initialized from `process.env` |
| 30 | + * 2. They are then augmented/replaced with variables from the wrangler config (`wrangler.jsonc` and `.dev.vars*`) |
| 31 | + * 3. They are then augmented with variables from `.env*` files (existing values are not replaced). |
7 | 32 | * |
8 | 33 | * @param options Options to pass to `getPlatformProxy`, i.e. to set the environment |
| 34 | + * @param buildOpts Open Next build options |
9 | 35 | * @returns the env vars |
10 | 36 | */ |
11 | | -export async function getEnvFromPlatformProxy(options: GetPlatformProxyOptions) { |
12 | | - const envVars = {} as WorkerEnvVar; |
13 | | - const proxy = await getPlatformProxy<CloudflareEnv>(options); |
| 37 | +export async function getEnvFromPlatformProxy(options: GetPlatformProxyOptions, buildOpts: BuildOptions) { |
| 38 | + // 1. Start from `process.env` |
| 39 | + const envVars = process.env; |
| 40 | + |
| 41 | + // 2. Apply vars from workers `env` |
| 42 | + const proxy = await getPlatformProxy<CloudflareEnv>({ |
| 43 | + ...options, |
| 44 | + // Next.js uses a different mechanism to load `.env*` files from wrangler. |
| 45 | + // We prevent wrangler for loading the files and handle that in `getEnvFromPlatformProxy`. |
| 46 | + envFiles: [], |
| 47 | + }); |
| 48 | + |
14 | 49 | Object.entries(proxy.env).forEach(([key, value]) => { |
15 | 50 | if (typeof value === "string") { |
| 51 | + // filter out bindings by only considering string values |
16 | 52 | envVars[key as keyof CloudflareEnv] = value; |
17 | 53 | } |
18 | 54 | }); |
| 55 | + |
19 | 56 | await proxy.dispose(); |
20 | | - return envVars; |
| 57 | + |
| 58 | + // 3. Apply new vars from `.env*` files |
| 59 | + let mode: "production" | "development" | "test" = "production"; |
| 60 | + if (envVars.NEXTJS_ENV === "development") { |
| 61 | + mode = "development"; |
| 62 | + } else if (envVars.NEXTJS_ENV === "test") { |
| 63 | + mode = "test"; |
| 64 | + } |
| 65 | + |
| 66 | + const dotEnvVars = extractProjectEnvVars(mode, buildOpts); |
| 67 | + |
| 68 | + for (const varName in dotEnvVars) { |
| 69 | + envVars[varName] ??= dotEnvVars[varName]; |
| 70 | + } |
| 71 | + |
| 72 | + return envVars as unknown as WorkerEnvVar; |
21 | 73 | } |
22 | 74 |
|
23 | 75 | /** |
|
0 commit comments