@sveltejs/kit 1.0.0-next.416 → 1.0.0-next.419
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 +5 -7
- package/src/cli.js +8 -15
- package/src/core/config/options.js +1 -7
- package/src/core/sync/create_manifest_data/index.js +14 -4
- package/src/core/sync/write_types.js +40 -9
- package/src/runtime/client/client.js +1 -1
- package/src/runtime/client/types.d.ts +2 -2
- package/src/runtime/server/endpoint.js +3 -1
- package/src/runtime/server/index.js +1 -1
- package/src/runtime/server/page/index.js +19 -11
- package/src/runtime/server/page/load_data.js +3 -3
- package/src/runtime/server/page/render.js +26 -8
- package/src/runtime/server/page/types.d.ts +2 -2
- package/src/utils/escape.js +1 -1
- package/src/vite/build/build_server.js +0 -1
- package/src/vite/build/utils.js +15 -11
- package/src/vite/dev/index.js +14 -15
- package/src/vite/index.js +2 -2
- package/types/index.d.ts +27 -26
- package/types/internal.d.ts +0 -1
- package/types/private.d.ts +0 -27
- package/src/packaging/index.js +0 -218
- package/src/packaging/types.d.ts +0 -8
- package/src/packaging/typescript.js +0 -150
- package/src/packaging/utils.js +0 -143
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.419",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/sveltejs/kit",
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"type": "module",
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@sveltejs/vite-plugin-svelte": "^1.0.1",
|
|
14
|
-
"chokidar": "^3.5.3",
|
|
15
14
|
"cookie": "^0.5.0",
|
|
16
15
|
"devalue": "^2.0.1",
|
|
17
16
|
"kleur": "^4.1.4",
|
|
@@ -37,14 +36,14 @@
|
|
|
37
36
|
"rollup": "^2.75.7",
|
|
38
37
|
"svelte": "^3.48.0",
|
|
39
38
|
"svelte-preprocess": "^4.10.6",
|
|
40
|
-
"
|
|
39
|
+
"tiny-glob": "^0.2.9",
|
|
41
40
|
"typescript": "^4.7.4",
|
|
42
41
|
"uvu": "^0.5.3",
|
|
43
|
-
"vite": "
|
|
42
|
+
"vite": "3.0.2"
|
|
44
43
|
},
|
|
45
44
|
"peerDependencies": {
|
|
46
45
|
"svelte": "^3.44.0",
|
|
47
|
-
"vite": "
|
|
46
|
+
"vite": "3.0.2"
|
|
48
47
|
},
|
|
49
48
|
"bin": {
|
|
50
49
|
"svelte-kit": "svelte-kit.js"
|
|
@@ -88,10 +87,9 @@
|
|
|
88
87
|
"check": "tsc",
|
|
89
88
|
"check:all": "tsc && pnpm -r --filter=\"./**\" check",
|
|
90
89
|
"format": "npm run lint -- --write",
|
|
91
|
-
"test": "npm run test:unit && npm run test:
|
|
90
|
+
"test": "npm run test:unit && npm run test:integration",
|
|
92
91
|
"test:integration": "pnpm run -r --workspace-concurrency 1 --filter=\"./test/**\" test",
|
|
93
92
|
"test:unit": "uvu src \"(spec\\.js|test[\\\\/]index\\.js)\" -i packaging",
|
|
94
|
-
"test:packaging": "uvu src/packaging \"(spec\\.js|test[\\\\/]index\\.js)\"",
|
|
95
93
|
"types": "node scripts/extract-types.js",
|
|
96
94
|
"postinstall": "node svelte-kit.js sync"
|
|
97
95
|
}
|
package/src/cli.js
CHANGED
|
@@ -22,21 +22,6 @@ function handle_error(e) {
|
|
|
22
22
|
const pkg = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
|
|
23
23
|
const prog = sade('svelte-kit').version(pkg.version);
|
|
24
24
|
|
|
25
|
-
prog
|
|
26
|
-
.command('package')
|
|
27
|
-
.describe('Create a package')
|
|
28
|
-
.option('-w, --watch', 'Rerun when files change', false)
|
|
29
|
-
.action(async ({ watch }) => {
|
|
30
|
-
try {
|
|
31
|
-
const config = await load_config();
|
|
32
|
-
const packaging = await import('./packaging/index.js');
|
|
33
|
-
|
|
34
|
-
await (watch ? packaging.watch(config) : packaging.build(config));
|
|
35
|
-
} catch (error) {
|
|
36
|
-
handle_error(error);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
25
|
prog
|
|
41
26
|
.command('sync')
|
|
42
27
|
.describe('Synchronise generated files')
|
|
@@ -78,6 +63,14 @@ prog
|
|
|
78
63
|
replace('dev');
|
|
79
64
|
replace('build');
|
|
80
65
|
replace('preview');
|
|
66
|
+
prog
|
|
67
|
+
.command('package')
|
|
68
|
+
.describe('No longer available - use @sveltejs/package instead')
|
|
69
|
+
.action(() => {
|
|
70
|
+
console.error(
|
|
71
|
+
'svelte-kit package has been removed. It now lives in its own npm package. See the PR on how to migrate: https://github.com/sveltejs/kit/pull/5730'
|
|
72
|
+
);
|
|
73
|
+
});
|
|
81
74
|
|
|
82
75
|
prog.parse(process.argv, { unknown: (arg) => `Unknown option: ${arg}` });
|
|
83
76
|
|
|
@@ -173,13 +173,7 @@ const options = object(
|
|
|
173
173
|
|
|
174
174
|
outDir: string('.svelte-kit'),
|
|
175
175
|
|
|
176
|
-
package:
|
|
177
|
-
dir: string('package'),
|
|
178
|
-
// excludes all .d.ts and filename starting with _
|
|
179
|
-
exports: fun((filepath) => !/^_|\/_|\.d\.ts$/.test(filepath)),
|
|
180
|
-
files: fun(() => true),
|
|
181
|
-
emitTypes: boolean(true)
|
|
182
|
-
}),
|
|
176
|
+
package: error((keypath) => `${keypath} has been removed — use @sveltejs/package instead`),
|
|
183
177
|
|
|
184
178
|
paths: object({
|
|
185
179
|
base: validate('', (input, keypath) => {
|
|
@@ -172,12 +172,22 @@ export default function create_manifest_data({
|
|
|
172
172
|
if (item.is_page) {
|
|
173
173
|
const route = /** @type {import('types').PageData} */ (route_map.get(id));
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
// This ensures that layouts and errors are set for pages that have no Svelte file
|
|
176
|
+
// and only redirect or throw an error, but are set to the Svelte file definition if it exists.
|
|
177
|
+
// This ensures the proper error page is used and rendered in the proper layout.
|
|
178
|
+
if (item.kind === 'component' || route.layouts.length === 0) {
|
|
179
|
+
const { layouts, errors } = trace(
|
|
180
|
+
tree,
|
|
181
|
+
id,
|
|
182
|
+
item.kind === 'component' ? item.uses_layout : undefined,
|
|
183
|
+
project_relative
|
|
184
|
+
);
|
|
179
185
|
route.layouts = layouts;
|
|
180
186
|
route.errors = errors;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (item.kind === 'component') {
|
|
190
|
+
route.leaf.component = project_relative;
|
|
181
191
|
} else if (item.kind === 'server') {
|
|
182
192
|
route.leaf.server = project_relative;
|
|
183
193
|
} else {
|
|
@@ -246,12 +246,18 @@ function write_types_for_dir(config, manifest_data, routes_dir, dir, groups, ts)
|
|
|
246
246
|
|
|
247
247
|
exports.push(`export type PageData = ${data};`);
|
|
248
248
|
if (load) {
|
|
249
|
-
exports.push(
|
|
249
|
+
exports.push(
|
|
250
|
+
`export type PageLoad<OutputData extends Record<string, any> | void = Record<string, any> | void> = ${load};`
|
|
251
|
+
);
|
|
252
|
+
exports.push('export type PageLoadEvent = Parameters<PageLoad>[0];');
|
|
250
253
|
}
|
|
251
254
|
|
|
252
255
|
exports.push(`export type PageServerData = ${server_data};`);
|
|
253
256
|
if (server_load) {
|
|
254
|
-
exports.push(
|
|
257
|
+
exports.push(
|
|
258
|
+
`export type PageServerLoad<OutputData extends Record<string, any> | void = Record<string, any> | void> = ${server_load};`
|
|
259
|
+
);
|
|
260
|
+
exports.push('export type PageServerLoadEvent = Parameters<PageServerLoad>[0];');
|
|
255
261
|
}
|
|
256
262
|
|
|
257
263
|
if (group.leaf.server) {
|
|
@@ -292,12 +298,18 @@ function write_types_for_dir(config, manifest_data, routes_dir, dir, groups, ts)
|
|
|
292
298
|
|
|
293
299
|
exports.push(`export type LayoutData = ${data};`);
|
|
294
300
|
if (load) {
|
|
295
|
-
exports.push(
|
|
301
|
+
exports.push(
|
|
302
|
+
`export type LayoutLoad<OutputData extends Record<string, any> | void = Record<string, any> | void> = ${load};`
|
|
303
|
+
);
|
|
304
|
+
exports.push('export type LayoutLoadEvent = Parameters<LayoutLoad>[0];');
|
|
296
305
|
}
|
|
297
306
|
|
|
298
307
|
exports.push(`export type LayoutServerData = ${server_data};`);
|
|
299
308
|
if (server_load) {
|
|
300
|
-
exports.push(
|
|
309
|
+
exports.push(
|
|
310
|
+
`export type LayoutServerLoad<OutputData extends Record<string, any> | void = Record<string, any> | void> = ${server_load};`
|
|
311
|
+
);
|
|
312
|
+
exports.push('export type LayoutServerLoadEvent = Parameters<LayoutServerLoad>[0];');
|
|
301
313
|
}
|
|
302
314
|
}
|
|
303
315
|
|
|
@@ -311,9 +323,15 @@ function write_types_for_dir(config, manifest_data, routes_dir, dir, groups, ts)
|
|
|
311
323
|
/** @type {string[]} */
|
|
312
324
|
const load_exports = [];
|
|
313
325
|
|
|
326
|
+
/** @type {string[]} */
|
|
327
|
+
const load_event_exports = [];
|
|
328
|
+
|
|
314
329
|
/** @type {string[]} */
|
|
315
330
|
const server_load_exports = [];
|
|
316
331
|
|
|
332
|
+
/** @type {string[]} */
|
|
333
|
+
const server_load_event_exports = [];
|
|
334
|
+
|
|
317
335
|
for (const [name, node] of group.named_layouts) {
|
|
318
336
|
const { data, server_data, load, server_load, written_proxies } = process_node(
|
|
319
337
|
ts,
|
|
@@ -326,26 +344,39 @@ function write_types_for_dir(config, manifest_data, routes_dir, dir, groups, ts)
|
|
|
326
344
|
data_exports.push(`export type ${name} = ${data};`);
|
|
327
345
|
server_data_exports.push(`export type ${name} = ${server_data};`);
|
|
328
346
|
if (load) {
|
|
329
|
-
load_exports.push(
|
|
347
|
+
load_exports.push(
|
|
348
|
+
`export type ${name}<OutputData extends Record<string, any> | void = Record<string, any> | void> = ${load};`
|
|
349
|
+
);
|
|
350
|
+
load_event_exports.push(`export type ${name} = Parameters<LayoutLoad.${name}>[0];`);
|
|
330
351
|
}
|
|
331
352
|
if (server_load) {
|
|
332
|
-
server_load_exports.push(
|
|
353
|
+
server_load_exports.push(
|
|
354
|
+
`export type ${name}<OutputData extends Record<string, any> | void = Record<string, any> | void> = ${load};`
|
|
355
|
+
);
|
|
356
|
+
server_load_event_exports.push(
|
|
357
|
+
`export type ${name} = Parameters<LayoutServerLoad.${name}>[0];`
|
|
358
|
+
);
|
|
333
359
|
}
|
|
334
360
|
}
|
|
335
361
|
|
|
336
362
|
exports.push(`\nexport namespace LayoutData {\n\t${data_exports.join('\n\t')}\n}`);
|
|
337
363
|
exports.push(`\nexport namespace LayoutLoad {\n\t${load_exports.join('\n\t')}\n}`);
|
|
364
|
+
exports.push(`\nexport namespace LayoutLoadEvent {\n\t${load_event_exports.join('\n\t')}\n}`);
|
|
338
365
|
exports.push(
|
|
339
366
|
`\nexport namespace LayoutServerData {\n\t${server_data_exports.join('\n\t')}\n}`
|
|
340
367
|
);
|
|
341
368
|
exports.push(
|
|
342
369
|
`\nexport namespace LayoutServerLoad {\n\t${server_load_exports.join('\n\t')}\n}`
|
|
343
370
|
);
|
|
371
|
+
exports.push(
|
|
372
|
+
`\nexport namespace LayoutServerLoadEvent {\n\t${server_load_event_exports.join('\n\t')}\n}`
|
|
373
|
+
);
|
|
344
374
|
}
|
|
345
375
|
}
|
|
346
376
|
|
|
347
377
|
if (group.endpoint) {
|
|
348
378
|
exports.push(`export type RequestHandler = Kit.RequestHandler<RouteParams>;`);
|
|
379
|
+
exports.push(`export type RequestEvent = Kit.RequestEvent<RouteParams>;`);
|
|
349
380
|
}
|
|
350
381
|
|
|
351
382
|
const output = [imports.join('\n'), declarations.join('\n'), exports.join('\n')]
|
|
@@ -384,7 +415,7 @@ function process_node(ts, node, outdir, params, groups) {
|
|
|
384
415
|
}
|
|
385
416
|
|
|
386
417
|
server_data = get_data_type(node.server, 'load', 'null', proxy);
|
|
387
|
-
server_load = `Kit.ServerLoad<${params}, ${get_parent_type('LayoutServerData')}>`;
|
|
418
|
+
server_load = `Kit.ServerLoad<${params}, ${get_parent_type('LayoutServerData')}, OutputData>`;
|
|
388
419
|
|
|
389
420
|
if (proxy) {
|
|
390
421
|
const types = [];
|
|
@@ -415,7 +446,7 @@ function process_node(ts, node, outdir, params, groups) {
|
|
|
415
446
|
}
|
|
416
447
|
|
|
417
448
|
data = get_data_type(node.shared, 'load', server_data, proxy);
|
|
418
|
-
load = `Kit.Load<${params}, ${server_data}, ${get_parent_type('LayoutData')}>`;
|
|
449
|
+
load = `Kit.Load<${params}, ${server_data}, ${get_parent_type('LayoutData')}, OutputData>`;
|
|
419
450
|
} else {
|
|
420
451
|
data = server_data;
|
|
421
452
|
}
|
|
@@ -468,7 +499,7 @@ function process_node(ts, node, outdir, params, groups) {
|
|
|
468
499
|
parent = parent_layout.parent;
|
|
469
500
|
}
|
|
470
501
|
|
|
471
|
-
let parent_str = parent_imports[0] || '
|
|
502
|
+
let parent_str = parent_imports[0] || 'Record<never, never>';
|
|
472
503
|
for (let i = 1; i < parent_imports.length; i++) {
|
|
473
504
|
// Omit is necessary because a parent could have a property with the same key which would
|
|
474
505
|
// cause a type conflict. At runtime the child overwrites the parent property in this case,
|
|
@@ -448,7 +448,7 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
448
448
|
* url: URL;
|
|
449
449
|
* params: Record<string, string>;
|
|
450
450
|
* routeId: string | null;
|
|
451
|
-
* server_data:
|
|
451
|
+
* server_data: Record<string, any> | null;
|
|
452
452
|
* }} options
|
|
453
453
|
* @returns {Promise<import('./types').BranchNode>}
|
|
454
454
|
*/
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
prefetch,
|
|
7
7
|
prefetchRoutes
|
|
8
8
|
} from '$app/navigation';
|
|
9
|
-
import { CSRPageNode, CSRRoute
|
|
9
|
+
import { CSRPageNode, CSRRoute } from 'types';
|
|
10
10
|
import { HttpError } from '../../index/private.js';
|
|
11
11
|
import { SerializedHttpError } from '../server/page/types.js';
|
|
12
12
|
|
|
@@ -92,7 +92,7 @@ export interface ServerDataRedirected {
|
|
|
92
92
|
export interface ServerDataLoaded {
|
|
93
93
|
type: 'data';
|
|
94
94
|
nodes: Array<{
|
|
95
|
-
data?:
|
|
95
|
+
data?: Record<string, any> | null; // TODO or `-1` to indicate 'reuse cached data'?
|
|
96
96
|
status?: number;
|
|
97
97
|
message?: string;
|
|
98
98
|
error?: {
|
|
@@ -29,7 +29,9 @@ export async function render_endpoint(event, route) {
|
|
|
29
29
|
return method_not_allowed(mod, method);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const response = await handler(
|
|
32
|
+
const response = await handler(
|
|
33
|
+
/** @type {import('types').RequestEvent<Record<string, any>>} */ (event)
|
|
34
|
+
);
|
|
33
35
|
|
|
34
36
|
if (!(response instanceof Response)) {
|
|
35
37
|
return new Response(
|
|
@@ -257,7 +257,7 @@ export async function respond(request, options, state) {
|
|
|
257
257
|
event,
|
|
258
258
|
node,
|
|
259
259
|
parent: async () => {
|
|
260
|
-
/** @type {
|
|
260
|
+
/** @type {Record<string, any>} */
|
|
261
261
|
const data = {};
|
|
262
262
|
for (let j = 0; j < i; j += 1) {
|
|
263
263
|
const parent = await promises[j];
|
|
@@ -77,7 +77,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
if (event.request.method === 'POST' && result?.location) {
|
|
80
|
-
return redirect_response(
|
|
80
|
+
return redirect_response(303, result.location);
|
|
81
81
|
}
|
|
82
82
|
} else {
|
|
83
83
|
event.setHeaders({
|
|
@@ -95,6 +95,9 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
const should_prerender_data = nodes.some((node) => node?.server);
|
|
99
|
+
const data_pathname = `${event.url.pathname.replace(/\/$/, '')}/__data.json`;
|
|
100
|
+
|
|
98
101
|
if (!resolve_opts.ssr) {
|
|
99
102
|
return await render_response({
|
|
100
103
|
branch: [],
|
|
@@ -137,7 +140,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
137
140
|
/** @type {Error | null} */
|
|
138
141
|
let load_error = null;
|
|
139
142
|
|
|
140
|
-
/** @type {Array<Promise<
|
|
143
|
+
/** @type {Array<Promise<Record<string, any> | null>>} */
|
|
141
144
|
const server_promises = nodes.map((node, i) => {
|
|
142
145
|
if (load_error) {
|
|
143
146
|
// if an error happens immediately, don't bother with the rest of the nodes
|
|
@@ -156,7 +159,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
156
159
|
event,
|
|
157
160
|
node,
|
|
158
161
|
parent: async () => {
|
|
159
|
-
/** @type {
|
|
162
|
+
/** @type {Record<string, any>} */
|
|
160
163
|
const data = {};
|
|
161
164
|
for (let j = 0; j < i; j += 1) {
|
|
162
165
|
Object.assign(data, await server_promises[j]);
|
|
@@ -214,6 +217,16 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
214
217
|
const error = normalize_error(e);
|
|
215
218
|
|
|
216
219
|
if (error instanceof Redirect) {
|
|
220
|
+
if (state.prerendering && should_prerender_data) {
|
|
221
|
+
state.prerendering.dependencies.set(data_pathname, {
|
|
222
|
+
response: new Response(undefined),
|
|
223
|
+
body: JSON.stringify({
|
|
224
|
+
type: 'redirect',
|
|
225
|
+
location: error.location
|
|
226
|
+
})
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
217
230
|
return redirect_response(error.status, error.location);
|
|
218
231
|
}
|
|
219
232
|
|
|
@@ -267,19 +280,14 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
267
280
|
}
|
|
268
281
|
}
|
|
269
282
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
const pathname = `${event.url.pathname.replace(/\/$/, '')}/__data.json`;
|
|
273
|
-
|
|
274
|
-
const dependency = {
|
|
283
|
+
if (state.prerendering && should_prerender_data) {
|
|
284
|
+
state.prerendering.dependencies.set(data_pathname, {
|
|
275
285
|
response: new Response(undefined),
|
|
276
286
|
body: JSON.stringify({
|
|
277
287
|
type: 'data',
|
|
278
288
|
nodes: branch.map((branch_node) => ({ data: branch_node?.server_data }))
|
|
279
289
|
})
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
state.prerendering.dependencies.set(pathname, dependency);
|
|
290
|
+
});
|
|
283
291
|
}
|
|
284
292
|
|
|
285
293
|
// TODO use validation_errors
|
|
@@ -5,7 +5,7 @@ import { LoadURL, PrerenderingURL } from '../../../utils/url.js';
|
|
|
5
5
|
* @param {{
|
|
6
6
|
* event: import('types').RequestEvent;
|
|
7
7
|
* node: import('types').SSRNode | undefined;
|
|
8
|
-
* parent: () => Promise<
|
|
8
|
+
* parent: () => Promise<Record<string, any>>;
|
|
9
9
|
* }} opts
|
|
10
10
|
*/
|
|
11
11
|
export async function load_server_data({ event, node, parent }) {
|
|
@@ -37,7 +37,7 @@ export async function load_server_data({ event, node, parent }) {
|
|
|
37
37
|
* fetcher: typeof fetch;
|
|
38
38
|
* node: import('types').SSRNode | undefined;
|
|
39
39
|
* parent: () => Promise<Record<string, any>>;
|
|
40
|
-
* server_data_promise: Promise<
|
|
40
|
+
* server_data_promise: Promise<Record<string, any> | null>;
|
|
41
41
|
* state: import('types').SSRState;
|
|
42
42
|
* }} opts
|
|
43
43
|
*/
|
|
@@ -70,7 +70,7 @@ export async function load_data({ event, fetcher, node, parent, server_data_prom
|
|
|
70
70
|
|
|
71
71
|
/** @param {Record<string, any>} object */
|
|
72
72
|
async function unwrap_promises(object) {
|
|
73
|
-
/** @type {
|
|
73
|
+
/** @type {Record<string, any>} */
|
|
74
74
|
const unwrapped = {};
|
|
75
75
|
|
|
76
76
|
for (const key in object) {
|
|
@@ -86,7 +86,7 @@ export async function render_response({
|
|
|
86
86
|
/** @type {import('types').Page} */
|
|
87
87
|
page: {
|
|
88
88
|
error,
|
|
89
|
-
params: event.params,
|
|
89
|
+
params: /** @type {Record<string, any>} */ (event.params),
|
|
90
90
|
routeId: event.routeId,
|
|
91
91
|
status,
|
|
92
92
|
url: state.prerendering ? new PrerenderingURL(event.url) : event.url,
|
|
@@ -150,9 +150,31 @@ export async function render_response({
|
|
|
150
150
|
|
|
151
151
|
const target = hash(body);
|
|
152
152
|
|
|
153
|
+
/**
|
|
154
|
+
* The prefix to use for static assets. Replaces `%sveltekit.assets%` in the template
|
|
155
|
+
* @type {string}
|
|
156
|
+
*/
|
|
157
|
+
let assets;
|
|
158
|
+
|
|
159
|
+
if (options.paths.assets) {
|
|
160
|
+
// if an asset path is specified, use it
|
|
161
|
+
assets = options.paths.assets;
|
|
162
|
+
} else if (state.prerendering?.fallback) {
|
|
163
|
+
// if we're creating a fallback page, asset paths need to be root-relative
|
|
164
|
+
assets = options.paths.base;
|
|
165
|
+
} else {
|
|
166
|
+
// otherwise we want asset paths to be relative to the page, so that they
|
|
167
|
+
// will work in odd contexts like IPFS, the internet archive, and so on
|
|
168
|
+
const segments = event.url.pathname.slice(options.paths.base.length).split('/').slice(2);
|
|
169
|
+
assets = segments.length > 0 ? segments.map(() => '..').join('/') : '.';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** @param {string} path */
|
|
173
|
+
const prefixed = (path) => (path.startsWith('/') ? path : `${assets}/${path}`);
|
|
174
|
+
|
|
153
175
|
// prettier-ignore
|
|
154
176
|
const init_app = `
|
|
155
|
-
import { set_public_env, start } from ${s(
|
|
177
|
+
import { set_public_env, start } from ${s(prefixed(entry.file))};
|
|
156
178
|
|
|
157
179
|
set_public_env(${s(options.public_env)});
|
|
158
180
|
|
|
@@ -195,7 +217,7 @@ export async function render_response({
|
|
|
195
217
|
}
|
|
196
218
|
|
|
197
219
|
for (const dep of stylesheets) {
|
|
198
|
-
const path =
|
|
220
|
+
const path = prefixed(dep);
|
|
199
221
|
const attributes = [];
|
|
200
222
|
|
|
201
223
|
if (csp.style_needs_nonce) {
|
|
@@ -217,7 +239,7 @@ export async function render_response({
|
|
|
217
239
|
|
|
218
240
|
if (page_config.router || page_config.hydrate) {
|
|
219
241
|
for (const dep of modulepreloads) {
|
|
220
|
-
const path =
|
|
242
|
+
const path = prefixed(dep);
|
|
221
243
|
link_header_preloads.add(`<${encodeURI(path)}>; rel="modulepreload"; nopush`);
|
|
222
244
|
if (state.prerendering) {
|
|
223
245
|
head += `\n\t<link rel="modulepreload" href="${path}">`;
|
|
@@ -292,10 +314,6 @@ export async function render_response({
|
|
|
292
314
|
}
|
|
293
315
|
}
|
|
294
316
|
|
|
295
|
-
const segments = event.url.pathname.slice(options.paths.base.length).split('/').slice(2);
|
|
296
|
-
const assets =
|
|
297
|
-
options.paths.assets || (segments.length > 0 ? segments.map(() => '..').join('/') : '.');
|
|
298
|
-
|
|
299
317
|
// TODO flush chunks as early as we can
|
|
300
318
|
const html =
|
|
301
319
|
(await resolve_opts.transformPageChunk({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ResponseHeaders, SSRNode, CspDirectives } from 'types';
|
|
2
2
|
import { HttpError } from '../../../index/private';
|
|
3
3
|
|
|
4
4
|
export interface Fetched {
|
|
@@ -21,7 +21,7 @@ export interface FetchState {
|
|
|
21
21
|
export type Loaded = {
|
|
22
22
|
node: SSRNode;
|
|
23
23
|
data: Record<string, any> | null;
|
|
24
|
-
server_data:
|
|
24
|
+
server_data: any;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
type CspMode = 'hash' | 'nonce' | 'auto';
|
package/src/utils/escape.js
CHANGED
|
@@ -37,7 +37,7 @@ const render_json_payload_script_regex = new RegExp(
|
|
|
37
37
|
* Attribute names must be type-checked so we don't need to escape them.
|
|
38
38
|
*
|
|
39
39
|
* @param {import('types').PayloadScriptAttributes} attrs A list of attributes to be added to the element.
|
|
40
|
-
* @param {
|
|
40
|
+
* @param {any} payload The data to be carried by the element. Must be serializable to JSON.
|
|
41
41
|
* @returns {string} The raw HTML of a script element carrying the JSON payload.
|
|
42
42
|
* @example const html = render_json_payload_script({ type: 'data', url: '/data.json' }, { foo: 'bar' });
|
|
43
43
|
*/
|
package/src/vite/build/utils.js
CHANGED
|
@@ -88,9 +88,11 @@ export function find_deps(manifest, entry, add_dynamic_css) {
|
|
|
88
88
|
* @return {import('vite').UserConfig}
|
|
89
89
|
*/
|
|
90
90
|
export const get_default_config = function ({ config, input, ssr, outDir }) {
|
|
91
|
+
const prefix = `${config.kit.appDir}/immutable`;
|
|
92
|
+
|
|
91
93
|
return {
|
|
92
94
|
appType: 'custom',
|
|
93
|
-
base: assets_base(config.kit),
|
|
95
|
+
base: ssr ? assets_base(config.kit) : './',
|
|
94
96
|
build: {
|
|
95
97
|
cssCodeSplit: true,
|
|
96
98
|
// don't use the default name to avoid collisions with 'static/manifest.json'
|
|
@@ -101,11 +103,9 @@ export const get_default_config = function ({ config, input, ssr, outDir }) {
|
|
|
101
103
|
input,
|
|
102
104
|
output: {
|
|
103
105
|
format: 'esm',
|
|
104
|
-
entryFileNames: ssr ? '[name].js' : `${
|
|
105
|
-
chunkFileNames: ssr
|
|
106
|
-
|
|
107
|
-
: `${config.kit.appDir}/immutable/chunks/[name]-[hash].js`,
|
|
108
|
-
assetFileNames: `${config.kit.appDir}/immutable/assets/[name]-[hash][extname]`
|
|
106
|
+
entryFileNames: ssr ? '[name].js' : `${prefix}/[name]-[hash].js`,
|
|
107
|
+
chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[name]-[hash].js`,
|
|
108
|
+
assetFileNames: `${prefix}/assets/[name]-[hash][extname]`
|
|
109
109
|
},
|
|
110
110
|
preserveEntrySignatures: 'strict'
|
|
111
111
|
},
|
|
@@ -125,6 +125,14 @@ export const get_default_config = function ({ config, input, ssr, outDir }) {
|
|
|
125
125
|
},
|
|
126
126
|
ssr: {
|
|
127
127
|
noExternal: ['@sveltejs/kit']
|
|
128
|
+
},
|
|
129
|
+
worker: {
|
|
130
|
+
rollupOptions: {
|
|
131
|
+
output: {
|
|
132
|
+
entryFileNames: `${prefix}/workers/[name]-[hash].js`,
|
|
133
|
+
chunkFileNames: `${prefix}/workers/chunks/[name]-[hash].js`
|
|
134
|
+
}
|
|
135
|
+
}
|
|
128
136
|
}
|
|
129
137
|
};
|
|
130
138
|
};
|
|
@@ -134,11 +142,7 @@ export const get_default_config = function ({ config, input, ssr, outDir }) {
|
|
|
134
142
|
* @returns {string}
|
|
135
143
|
*/
|
|
136
144
|
export function assets_base(config) {
|
|
137
|
-
|
|
138
|
-
// during `svelte-kit preview`, because we use a local asset path. This
|
|
139
|
-
// may be fixed in Vite 3: https://github.com/vitejs/vite/issues/2009
|
|
140
|
-
const { base, assets } = config.paths;
|
|
141
|
-
return `${assets || base}/`;
|
|
145
|
+
return config.paths.assets || config.paths.base || './';
|
|
142
146
|
}
|
|
143
147
|
|
|
144
148
|
const method_names = new Set(['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']);
|
package/src/vite/dev/index.js
CHANGED
|
@@ -286,6 +286,20 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
286
286
|
}
|
|
287
287
|
});
|
|
288
288
|
|
|
289
|
+
const runtime_base = runtime_directory.startsWith(process.cwd())
|
|
290
|
+
? `/${path.relative('.', runtime_directory)}`
|
|
291
|
+
: `/@fs${
|
|
292
|
+
// Windows/Linux separation - Windows starts with a drive letter, we need a / in front there
|
|
293
|
+
runtime_directory.startsWith('/') ? '' : '/'
|
|
294
|
+
}${runtime_directory}`;
|
|
295
|
+
|
|
296
|
+
const { set_private_env } = await vite.ssrLoadModule(`${runtime_base}/env-private.js`);
|
|
297
|
+
const { set_public_env } = await vite.ssrLoadModule(`${runtime_base}/env-public.js`);
|
|
298
|
+
|
|
299
|
+
const env = get_env(vite_config.mode, svelte_config.kit.env.publicPrefix);
|
|
300
|
+
set_private_env(env.private);
|
|
301
|
+
set_public_env(env.public);
|
|
302
|
+
|
|
289
303
|
return () => {
|
|
290
304
|
const serve_static_middleware = vite.middlewares.stack.find(
|
|
291
305
|
(middleware) =>
|
|
@@ -320,20 +334,6 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
320
334
|
);
|
|
321
335
|
}
|
|
322
336
|
|
|
323
|
-
// For some reason using runtime_prefix here is buggy, since Vite will later load the modules
|
|
324
|
-
// again with a slightly different url (with the drive letter) on windows
|
|
325
|
-
const runtime_base = `/@fs${
|
|
326
|
-
// Windows/Linux separation - Windows starts with a drive letter, we need a / in front there
|
|
327
|
-
runtime_directory.startsWith('/') ? '' : '/'
|
|
328
|
-
}${runtime_directory}`;
|
|
329
|
-
|
|
330
|
-
const { set_private_env } = await vite.ssrLoadModule(`${runtime_base}/env-private.js`);
|
|
331
|
-
const { set_public_env } = await vite.ssrLoadModule(`${runtime_base}/env-public.js`);
|
|
332
|
-
|
|
333
|
-
const env = get_env(vite_config.mode, svelte_config.kit.env.publicPrefix);
|
|
334
|
-
set_private_env(env.private);
|
|
335
|
-
set_public_env(env.public);
|
|
336
|
-
|
|
337
337
|
/** @type {Partial<import('types').Hooks>} */
|
|
338
338
|
const user_hooks = resolve_entry(svelte_config.kit.files.hooks)
|
|
339
339
|
? await vite.ssrLoadModule(`/${svelte_config.kit.files.hooks}`)
|
|
@@ -432,7 +432,6 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
432
432
|
base: svelte_config.kit.paths.base,
|
|
433
433
|
assets
|
|
434
434
|
},
|
|
435
|
-
prefix: '',
|
|
436
435
|
prerender: {
|
|
437
436
|
default: svelte_config.kit.prerender.default,
|
|
438
437
|
enabled: svelte_config.kit.prerender.enabled
|
package/src/vite/index.js
CHANGED
|
@@ -207,7 +207,7 @@ function kit() {
|
|
|
207
207
|
paths = {
|
|
208
208
|
build_dir: `${svelte_config.kit.outDir}/build`,
|
|
209
209
|
output_dir: `${svelte_config.kit.outDir}/output`,
|
|
210
|
-
client_out_dir: `${svelte_config.kit.outDir}/output/client
|
|
210
|
+
client_out_dir: `${svelte_config.kit.outDir}/output/client`
|
|
211
211
|
};
|
|
212
212
|
|
|
213
213
|
illegal_imports = new Set([
|
|
@@ -230,7 +230,7 @@ function kit() {
|
|
|
230
230
|
/** @type {import('vite').UserConfig} */
|
|
231
231
|
const result = {
|
|
232
232
|
appType: 'custom',
|
|
233
|
-
base: '
|
|
233
|
+
base: './',
|
|
234
234
|
build: {
|
|
235
235
|
rollupOptions: {
|
|
236
236
|
// Vite dependency crawler needs an explicit JS entry point
|
package/types/index.d.ts
CHANGED
|
@@ -7,8 +7,6 @@ import { CompileOptions } from 'svelte/types/compiler/interfaces';
|
|
|
7
7
|
import {
|
|
8
8
|
AdapterEntry,
|
|
9
9
|
CspDirectives,
|
|
10
|
-
JSONObject,
|
|
11
|
-
JSONValue,
|
|
12
10
|
Logger,
|
|
13
11
|
MaybePromise,
|
|
14
12
|
Prerendered,
|
|
@@ -109,6 +107,13 @@ export interface Config {
|
|
|
109
107
|
extensions?: string[];
|
|
110
108
|
kit?: KitConfig;
|
|
111
109
|
preprocess?: any;
|
|
110
|
+
package?: {
|
|
111
|
+
source?: string;
|
|
112
|
+
dir?: string;
|
|
113
|
+
emitTypes?: boolean;
|
|
114
|
+
exports?: (filepath: string) => boolean;
|
|
115
|
+
files?: (filepath: string) => boolean;
|
|
116
|
+
};
|
|
112
117
|
[key: string]: any;
|
|
113
118
|
}
|
|
114
119
|
|
|
@@ -144,12 +149,6 @@ export interface KitConfig {
|
|
|
144
149
|
allowed?: string[];
|
|
145
150
|
};
|
|
146
151
|
outDir?: string;
|
|
147
|
-
package?: {
|
|
148
|
-
dir?: string;
|
|
149
|
-
emitTypes?: boolean;
|
|
150
|
-
exports?(filepath: string): boolean;
|
|
151
|
-
files?(filepath: string): boolean;
|
|
152
|
-
};
|
|
153
152
|
paths?: {
|
|
154
153
|
assets?: string;
|
|
155
154
|
base?: string;
|
|
@@ -194,18 +193,18 @@ export interface HandleError {
|
|
|
194
193
|
* rather than using `Load` directly.
|
|
195
194
|
*/
|
|
196
195
|
export interface Load<
|
|
197
|
-
Params extends Record<string, string
|
|
198
|
-
InputData extends
|
|
199
|
-
ParentData extends Record<string, any>
|
|
200
|
-
OutputData extends Record<string, any> = Record<string, any>
|
|
196
|
+
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
|
|
197
|
+
InputData extends Record<string, any> | null = Record<string, any> | null,
|
|
198
|
+
ParentData extends Record<string, any> = Record<string, any>,
|
|
199
|
+
OutputData extends Record<string, any> | void = Record<string, any> | void
|
|
201
200
|
> {
|
|
202
|
-
(event: LoadEvent<Params, InputData, ParentData>): MaybePromise<OutputData
|
|
201
|
+
(event: LoadEvent<Params, InputData, ParentData>): MaybePromise<OutputData>;
|
|
203
202
|
}
|
|
204
203
|
|
|
205
204
|
export interface LoadEvent<
|
|
206
|
-
Params extends Record<string, string
|
|
207
|
-
Data extends
|
|
208
|
-
ParentData extends Record<string, any>
|
|
205
|
+
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
|
|
206
|
+
Data extends Record<string, any> | null = Record<string, any> | null,
|
|
207
|
+
ParentData extends Record<string, any> = Record<string, any>
|
|
209
208
|
> {
|
|
210
209
|
fetch(info: RequestInfo, init?: RequestInit): Promise<Response>;
|
|
211
210
|
params: Params;
|
|
@@ -235,7 +234,9 @@ export interface ParamMatcher {
|
|
|
235
234
|
(param: string): boolean;
|
|
236
235
|
}
|
|
237
236
|
|
|
238
|
-
export interface RequestEvent<
|
|
237
|
+
export interface RequestEvent<
|
|
238
|
+
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>
|
|
239
|
+
> {
|
|
239
240
|
clientAddress: string;
|
|
240
241
|
locals: App.Locals;
|
|
241
242
|
params: Params;
|
|
@@ -260,8 +261,6 @@ export interface ResolveOptions {
|
|
|
260
261
|
transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise<string | undefined>;
|
|
261
262
|
}
|
|
262
263
|
|
|
263
|
-
export type ResponseBody = JSONValue | Uint8Array | ReadableStream | Error;
|
|
264
|
-
|
|
265
264
|
export class Server {
|
|
266
265
|
constructor(manifest: SSRManifest);
|
|
267
266
|
init(options: ServerInitOptions): void;
|
|
@@ -295,21 +294,23 @@ export interface SSRManifest {
|
|
|
295
294
|
* rather than using `ServerLoad` directly.
|
|
296
295
|
*/
|
|
297
296
|
export interface ServerLoad<
|
|
298
|
-
Params extends Record<string, string
|
|
299
|
-
ParentData extends
|
|
300
|
-
OutputData extends
|
|
297
|
+
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
|
|
298
|
+
ParentData extends Record<string, any> = Record<string, any>,
|
|
299
|
+
OutputData extends Record<string, any> | void = Record<string, any> | void
|
|
301
300
|
> {
|
|
302
|
-
(event: ServerLoadEvent<Params, ParentData>): MaybePromise<OutputData
|
|
301
|
+
(event: ServerLoadEvent<Params, ParentData>): MaybePromise<OutputData>;
|
|
303
302
|
}
|
|
304
303
|
|
|
305
304
|
export interface ServerLoadEvent<
|
|
306
|
-
Params extends Record<string, string
|
|
307
|
-
ParentData extends
|
|
305
|
+
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
|
|
306
|
+
ParentData extends Record<string, any> = Record<string, any>
|
|
308
307
|
> extends RequestEvent<Params> {
|
|
309
308
|
parent: () => Promise<ParentData>;
|
|
310
309
|
}
|
|
311
310
|
|
|
312
|
-
export interface Action<
|
|
311
|
+
export interface Action<
|
|
312
|
+
Params extends Partial<Record<string, string>> = Partial<Record<string, string>>
|
|
313
|
+
> {
|
|
313
314
|
(event: RequestEvent<Params>): MaybePromise<
|
|
314
315
|
| { status?: number; errors: Record<string, string>; location?: never }
|
|
315
316
|
| { status?: never; errors?: never; location: string }
|
package/types/internal.d.ts
CHANGED
package/types/private.d.ts
CHANGED
|
@@ -26,15 +26,6 @@ export interface AdapterEntry {
|
|
|
26
26
|
}) => MaybePromise<void>;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
// TODO is this still used?
|
|
30
|
-
export type BodyValidator<T> = {
|
|
31
|
-
[P in keyof T]: T[P] extends { [k: string]: unknown }
|
|
32
|
-
? BodyValidator<T[P]> // recurse when T[P] is an object
|
|
33
|
-
: T[P] extends BigInt | Function | Symbol
|
|
34
|
-
? never
|
|
35
|
-
: T[P];
|
|
36
|
-
};
|
|
37
|
-
|
|
38
29
|
// Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts
|
|
39
30
|
//
|
|
40
31
|
// MIT License
|
|
@@ -145,20 +136,6 @@ export interface CspDirectives {
|
|
|
145
136
|
|
|
146
137
|
export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
147
138
|
|
|
148
|
-
export interface JSONObject {
|
|
149
|
-
[key: string]: JSONValue;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export type JSONValue =
|
|
153
|
-
| string
|
|
154
|
-
| number
|
|
155
|
-
| boolean
|
|
156
|
-
| null
|
|
157
|
-
| undefined
|
|
158
|
-
| ToJSON
|
|
159
|
-
| JSONValue[]
|
|
160
|
-
| JSONObject;
|
|
161
|
-
|
|
162
139
|
export interface Logger {
|
|
163
140
|
(msg: string): void;
|
|
164
141
|
success(msg: string): void;
|
|
@@ -229,8 +206,4 @@ export interface RouteSegment {
|
|
|
229
206
|
rest: boolean;
|
|
230
207
|
}
|
|
231
208
|
|
|
232
|
-
export interface ToJSON {
|
|
233
|
-
toJSON(...args: any[]): Exclude<JSONValue, ToJSON>;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
209
|
export type TrailingSlash = 'never' | 'always' | 'ignore';
|
package/src/packaging/index.js
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import { dirname, join, relative } from 'path';
|
|
3
|
-
import colors from 'kleur';
|
|
4
|
-
import chokidar from 'chokidar';
|
|
5
|
-
import { preprocess } from 'svelte/compiler';
|
|
6
|
-
import { copy, mkdirp, rimraf } from '../utils/filesystem.js';
|
|
7
|
-
import { analyze, generate_pkg, resolve_lib_alias, scan, strip_lang_tags, write } from './utils.js';
|
|
8
|
-
import { emit_dts, transpile_ts } from './typescript.js';
|
|
9
|
-
import { write_tsconfig } from '../core/sync/write_tsconfig.js';
|
|
10
|
-
|
|
11
|
-
const essential_files = ['README', 'LICENSE', 'CHANGELOG', '.gitignore', '.npmignore'];
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @param {import('types').ValidatedConfig} config
|
|
15
|
-
* @param {string} cwd
|
|
16
|
-
*/
|
|
17
|
-
export async function build(config, cwd = process.cwd()) {
|
|
18
|
-
const { lib } = config.kit.files;
|
|
19
|
-
const { dir } = config.kit.package;
|
|
20
|
-
|
|
21
|
-
if (!fs.existsSync(lib)) {
|
|
22
|
-
throw new Error(`${lib} does not exist`);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
rimraf(dir);
|
|
26
|
-
mkdirp(dir);
|
|
27
|
-
|
|
28
|
-
// Make sure generated tsconfig is up-to-date
|
|
29
|
-
write_tsconfig(config.kit, cwd);
|
|
30
|
-
|
|
31
|
-
const files = scan(config);
|
|
32
|
-
|
|
33
|
-
if (config.kit.package.emitTypes) {
|
|
34
|
-
await emit_dts(config, cwd, files);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const pkg = generate_pkg(cwd, files);
|
|
38
|
-
|
|
39
|
-
if (!pkg.svelte && files.some((file) => file.is_svelte)) {
|
|
40
|
-
// Several heuristics in Kit/vite-plugin-svelte to tell Vite to mark Svelte packages
|
|
41
|
-
// rely on the "svelte" property. Vite/Rollup/Webpack plugin can all deal with it.
|
|
42
|
-
// See https://github.com/sveltejs/kit/issues/1959 for more info and related threads.
|
|
43
|
-
if (pkg.exports['.']) {
|
|
44
|
-
const svelte_export =
|
|
45
|
-
typeof pkg.exports['.'] === 'string'
|
|
46
|
-
? pkg.exports['.']
|
|
47
|
-
: pkg.exports['.'].import || pkg.exports['.'].default;
|
|
48
|
-
if (svelte_export) {
|
|
49
|
-
pkg.svelte = svelte_export;
|
|
50
|
-
} else {
|
|
51
|
-
console.warn(
|
|
52
|
-
'Cannot generate a "svelte" entry point because the "." entry in "exports" is not a string. If you set it by hand, please also set one of the options as a "svelte" entry point\n'
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
} else {
|
|
56
|
-
console.warn(
|
|
57
|
-
'Cannot generate a "svelte" entry point because the "." entry in "exports" is missing. Please specify one or set a "svelte" entry point yourself\n'
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
write(join(dir, 'package.json'), JSON.stringify(pkg, null, 2));
|
|
63
|
-
|
|
64
|
-
for (const file of files) {
|
|
65
|
-
await process_file(config, file);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const whitelist = fs.readdirSync(cwd).filter((file) => {
|
|
69
|
-
const lowercased = file.toLowerCase();
|
|
70
|
-
return essential_files.some((name) => lowercased.startsWith(name.toLowerCase()));
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
for (const pathname of whitelist) {
|
|
74
|
-
const full_path = join(cwd, pathname);
|
|
75
|
-
if (fs.lstatSync(full_path).isDirectory()) continue; // just to be sure
|
|
76
|
-
|
|
77
|
-
const package_path = join(dir, pathname);
|
|
78
|
-
if (!fs.existsSync(package_path)) fs.copyFileSync(full_path, package_path);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const from = relative(cwd, lib);
|
|
82
|
-
const to = relative(cwd, dir);
|
|
83
|
-
console.log(colors.bold().green(`${from} -> ${to}`));
|
|
84
|
-
console.log(`Successfully built '${pkg.name}' package. To publish it to npm:`);
|
|
85
|
-
console.log(colors.bold().cyan(` cd ${to}`));
|
|
86
|
-
console.log(colors.bold().cyan(' npm publish\n'));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* @param {import('types').ValidatedConfig} config
|
|
91
|
-
*/
|
|
92
|
-
export async function watch(config, cwd = process.cwd()) {
|
|
93
|
-
await build(config, cwd);
|
|
94
|
-
|
|
95
|
-
const message = `\nWatching ${relative(cwd, config.kit.files.lib)} for changes...\n`;
|
|
96
|
-
|
|
97
|
-
console.log(message);
|
|
98
|
-
|
|
99
|
-
const { lib } = config.kit.files;
|
|
100
|
-
const { dir } = config.kit.package;
|
|
101
|
-
|
|
102
|
-
/** @type {Array<{ file: import('./types').File, type: string }>} */
|
|
103
|
-
const pending = [];
|
|
104
|
-
|
|
105
|
-
/** @type {Array<(value?: any) => void>} */
|
|
106
|
-
const fulfillers = [];
|
|
107
|
-
|
|
108
|
-
/** @type {NodeJS.Timeout} */
|
|
109
|
-
let timeout;
|
|
110
|
-
|
|
111
|
-
const watcher = chokidar.watch(lib, { ignoreInitial: true });
|
|
112
|
-
const ready = new Promise((resolve) => watcher.on('ready', resolve));
|
|
113
|
-
|
|
114
|
-
watcher.on('all', async (type, path) => {
|
|
115
|
-
const file = analyze(config, relative(lib, path));
|
|
116
|
-
if (!file.is_included) return;
|
|
117
|
-
|
|
118
|
-
pending.push({ file, type });
|
|
119
|
-
|
|
120
|
-
clearTimeout(timeout);
|
|
121
|
-
timeout = setTimeout(async () => {
|
|
122
|
-
const files = scan(config);
|
|
123
|
-
|
|
124
|
-
let should_update_pkg = false;
|
|
125
|
-
|
|
126
|
-
const events = pending.slice();
|
|
127
|
-
pending.length = 0;
|
|
128
|
-
|
|
129
|
-
for (const { file, type } of events) {
|
|
130
|
-
if ((type === 'unlink' || type === 'add') && file.is_exported) {
|
|
131
|
-
should_update_pkg = true;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (type === 'unlink') {
|
|
135
|
-
for (const candidate of [
|
|
136
|
-
file.name,
|
|
137
|
-
`${file.base}.d.ts`,
|
|
138
|
-
`${file.base}.d.mts`,
|
|
139
|
-
`${file.base}.d.cts`
|
|
140
|
-
]) {
|
|
141
|
-
const resolved = join(dir, candidate);
|
|
142
|
-
|
|
143
|
-
if (fs.existsSync(resolved)) {
|
|
144
|
-
fs.unlinkSync(resolved);
|
|
145
|
-
|
|
146
|
-
const parent = dirname(resolved);
|
|
147
|
-
if (parent !== dir && fs.readdirSync(parent).length === 0) {
|
|
148
|
-
fs.rmdirSync(parent);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
console.log(`Removed ${file.dest}`);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (type === 'add' || type === 'change') {
|
|
156
|
-
await process_file(config, file);
|
|
157
|
-
console.log(`Processing ${file.name}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (should_update_pkg) {
|
|
162
|
-
const pkg = generate_pkg(cwd, files);
|
|
163
|
-
write(join(dir, 'package.json'), JSON.stringify(pkg, null, 2));
|
|
164
|
-
console.log('Updated package.json');
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (config.kit.package.emitTypes) {
|
|
168
|
-
await emit_dts(config, cwd, scan(config));
|
|
169
|
-
console.log('Updated .d.ts files');
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
console.log(message);
|
|
173
|
-
|
|
174
|
-
fulfillers.forEach((fn) => fn());
|
|
175
|
-
}, 100);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
watcher,
|
|
180
|
-
ready,
|
|
181
|
-
settled: () =>
|
|
182
|
-
new Promise((fulfil, reject) => {
|
|
183
|
-
fulfillers.push(fulfil);
|
|
184
|
-
setTimeout(() => reject(new Error('Timed out')), 1000);
|
|
185
|
-
})
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* @param {import('types').ValidatedConfig} config
|
|
191
|
-
* @param {import('./types').File} file
|
|
192
|
-
*/
|
|
193
|
-
async function process_file(config, file) {
|
|
194
|
-
if (!file.is_included) return;
|
|
195
|
-
|
|
196
|
-
const filename = join(config.kit.files.lib, file.name);
|
|
197
|
-
const dest = join(config.kit.package.dir, file.dest);
|
|
198
|
-
|
|
199
|
-
if (file.is_svelte || file.name.endsWith('.ts')) {
|
|
200
|
-
let contents = fs.readFileSync(filename, 'utf-8');
|
|
201
|
-
|
|
202
|
-
if (file.is_svelte) {
|
|
203
|
-
if (config.preprocess) {
|
|
204
|
-
const preprocessed = (await preprocess(contents, config.preprocess, { filename })).code;
|
|
205
|
-
contents = strip_lang_tags(preprocessed);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (file.name.endsWith('.ts') && !file.name.endsWith('.d.ts')) {
|
|
210
|
-
contents = await transpile_ts(filename, contents);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
contents = resolve_lib_alias(file.name, contents, config);
|
|
214
|
-
write(dest, contents);
|
|
215
|
-
} else {
|
|
216
|
-
copy(filename, dest);
|
|
217
|
-
}
|
|
218
|
-
}
|
package/src/packaging/types.d.ts
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { createRequire } from 'module';
|
|
4
|
-
import { posixify, mkdirp, rimraf, walk } from '../utils/filesystem.js';
|
|
5
|
-
import { resolve_lib_alias, write } from './utils.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @param {import('types').ValidatedConfig} config
|
|
9
|
-
* @param {string} cwd
|
|
10
|
-
* @param {import('./types').File[]} files
|
|
11
|
-
*/
|
|
12
|
-
export async function emit_dts(config, cwd, files) {
|
|
13
|
-
const tmp = `${config.kit.outDir}/package/types`;
|
|
14
|
-
rimraf(tmp);
|
|
15
|
-
mkdirp(tmp);
|
|
16
|
-
|
|
17
|
-
const require = createRequire(import.meta.url);
|
|
18
|
-
const emit = await try_load_svelte2tsx();
|
|
19
|
-
await emit({
|
|
20
|
-
libRoot: config.kit.files.lib,
|
|
21
|
-
svelteShimsPath: require.resolve('svelte2tsx/svelte-shims.d.ts'),
|
|
22
|
-
declarationDir: path.relative(cwd, tmp)
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const handwritten = new Set();
|
|
26
|
-
const excluded = new Set();
|
|
27
|
-
|
|
28
|
-
// remove excluded files, and files that conflict with hand-written .d.ts
|
|
29
|
-
for (const file of files) {
|
|
30
|
-
if (file.name.endsWith('.d.ts')) {
|
|
31
|
-
handwritten.add(file.name);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!file.is_included) {
|
|
35
|
-
excluded.add(file.base + '.d.ts');
|
|
36
|
-
excluded.add(file.base + '.d.mts');
|
|
37
|
-
excluded.add(file.base + '.d.cts');
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// resolve $lib alias (TODO others), copy into package dir
|
|
42
|
-
for (const file of walk(tmp)) {
|
|
43
|
-
const normalized = posixify(file);
|
|
44
|
-
|
|
45
|
-
if (handwritten.has(normalized)) {
|
|
46
|
-
console.warn(`Using $lib/${normalized} instead of generated .d.ts file`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// don't overwrite hand-written .d.ts files
|
|
50
|
-
if (excluded.has(normalized)) continue;
|
|
51
|
-
|
|
52
|
-
const source = fs.readFileSync(path.join(tmp, normalized), 'utf8');
|
|
53
|
-
write(
|
|
54
|
-
path.join(config.kit.package.dir, normalized),
|
|
55
|
-
resolve_lib_alias(normalized, source, config)
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function try_load_svelte2tsx() {
|
|
61
|
-
const svelte2tsx = await load();
|
|
62
|
-
const emit_dts = svelte2tsx.emitDts;
|
|
63
|
-
if (!emit_dts) {
|
|
64
|
-
throw new Error(
|
|
65
|
-
'You need to install svelte2tsx >=0.4.1 if you want to generate type definitions'
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
return emit_dts;
|
|
69
|
-
|
|
70
|
-
async function load() {
|
|
71
|
-
try {
|
|
72
|
-
return await import('svelte2tsx');
|
|
73
|
-
} catch (e) {
|
|
74
|
-
throw new Error(
|
|
75
|
-
'You need svelte2tsx and typescript if you want to generate type definitions. Install it through your package manager, or disable generation which is highly discouraged. See https://kit.svelte.dev/docs/packaging'
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @param {string} filename
|
|
83
|
-
* @param {string} source
|
|
84
|
-
*/
|
|
85
|
-
export async function transpile_ts(filename, source) {
|
|
86
|
-
const ts = await try_load_ts();
|
|
87
|
-
return ts.transpileModule(source, {
|
|
88
|
-
compilerOptions: load_tsconfig(filename, ts),
|
|
89
|
-
fileName: filename
|
|
90
|
-
}).outputText;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async function try_load_ts() {
|
|
94
|
-
try {
|
|
95
|
-
return (await import('typescript')).default;
|
|
96
|
-
} catch (e) {
|
|
97
|
-
throw new Error(
|
|
98
|
-
'You need to install TypeScript if you want to transpile TypeScript files and/or generate type definitions'
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @param {string} filename
|
|
105
|
-
* @param {import('typescript')} ts
|
|
106
|
-
*/
|
|
107
|
-
function load_tsconfig(filename, ts) {
|
|
108
|
-
let config_filename;
|
|
109
|
-
|
|
110
|
-
// ts.findConfigFile is broken (it will favour a distant tsconfig
|
|
111
|
-
// over a near jsconfig, and then only when you call it twice)
|
|
112
|
-
// so we implement it ourselves
|
|
113
|
-
let dir = filename;
|
|
114
|
-
while (dir !== (dir = path.dirname(dir))) {
|
|
115
|
-
const tsconfig = path.join(dir, 'tsconfig.json');
|
|
116
|
-
const jsconfig = path.join(dir, 'jsconfig.json');
|
|
117
|
-
|
|
118
|
-
if (fs.existsSync(tsconfig)) {
|
|
119
|
-
config_filename = tsconfig;
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (fs.existsSync(jsconfig)) {
|
|
124
|
-
config_filename = jsconfig;
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (!config_filename) {
|
|
130
|
-
throw new Error('Failed to locate tsconfig or jsconfig');
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const { error, config } = ts.readConfigFile(config_filename, ts.sys.readFile);
|
|
134
|
-
|
|
135
|
-
if (error) {
|
|
136
|
-
throw new Error('Malformed tsconfig\n' + JSON.stringify(error, null, 2));
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Do this so TS will not search for initial files which might take a while
|
|
140
|
-
config.include = [];
|
|
141
|
-
config.files = [];
|
|
142
|
-
const { options } = ts.parseJsonConfigFileContent(
|
|
143
|
-
config,
|
|
144
|
-
ts.sys,
|
|
145
|
-
path.dirname(config_filename),
|
|
146
|
-
{ sourceMap: false },
|
|
147
|
-
config_filename
|
|
148
|
-
);
|
|
149
|
-
return options;
|
|
150
|
-
}
|
package/src/packaging/utils.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { posixify, mkdirp, walk } from '../utils/filesystem.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Resolves the `$lib` alias.
|
|
7
|
-
*
|
|
8
|
-
* TODO: make this more generic to also handle other aliases the user could have defined via
|
|
9
|
-
* `kit.alias`. Also investigate how to do this in a more robust way (right now regex string
|
|
10
|
-
* replacement is used).
|
|
11
|
-
* For more discussion see https://github.com/sveltejs/kit/pull/2453
|
|
12
|
-
*
|
|
13
|
-
* @param {string} file Relative to the lib root
|
|
14
|
-
* @param {string} content
|
|
15
|
-
* @param {import('types').ValidatedConfig} config
|
|
16
|
-
* @returns {string}
|
|
17
|
-
*/
|
|
18
|
-
export function resolve_lib_alias(file, content, config) {
|
|
19
|
-
/**
|
|
20
|
-
* @param {string} match
|
|
21
|
-
* @param {string} _
|
|
22
|
-
* @param {string} import_path
|
|
23
|
-
*/
|
|
24
|
-
const replace_import_path = (match, _, import_path) => {
|
|
25
|
-
if (!import_path.startsWith('$lib/')) {
|
|
26
|
-
return match;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const full_path = path.join(config.kit.files.lib, file);
|
|
30
|
-
const full_import_path = path.join(config.kit.files.lib, import_path.slice('$lib/'.length));
|
|
31
|
-
let resolved = posixify(path.relative(path.dirname(full_path), full_import_path));
|
|
32
|
-
resolved = resolved.startsWith('.') ? resolved : './' + resolved;
|
|
33
|
-
return match.replace(import_path, resolved);
|
|
34
|
-
};
|
|
35
|
-
content = content.replace(/from\s+('|")([^"';,]+?)\1/g, replace_import_path);
|
|
36
|
-
content = content.replace(/import\s*\(\s*('|")([^"';,]+?)\1\s*\)/g, replace_import_path);
|
|
37
|
-
return content;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Strip out lang="X" or type="text/X" tags. Doing it here is only a temporary solution.
|
|
42
|
-
* See https://github.com/sveltejs/kit/issues/2450 for ideas for places where it's handled better.
|
|
43
|
-
*
|
|
44
|
-
* @param {string} content
|
|
45
|
-
*/
|
|
46
|
-
export function strip_lang_tags(content) {
|
|
47
|
-
return content
|
|
48
|
-
.replace(/(<!--[^]*?-->)|(<script[^>]*?)\s(?:type|lang)=(["']).*?\3/g, '$1$2')
|
|
49
|
-
.replace(/(<!--[^]*?-->)|(<style[^>]*?)\s(?:type|lang)=(["']).*?\3/g, '$1$2');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* @param {string} file
|
|
54
|
-
* @param {Parameters<typeof fs.writeFileSync>[1]} contents
|
|
55
|
-
*/
|
|
56
|
-
export function write(file, contents) {
|
|
57
|
-
mkdirp(path.dirname(file));
|
|
58
|
-
fs.writeFileSync(file, contents);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @param {import('types').ValidatedConfig} config
|
|
63
|
-
* @returns {import('./types').File[]}
|
|
64
|
-
*/
|
|
65
|
-
export function scan(config) {
|
|
66
|
-
return walk(config.kit.files.lib).map((file) => analyze(config, file));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @param {import('types').ValidatedConfig} config
|
|
71
|
-
* @param {string} file
|
|
72
|
-
* @returns {import('./types').File}
|
|
73
|
-
*/
|
|
74
|
-
export function analyze(config, file) {
|
|
75
|
-
const name = posixify(file);
|
|
76
|
-
|
|
77
|
-
const svelte_extension = config.extensions.find((ext) => name.endsWith(ext));
|
|
78
|
-
|
|
79
|
-
const base = svelte_extension ? name : name.slice(0, -path.extname(name).length);
|
|
80
|
-
|
|
81
|
-
const dest = svelte_extension
|
|
82
|
-
? name.slice(0, -svelte_extension.length) + '.svelte'
|
|
83
|
-
: name.endsWith('.d.ts')
|
|
84
|
-
? name
|
|
85
|
-
: name.endsWith('.ts')
|
|
86
|
-
? name.slice(0, -3) + '.js'
|
|
87
|
-
: name;
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
name,
|
|
91
|
-
dest,
|
|
92
|
-
base,
|
|
93
|
-
is_included: config.kit.package.files(name),
|
|
94
|
-
is_exported: config.kit.package.exports(name),
|
|
95
|
-
is_svelte: !!svelte_extension
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* @param {string} cwd
|
|
101
|
-
* @param {import('./types').File[]} files
|
|
102
|
-
*/
|
|
103
|
-
export function generate_pkg(cwd, files) {
|
|
104
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
|
|
105
|
-
|
|
106
|
-
// Remove fields that are specific to the original package.json
|
|
107
|
-
// See: https://pnpm.io/package_json#publishconfigdirectory
|
|
108
|
-
delete pkg.publishConfig?.directory;
|
|
109
|
-
delete pkg.linkDirectory?.directory;
|
|
110
|
-
delete pkg.scripts;
|
|
111
|
-
|
|
112
|
-
pkg.type = 'module';
|
|
113
|
-
|
|
114
|
-
pkg.exports = {
|
|
115
|
-
'./package.json': './package.json',
|
|
116
|
-
...pkg.exports
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
/** @type {Record<string, string>} */
|
|
120
|
-
const clashes = {};
|
|
121
|
-
|
|
122
|
-
for (const file of files) {
|
|
123
|
-
if (file.is_included && file.is_exported) {
|
|
124
|
-
const original = `$lib/${file.name}`;
|
|
125
|
-
const entry = `./${file.dest}`;
|
|
126
|
-
const key = entry.replace(/\/index\.js$|(\/[^/]+)\.js$/, '$1');
|
|
127
|
-
|
|
128
|
-
if (clashes[key]) {
|
|
129
|
-
throw new Error(
|
|
130
|
-
`Duplicate "${key}" export. Please remove or rename either ${clashes[key]} or ${original}`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (!pkg.exports[key]) {
|
|
135
|
-
pkg.exports[key] = entry;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
clashes[key] = original;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return pkg;
|
|
143
|
-
}
|