From 40a286f6e0b1fa4757a1fdf51c0cb2703b91102f Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Wed, 12 Aug 2026 23:55:44 +0530 Subject: [PATCH 1/3] fix(sites): keep framework start commands out of the console The create-site flows read startCommand off a framework adapter and offered it as a prefilled value and a placeholder. The API never returns that field - FrameworkAdapter does not declare it - so the reads always resolved to undefined, and the cast that made them typecheck was the only thing hiding it. Had the field ever been returned, the console would have put an internal runtime command in front of every user creating a site. Drop the field from the create flows entirely and let the server pick its own default. In site settings the input stays, but it moves under a collapsed Advanced section, loses the Reset-to-default button that had nothing to reset to, and takes a generic placeholder. --- src/lib/stores/sites.ts | 6 -- .../sites/create-site/configuration.svelte | 29 ++------ .../sites/create-site/deploy/+page.svelte | 19 +---- .../sites/create-site/manual/+page.svelte | 6 +- .../repository-[repository]/+page.svelte | 9 +-- .../settings/updateBuildSettings.svelte | 71 +++++++++---------- 6 files changed, 42 insertions(+), 98 deletions(-) diff --git a/src/lib/stores/sites.ts b/src/lib/stores/sites.ts index ef39511ee2..29d8113323 100644 --- a/src/lib/stores/sites.ts +++ b/src/lib/stores/sites.ts @@ -1,9 +1,3 @@ -import type { Models } from '@appwrite.io/console'; - -export type FrameworkAdapterWithStartCommand = Models.FrameworkAdapter & { - startCommand?: string; -}; - export function getFrameworkIcon(framework: string) { switch (true) { case framework.toLocaleLowerCase().includes('sveltekit'): diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/configuration.svelte b/src/routes/(console)/project-[region]-[project]/sites/create-site/configuration.svelte index f6d8129d64..8ab02601a5 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/configuration.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/create-site/configuration.svelte @@ -3,22 +3,20 @@ import { Fieldset, Layout, Accordion } from '@appwrite.io/pink-svelte'; import type { Models } from '@appwrite.io/console'; import { iconPath } from '$lib/stores/app'; - import { getFrameworkIcon, type FrameworkAdapterWithStartCommand } from '$lib/stores/sites'; + import { getFrameworkIcon } from '$lib/stores/sites'; import { EnvironmentVariables } from '$lib/components/variables'; export let frameworks: Models.Framework[]; export let selectedFramework: Models.Framework; $: frameworkData = frameworks.find((framework) => framework.key === selectedFramework?.key); - $: adapterData = (frameworkData?.adapters.find((adapter) => adapter.key === 'ssr') ?? - frameworkData?.adapters.find( - (adapter) => adapter.key === 'static' - )) as FrameworkAdapterWithStartCommand; + $: adapterData = + frameworkData?.adapters.find((adapter) => adapter.key === 'ssr') ?? + frameworkData?.adapters.find((adapter) => adapter.key === 'static'); export let variables: Partial[] = []; export let isLoading = false; export let installCommand = ''; export let buildCommand = ''; - export let startCommand = ''; export let outputDirectory = ''; let frameworkId = selectedFramework.key; @@ -28,7 +26,6 @@ $: if (frameworkData && adapterDefaultsKey !== lastAdapterDefaultsKey) { installCommand = adapterData?.installCommand ?? ''; buildCommand = adapterData?.buildCommand ?? ''; - startCommand = adapterData?.startCommand ?? ''; outputDirectory = adapterData?.outputDirectory ?? ''; lastAdapterDefaultsKey = adapterDefaultsKey; } @@ -86,24 +83,6 @@ Reset - {#if adapterData?.key === 'ssr'} - - - - - {/if} data.frameworks.frameworks.find((f) => f.key === framework)?.adapters?.[0] - ); - const shouldShowStartCommand = $derived(primaryAdapter?.key === Adapter.Ssr); - $effect(() => { if (framework && data.frameworks && !hasCustomCommands) { const fw = data.frameworks.frameworks.find((f) => f.key === framework); @@ -94,7 +87,6 @@ const adapter = fw.adapters[0]; installCommand = adapter.installCommand || ''; buildCommand = adapter.buildCommand || ''; - startCommand = (adapter as FrameworkAdapterWithStartCommand).startCommand || ''; outputDirectory = adapter.outputDirectory || ''; } } @@ -111,11 +103,10 @@ // Build configuration - use from URL params or defaults installCommand = page.url.searchParams.get('install') || ''; buildCommand = page.url.searchParams.get('build') || ''; - startCommand = page.url.searchParams.get('start') || ''; outputDirectory = page.url.searchParams.get('output') || ''; // Check if custom commands were provided via URL - hasCustomCommands = !!(installCommand || buildCommand || startCommand || outputDirectory); + hasCustomCommands = !!(installCommand || buildCommand || outputDirectory); // If no custom commands, auto-fill from framework defaults if (!hasCustomCommands && data.frameworks) { @@ -124,7 +115,6 @@ const adapter = fw.adapters[0]; installCommand = adapter.installCommand || ''; buildCommand = adapter.buildCommand || ''; - startCommand = (adapter as FrameworkAdapterWithStartCommand).startCommand || ''; outputDirectory = adapter.outputDirectory || ''; } } @@ -155,7 +145,6 @@ buildRuntime: selectedFramework.buildRuntime, installCommand: installCommand || undefined, buildCommand: buildCommand || undefined, - startCommand: shouldShowStartCommand ? startCommand || undefined : undefined, outputDirectory: outputDirectory || undefined, adapter: framework === Framework.Other ? Adapter.Static : undefined, providerSilentMode: false @@ -284,12 +273,6 @@ label="Build command" placeholder={buildCommand || 'npm run build'} bind:value={buildCommand} /> - {#if shouldShowStartCommand} - - {/if} f.key === 'other') ?? data.frameworks.frameworks?.[0]; - let adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand; + let adapter = framework?.adapters[0]; let installCommand = adapter?.installCommand; let buildCommand = adapter?.buildCommand; - let startCommand = adapter?.startCommand; let outputDirectory = adapter?.outputDirectory; let variables: Partial[] = []; let files: FileList; @@ -79,7 +77,6 @@ buildRuntime, installCommand: installCommand || undefined, buildCommand: buildCommand || undefined, - startCommand: startCommand || undefined, outputDirectory: outputDirectory || undefined }); @@ -254,7 +251,6 @@ f.key === 'other'); - let adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand; + let adapter = framework?.adapters[0]; let branch: string; let rootDir = './'; let installCommand = adapter?.installCommand; let buildCommand = adapter?.buildCommand; - let startCommand = adapter?.startCommand; let outputDirectory = adapter?.outputDirectory; let variables: Partial[] = []; let silentMode = false; @@ -83,10 +81,9 @@ if (!framework) { framework = data.frameworks.frameworks.find((f) => f.key === 'other'); } - adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand; + adapter = framework?.adapters[0]; installCommand = adapter?.installCommand; buildCommand = adapter?.buildCommand; - startCommand = adapter?.startCommand; outputDirectory = adapter?.outputDirectory; const detectedVariables = normalizeDetectedVariables(response?.variables); if (detectedVariables.length) { @@ -124,7 +121,6 @@ buildRuntime, installCommand: installCommand || undefined, buildCommand: buildCommand || undefined, - startCommand: startCommand || undefined, outputDirectory: outputDirectory || undefined, installationId: data.installation.$id, providerRepositoryId: data.repository.id, @@ -223,7 +219,6 @@ a.key === adapter) ?? - selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand + let frameworkAdapterData = $derived( + selectedFramework.adapters.find((a) => a.key === adapter) ?? selectedFramework.adapters[0] ); $effect(() => { @@ -77,17 +84,18 @@ } //Update values - const data = (selectedFramework.adapters.find((a) => a.key === adapter) ?? - selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand; + const data = + selectedFramework.adapters.find((a) => a.key === adapter) ?? + selectedFramework.adapters[0]; installCommand = data.installCommand; buildCommand = data.buildCommand; - startCommand = data.startCommand; outputDirectory = data.outputDirectory; adapter = data.key as Adapter; fallback = data.fallbackFile; } else if (hasFrameworkSelectionChanged) { - const data = (selectedFramework.adapters.find((a) => a.key === adapter) ?? - selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand; + const data = + selectedFramework.adapters.find((a) => a.key === adapter) ?? + selectedFramework.adapters[0]; const isOriginalAdapter = adapter === site.adapter; installCommand = isOriginalAdapter @@ -96,9 +104,6 @@ buildCommand = isOriginalAdapter ? (site?.buildCommand ?? frameworkAdapterData.buildCommand) : data.buildCommand; - startCommand = isOriginalAdapter - ? (site?.startCommand ?? frameworkAdapterData.startCommand) - : data.startCommand; outputDirectory = isOriginalAdapter ? (site?.outputDirectory ?? frameworkAdapterData.outputDirectory) : data.outputDirectory; @@ -193,17 +198,13 @@ } } - function reset(type: 'installCommand' | 'buildCommand' | 'startCommand' | 'outputDirectory') { - const data = selectedFramework.adapters.find( - (a) => a.key === adapter - ) as FrameworkAdapterWithStartCommand; + function reset(type: 'installCommand' | 'buildCommand' | 'outputDirectory') { + const data = selectedFramework.adapters.find((a) => a.key === adapter); if (type === 'installCommand') { installCommand = data.installCommand; } else if (type === 'buildCommand') { buildCommand = data.buildCommand; - } else if (type === 'startCommand') { - startCommand = data.startCommand; } else if (type === 'outputDirectory') { outputDirectory = data.outputDirectory; } @@ -332,24 +333,6 @@ Reset - {#if adapter === Adapter.Ssr} - - - - - {/if} {/if} + {#if adapter === Adapter.Ssr} + + + Leave empty to let your framework start the way Appwrite + expects. Set a command only if your site needs its own + entrypoint. + + + + {/if} From 6e64d0ce57b5063c29f3af91ffb17ce12c02f18c Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Thu, 13 Aug 2026 00:54:31 +0530 Subject: [PATCH 2/3] Match the start command copy used by the new console --- .../sites/site-[site]/settings/updateBuildSettings.svelte | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte index 890bb95182..feba962b5c 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte @@ -367,9 +367,8 @@ {#if adapter === Adapter.Ssr} - Leave empty to let your framework start the way Appwrite - expects. Set a command only if your site needs its own - entrypoint. + Command used to start your SSR server after a successful deploy. + Leave it empty to use the framework default. Date: Thu, 13 Aug 2026 11:20:18 +0530 Subject: [PATCH 3/3] Clear the start command when the framework or adapter changes A start command names an entrypoint belonging to one framework. Carrying it across a switch submits it against a runtime that has no such entrypoint, and a switch to static leaves a command the form no longer shows. Reset it alongside the other framework-derived fields, and send it only for the ssr adapter, matching the fallbackFile line beside it. --- .../sites/site-[site]/settings/updateBuildSettings.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte index feba962b5c..527fae9631 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/updateBuildSettings.svelte @@ -92,6 +92,7 @@ outputDirectory = data.outputDirectory; adapter = data.key as Adapter; fallback = data.fallbackFile; + startCommand = ''; } else if (hasFrameworkSelectionChanged) { const data = selectedFramework.adapters.find((a) => a.key === adapter) ?? @@ -110,6 +111,7 @@ fallback = isOriginalAdapter ? (site?.fallbackFile ?? data.fallbackFile) : data.fallbackFile; + startCommand = isOriginalAdapter ? (site?.startCommand ?? '') : ''; } lastFrameworkAdapterKey = `${selectedFramework.key}:${adapter ?? ''}`; @@ -167,7 +169,7 @@ timeout: site.timeout || undefined, installCommand: installCommand || undefined, buildCommand: buildCommand || undefined, - startCommand: startCommand || undefined, + startCommand: adptr?.key === 'ssr' ? startCommand || undefined : undefined, outputDirectory: outputDirectory || undefined, buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined, adapter: (adptr?.key as Adapter) || undefined,