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}