Skip to content

Commit

Permalink
make env vars a bit easier to understand/follow in adapter-node (#4360)
Browse files Browse the repository at this point in the history
* make env vars a bit easier to understand/follow in adapter-node

* tidy up types

* fail noisily if opts.env is provided

* changeset

* update docs

* lint

* rename env in README

* custom prefix instead of names themselves

* tweak changeset

* typo

* oops

* lint

* error if env var namespace is already occupied

* Update packages/adapter-node/tsconfig.json

Co-authored-by: Maurício Kishi <mrkishi@users.noreply.github.com>

Co-authored-by: mrkishi <mauriciokishi@gmail.com>
Co-authored-by: Maurício Kishi <mrkishi@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 17, 2022
1 parent 7cb5ee9 commit 37520a3
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 103 deletions.
5 changes: 5 additions & 0 deletions .changeset/thirty-kings-yell.md
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-node': patch
---

[breaking] Replace `options.env` with `options.envPrefix`
35 changes: 7 additions & 28 deletions packages/adapter-node/README.md
Expand Up @@ -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: ''
})
}
};
Expand All @@ -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
```

Expand Down
17 changes: 2 additions & 15 deletions 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;
Expand Down
36 changes: 12 additions & 24 deletions packages/adapter-node/index.js
Expand Up @@ -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',

Expand All @@ -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)
}
});

Expand Down
34 changes: 34 additions & 0 deletions 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;
}
11 changes: 0 additions & 11 deletions packages/adapter-node/src/handler.d.ts

This file was deleted.

23 changes: 14 additions & 9 deletions packages/adapter-node/src/handler.js
Expand Up @@ -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));

Expand Down Expand Up @@ -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`
);
}

Expand All @@ -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();
Expand Down
9 changes: 4 additions & 5 deletions 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
Expand Down
11 changes: 0 additions & 11 deletions packages/adapter-node/src/types.d.ts

This file was deleted.

0 comments on commit 37520a3

Please sign in to comment.