From 6a149666c1772b443c0db9385ee7521275b27487 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:34:30 +0200 Subject: [PATCH 01/22] chore: enhance download script to ask for folder (#18112) If project that is downloaded is a project that can't be transfered into the playground (because it relies on SvelteKit stuff), instead of failing it now asks if you want to put it into another folder within the playgrounds folder --- playgrounds/sandbox/scripts/download.js | 94 ++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 9 deletions(-) diff --git a/playgrounds/sandbox/scripts/download.js b/playgrounds/sandbox/scripts/download.js index 538b4956fe..5b915c8abd 100644 --- a/playgrounds/sandbox/scripts/download.js +++ b/playgrounds/sandbox/scripts/download.js @@ -2,6 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { parseArgs } from 'node:util'; import { execSync } from 'node:child_process'; +import readline from 'node:readline/promises'; import { chromium } from 'playwright'; const { values, positionals } = parseArgs({ @@ -546,9 +547,9 @@ function convert_vite_project(repo_dir) { /** * Process a local or cloned directory * @param {string} dir_path - * @returns {Array<{name: string, contents: string}>} + * @returns {Promise | null>} */ -function process_directory(dir_path) { +async function process_directory(dir_path) { const all_files = get_all_files(dir_path); const project_info = detect_project_type(all_files); @@ -558,7 +559,18 @@ function process_directory(dir_path) { if (project_info.has_app_imports) { console.error('Error: This SvelteKit project uses $app/* imports which cannot be converted.'); console.error('The playground does not support SvelteKit runtime features.'); - process.exit(1); + + const fallback_dir = path.resolve(base_dir, '..', '..', 'kit-sandbox-tmp'); + const should_copy = await prompt_download_to_kit_sandbox_tmp(fallback_dir); + + if (!should_copy) { + process.exit(1); + } + + copy_project_to_directory(dir_path, fallback_dir); + console.log(`Project copied to ${fallback_dir}`); + + return null; } // Convert based on project type @@ -571,6 +583,66 @@ function process_directory(dir_path) { } } +/** + * Ask whether to copy the project to playgrounds/kit-sandbox-tmp + * @param {string} fallback_dir + * @returns {Promise} + */ +async function prompt_download_to_kit_sandbox_tmp(fallback_dir) { + if (!process.stdin.isTTY || !process.stdout.isTTY) { + return false; + } + + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); + + try { + const answer = await rl.question( + `Would you like to copy this project into ${fallback_dir} instead? [y/N] ` + ); + return /^(y|yes)$/i.test(answer.trim()); + } finally { + rl.close(); + } +} + +/** + * Copy a project directory while skipping generated and dependency folders + * @param {string} source_dir + * @param {string} target_dir + */ +function copy_project_to_directory(source_dir, target_dir) { + const skip_dirs = new Set(['node_modules', '.git', '.svelte-kit', 'build', 'dist']); + + if (fs.existsSync(target_dir)) { + fs.rmSync(target_dir, { recursive: true, force: true }); + } + + /** @param {string} from_dir */ + function copy_recursive(from_dir) { + const relative_dir = path.relative(source_dir, from_dir); + const to_dir = relative_dir ? path.join(target_dir, relative_dir) : target_dir; + + fs.mkdirSync(to_dir, { recursive: true }); + + for (const entry of fs.readdirSync(from_dir, { withFileTypes: true })) { + if (entry.isDirectory() && skip_dirs.has(entry.name)) { + continue; + } + + const source_path = path.join(from_dir, entry.name); + const target_path = path.join(to_dir, entry.name); + + if (entry.isDirectory()) { + copy_recursive(source_path); + } else if (entry.isFile()) { + fs.copyFileSync(source_path, target_path); + } + } + } + + copy_recursive(source_dir); +} + /** * Reset a directory so it exists and is empty * @param {string} dir_path @@ -602,7 +674,7 @@ let files; // Check if it's a local directory first (before URL parsing) if (is_local) { console.log(`Processing local directory: ${url_arg}`); - files = process_directory(url_arg); + files = await process_directory(url_arg); } else if (resolved_test_path) { // Copy files from test console.log(`Processing test ${url_arg}`); @@ -616,21 +688,21 @@ if (is_local) { }); } else if (url && is_github_url(url)) { // GitHub repository handling - await with_tmp_dir(base_dir, (tmp_dir) => { + await with_tmp_dir(base_dir, async (tmp_dir) => { clone_github_repo(url, tmp_dir); - files = process_directory(tmp_dir); + files = await process_directory(tmp_dir); }); } else if (url && is_stackblitz_github_url(url)) { // StackBlitz GitHub project handling (redirect to GitHub clone) - await with_tmp_dir(base_dir, (tmp_dir) => { + await with_tmp_dir(base_dir, async (tmp_dir) => { clone_stackblitz_github_project(url, tmp_dir); - files = process_directory(tmp_dir); + files = await process_directory(tmp_dir); }); } else if (url && is_stackblitz_edit_url(url)) { // StackBlitz edit URLs - use browser automation to download await with_tmp_dir(base_dir, async (tmp_dir) => { await download_stackblitz_project(url, tmp_dir); - files = process_directory(tmp_dir); + files = await process_directory(tmp_dir); }); } else if (url && url.origin === 'https://svelte.dev' && url.pathname.startsWith('/playground/')) { // Svelte playground URL handling (existing logic) @@ -680,6 +752,10 @@ if (is_local) { process.exit(1); } +if (files === null) { + process.exit(0); +} + // Output files if (create_test_name) { const test_parts = create_test_name.split('/').filter(Boolean); From 48dc9b40c0249ffba7067f3c3605e4f1fb376b5e Mon Sep 17 00:00:00 2001 From: Rohan Santhosh Kumar <181558744+Rohan5commit@users.noreply.github.com> Date: Mon, 20 Apr 2026 20:12:58 +0800 Subject: [PATCH 02/22] docs: fix spacing around option tag in bind docs (#18114) ## Summary - Fix the missing space before `