diff --git a/.changeset/brave-clowns-behave.md b/.changeset/brave-clowns-behave.md new file mode 100644 index 000000000000..60c95caf6464 --- /dev/null +++ b/.changeset/brave-clowns-behave.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': minor +--- + +feat: add a `kit.files.src` option diff --git a/packages/kit/src/core/config/fixtures/custom-src/svelte.config.js b/packages/kit/src/core/config/fixtures/custom-src/svelte.config.js new file mode 100644 index 000000000000..cfbf957434bf --- /dev/null +++ b/packages/kit/src/core/config/fixtures/custom-src/svelte.config.js @@ -0,0 +1,7 @@ +export default { + kit: { + files: { + src: 'source' + } + } +}; diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js index 7fc38bc483dd..ae35a708132b 100644 --- a/packages/kit/src/core/config/index.js +++ b/packages/kit/src/core/config/index.js @@ -126,6 +126,17 @@ export function validate_config(config) { } const validated = options(config, 'config'); + const files = validated.kit.files; + + files.hooks.client ??= path.join(files.src, 'hooks.client'); + files.hooks.server ??= path.join(files.src, 'hooks.server'); + files.hooks.universal ??= path.join(files.src, 'hooks'); + files.lib ??= path.join(files.src, 'lib'); + files.params ??= path.join(files.src, 'params'); + files.routes ??= path.join(files.src, 'routes'); + files.serviceWorker ??= path.join(files.src, 'service-worker'); + files.appTemplate ??= path.join(files.src, 'app.html'); + files.errorTemplate ??= path.join(files.src, 'error.html'); if (validated.kit.router.resolution === 'server') { if (validated.kit.router.type === 'hash') { diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index 90da427483d7..1a979613bba6 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -80,6 +80,7 @@ const get_defaults = (prefix = '') => ({ remoteFunctions: false }, files: { + src: join(prefix, 'src'), assets: join(prefix, 'static'), hooks: { client: join(prefix, 'src/hooks.client'), @@ -407,3 +408,15 @@ test('errors on loading config with incorrect default export', async () => { 'The Svelte config file must have a configuration object as its default export. See https://svelte.dev/docs/kit/configuration' ); }); + +test('uses src prefix for other kit.files options', async () => { + const cwd = join(__dirname, 'fixtures/custom-src'); + + const config = await load_config({ cwd }); + remove_keys(config, ([, v]) => typeof v === 'function'); + + const defaults = get_defaults(cwd + '/'); + defaults.kit.version.name = config.kit.version.name; + + expect(config.kit.files.lib).toEqual(join(cwd, 'source/lib')); +}); diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index 577ca4c9445d..8caa72e9cfb8 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -1,4 +1,3 @@ -import { join } from 'node:path'; import process from 'node:process'; /** @typedef {import('./types.js').Validator} Validator */ @@ -125,18 +124,19 @@ const options = object( }), files: object({ + src: string('src'), assets: string('static'), hooks: object({ - client: string(join('src', 'hooks.client')), - server: string(join('src', 'hooks.server')), - universal: string(join('src', 'hooks')) + client: string(null), + server: string(null), + universal: string(null) }), - lib: string(join('src', 'lib')), - params: string(join('src', 'params')), - routes: string(join('src', 'routes')), - serviceWorker: string(join('src', 'service-worker')), - appTemplate: string(join('src', 'app.html')), - errorTemplate: string(join('src', 'error.html')) + lib: string(null), + params: string(null), + routes: string(null), + serviceWorker: string(null), + appTemplate: string(null), + errorTemplate: string(null) }), inlineStyleThreshold: number(0), diff --git a/packages/kit/src/core/sync/create_manifest_data/index.spec.js b/packages/kit/src/core/sync/create_manifest_data/index.spec.js index c681184446a6..c321507a5b42 100644 --- a/packages/kit/src/core/sync/create_manifest_data/index.spec.js +++ b/packages/kit/src/core/sync/create_manifest_data/index.spec.js @@ -3,8 +3,8 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { assert, expect, test } from 'vitest'; import create_manifest_data from './index.js'; -import options from '../../config/options.js'; import { sort_routes } from './sort.js'; +import { validate_config } from '../../config/index.js'; const cwd = fileURLToPath(new URL('./test', import.meta.url)); @@ -13,7 +13,7 @@ const cwd = fileURLToPath(new URL('./test', import.meta.url)); * @param {import('@sveltejs/kit').Config} config */ const create = (dir, config = {}) => { - const initial = options(config, 'config'); + const initial = validate_config(config); initial.kit.files.assets = path.resolve(cwd, 'static'); initial.kit.files.params = path.resolve(cwd, 'params'); diff --git a/packages/kit/src/core/sync/write_types/index.spec.js b/packages/kit/src/core/sync/write_types/index.spec.js index 92ad3d68d0ca..d6bfc36f7578 100644 --- a/packages/kit/src/core/sync/write_types/index.spec.js +++ b/packages/kit/src/core/sync/write_types/index.spec.js @@ -4,9 +4,9 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { assert, expect, test } from 'vitest'; import { rimraf } from '../../../utils/filesystem.js'; -import options from '../../config/options.js'; import create_manifest_data from '../create_manifest_data/index.js'; import { tweak_types, write_all_types } from './index.js'; +import { validate_config } from '../../config/index.js'; const cwd = fileURLToPath(new URL('./test', import.meta.url)); @@ -16,7 +16,7 @@ const cwd = fileURLToPath(new URL('./test', import.meta.url)); function run_test(dir) { rimraf(path.join(cwd, dir, '.svelte-kit')); - const initial = options({}, 'config'); + const initial = validate_config({}); initial.kit.files.assets = path.resolve(cwd, 'static'); initial.kit.files.params = path.resolve(cwd, dir, 'params'); diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 1982000eb2f9..27f23d15a691 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -422,6 +422,12 @@ export interface KitConfig { * Where to find various files within your project. */ files?: { + /** + * the location of your source code + * @default "src" + * @since 2.28 + */ + src?: string; /** * a place to put static files that should have stable URLs and undergo no processing, such as `favicon.ico` or `manifest.json` * @default "static" diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 5458c54e9715..4880d7e55d1c 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -399,6 +399,12 @@ declare module '@sveltejs/kit' { * Where to find various files within your project. */ files?: { + /** + * the location of your source code + * @default "src" + * @since 2.28 + */ + src?: string; /** * a place to put static files that should have stable URLs and undergo no processing, such as `favicon.ico` or `manifest.json` * @default "static" diff --git a/packages/package/test/index.spec.js b/packages/package/test/index.spec.js index 5bc0412ad7af..c4cec8f8da56 100644 --- a/packages/package/test/index.spec.js +++ b/packages/package/test/index.spec.js @@ -133,11 +133,12 @@ test('create package with typescript using nodenext', async () => { await test_make_package('typescript-nodenext'); }); -// only run this test in older Node versions -// TODO: remove after dropping support for Node 20 -const is_node_without_ts_support = - process.versions.node && Number(process.versions.node.split('.', 1)[0]) < 22; -if (!is_node_without_ts_support) { +// only run this test in newer Node versions +// TODO: remove after dropping support for Node < 22.18 +const [major, minor] = process.versions.node.split('.', 2).map((str) => +str); +const has_ts_support = major > 22 || (major === 22 && minor >= 18); + +if (has_ts_support) { test('create package with typescript using nodenext and svelte.config.ts', async () => { await test_make_package('typescript-svelte-config'); });