diff --git a/src/lib/stores/sites.ts b/src/lib/stores/sites.ts index 29d8113323..ef39511ee2 100644 --- a/src/lib/stores/sites.ts +++ b/src/lib/stores/sites.ts @@ -1,3 +1,9 @@ +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/lib/stores/uploader.ts b/src/lib/stores/uploader.ts index efc16f2559..97f475f992 100644 --- a/src/lib/stores/uploader.ts +++ b/src/lib/stores/uploader.ts @@ -166,12 +166,14 @@ const createUploader = () => { code, buildCommand, installCommand, + startCommand, outputDirectory }: { siteId: string; code: File; buildCommand?: string; installCommand?: string; + startCommand?: string; outputDirectory?: string; }) => { const newDeployment: UploaderFile = { @@ -188,15 +190,13 @@ const createUploader = () => { n.files.unshift(newDeployment); return n; }); - const uploadedFile = await temporarySites( - page.params.region, - page.params.project - ).createDeployment({ + const deploymentPayload = { siteId, code, activate: true, buildCommand, installCommand, + startCommand, outputDirectory, onProgress: (progress) => { newDeployment.$id = progress.$id; @@ -204,7 +204,11 @@ const createUploader = () => { newDeployment.status = progress.progress === 100 ? 'success' : 'pending'; updateFile(progress.$id, newDeployment); } - }); + }; + const uploadedFile = await temporarySites( + page.params.region, + page.params.project + ).createDeployment(deploymentPayload); newDeployment.$id = uploadedFile.$id; newDeployment.progress = 100; newDeployment.status = 'success'; diff --git a/src/routes/(console)/project-[region]-[project]/settings/updateProtocols.svelte b/src/routes/(console)/project-[region]-[project]/settings/updateProtocols.svelte index e285400159..52f607ee93 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/updateProtocols.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/updateProtocols.svelte @@ -162,7 +162,9 @@ - +
+ +
{#each $protocols.list as protocol, index} @@ -218,6 +220,11 @@ width: 100%; } + .protocol-list-content { + max-width: 36rem; + padding-top: var(--space-6); + } + .protocol-toolbar { display: flex; justify-content: flex-end; @@ -228,10 +235,6 @@ width: 100%; } - .protocol-list-content { - padding-top: var(--space-6); - } - .protocol-control { display: flex; align-items: center; 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 8b1a9ad3f6..f6d8129d64 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,34 +3,34 @@ import { Fieldset, Layout, Accordion } from '@appwrite.io/pink-svelte'; import type { Models } from '@appwrite.io/console'; import { iconPath } from '$lib/stores/app'; - import { getFrameworkIcon } from '$lib/stores/sites'; + import { getFrameworkIcon, type FrameworkAdapterWithStartCommand } 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'); + $: adapterData = (frameworkData?.adapters.find((adapter) => adapter.key === 'ssr') ?? + frameworkData?.adapters.find( + (adapter) => adapter.key === 'static' + )) as FrameworkAdapterWithStartCommand; export let variables: Partial[] = []; export let isLoading = false; export let installCommand = ''; export let buildCommand = ''; + export let startCommand = ''; export let outputDirectory = ''; let frameworkId = selectedFramework.key; + let lastAdapterDefaultsKey = ''; - $: if (!installCommand || !buildCommand || !outputDirectory) { - installCommand ||= adapterData?.installCommand; - buildCommand ||= adapterData?.buildCommand; - outputDirectory ||= adapterData?.outputDirectory; - } - - $: if (frameworkData) { - installCommand = adapterData?.installCommand; - buildCommand = adapterData?.buildCommand; - outputDirectory = adapterData?.outputDirectory; + $: adapterDefaultsKey = `${frameworkData?.key ?? ''}:${adapterData?.key ?? ''}`; + $: if (frameworkData && adapterDefaultsKey !== lastAdapterDefaultsKey) { + installCommand = adapterData?.installCommand ?? ''; + buildCommand = adapterData?.buildCommand ?? ''; + startCommand = adapterData?.startCommand ?? ''; + outputDirectory = adapterData?.outputDirectory ?? ''; + lastAdapterDefaultsKey = adapterDefaultsKey; } @@ -65,7 +65,8 @@ @@ -79,11 +80,30 @@ + {#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); @@ -87,6 +94,7 @@ const adapter = fw.adapters[0]; installCommand = adapter.installCommand || ''; buildCommand = adapter.buildCommand || ''; + startCommand = (adapter as FrameworkAdapterWithStartCommand).startCommand || ''; outputDirectory = adapter.outputDirectory || ''; } } @@ -103,10 +111,11 @@ // 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 || outputDirectory); + hasCustomCommands = !!(installCommand || buildCommand || startCommand || outputDirectory); // If no custom commands, auto-fill from framework defaults if (!hasCustomCommands && data.frameworks) { @@ -115,6 +124,7 @@ const adapter = fw.adapters[0]; installCommand = adapter.installCommand || ''; buildCommand = adapter.buildCommand || ''; + startCommand = (adapter as FrameworkAdapterWithStartCommand).startCommand || ''; outputDirectory = adapter.outputDirectory || ''; } } @@ -145,6 +155,7 @@ 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 @@ -272,6 +283,12 @@ 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]; + let adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand; let installCommand = adapter?.installCommand; let buildCommand = adapter?.buildCommand; + let startCommand = adapter?.startCommand; let outputDirectory = adapter?.outputDirectory; let variables: Partial[] = []; let files: FileList; @@ -73,6 +75,7 @@ buildRuntime, installCommand: installCommand || undefined, buildCommand: buildCommand || undefined, + startCommand: startCommand || undefined, outputDirectory: outputDirectory || undefined }); @@ -98,6 +101,7 @@ code: files[0], buildCommand: buildCommand || undefined, installCommand: installCommand || undefined, + startCommand: startCommand || undefined, outputDirectory: outputDirectory || undefined }); @@ -243,6 +247,7 @@ f.key === 'other'); - let adapter = framework?.adapters[0]; + let adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand; 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; @@ -81,9 +83,10 @@ if (!framework) { framework = data.frameworks.frameworks.find((f) => f.key === 'other'); } - adapter = framework?.adapters[0]; + adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand; installCommand = adapter?.installCommand; buildCommand = adapter?.buildCommand; + startCommand = adapter?.startCommand; outputDirectory = adapter?.outputDirectory; const detectedVariables = normalizeDetectedVariables(response?.variables); if (detectedVariables.length) { @@ -119,9 +122,10 @@ name, framework: fr, buildRuntime, - installCommand, - buildCommand, - outputDirectory, + installCommand: installCommand || undefined, + buildCommand: buildCommand || undefined, + startCommand: startCommand || undefined, + outputDirectory: outputDirectory || undefined, installationId: data.installation.$id, providerRepositoryId: data.repository.id, providerBranch: branch, @@ -218,6 +222,7 @@ framework.key === site.framework) ); let showFallback = $derived(adapter === Adapter.Static); + let lastFrameworkAdapterKey = $state(''); let isUntouched = $derived( installCommand === site?.installCommand && buildCommand === site?.buildCommand && + startCommand === site?.startCommand && outputDirectory === site?.outputDirectory && selectedFramework?.key === site?.framework && (fallback ?? '') === (site?.fallbackFile ?? '') && (adapter ?? '') === (site?.adapter ?? '') ); - let frameworkAdapterData = $derived( - selectedFramework.adapters.find((a) => a.key === adapter) ?? selectedFramework.adapters[0] + let frameworkAdapterData: FrameworkAdapterWithStartCommand = $derived( + (selectedFramework.adapters.find((a) => a.key === adapter) ?? + selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand ); $effect(() => { - if (adapter) { - const data = selectedFramework.adapters.find((a) => a.key === adapter); - if (data) { - installCommand = data.installCommand; - buildCommand = data.buildCommand; - outputDirectory = data.outputDirectory; - fallback = data.fallbackFile; - } - } - }); + if (!selectedFramework) return; + + const frameworkAdapterKey = `${selectedFramework.key}:${adapter ?? ''}`; + const hasFrameworkSelectionChanged = frameworkAdapterKey !== lastFrameworkAdapterKey; - $effect(() => { if (selectedFramework?.key !== site.framework) { // Update adapter const singleAdapter = selectedFramework?.adapters?.length <= 1; @@ -78,21 +75,37 @@ } //Update values - const data = - selectedFramework.adapters.find((a) => a.key === adapter) ?? - selectedFramework.adapters[0]; + const data = (selectedFramework.adapters.find((a) => a.key === adapter) ?? + selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand; installCommand = data.installCommand; buildCommand = data.buildCommand; + startCommand = data.startCommand; outputDirectory = data.outputDirectory; adapter = data.key as Adapter; fallback = data.fallbackFile; - } else { - adapter = site.adapter as Adapter; - installCommand = site?.installCommand ?? frameworkAdapterData.installCommand; - buildCommand = site?.buildCommand ?? frameworkAdapterData.buildCommand; - outputDirectory = site?.outputDirectory ?? frameworkAdapterData.outputDirectory; - fallback = site?.fallbackFile ?? frameworkAdapterData.fallbackFile; + } else if (hasFrameworkSelectionChanged) { + const data = (selectedFramework.adapters.find((a) => a.key === adapter) ?? + selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand; + const isOriginalAdapter = adapter === site.adapter; + + installCommand = isOriginalAdapter + ? (site?.installCommand ?? frameworkAdapterData.installCommand) + : data.installCommand; + buildCommand = isOriginalAdapter + ? (site?.buildCommand ?? frameworkAdapterData.buildCommand) + : data.buildCommand; + startCommand = isOriginalAdapter + ? (site?.startCommand ?? frameworkAdapterData.startCommand) + : data.startCommand; + outputDirectory = isOriginalAdapter + ? (site?.outputDirectory ?? frameworkAdapterData.outputDirectory) + : data.outputDirectory; + fallback = isOriginalAdapter + ? (site?.fallbackFile ?? data.fallbackFile) + : data.fallbackFile; } + + lastFrameworkAdapterKey = `${selectedFramework.key}:${adapter ?? ''}`; }); $effect(() => { @@ -149,6 +162,7 @@ timeout: site.timeout || undefined, installCommand: installCommand || undefined, buildCommand: buildCommand || undefined, + startCommand: startCommand || undefined, outputDirectory: outputDirectory || undefined, buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined, adapter: (adptr?.key as Adapter) || undefined, @@ -178,13 +192,17 @@ } } - function reset(type: 'installCommand' | 'buildCommand' | 'outputDirectory') { - const data = selectedFramework.adapters.find((a) => a.key === adapter); + function reset(type: 'installCommand' | 'buildCommand' | 'startCommand' | 'outputDirectory') { + const data = selectedFramework.adapters.find( + (a) => a.key === adapter + ) as FrameworkAdapterWithStartCommand; 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; } @@ -292,7 +310,8 @@ secondary size="s" on:click={() => reset('installCommand')} - disabled={installCommand === frameworkAdapterData?.installCommand}> + disabled={(installCommand ?? '') === + (frameworkAdapterData?.installCommand ?? '')}> Reset @@ -306,11 +325,30 @@ + {#if adapter === Adapter.Ssr} + + + + + {/if}