Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Consistent handling of environment variables #5663

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
1ec3064
feat: Add env config object
elliott-with-the-longest-name-on-github Jul 17, 2022
2b5e0c4
feat: Added types
elliott-with-the-longest-name-on-github Jul 17, 2022
91d0413
feat: Add .d.ts import to tsconfig
elliott-with-the-longest-name-on-github Jul 18, 2022
12a3fd1
feat: Generate env var dump code
elliott-with-the-longest-name-on-github Jul 18, 2022
498d4f2
fix: imports
elliott-with-the-longest-name-on-github Jul 21, 2022
5d4960d
Merge branch 'master' into 4296/sejohnson-environment-variables
elliott-with-the-longest-name-on-github Jul 21, 2022
08600df
fix: Remove old error mechanism
elliott-with-the-longest-name-on-github Jul 21, 2022
d5baa47
feat: Rough edges of server-side module protection
elliott-with-the-longest-name-on-github Jul 21, 2022
87b3760
fix: Performance and add Vite overlay
elliott-with-the-longest-name-on-github Jul 21, 2022
27b7cee
feat: First full draft of static environment vars
elliott-with-the-longest-name-on-github Jul 21, 2022
42ac833
fix unit tests
Rich-Harris Jul 21, 2022
6522e56
fix: Rich is smarter than I am
elliott-with-the-longest-name-on-github Jul 22, 2022
fb88ba9
Merge branch '4296/sejohnson-environment-variables' of github.com:tcc…
elliott-with-the-longest-name-on-github Jul 22, 2022
736e1f3
feat: Let know about Vite mode
elliott-with-the-longest-name-on-github Jul 22, 2022
9c1381a
feat: Added to sync CLI
elliott-with-the-longest-name-on-github Jul 22, 2022
351c4cb
feat: Added runtime variable support
elliott-with-the-longest-name-on-github Jul 22, 2022
944ff73
feat: Make server.init multicalls a noop
elliott-with-the-longest-name-on-github Jul 22, 2022
a040078
feat: Set runtime env in preview
elliott-with-the-longest-name-on-github Jul 22, 2022
34801e1
this doesn't work?!: Set runtime env in dev
elliott-with-the-longest-name-on-github Jul 22, 2022
035a2cd
feat: Added runtime env handler to cloudflare for testing
elliott-with-the-longest-name-on-github Jul 22, 2022
48f8cba
Update packages/kit/src/cli.js
Rich-Harris Jul 22, 2022
61e3a67
Update packages/kit/src/core/sync/write_env.js
Rich-Harris Jul 22, 2022
1e6906a
Update packages/kit/src/core/sync/write_env.js
Rich-Harris Jul 22, 2022
1f70c4d
Update packages/kit/src/vite/build/build_server.js
Rich-Harris Jul 22, 2022
5f41062
Update packages/kit/src/core/sync/write_env.js
Rich-Harris Jul 22, 2022
069e3dc
make mode required
Rich-Harris Jul 22, 2022
5774f08
move env/runtime to a file
Rich-Harris Jul 22, 2022
9091d2c
simplify write_env
Rich-Harris Jul 22, 2022
cf09ed7
Update packages/kit/src/vite/preview/index.js
Rich-Harris Jul 22, 2022
b7b1fca
remove unnecessary index.js suffix
Rich-Harris Jul 22, 2022
b4a1ee4
simplify
Rich-Harris Jul 22, 2022
da76b16
Merge branch '4296/sejohnson-environment-variables' of github.com:tcc…
Rich-Harris Jul 22, 2022
905ef24
tabs
Rich-Harris Jul 22, 2022
d2352b3
make init sync, make options required
Rich-Harris Jul 22, 2022
a858d19
format
Rich-Harris Jul 22, 2022
17ffba0
cast process.env
Rich-Harris Jul 22, 2022
af2b1aa
remove the overlay stuff, just throw an error
Rich-Harris Jul 22, 2022
b0477aa
just throw
Rich-Harris Jul 22, 2022
490f3fc
simplify traversal
Rich-Harris Jul 22, 2022
13bc94a
make build-time traversal more efficient
Rich-Harris Jul 22, 2022
40a6eaa
move dev code into dev module
Rich-Harris Jul 22, 2022
a1ccfa9
Merge branch 'master' into 4296/sejohnson-environment-variables
Rich-Harris Jul 22, 2022
312a7bc
always set env
Rich-Harris Jul 22, 2022
672eb85
simplify
Rich-Harris Jul 22, 2022
8ce2740
remove hard-coded .svelte-kit
Rich-Harris Jul 22, 2022
65ee08c
rename env/runtime to env/platform and get it working in dev
Rich-Harris Jul 22, 2022
133cc7a
remove outdated comment
Rich-Harris Jul 22, 2022
e56bf28
docs
Rich-Harris Jul 22, 2022
e677102
App.RuntimeEnv -> App.Env
Rich-Harris Jul 22, 2022
e5676a8
add Env interface where necessary
Rich-Harris Jul 22, 2022
f768a9c
update more adapters
Rich-Harris Jul 22, 2022
f685c40
changesets
Rich-Harris Jul 22, 2022
3ac79c5
tweak changesets
Rich-Harris Jul 22, 2022
0429f87
add a test
Rich-Harris Jul 22, 2022
79cc250
replace doc links
Rich-Harris Jul 22, 2022
b0e96f5
Merge branch 'master' into 4296/sejohnson-environment-variables
elliott-with-the-longest-name-on-github Jul 25, 2022
0614a33
fix: Invalid js identifiers skipped
elliott-with-the-longest-name-on-github Jul 25, 2022
23676f2
rename modules
Rich-Harris Jul 25, 2022
dc8086d
Merge branch 'master' into 4296/sejohnson-environment-variables
Rich-Harris Jul 25, 2022
5a43648
fix some stuff, break some stuff
Rich-Harris Jul 25, 2022
03b27b1
update tests
Rich-Harris Jul 25, 2022
ce5c113
ok i think thats almost everything
Rich-Harris Jul 25, 2022
e0dc066
oops
Rich-Harris Jul 25, 2022
ca24e31
merge master
Rich-Harris Jul 25, 2022
04c80fc
hide functions
Rich-Harris Jul 25, 2022
831c5b3
separate PrivateEnv from PublicEnv
Rich-Harris Jul 25, 2022
7f03ac7
expose entry points
Rich-Harris Jul 25, 2022
ca72f76
fix turbo config
Rich-Harris Jul 25, 2022
8d8eaa0
fix
Rich-Harris Jul 25, 2022
c8e7ab5
Update .changeset/beige-gorillas-tell.md
Rich-Harris Jul 25, 2022
84d06f4
Update packages/kit/src/runtime/env-public.js
Rich-Harris Jul 25, 2022
caf7cab
Update packages/kit/src/runtime/env-private.js
Rich-Harris Jul 25, 2022
3416554
Update packages/kit/src/runtime/env-public.js
Rich-Harris Jul 25, 2022
6264418
Update packages/kit/src/runtime/env-private.js
Rich-Harris Jul 25, 2022
d7a4159
Update packages/kit/src/core/sync/sync.js
Rich-Harris Jul 25, 2022
c53600f
Update packages/kit/src/vite/utils.js
Rich-Harris Jul 25, 2022
96c7a4a
Update packages/kit/src/vite/utils.js
Rich-Harris Jul 25, 2022
eb34e95
Update packages/kit/test/apps/basics/.env
Rich-Harris Jul 25, 2022
63f6604
Update packages/kit/test/apps/basics/.gitignore
Rich-Harris Jul 25, 2022
4449fb2
write_env in init, not update
Rich-Harris Jul 25, 2022
38025be
lint
Rich-Harris Jul 25, 2022
c9d222a
simplify valid identifier check, allow exports of reserved words
Rich-Harris Jul 25, 2022
a08d383
move types/ambient.d.ts to ambient.d.ts so it doesnt get nuked on update
Rich-Harris Jul 25, 2022
d2b10d9
Update documentation/docs/15-configuration.md
Rich-Harris Jul 26, 2022
5253136
remove env vars FAQ
Rich-Harris Jul 26, 2022
2d203db
feat: Testing for import analysis
elliott-with-the-longest-name-on-github Jul 26, 2022
bdffe39
Update packages/kit/types/ambient.d.ts
Rich-Harris Jul 26, 2022
b5cabd0
warn if env vars are invalid
Rich-Harris Jul 26, 2022
ec655c9
Merge branch '4296/sejohnson-environment-variables' of github.com:tcc…
Rich-Harris Jul 26, 2022
fd65c1e
oops
Rich-Harris Jul 26, 2022
26ad507
argh
Rich-Harris Jul 26, 2022
9c56f37
Update packages/kit/scripts/extract-types.js
Rich-Harris Jul 26, 2022
30f98f0
explain why we strip the origin
Rich-Harris Jul 26, 2022
92a1559
Update packages/kit/types/ambient.d.ts
Rich-Harris Jul 26, 2022
c1a5d52
temporarily disable
Rich-Harris Jul 26, 2022
9499d83
Merge branch '4296/sejohnson-environment-variables' of github.com:tcc…
Rich-Harris Jul 26, 2022
b2d41ac
Revert "temporarily disable"
Rich-Harris Jul 26, 2022
5f3dc7b
tidy up
Rich-Harris Jul 26, 2022
f257a0e
remove another unused import
Rich-Harris Jul 26, 2022
3c15b90
Update packages/kit/src/vite/utils.js
elliott-with-the-longest-name-on-github Jul 26, 2022
49ecafd
Update packages/kit/src/vite/utils.js
elliott-with-the-longest-name-on-github Jul 26, 2022
06fcd1c
Update packages/kit/src/vite/utils.js
elliott-with-the-longest-name-on-github Jul 26, 2022
4a17268
Update packages/kit/src/vite/utils.js
elliott-with-the-longest-name-on-github Jul 26, 2022
a5e3a87
Update packages/kit/src/core/sync/write_env.js
elliott-with-the-longest-name-on-github Jul 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/beige-gorillas-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@sveltejs/adapter-cloudflare': patch
'@sveltejs/adapter-cloudflare-workers': patch
'@sveltejs/adapter-netlify': patch
'@sveltejs/adapter-node': patch
'@sveltejs/adapter-vercel': patch
---

