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: generated types for page and endpoint paths #9938

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/afraid-cougars-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': minor
---

feat: typed responses when fetching from endpoints
1 change: 1 addition & 0 deletions packages/kit/src/core/sync/write_tsconfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export function get_tsconfig(kit, include_base_url) {
const include = new Set([
'ambient.d.ts',
'./types/**/$types.d.ts',
'./types/$api.d.ts',
config_relative('vite.config.js'),
config_relative('vite.config.ts')
]);
Expand Down
1 change: 1 addition & 0 deletions packages/kit/src/core/sync/write_tsconfig.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ test('Creates tsconfig include from kit.files', () => {
expect(include).toEqual([
'ambient.d.ts',
'./types/**/$types.d.ts',
'./types/$api.d.ts',
'../vite.config.js',
'../vite.config.ts',
'../app/**/*.js',
Expand Down
25 changes: 18 additions & 7 deletions packages/kit/src/core/sync/write_types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import MagicString from 'magic-string';
import { posixify, rimraf, walk } from '../../../utils/filesystem.js';
import { compact } from '../../../utils/array.js';
import { ts } from '../ts.js';
import { write_api } from './write_api/index.js';

/**
* @typedef {{
Expand Down Expand Up @@ -123,6 +124,8 @@ export async function write_all_types(config, manifest_data) {
}
}

write_api(config, manifest_data);

fs.writeFileSync(meta_data_file, JSON.stringify(meta_data, null, '\t'));
}

Expand All @@ -148,6 +151,7 @@ export async function write_types(config, manifest_data, file) {
if (!route.leaf && !route.layout && !route.endpoint) return; // nothing to do

update_types(config, create_routes_map(manifest_data), route);
write_api(config, manifest_data);
}

/**
Expand Down Expand Up @@ -235,6 +239,11 @@ function update_types(config, routes, route, to_delete = new Set()) {
);
}

const api_types_path = posixify(
path.relative(outdir, path.join(config.kit.outDir, 'types', '$api')) // TODO: potential failure point if api file is moved
);
declarations.push(`type FetchType = typeof import('${api_types_path}').fetch;`);

if (route.leaf) {
let route_info = routes.get(route.leaf);
if (!route_info) {
Expand Down Expand Up @@ -263,10 +272,10 @@ function update_types(config, routes, route, to_delete = new Set()) {

if (route.leaf.server) {
exports.push(
'export type Action<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Action<RouteParams, OutputData, RouteId>'
'export type Action<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Action<RouteParams, OutputData, RouteId, FetchType>'
);
exports.push(
'export type Actions<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Actions<RouteParams, OutputData, RouteId>'
'export type Actions<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Actions<RouteParams, OutputData, RouteId, FetchType>'
);
}
}
Expand Down Expand Up @@ -335,11 +344,13 @@ function update_types(config, routes, route, to_delete = new Set()) {
}

if (route.endpoint) {
exports.push('export type RequestHandler = Kit.RequestHandler<RouteParams, RouteId>;');
exports.push(
'export type RequestHandler = Kit.RequestHandler<RouteParams, RouteId, FetchType>;'
);
}

if (route.leaf?.server || route.layout?.server || route.endpoint) {
exports.push('export type RequestEvent = Kit.RequestEvent<RouteParams, RouteId>;');
exports.push('export type RequestEvent = Kit.RequestEvent<RouteParams, RouteId, FetchType>;');
}

const output = [imports.join('\n'), declarations.join('\n'), exports.join('\n')]
Expand Down Expand Up @@ -398,7 +409,7 @@ function process_node(node, outdir, is_page, proxies, all_pages_have_load = true
? 'Partial<App.PageData> & Record<string, any> | void'
: `OutputDataShape<${parent_type}>`;
exports.push(
`export type ${prefix}ServerLoad<OutputData extends ${output_data_shape} = ${output_data_shape}> = Kit.ServerLoad<${params}, ${parent_type}, OutputData, ${route_id}>;`
`export type ${prefix}ServerLoad<OutputData extends ${output_data_shape} = ${output_data_shape}> = Kit.ServerLoad<${params}, ${parent_type}, OutputData, ${route_id}, FetchType>;`
);

exports.push(`export type ${prefix}ServerLoadEvent = Parameters<${prefix}ServerLoad>[0];`);
Expand Down Expand Up @@ -452,7 +463,7 @@ function process_node(node, outdir, is_page, proxies, all_pages_have_load = true
? 'Partial<App.PageData> & Record<string, any> | void'
: `OutputDataShape<${parent_type}>`;
exports.push(
`export type ${prefix}Load<OutputData extends ${output_data_shape} = ${output_data_shape}> = Kit.Load<${params}, ${prefix}ServerData, ${parent_type}, OutputData, ${route_id}>;`
`export type ${prefix}Load<OutputData extends ${output_data_shape} = ${output_data_shape}> = Kit.Load<${params}, ${prefix}ServerData, ${parent_type}, OutputData, ${route_id}, FetchType>;`
);

exports.push(`export type ${prefix}LoadEvent = Parameters<${prefix}Load>[0];`);
Expand Down Expand Up @@ -569,7 +580,7 @@ function path_to_original(outdir, file_path) {
/**
* @param {string} file_path
*/
function replace_ext_with_js(file_path) {
export function replace_ext_with_js(file_path) {
// Another extension than `.js` (or nothing, but that fails with node16 moduleResolution)
// will result in TS failing to lookup the file
const ext = path.extname(file_path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@sveltejs/kit": ["../../../../exports/public"],
"types": ["../../../../types/internal"]
"@sveltejs/kit": ["../../../../../exports/public"],
"types": ["../../../../../types/internal"]
}
},
"include": ["./**/*.js"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2020",
"module": "es2022",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@sveltejs/kit": ["../../../../../exports/public"],
"types": ["../../../../../types/internal"]
}
},
"include": ["./**/*.js"],
"exclude": ["./**/.svelte-kit/**"]
}
19 changes: 19 additions & 0 deletions packages/kit/src/core/sync/write_types/test/layout/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2020",
"module": "es2022",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@sveltejs/kit": ["../../../../../exports/public"],
"types": ["../../../../../types/internal"]
}
},
"include": ["./**/*.js"],
"exclude": ["./**/.svelte-kit/**"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2020",
"module": "es2022",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@sveltejs/kit": ["../../../../../exports/public"],
"types": ["../../../../../types/internal"]
}
},
"include": ["./**/*.js"],
"exclude": ["./**/.svelte-kit/**"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2020",
"module": "es2022",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@sveltejs/kit": ["../../../../../exports/public"],
"types": ["../../../../../types/internal"]
}
},
"include": ["./**/*.js"],
"exclude": ["./**/.svelte-kit/**"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2020",
"module": "es2022",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@sveltejs/kit": ["../../../../../exports/public"],
"types": ["../../../../../types/internal"]
}
},
"include": ["./**/*.js"],
"exclude": ["./**/.svelte-kit/**"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2020",
"module": "es2022",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@sveltejs/kit": ["../../../../../exports/public"],
"types": ["../../../../../types/internal"]
}
},
"include": ["./**/*.js"],
"exclude": ["./**/.svelte-kit/**"]
}
19 changes: 19 additions & 0 deletions packages/kit/src/core/sync/write_types/test/slugs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2020",
"module": "es2022",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@sveltejs/kit": ["../../../../../exports/public"],
"types": ["../../../../../types/internal"]
}
},
"include": ["./**/*.js"],
"exclude": ["./**/.svelte-kit/**"]
}
Loading