@sveltejs/kit 3.0.0-next.14 → 3.0.0-next.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -3
- package/src/cli.js +6 -3
- package/src/core/adapt/builder.js +12 -5
- package/src/core/config/index.js +4 -5
- package/src/core/env.js +3 -3
- package/src/core/postbuild/prerender.js +6 -10
- package/src/core/sync/sync.js +3 -2
- package/src/core/sync/utils.js +2 -2
- package/src/core/sync/write_tsconfig/index.js +71 -53
- package/src/core/sync/write_tsconfig/utils.js +0 -61
- package/src/core/sync/write_tsconfig/validate.js +128 -0
- package/src/core/sync/write_types/index.js +2 -2
- package/src/exports/public.d.ts +22 -16
- package/src/exports/vite/build/build_server.js +2 -3
- package/src/exports/vite/dev/index.js +44 -36
- package/src/exports/vite/index.js +46 -5
- package/src/exports/vite/utils.js +61 -8
- package/src/runner.js +4 -2
- package/src/runtime/app/forms.js +4 -7
- package/src/runtime/app/internal/transport.js +53 -0
- package/src/runtime/app/paths/client.js +2 -2
- package/src/runtime/app/paths/internal/client.js +2 -2
- package/src/runtime/app/server/remote/prerender.js +6 -10
- package/src/runtime/app/server/remote/query.js +3 -3
- package/src/runtime/app/server/remote/requested.js +2 -2
- package/src/runtime/app/server/remote/shared.js +1 -16
- package/src/runtime/client/client.js +29 -25
- package/src/runtime/client/parse.js +1 -1
- package/src/runtime/client/remote-functions/command.svelte.js +1 -2
- package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
- package/src/runtime/client/remote-functions/query/proxy.js +2 -2
- package/src/runtime/client/remote-functions/query-live/proxy.js +2 -2
- package/src/runtime/pathname.js +7 -1
- package/src/runtime/server/data/index.js +5 -8
- package/src/runtime/server/dev.js +22 -0
- package/src/runtime/server/endpoint.js +3 -4
- package/src/runtime/server/fetch.js +22 -24
- package/src/runtime/server/index.js +54 -22
- package/src/runtime/server/internal.js +12 -5
- package/src/runtime/server/page/actions.js +18 -43
- package/src/runtime/server/page/data_serializer.js +12 -13
- package/src/runtime/server/page/index.js +16 -32
- package/src/runtime/server/page/load_data.js +26 -15
- package/src/runtime/server/page/render.js +9 -11
- package/src/runtime/server/page/respond_with_error.js +8 -20
- package/src/runtime/server/remote-functions.js +11 -15
- package/src/runtime/server/respond.js +26 -31
- package/src/runtime/server/state.js +36 -19
- package/src/runtime/server/utils.js +0 -20
- package/src/runtime/shared.js +16 -38
- package/src/types/internal.d.ts +45 -52
- package/src/utils/filesystem.js +1 -23
- package/src/version.js +1 -1
- package/types/index.d.ts +24 -18
- package/types/index.d.ts.map +1 -1
- package/src/runtime/server/app.js +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "3.0.0-next.
|
|
3
|
+
"version": "3.0.0-next.16",
|
|
4
4
|
"description": "SvelteKit is the fastest way to build Svelte apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@opentelemetry/api": "^1.9.0",
|
|
33
|
-
"@playwright/test": "
|
|
33
|
+
"@playwright/test": "^1.62.0",
|
|
34
34
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
35
35
|
"@types/connect": "^3.4.38",
|
|
36
36
|
"@types/node": "^22.19.19",
|
|
37
37
|
"dts-buddy": "^0.8.3",
|
|
38
|
-
"jsdom": "^
|
|
38
|
+
"jsdom": "^30.0.0",
|
|
39
39
|
"rolldown": "^1.2.0",
|
|
40
40
|
"svelte": "^5.56.3",
|
|
41
41
|
"svelte-preprocess": "^6.0.5",
|
|
@@ -71,6 +71,9 @@
|
|
|
71
71
|
"svelte-kit.js"
|
|
72
72
|
],
|
|
73
73
|
"imports": {
|
|
74
|
+
"#app/internal/transport": {
|
|
75
|
+
"default": "./src/runtime/app/internal/transport.js"
|
|
76
|
+
},
|
|
74
77
|
"#app/paths": {
|
|
75
78
|
"workerd": "./src/runtime/app/paths/server.js",
|
|
76
79
|
"browser": "./src/runtime/app/paths/client.js",
|
package/src/cli.js
CHANGED
|
@@ -2,8 +2,9 @@ import fs from 'node:fs';
|
|
|
2
2
|
import process from 'node:process';
|
|
3
3
|
import { parseArgs, styleText } from 'node:util';
|
|
4
4
|
import { extract_svelte_config, load_vite_config } from './core/config/index.js';
|
|
5
|
-
import { coalesce_to_error } from './utils/error.js';
|
|
6
5
|
import { resolve_explicit_env_entry } from './core/env.js';
|
|
6
|
+
import { coalesce_to_error } from './utils/error.js';
|
|
7
|
+
import { import_peer } from './utils/import.js';
|
|
7
8
|
|
|
8
9
|
/** @param {unknown} e */
|
|
9
10
|
function handle_error(e) {
|
|
@@ -96,14 +97,16 @@ if (command === 'sync') {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
try {
|
|
99
|
-
const
|
|
100
|
+
const vite = /** @type {import('vite')} */ (await import_peer('vite', process.cwd()));
|
|
101
|
+
|
|
102
|
+
const vite_config = await load_vite_config(values.config, vite);
|
|
100
103
|
const sveltekit_config = extract_svelte_config(vite_config);
|
|
101
104
|
|
|
102
105
|
const sync = await import('./core/sync/sync.js');
|
|
103
106
|
sync.all_types(sveltekit_config, vite_config.root);
|
|
104
107
|
|
|
105
108
|
const explicit_env_entry = resolve_explicit_env_entry(sveltekit_config.kit);
|
|
106
|
-
await sync.env(sveltekit_config.kit, explicit_env_entry, vite_config.root, values.mode);
|
|
109
|
+
await sync.env(vite, sveltekit_config.kit, explicit_env_entry, vite_config.root, values.mode);
|
|
107
110
|
} catch (error) {
|
|
108
111
|
handle_error(error);
|
|
109
112
|
} finally {
|
|
@@ -5,12 +5,19 @@
|
|
|
5
5
|
/** @import { RouteData, ValidatedConfig, BuildData, ServerMetadata, ServerMetadataRoute, Prerendered, PrerenderMap, Logger, RemoteChunk } from 'types' */
|
|
6
6
|
import { loadEnv } from 'vite';
|
|
7
7
|
import * as devalue from 'devalue';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
createReadStream,
|
|
10
|
+
createWriteStream,
|
|
11
|
+
existsSync,
|
|
12
|
+
mkdirSync,
|
|
13
|
+
rmSync,
|
|
14
|
+
statSync
|
|
15
|
+
} from 'node:fs';
|
|
9
16
|
import { extname, resolve, join, dirname, relative } from 'node:path';
|
|
10
17
|
import { pipeline } from 'node:stream';
|
|
11
18
|
import { promisify } from 'node:util';
|
|
12
19
|
import zlib from 'node:zlib';
|
|
13
|
-
import { copy
|
|
20
|
+
import { copy } from '../../utils/filesystem.js';
|
|
14
21
|
import { posixify } from '../../utils/os.js';
|
|
15
22
|
import { generate_manifest } from '../generate_manifest/index.js';
|
|
16
23
|
import { get_route_segments } from '../../utils/routing.js';
|
|
@@ -99,8 +106,8 @@ export function create_builder({
|
|
|
99
106
|
|
|
100
107
|
return {
|
|
101
108
|
log,
|
|
102
|
-
rimraf,
|
|
103
|
-
mkdirp,
|
|
109
|
+
rimraf: (dir) => rmSync(dir, { force: true, recursive: true }),
|
|
110
|
+
mkdirp: (dir) => mkdirSync(dir, { recursive: true }),
|
|
104
111
|
copy,
|
|
105
112
|
|
|
106
113
|
config,
|
|
@@ -271,7 +278,7 @@ export function create_builder({
|
|
|
271
278
|
exports: module.exports
|
|
272
279
|
});
|
|
273
280
|
|
|
274
|
-
|
|
281
|
+
rmSync(entrypoint, { force: true, recursive: true });
|
|
275
282
|
write(entrypoint, facade);
|
|
276
283
|
}
|
|
277
284
|
};
|
package/src/core/config/index.js
CHANGED
|
@@ -120,13 +120,12 @@ export function load_error_page(config) {
|
|
|
120
120
|
|
|
121
121
|
/**
|
|
122
122
|
* @param {string} [config]
|
|
123
|
+
* @param {typeof import('vite')} [vite]
|
|
123
124
|
*/
|
|
124
|
-
export async function load_vite_config(config) {
|
|
125
|
-
|
|
126
|
-
await import_peer('vite', process.cwd())
|
|
127
|
-
);
|
|
125
|
+
export async function load_vite_config(config, vite) {
|
|
126
|
+
vite ??= /** @type {import('vite')} */ (await import_peer('vite', process.cwd()));
|
|
128
127
|
|
|
129
|
-
return resolveConfig({ configFile: config }, 'build', process.env.MODE ?? 'production');
|
|
128
|
+
return vite.resolveConfig({ configFile: config }, 'build', process.env.MODE ?? 'production');
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
/**
|
package/src/core/env.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
/** @import { EnvVarConfig } from '@sveltejs/kit' */
|
|
3
3
|
/** @import { ValidatedKitConfig } from 'types' */
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import * as vite from 'vite';
|
|
6
5
|
import * as devalue from 'devalue';
|
|
7
6
|
import { GENERATED_COMMENT } from '../constants.js';
|
|
8
7
|
import { dedent } from './sync/utils.js';
|
|
@@ -25,13 +24,14 @@ export function resolve_explicit_env_entry(config) {
|
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
/**
|
|
27
|
+
* @param {typeof import('vite')} vite
|
|
28
28
|
* @param {ValidatedKitConfig} kit
|
|
29
29
|
* @param {string | null} file
|
|
30
30
|
* @param {string} root
|
|
31
31
|
* @param {string} mode
|
|
32
32
|
* @returns {Promise<Record<string, EnvVarConfig<any>> | null>}
|
|
33
33
|
*/
|
|
34
|
-
export async function load_explicit_env(kit, file, root, mode) {
|
|
34
|
+
export async function load_explicit_env(vite, kit, file, root, mode) {
|
|
35
35
|
if (!file) return null;
|
|
36
36
|
|
|
37
37
|
const server = await vite.createServer({
|
|
@@ -53,7 +53,7 @@ export async function load_explicit_env(kit, file, root, mode) {
|
|
|
53
53
|
/** @type {Record<string, EnvVarConfig<any>>} */
|
|
54
54
|
let variables;
|
|
55
55
|
|
|
56
|
-
const runner = get_runner(server);
|
|
56
|
+
const runner = get_runner(vite, server);
|
|
57
57
|
|
|
58
58
|
/** @type {import('../runtime/app/env/internal.js')} */ (
|
|
59
59
|
await runner.import(`${runtime_directory}/app/env/internal.js`)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { existsSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
|
-
import {
|
|
4
|
+
import { walk } from '../../utils/filesystem.js';
|
|
5
5
|
import { posixify } from '../../utils/os.js';
|
|
6
6
|
import { noop } from '../../utils/functions.js';
|
|
7
7
|
import { decode_uri, is_root_relative, resolve } from '../../utils/url.js';
|
|
@@ -157,7 +157,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
157
157
|
const file = output_filename('/', true);
|
|
158
158
|
const dest = `${config.outDir}/output/prerendered/pages/${file}`;
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
161
161
|
writeFileSync(dest, fallback);
|
|
162
162
|
|
|
163
163
|
prerendered.pages.set('/', { file });
|
|
@@ -480,7 +480,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
480
480
|
}
|
|
481
481
|
|
|
482
482
|
if (!headers['x-sveltekit-normalize']) {
|
|
483
|
-
|
|
483
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
484
484
|
|
|
485
485
|
writeFileSync(
|
|
486
486
|
dest,
|
|
@@ -526,7 +526,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
526
526
|
);
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
-
|
|
529
|
+
mkdirSync(dir, { recursive: true });
|
|
530
530
|
|
|
531
531
|
writeFileSync(dest, body);
|
|
532
532
|
written.add(file);
|
|
@@ -629,14 +629,10 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
629
629
|
}
|
|
630
630
|
}
|
|
631
631
|
|
|
632
|
-
const transport = (await internal.get_hooks()).transport ?? {};
|
|
633
632
|
for (const internals of prerender_functions) {
|
|
634
633
|
if (internals.has_arg) {
|
|
635
634
|
for (const arg of (await internals.inputs?.()) ?? []) {
|
|
636
|
-
void enqueue(
|
|
637
|
-
null,
|
|
638
|
-
remote_prefix + internals.id + '/' + stringify_remote_arg(arg, transport)
|
|
639
|
-
);
|
|
635
|
+
void enqueue(null, remote_prefix + internals.id + '/' + stringify_remote_arg(arg));
|
|
640
636
|
}
|
|
641
637
|
} else {
|
|
642
638
|
void enqueue(null, remote_prefix + internals.id);
|
package/src/core/sync/sync.js
CHANGED
|
@@ -89,13 +89,14 @@ export function all_types(config, root) {
|
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
91
|
* Generate modules and types for explicit env vars
|
|
92
|
+
* @param {typeof import('vite')} vite
|
|
92
93
|
* @param {import('types').ValidatedKitConfig} kit
|
|
93
94
|
* @param {string | null} entry
|
|
94
95
|
* @param {string} root The Vite root
|
|
95
96
|
* @param {string} mode The Vite mode
|
|
96
97
|
*/
|
|
97
|
-
export async function env(kit, entry, root, mode) {
|
|
98
|
-
const env_config = await load_explicit_env(kit, entry, root, mode);
|
|
98
|
+
export async function env(vite, kit, entry, root, mode) {
|
|
99
|
+
const env_config = await load_explicit_env(vite, kit, entry, root, mode);
|
|
99
100
|
|
|
100
101
|
write_env(entry, env_config, root);
|
|
101
102
|
|
package/src/core/sync/utils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { styleText } from 'node:util';
|
|
4
|
-
import {
|
|
4
|
+
import { resolve_entry } from '../../utils/filesystem.js';
|
|
5
5
|
|
|
6
6
|
/** @type {Map<string, string>} */
|
|
7
7
|
const previous_contents = new Map();
|
|
@@ -22,7 +22,7 @@ export function write_if_changed(file, code) {
|
|
|
22
22
|
*/
|
|
23
23
|
export function write(file, code) {
|
|
24
24
|
previous_contents.set(file, code);
|
|
25
|
-
|
|
25
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
26
26
|
fs.writeFileSync(file, code);
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -6,13 +6,12 @@ import { styleText } from 'node:util';
|
|
|
6
6
|
import { write_if_changed } from '../utils.js';
|
|
7
7
|
import {
|
|
8
8
|
ESSENTIAL_OPTIONS,
|
|
9
|
-
extends_id,
|
|
10
9
|
get_subpath_imports,
|
|
11
10
|
normalize_config,
|
|
12
11
|
RECOMMENDED_OPTIONS,
|
|
13
|
-
remove_trailing_slashstar
|
|
14
|
-
validate_resolved_config
|
|
12
|
+
remove_trailing_slashstar
|
|
15
13
|
} from './utils.js';
|
|
14
|
+
import { extends_id, validate_resolved_config } from './validate.js';
|
|
16
15
|
|
|
17
16
|
/** @type {import('typescript')} */
|
|
18
17
|
let ts;
|
|
@@ -29,16 +28,16 @@ try {
|
|
|
29
28
|
*/
|
|
30
29
|
export function write_tsconfig(kit, root) {
|
|
31
30
|
const paths = get_paths(kit, root);
|
|
31
|
+
const types = ['$app/types'];
|
|
32
32
|
|
|
33
33
|
write_parent_tsconfig(
|
|
34
|
-
root,
|
|
35
34
|
root,
|
|
36
35
|
'$app/tsconfig',
|
|
37
36
|
{
|
|
38
37
|
compilerOptions: {
|
|
39
38
|
paths,
|
|
40
39
|
rootDirs: ['.', `${kit.outDir}/types`],
|
|
41
|
-
types
|
|
40
|
+
types,
|
|
42
41
|
|
|
43
42
|
// This is required for svelte-package to work as expected
|
|
44
43
|
// Can be overwritten
|
|
@@ -46,45 +45,48 @@ export function write_tsconfig(kit, root) {
|
|
|
46
45
|
|
|
47
46
|
...ESSENTIAL_OPTIONS,
|
|
48
47
|
...RECOMMENDED_OPTIONS
|
|
49
|
-
}
|
|
50
|
-
exclude: [kit.files.serviceWorker]
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
extends: '$app/tsconfig',
|
|
54
|
-
include: ['src']
|
|
48
|
+
}
|
|
55
49
|
},
|
|
56
50
|
kit.typescript.config
|
|
57
51
|
);
|
|
58
52
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
53
|
+
validate_config(root, {
|
|
54
|
+
paths,
|
|
55
|
+
types,
|
|
56
|
+
exclusions: [kit.files.serviceWorker],
|
|
57
|
+
example: {
|
|
58
|
+
extends: '$app/tsconfig'
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
write_parent_tsconfig(root, '$app/tsconfig/service-worker', {
|
|
63
|
+
compilerOptions: {
|
|
64
|
+
paths,
|
|
65
|
+
types,
|
|
66
|
+
lib: ['ESNext', 'WebWorker'],
|
|
67
|
+
...ESSENTIAL_OPTIONS,
|
|
68
|
+
...RECOMMENDED_OPTIONS
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
validate_config(kit.files.serviceWorker, {
|
|
73
|
+
paths,
|
|
74
|
+
types,
|
|
75
|
+
example: {
|
|
72
76
|
extends: '$app/tsconfig/service-worker'
|
|
73
77
|
}
|
|
74
|
-
);
|
|
78
|
+
});
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
/**
|
|
78
82
|
* Write a generated `tsconfig.json` inside `node_modules`, for the
|
|
79
83
|
* user config to extend
|
|
80
84
|
* @param {string} root The project root
|
|
81
|
-
* @param {string} dir The directory to resolve a user config from
|
|
82
85
|
* @param {string} id The id of the generated config
|
|
83
86
|
* @param {any} config The contents of the generated tsconfig, with paths relative to `root`
|
|
84
|
-
* @param {any} example What to print if the user config does _not_ extend the generated config
|
|
85
87
|
* @param {ValidatedKitConfig['typescript']['config']} [transform] TODO get rid of this
|
|
86
88
|
*/
|
|
87
|
-
function write_parent_tsconfig(root,
|
|
89
|
+
function write_parent_tsconfig(root, id, config, transform) {
|
|
88
90
|
// simplified tsconfig resolvers (e.g. Playwright's) only find `${id}.json`, not `${id}/tsconfig.json`
|
|
89
91
|
const out_file = path.join(root, `node_modules/${id}.json`);
|
|
90
92
|
|
|
@@ -92,44 +94,60 @@ function write_parent_tsconfig(root, dir, id, config, example, transform) {
|
|
|
92
94
|
normalized = transform?.(normalized) ?? normalized;
|
|
93
95
|
|
|
94
96
|
write_if_changed(out_file, JSON.stringify(normalized, null, '\t'));
|
|
97
|
+
}
|
|
95
98
|
|
|
99
|
+
/**
|
|
100
|
+
* @param {string} dir The directory to resolve a user config from
|
|
101
|
+
* @param {Object} options
|
|
102
|
+
* @param {Record<string, string[]>} options.paths The expected paths
|
|
103
|
+
* @param {string[]} options.types The expected types
|
|
104
|
+
* @param {string[]} [options.exclusions] Files that should be excluded
|
|
105
|
+
* @param {any} options.example What to print if the user config does _not_ extend the generated config
|
|
106
|
+
*/
|
|
107
|
+
function validate_config(dir, options) {
|
|
96
108
|
if (!ts) {
|
|
97
109
|
// The user has not installed TypeScript. Skip validation of config.
|
|
98
110
|
return;
|
|
99
111
|
}
|
|
100
112
|
|
|
101
113
|
const user_config = load_user_tsconfig(dir);
|
|
114
|
+
if (!user_config || !modified_since_last_check(user_config.file)) return;
|
|
102
115
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
);
|
|
116
|
+
// now that we've written the parent config, we can resolve the
|
|
117
|
+
// user config and validate that nothing important was overwritten
|
|
118
|
+
if (!extends_id(user_config.options, options.example.extends)) {
|
|
119
|
+
console.warn(
|
|
120
|
+
styleText(
|
|
121
|
+
['bold', 'yellow'],
|
|
122
|
+
`${path.relative(process.cwd(), user_config.file)} should extend SvelteKit's built-in configuration:`
|
|
123
|
+
)
|
|
124
|
+
);
|
|
113
125
|
|
|
114
|
-
|
|
126
|
+
console.warn(JSON.stringify(options.example, null, ' '));
|
|
115
127
|
|
|
116
|
-
|
|
117
|
-
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
118
130
|
|
|
119
|
-
|
|
120
|
-
const warnings = validate_resolved_config(resolved, config.compilerOptions);
|
|
131
|
+
const resolved = ts.parseJsonConfigFileContent(user_config.options, ts.sys, dir);
|
|
121
132
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
133
|
+
const warnings = validate_resolved_config(
|
|
134
|
+
dir,
|
|
135
|
+
resolved,
|
|
136
|
+
options.paths,
|
|
137
|
+
options.types,
|
|
138
|
+
options.exclusions
|
|
139
|
+
);
|
|
129
140
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
141
|
+
if (warnings.length > 0) {
|
|
142
|
+
console.warn(
|
|
143
|
+
styleText(
|
|
144
|
+
['bold', 'yellow'],
|
|
145
|
+
`Found issues while validating ${path.relative(process.cwd(), user_config.file)}`
|
|
146
|
+
)
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
for (const warning of warnings) {
|
|
150
|
+
console.warn(` - ${warning}`);
|
|
133
151
|
}
|
|
134
152
|
}
|
|
135
153
|
}
|
|
@@ -36,16 +36,6 @@ export const RECOMMENDED_OPTIONS = {
|
|
|
36
36
|
noEmit: true // prevent tsconfig error "overwriting input files" - Vite handles the build and ignores this
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
/**
|
|
40
|
-
* Validates that a tsconfig contains `"extends": "<id>"`
|
|
41
|
-
* @param {any} options
|
|
42
|
-
* @param {string} id
|
|
43
|
-
*/
|
|
44
|
-
export function extends_id(options, id) {
|
|
45
|
-
const o = options.extends;
|
|
46
|
-
return Array.isArray(o) ? o.includes(id) : o === id;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
39
|
/**
|
|
50
40
|
* Makes paths relative to the output file
|
|
51
41
|
* @param {string} out
|
|
@@ -76,57 +66,6 @@ export function normalize_config(out, config, transform) {
|
|
|
76
66
|
return transform?.(normalized) ?? normalized;
|
|
77
67
|
}
|
|
78
68
|
|
|
79
|
-
/**
|
|
80
|
-
* @param {any} resolved
|
|
81
|
-
* @param {any} options
|
|
82
|
-
*/
|
|
83
|
-
export function validate_resolved_config(resolved, options) {
|
|
84
|
-
const warnings = [];
|
|
85
|
-
|
|
86
|
-
const join = (/** @type {string[]} */ array) =>
|
|
87
|
-
array
|
|
88
|
-
.map((v) => JSON.stringify(v))
|
|
89
|
-
.join(', ')
|
|
90
|
-
.replace(/, ([^,]*)$/, ' and $1');
|
|
91
|
-
|
|
92
|
-
const missing_types = options.types?.filter(
|
|
93
|
-
(/** @type {string} */ type) => !resolved.types?.includes(type)
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
if (missing_types.length > 0) {
|
|
97
|
-
warnings.push(`"types" was overwritten. It must include ${join(missing_types)}`);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (options.paths) {
|
|
101
|
-
/** @type {Set<string>} */
|
|
102
|
-
const mismatch = new Set();
|
|
103
|
-
|
|
104
|
-
for (const [k, expected] of Object.entries(options.paths)) {
|
|
105
|
-
const actual = resolved.paths?.[k]?.map((/** @type {string} */ x) =>
|
|
106
|
-
path.resolve(/** @type {string} */ (resolved.pathsBasePath), x)
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
if (JSON.stringify(expected) !== JSON.stringify(actual)) {
|
|
110
|
-
mismatch.add(remove_trailing_slashstar(k));
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (mismatch.size > 0) {
|
|
115
|
-
const joined = join([...mismatch]);
|
|
116
|
-
|
|
117
|
-
warnings.push(`"paths" was overwritten. Imports from ${joined} may not typecheck`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
for (const key in ESSENTIAL_OPTIONS) {
|
|
122
|
-
if (resolved[key] !== options[key]) {
|
|
123
|
-
warnings.push(`"${key}" was overwritten. It should be ${JSON.stringify(options[key])}`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return warnings;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
69
|
/**
|
|
131
70
|
* @param {string} file
|
|
132
71
|
*/
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/** @import ts from 'typescript' */
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ESSENTIAL_OPTIONS, remove_trailing_slashstar } from './utils.js';
|
|
4
|
+
import { posixify } from '../../../utils/os.js';
|
|
5
|
+
|
|
6
|
+
const formatter = new Intl.ListFormat('en-gb', { type: 'conjunction' });
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {string[]} things
|
|
10
|
+
*/
|
|
11
|
+
function join(things) {
|
|
12
|
+
return formatter.format(things.map((thing) => JSON.stringify(thing)));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} dir
|
|
17
|
+
* @param {ts.ParsedCommandLine} resolved
|
|
18
|
+
* @param {Record<string, string[]>} paths
|
|
19
|
+
* @param {string[]} types
|
|
20
|
+
* @param {string[]} [exclusions]
|
|
21
|
+
*/
|
|
22
|
+
export function validate_resolved_config(dir, resolved, paths, types, exclusions) {
|
|
23
|
+
/** @type {string[]} */
|
|
24
|
+
const warnings = [];
|
|
25
|
+
|
|
26
|
+
if (resolved.options.types) {
|
|
27
|
+
validate_types(warnings, types, resolved.options.types);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (resolved.options.paths) {
|
|
31
|
+
validate_paths(
|
|
32
|
+
warnings,
|
|
33
|
+
/** @type {string} */ (resolved.options.pathsBasePath),
|
|
34
|
+
paths,
|
|
35
|
+
resolved.options.paths
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (exclusions) {
|
|
40
|
+
validate_exclusions(warnings, dir, exclusions, resolved.fileNames);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for (const key in ESSENTIAL_OPTIONS) {
|
|
44
|
+
if (resolved.options[key] !== ESSENTIAL_OPTIONS[key]) {
|
|
45
|
+
warnings.push(
|
|
46
|
+
`"${key}" was overwritten. It should be ${JSON.stringify(ESSENTIAL_OPTIONS[key])}`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return warnings;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {string[]} warnings
|
|
56
|
+
* @param {string[]} expected
|
|
57
|
+
* @param {string[]} actual
|
|
58
|
+
*/
|
|
59
|
+
export function validate_types(warnings, expected, actual) {
|
|
60
|
+
const missing_types = expected.filter((/** @type {string} */ type) => !actual.includes(type));
|
|
61
|
+
|
|
62
|
+
if (missing_types.length > 0) {
|
|
63
|
+
warnings.push(`"types" was overwritten. It must include ${join(missing_types)}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return warnings;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param {string[]} warnings
|
|
71
|
+
* @param {string} base
|
|
72
|
+
* @param {Record<string, string[]>} expected
|
|
73
|
+
* @param {ts.MapLike<string[]>} actual
|
|
74
|
+
*/
|
|
75
|
+
export function validate_paths(warnings, base, expected, actual) {
|
|
76
|
+
/** @type {Set<string>} */
|
|
77
|
+
const mismatch = new Set();
|
|
78
|
+
|
|
79
|
+
for (const [k, e] of Object.entries(expected)) {
|
|
80
|
+
const a = actual[k]?.map((/** @type {string} */ x) =>
|
|
81
|
+
path.resolve(/** @type {string} */ (base), x)
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (JSON.stringify(e) !== JSON.stringify(a)) {
|
|
85
|
+
mismatch.add(remove_trailing_slashstar(k));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (mismatch.size > 0) {
|
|
90
|
+
const joined = join([...mismatch]);
|
|
91
|
+
|
|
92
|
+
warnings.push(`"paths" was overwritten. Imports from ${joined} may not typecheck`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return warnings;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {string[]} warnings
|
|
100
|
+
* @param {string} dir
|
|
101
|
+
* @param {string[]} exclusions
|
|
102
|
+
* @param {string[]} files
|
|
103
|
+
*/
|
|
104
|
+
export function validate_exclusions(warnings, dir, exclusions, files) {
|
|
105
|
+
const missing_exclusions = exclusions.map(posixify).filter((exclusion) => {
|
|
106
|
+
return files.some(
|
|
107
|
+
(f) => f === exclusion || f.startsWith(exclusion + '/') || f.startsWith(exclusion + '.')
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (missing_exclusions.length > 0) {
|
|
112
|
+
warnings.push(
|
|
113
|
+
`${join(missing_exclusions.map((file) => posixify(path.relative(dir, file))))} should be added to the "exclude" array`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return warnings;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Validates that a tsconfig contains `"extends": "<id>"`
|
|
122
|
+
* @param {any} options
|
|
123
|
+
* @param {string} id
|
|
124
|
+
*/
|
|
125
|
+
export function extends_id(options, id) {
|
|
126
|
+
const o = options.extends;
|
|
127
|
+
return Array.isArray(o) ? o.includes(id) : o === id;
|
|
128
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import MagicString from 'magic-string';
|
|
4
|
-
import {
|
|
4
|
+
import { walk, resolve_entry } from '../../../utils/filesystem.js';
|
|
5
5
|
import { compact } from '../../../utils/array.js';
|
|
6
6
|
import { posixify } from '../../../utils/os.js';
|
|
7
7
|
import { ts } from '../ts.js';
|
|
@@ -49,7 +49,7 @@ export function write_all_types(config, manifest_data, root) {
|
|
|
49
49
|
for (const file of walk(types_dir)) {
|
|
50
50
|
const dir = path.dirname(file);
|
|
51
51
|
if (!expected_directories.has(dir)) {
|
|
52
|
-
|
|
52
|
+
fs.rmSync(path.join(types_dir, file), { force: true, recursive: true });
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
}
|