diff --git a/.changeset/fix-sync-root-types-and-metadata-cache.md b/.changeset/fix-sync-root-types-and-metadata-cache.md new file mode 100644 index 000000000000..57bad05a5d20 --- /dev/null +++ b/.changeset/fix-sync-root-types-and-metadata-cache.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: retain root route types and metadata cache across sync runs diff --git a/packages/kit/src/core/sync/write_types/index.js b/packages/kit/src/core/sync/write_types/index.js index 326c05b4b641..d3e5106297bf 100644 --- a/packages/kit/src/core/sync/write_types/index.js +++ b/packages/kit/src/core/sync/write_types/index.js @@ -64,11 +64,15 @@ export function write_all_types(config, manifest_data, root) { posixify(path.relative(root, config.files.routes)) ); const expected_directories = new Set( - manifest_data.routes.map((route) => path.posix.join(routes_dir, route.id)) + manifest_data.routes.map((route) => { + const dir = path.posix.join(routes_dir, route.id); + return dir.endsWith('/') && dir !== '/' ? dir.slice(0, -1) : dir; + }) ); if (fs.existsSync(types_dir)) { for (const file of walk(types_dir)) { + if (file === 'route_meta_data.json') continue; const dir = path.posix.dirname(file); if (!expected_directories.has(dir)) { fs.rmSync(path.join(types_dir, file), { force: true, recursive: true }); diff --git a/packages/kit/src/core/sync/write_types/index.spec.js b/packages/kit/src/core/sync/write_types/index.spec.js index 78471e98656d..a54748e03ee4 100644 --- a/packages/kit/src/core/sync/write_types/index.spec.js +++ b/packages/kit/src/core/sync/write_types/index.spec.js @@ -402,3 +402,41 @@ test('prunes stale entries from route_meta_data.json when routes are deleted', ( fs.rmSync(tmp, { force: true, recursive: true }); } }); + +test('preserves root route $types.d.ts and route_meta_data.json on repeated sync runs', () => { + const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'sveltekit-sync-cache-test-')); + try { + const config = validate_config({}); + config.files.assets = path.resolve(cwd, 'static'); + const routes_dir = path.resolve(tmp, 'src', 'routes'); + fs.mkdirSync(routes_dir, { recursive: true }); + fs.writeFileSync(path.join(routes_dir, '+page.svelte'), '

Home

'); + + config.files.params = path.resolve(tmp, 'src', 'params'); + config.files.routes = routes_dir; + config.outDir = path.resolve(tmp, '.svelte-kit'); + + const manifest = create_manifest_data(config, tmp); + + // First sync run: generates types and route_meta_data.json + write_all_types(config, manifest, tmp); + + const root_types_file = path.join(config.outDir, 'types', 'src', 'routes', '$types.d.ts'); + const meta_data_file = path.join(config.outDir, 'types', 'route_meta_data.json'); + + expect(fs.existsSync(root_types_file)).toBe(true); + expect(fs.existsSync(meta_data_file)).toBe(true); + + // Append a marker comment to verify the root type file and cache are retained + fs.appendFileSync(root_types_file, '\n// marker-test-sync-cache'); + + // Second sync run: should not wipe root types or route_meta_data.json + write_all_types(config, manifest, tmp); + + expect(fs.existsSync(root_types_file)).toBe(true); + expect(fs.existsSync(meta_data_file)).toBe(true); + expect(fs.readFileSync(root_types_file, 'utf-8')).toContain('// marker-test-sync-cache'); + } finally { + fs.rmSync(tmp, { force: true, recursive: true }); + } +});