diff --git a/.changeset/thirty-kings-yell.md b/.changeset/thirty-kings-yell.md new file mode 100644 index 000000000000..bd1a72c729a9 --- /dev/null +++ b/.changeset/thirty-kings-yell.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-node': patch +--- + +[breaking] Replace `options.env` with `options.envPrefix` diff --git a/packages/adapter-node/README.md b/packages/adapter-node/README.md index 81d6d01ff6f8..383a5da88e37 100644 --- a/packages/adapter-node/README.md +++ b/packages/adapter-node/README.md @@ -83,18 +83,7 @@ export default { // default options are shown out: 'build', precompress: false, - env: { - path: 'SOCKET_PATH', - host: 'HOST', - port: 'PORT', - origin: 'ORIGIN', - xffDepth: 'XFF_DEPTH', - headers: { - address: 'ADDRESS_HEADER', - protocol: 'PROTOCOL_HEADER', - host: 'HOST_HEADER' - } - } + envPrefix: '' }) } }; @@ -108,28 +97,18 @@ The directory to build the server to. It defaults to `build` — i.e. `node buil Enables precompressing using gzip and brotli for assets and prerendered pages. It defaults to `false`. -### env +### envPrefix -If you need to change the name of the environment variables used to configure the deployment (for example, you need to run multiple deployments from a single environment), you can tell the app to expect custom environment variables using the `env` option: +If you need to change the name of the environment variables used to configure the deployment (for example, to deconflict with environment variables you don't control), you can specify a prefix: ```js -env: { - host: 'MY_HOST_VARIABLE', - port: 'MY_PORT_VARIABLE', - origin: 'MY_ORIGINURL', - xffDepth: 'MY_XFF_DEPTH', - headers: { - address: 'MY_ADDRESS_HEADER', - protocol: 'MY_PROTOCOL_HEADER', - host: 'MY_HOST_HEADER' - } -} +envPrefix: 'MY_CUSTOM_'; ``` ``` -MY_HOST_VARIABLE=127.0.0.1 \ -MY_PORT_VARIABLE=4000 \ -MY_ORIGINURL=https://my.site \ +MY_CUSTOM_HOST=127.0.0.1 \ +MY_CUSTOM_PORT=4000 \ +MY_CUSTOM_ORIGIN=https://my.site \ node build ``` diff --git a/packages/adapter-node/index.d.ts b/packages/adapter-node/index.d.ts index b7785dfb63e7..09411ffabb98 100644 --- a/packages/adapter-node/index.d.ts +++ b/packages/adapter-node/index.d.ts @@ -1,26 +1,13 @@ import { Adapter } from '@sveltejs/kit'; declare global { - const HOST_ENV: string; - const PATH_ENV: string; - const PORT_ENV: string; + const ENV_PREFIX: string; } interface AdapterOptions { out?: string; precompress?: boolean; - env?: { - path?: string; - host?: string; - port?: string; - origin?: string; - xffDepth?: string; - headers?: { - address?: string; - protocol?: string; - host?: string; - }; - }; + envPrefix?: string; } declare function plugin(options?: AdapterOptions): Adapter; diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js index b84f6b4e8b76..3eb6038a11cf 100644 --- a/packages/adapter-node/index.js +++ b/packages/adapter-node/index.js @@ -10,22 +10,17 @@ const pipe = promisify(pipeline); const files = fileURLToPath(new URL('./files', import.meta.url).href); /** @type {import('.')} */ -export default function ({ - out = 'build', - precompress, - env: { - path: path_env = 'SOCKET_PATH', - host: host_env = 'HOST', - port: port_env = 'PORT', - origin: origin_env = 'ORIGIN', - xffDepth: xff_depth_env = 'XFF_DEPTH', - headers: { - address: address_header_env = 'ADDRESS_HEADER', - protocol: protocol_header_env = 'PROTOCOL_HEADER', - host: host_header_env = 'HOST_HEADER' - } = {} - } = {} -} = {}) { +export default function (opts = {}) { + // TODO remove for 1.0 + // @ts-expect-error + if (opts.env) { + throw new Error( + 'options.env has been removed in favour of options.envPrefix. Consult the adapter-node README: https://github.com/sveltejs/kit/tree/master/packages/adapter-node' + ); + } + + const { out = 'build', precompress, envPrefix = '' } = opts; + return { name: '@sveltejs/adapter-node', @@ -49,14 +44,7 @@ export default function ({ replace: { SERVER: './server/index.js', MANIFEST: './manifest.js', - PATH_ENV: JSON.stringify(path_env), - HOST_ENV: JSON.stringify(host_env), - PORT_ENV: JSON.stringify(port_env), - ORIGIN: origin_env ? `process.env[${JSON.stringify(origin_env)}]` : 'undefined', - XFF_DEPTH_ENV: xff_depth_env, - PROTOCOL_HEADER: JSON.stringify(protocol_header_env), - HOST_HEADER: JSON.stringify(host_header_env), - ADDRESS_HEADER: JSON.stringify(address_header_env) + ENV_PREFIX: JSON.stringify(envPrefix) } }); diff --git a/packages/adapter-node/src/env.js b/packages/adapter-node/src/env.js new file mode 100644 index 000000000000..2f55c26b34c4 --- /dev/null +++ b/packages/adapter-node/src/env.js @@ -0,0 +1,34 @@ +/* global ENV_PREFIX */ + +const expected = new Set([ + 'SOCKET_PATH', + 'HOST', + 'PORT', + 'ORIGIN', + 'XFF_DEPTH', + 'ADDRESS_HEADER', + 'PROTOCOL_HEADER', + 'HOST_HEADER' +]); + +if (ENV_PREFIX) { + for (const name in process.env) { + if (name.startsWith(ENV_PREFIX)) { + const unprefixed = name.slice(ENV_PREFIX.length); + if (!expected.has(unprefixed)) { + throw new Error( + `You should change envPrefix (${ENV_PREFIX}) to avoid conflicts with existing environment variables — unexpectedly saw ${name}` + ); + } + } + } +} + +/** + * @param {string} name + * @param {any} fallback + */ +export function env(name, fallback) { + const prefixed = ENV_PREFIX + name; + return prefixed in process.env ? process.env[prefixed] : fallback; +} diff --git a/packages/adapter-node/src/handler.d.ts b/packages/adapter-node/src/handler.d.ts deleted file mode 100644 index 2249bf2757c6..000000000000 --- a/packages/adapter-node/src/handler.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Handle } from '@sveltejs/kit'; - -declare global { - const ORIGIN: string; - const ADDRESS_HEADER: string; - const HOST_HEADER: string; - const PROTOCOL_HEADER: string; - const XFF_DEPTH_ENV: string; -} - -export const handler: Handle; diff --git a/packages/adapter-node/src/handler.js b/packages/adapter-node/src/handler.js index 56a0ca91133e..d5c66d920b15 100644 --- a/packages/adapter-node/src/handler.js +++ b/packages/adapter-node/src/handler.js @@ -6,16 +6,17 @@ import { fileURLToPath } from 'url'; import { getRequest, setResponse } from '@sveltejs/kit/node'; import { Server } from 'SERVER'; import { manifest } from 'MANIFEST'; +import { env } from './env.js'; -/* global ORIGIN, ADDRESS_HEADER, PROTOCOL_HEADER, HOST_HEADER, XFF_DEPTH_ENV */ +/* global ENV_PREFIX */ const server = new Server(manifest); -const origin = ORIGIN; -const xff_depth = XFF_DEPTH_ENV ? parseInt(process.env[XFF_DEPTH_ENV]) : 1; +const origin = env('ORIGIN', undefined); +const xff_depth = parseInt(env('XFF_DEPTH', '1')); -const address_header = ADDRESS_HEADER && (process.env[ADDRESS_HEADER] || '').toLowerCase(); -const protocol_header = PROTOCOL_HEADER && process.env[PROTOCOL_HEADER]; -const host_header = (HOST_HEADER && process.env[HOST_HEADER]) || 'host'; +const address_header = env('ADDRESS_HEADER', '').toLowerCase(); +const protocol_header = env('PROTOCOL_HEADER', '').toLowerCase(); +const host_header = env('HOST_HEADER', 'host').toLowerCase(); const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -51,7 +52,9 @@ const ssr = async (req, res) => { if (address_header && !(address_header in req.headers)) { throw new Error( - `Address header was specified with ${ADDRESS_HEADER}=${process.env[ADDRESS_HEADER]} but is absent from request` + `Address header was specified with ${ + ENV_PREFIX + 'ADDRESS_HEADER' + }=${address_header} but is absent from request` ); } @@ -66,12 +69,14 @@ const ssr = async (req, res) => { const addresses = value.split(','); if (xff_depth < 1) { - throw new Error(`${XFF_DEPTH_ENV} must be a positive integer`); + throw new Error(`${ENV_PREFIX + 'XFF_DEPTH'} must be a positive integer`); } if (xff_depth > addresses.length) { throw new Error( - `${XFF_DEPTH_ENV} is ${xff_depth}, but only found ${addresses.length} addresses` + `${ENV_PREFIX + 'XFF_DEPTH'} is ${xff_depth}, but only found ${ + addresses.length + } addresses` ); } return addresses[addresses.length - xff_depth].trim(); diff --git a/packages/adapter-node/src/index.js b/packages/adapter-node/src/index.js index 65024cf97d36..873ed67468ed 100644 --- a/packages/adapter-node/src/index.js +++ b/packages/adapter-node/src/index.js @@ -1,12 +1,11 @@ import { handler } from './handler.js'; +import { env } from './env.js'; import compression from 'compression'; import polka from 'polka'; -/* global PATH_ENV, HOST_ENV, PORT_ENV */ - -export const path = process.env[PATH_ENV] || false; -export const host = process.env[HOST_ENV] || '0.0.0.0'; -export const port = process.env[PORT_ENV] || (!path && '3000'); +export const path = env('SOCKET_PATH', false); +export const host = env('HOST', '0.0.0.0'); +export const port = env('PORT', !path && '3000'); const server = polka().use( // https://github.com/lukeed/polka/issues/173 diff --git a/packages/adapter-node/src/types.d.ts b/packages/adapter-node/src/types.d.ts deleted file mode 100644 index 7500ca7e9a9b..000000000000 --- a/packages/adapter-node/src/types.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -declare global { - const PATH_ENV: string; - const HOST_ENV: string; - const PORT_ENV: string; - const ORIGIN: string; - - const PROTOCOL_HEADER: string; - const HOST_HEADER: string; -} - -export {};