Initialise `env`
5 changes: 5 additions & 0 deletions .changeset/pretty-kings-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

Add `$env/static/private`, `$env/static/public`, `$env/dynamic/private` and `$env/dynamic/public` modules
3 changes: 0 additions & 3 deletions documentation/docs/06-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ declare namespace App {
interface Locals {
user: User;
}
interface Platform {}
interface Session {}
interface Stuff {}
}

const getUserInformation: (cookie: string | null) => Promise<User>;
Expand Down
15 changes: 12 additions & 3 deletions documentation/docs/15-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ const config = {
// ...
}
},
moduleExtensions: ['.js', '.ts'],
env: {
publicPrefix: 'PUBLIC_'
},
files: {
assets: 'static',
hooks: 'src/hooks',
Expand All @@ -44,6 +46,7 @@ const config = {
parameter: '_method',
allowed: []
},
moduleExtensions: ['.js', '.ts'],
outDir: '.svelte-kit',
package: {
dir: 'package',
Expand Down Expand Up @@ -157,9 +160,11 @@ When pages are prerendered, the CSP header is added via a `<meta http-equiv>` ta

> Note that most [Svelte transitions](https://svelte.dev/tutorial/transition) work by creating an inline `<style>` element. If you use these in your app, you must either leave the `style-src` directive unspecified or add `unsafe-inline`.

### moduleExtensions
### env

An array of file extensions that SvelteKit will treat as modules. Files with extensions that match neither `config.extensions` nor `config.kit.moduleExtensions` will be ignored by the router.
Environment variable configuration:

- `publicPrefix` — a prefix that signals that an environment variable is safe to expose to client-side code. See [`$env/static/public`](/docs/modules#$env-static-public) and [`$env/dynamic/public`](/docs/modules#$env-dynamic-public). Note that Vite's [`envPrefix`](https://vitejs.dev/config/shared-options.html#envprefix) must be set separately if you are using Vite's environment variable handling - though use of that feature should generally be unnecessary.

### files

Expand All @@ -186,6 +191,10 @@ See [HTTP Method Overrides](/docs/routing#endpoints-http-method-overrides). An o
- `parameter` — query parameter name to use for passing the intended method value
- `allowed` - array of HTTP methods that can be used when overriding the original request method

### moduleExtensions

An array of file extensions that SvelteKit will treat as modules. Files with extensions that match neither `config.extensions` nor `config.kit.moduleExtensions` will be ignored by the router.

### outDir

The directory that SvelteKit writes files to during `dev` and `build`. You should exclude this directory from version control.
Expand Down
9 changes: 0 additions & 9 deletions documentation/faq/60-env-vars.md

This file was deleted.

2 changes: 2 additions & 0 deletions packages/adapter-cloudflare-workers/files/entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export default {
* @param {any} context
*/
async fetch(req, env, context) {
server.init({ env });

const url = new URL(req.url);

// static assets
Expand Down
1 change: 1 addition & 0 deletions packages/adapter-cloudflare/src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const prefix = `/${manifest.appDir}/`;
/** @type {import('worktop/cfw').Module.Worker<{ ASSETS: import('worktop/cfw.durable').Durable.Object }>} */
const worker = {
async fetch(req, env, context) {
server.init({ env });
// skip cache if "cache-control: no-cache" in request
let pragma = req.headers.get('cache-control') || '';
let res = !pragma.includes('no-cache') && (await Cache.lookup(req));
Expand Down
4 changes: 4 additions & 0 deletions packages/adapter-netlify/src/serverless.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import { split_headers } from './headers';
export function init(manifest) {
const server = new Server(manifest);

server.init({
env: process.env
});

return async (event, context) => {
const response = await server.respond(to_request(event), {
platform: { context },
Expand Down
1 change: 1 addition & 0 deletions packages/adapter-node/src/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { env } from './env.js';
/* global ENV_PREFIX */

const server = new Server(manifest);
server.init({ env: process.env });
const origin = env('ORIGIN', undefined);
const xff_depth = parseInt(env('XFF_DEPTH', '1'));

Expand Down
4 changes: 4 additions & 0 deletions packages/adapter-vercel/files/serverless.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ installPolyfills();

const server = new Server(manifest);

server.init({
env: process.env
});

/**
* @param {import('http').IncomingMessage} req
* @param {import('http').ServerResponse} res
Expand Down
4 changes: 4 additions & 0 deletions packages/create-svelte/templates/default/src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ declare namespace App {

// interface Platform {}

// interface PrivateEnv {}

// interface PublicEnv {}

// interface Session {}

// interface Stuff {}
Expand Down
2 changes: 2 additions & 0 deletions packages/create-svelte/templates/skeleton/src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
declare namespace App {
// interface Locals {}
// interface Platform {}
// interface PrivateEnv {}
// interface PublicEnv {}
// interface Session {}
// interface Stuff {}
}
4 changes: 4 additions & 0 deletions packages/kit/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export default [
'app/stores': 'src/runtime/app/stores.js',
'app/paths': 'src/runtime/app/paths.js',
'app/env': 'src/runtime/app/env.js',
'env/dynamic/private': 'src/runtime/env/dynamic/private.js',
'env/dynamic/public': 'src/runtime/env/dynamic/public.js',
'env-private': 'src/runtime/env-private.js',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason we don't call this env/runtime/private to match the env/dynamic/private above it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

felt unnecessary since we don't have entry points for static. in any case i'm thinking of these as temporary — this whole folder structure is due for a reshuffle (it's weird that we have env alongside env-[type], for example)

'env-public': 'src/runtime/env-public.js',
paths: 'src/runtime/paths.js',
env: 'src/runtime/env.js'
},
Expand Down
133 changes: 77 additions & 56 deletions packages/kit/scripts/extract-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import fs from 'fs';
import ts from 'typescript';
import prettier from 'prettier';
import { mkdirp } from '../src/utils/filesystem.js';
import { fileURLToPath } from 'url';

/** @typedef {{ name: string, comment: string, snippet: string }} Extracted */

/** @type {Array<{ name: string, comment: string, exports: Extracted[], types: Extracted[] }>} */
/** @type {Array<{ name: string, comment: string, exports: Extracted[], types: Extracted[], exempt?: boolean }>} */
const modules = [];

/**
Expand All @@ -19,59 +20,72 @@ function get_types(code, statements) {
/** @type {Extracted[]} */
const types = [];

for (const statement of statements) {
if (
ts.isClassDeclaration(statement) ||
ts.isInterfaceDeclaration(statement) ||
ts.isTypeAliasDeclaration(statement) ||
ts.isModuleDeclaration(statement) ||
ts.isVariableStatement(statement) ||
ts.isFunctionDeclaration(statement)
) {
const name_node = ts.isVariableStatement(statement)
? statement.declarationList.declarations[0]
: statement;

// @ts-ignore no idea why it's complaining here
const name = name_node.name?.escapedText;

let start = statement.pos;
let comment = '';

// @ts-ignore i think typescript is bad at typescript
if (statement.jsDoc) {
// @ts-ignore
comment = statement.jsDoc[0].comment;
// @ts-ignore
start = statement.jsDoc[0].end;
if (statements) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personal preference, but I'd write this as shown below. right now, it's a bit hard to see where the if block ends and what comes after it since it doesn't fit on one screen. it'd also save having to have the code inside indented as much

if (!statements) {
  return { types, exports };
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my personal preference goes the other way 😆 i know you love an early return, i much prefer positive conditions over negative ones — way fewer mental contortions — and not having duplicated identical return statements

for (const statement of statements) {
if (
ts.isClassDeclaration(statement) ||
ts.isInterfaceDeclaration(statement) ||
ts.isTypeAliasDeclaration(statement) ||
ts.isModuleDeclaration(statement) ||
ts.isVariableStatement(statement) ||
ts.isFunctionDeclaration(statement)
) {
const name_node = ts.isVariableStatement(statement)
? statement.declarationList.declarations[0]
: statement;

// @ts-ignore no idea why it's complaining here
const name = name_node.name?.escapedText;

let start = statement.pos;
let comment = '';

// @ts-ignore i think typescript is bad at typescript
if (statement.jsDoc) {
// @ts-ignore
comment = statement.jsDoc[0].comment;
// @ts-ignore
start = statement.jsDoc[0].end;
}

const i = code.indexOf('export', start);
start = i + 6;

const snippet = prettier.format(code.slice(start, statement.end).trim(), {
parser: 'typescript',
printWidth: 80,
useTabs: true,
singleQuote: true,
trailingComma: 'none'
});

const collection =
ts.isVariableStatement(statement) || ts.isFunctionDeclaration(statement)
? exports
: types;

collection.push({ name, comment, snippet });
}

const i = code.indexOf('export', start);
start = i + 6;

const snippet = prettier.format(code.slice(start, statement.end).trim(), {
parser: 'typescript',
printWidth: 80,
useTabs: true,
singleQuote: true,
trailingComma: 'none'
});

const collection =
ts.isVariableStatement(statement) || ts.isFunctionDeclaration(statement) ? exports : types;

collection.push({ name, comment, snippet });
} else {
// console.log(statement.kind);
}
}

types.sort((a, b) => (a.name < b.name ? -1 : 1));
exports.sort((a, b) => (a.name < b.name ? -1 : 1));
types.sort((a, b) => (a.name < b.name ? -1 : 1));
exports.sort((a, b) => (a.name < b.name ? -1 : 1));
}

return { types, exports };
}

/**
* Type declarations include fully qualified URLs so that they become links when
* you hover over names in an editor with TypeScript enabled. We need to remove
* the origin so that they become root-relative, so that they work in preview
* deployments and when developing locally
* @param {string} str
*/
function strip_origin(str) {
return str.replace(/https:\/\/kit\.svelte\.dev/g, '');
}

{
const code = fs.readFileSync('types/index.d.ts', 'utf-8');
const node = ts.createSourceFile('index.d.ts', code, ts.ScriptTarget.Latest);
Expand All @@ -95,13 +109,20 @@ function get_types(code, statements) {
});
}

modules.push({
name: '$lib',
comment:
'This is a simple alias to `src/lib`, or whatever directory is specified as [`config.kit.files.lib`](/docs/configuration#files). It allows you to access common components and utility modules without `../../../../` nonsense.',
exports: [],
types: []
});
const dir = fileURLToPath(new URL('./special-types', import.meta.url).href);
for (const file of fs.readdirSync(dir)) {
if (!file.endsWith('.md')) continue;

const comment = strip_origin(fs.readFileSync(`${dir}/${file}`, 'utf-8'));

modules.push({
name: file.replace(/\+/g, '/').slice(0, -3),
comment,
exports: [],
types: [],
exempt: true
});
}

{
const code = fs.readFileSync('types/ambient.d.ts', 'utf-8');
Expand All @@ -113,13 +134,13 @@ modules.push({
const name = statement.name.text || statement.name.escapedText;

// @ts-ignore
const comment = statement.jsDoc?.[0].comment ?? '';
const comment = strip_origin(statement.jsDoc?.[0].comment ?? '');

modules.push({
name,
comment,
// @ts-ignore
...get_types(code, statement.body.statements)
...get_types(code, statement.body?.statements)
});
}
}
Expand Down
7 changes: 7 additions & 0 deletions packages/kit/scripts/special-types/$env+static+private.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Environment variables [loaded by Vite](https://vitejs.dev/guide/env-and-mode.html#env-files) from `.env` files and `process.env`. Like [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-platform), this module cannot be imported into client-side code.

_Unlike_ [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-platform), the values exported from this module are statically injected into your bundle at build time, enabling optimisations like dead code elimination.

```ts
import { API_KEY } from '$env/static/private';
```
7 changes: 7 additions & 0 deletions packages/kit/scripts/special-types/$env+static+public.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Similar to [`$env/static/private`](https://kit.svelte.dev/docs/modules#$env-static-private), except that it only includes environment variables that begin with [`config.kit.env.publicPrefix`](https://kit.svelte.dev/docs/configuration#kit-env-publicprefix) (which defaults to `PUBLIC_`), and can therefore safely be exposed to client-side code.

Values are replaced statically at build time.

```ts
import { PUBLIC_BASE_URL } from '$env/static/public';
```
1 change: 1 addition & 0 deletions packages/kit/scripts/special-types/$lib.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a simple alias to `src/lib`, or whatever directory is specified as [`config.kit.files.lib`](https://kit.svelte.dev/docs/configuration#files). It allows you to access common components and utility modules without `../../../../` nonsense.
5 changes: 3 additions & 2 deletions packages/kit/src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ prog
prog
.command('sync')
.describe('Synchronise generated files')
.action(async () => {
.option('--mode', 'Specify a mode for loading environment variables', 'development')
.action(async ({ mode }) => {
if (!fs.existsSync('svelte.config.js')) {
console.warn('Missing svelte.config.js — skipping');
return;
Expand All @@ -47,7 +48,7 @@ prog
try {
const config = await load_config();
const sync = await import('./core/sync/sync.js');
sync.all(config);
sync.all(config, mode);
} catch (error) {
handle_error(error);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/kit/src/core/config/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ const get_defaults = (prefix = '') => ({
reportOnly: directive_defaults
},
endpointExtensions: undefined,
env: {
publicPrefix: 'PUBLIC_'
},
files: {
assets: join(prefix, 'static'),
hooks: join(prefix, 'src/hooks'),
Expand Down
4 changes: 4 additions & 0 deletions packages/kit/src/core/config/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ const options = object(
(keypath) => `${keypath} has been renamed to config.kit.moduleExtensions`
),

env: object({
publicPrefix: string('PUBLIC_')
}),

files: object({
assets: string('static'),
hooks: string(join('src', 'hooks')),
Expand Down
Loading