From 2f317447fbc1117e5b4b242ef3678145d35b7d5e Mon Sep 17 00:00:00 2001 From: Harsh Mahajan Date: Thu, 12 Feb 2026 18:27:18 +0530 Subject: [PATCH 1/6] feat: auto-fill detected env variables for sites/functions --- .../variables}/createVariableModal.svelte | 5 +- .../variables}/deleteVariableModal.svelte | 0 .../variables/environmentVariables.svelte | 260 ++++++++++++++++++ .../variables/importVariablesModal.svelte} | 0 .../variables}/secretVariableModal.svelte | 0 .../variables}/updateVariableModal.svelte | 4 +- .../variables}/variableEditorModal.svelte | 8 +- .../repository-[repository]/+page.svelte | 49 +++- .../configuration.svelte | 11 + .../sites/create-site/configuration.svelte | 234 +--------------- .../repository-[repository]/+page.svelte | 48 ++++ 11 files changed, 380 insertions(+), 239 deletions(-) rename src/{routes/(console)/project-[region]-[project]/sites/create-site => lib/components/variables}/createVariableModal.svelte (97%) rename src/{routes/(console)/project-[region]-[project]/sites/create-site => lib/components/variables}/deleteVariableModal.svelte (100%) create mode 100644 src/lib/components/variables/environmentVariables.svelte rename src/{routes/(console)/project-[region]-[project]/sites/create-site/importSiteVariablesModal.svelte => lib/components/variables/importVariablesModal.svelte} (100%) rename src/{routes/(console)/project-[region]-[project]/sites/create-site => lib/components/variables}/secretVariableModal.svelte (100%) rename src/{routes/(console)/project-[region]-[project]/sites/create-site => lib/components/variables}/updateVariableModal.svelte (94%) rename src/{routes/(console)/project-[region]-[project]/sites/create-site => lib/components/variables}/variableEditorModal.svelte (96%) diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/createVariableModal.svelte b/src/lib/components/variables/createVariableModal.svelte similarity index 97% rename from src/routes/(console)/project-[region]-[project]/sites/create-site/createVariableModal.svelte rename to src/lib/components/variables/createVariableModal.svelte index 8dc28a966d..3f7817ecfd 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/createVariableModal.svelte +++ b/src/lib/components/variables/createVariableModal.svelte @@ -11,6 +11,7 @@ export let show = false; export let variables: Partial[]; + export let productLabel = 'site'; let newVariables: Partial[] = [{ key: '', value: '' }]; let secret = false; @@ -65,8 +66,8 @@ - Set the environment variables or secret that will be passed to your site. Global variables - can be set in project settings + import { Empty, Paginator } from '$lib/components'; + import { Button } from '$lib/elements/forms'; + import { + ActionMenu, + Accordion, + Badge, + InteractiveText, + Icon, + Layout, + Popover, + Skeleton, + Table, + Tooltip, + Button as PinkButton + } from '@appwrite.io/pink-svelte'; + import { + IconDotsHorizontal, + IconCode, + IconUpload, + IconPlus, + IconTrash, + IconEyeOff, + IconPencil + } from '@appwrite.io/pink-icons-svelte'; + import type { Models } from '@appwrite.io/console'; + import VariableEditorModal from './variableEditorModal.svelte'; + import SecretVariableModal from './secretVariableModal.svelte'; + import ImportVariablesModal from './importVariablesModal.svelte'; + import CreateVariableModal from './createVariableModal.svelte'; + import DeleteVariableModal from './deleteVariableModal.svelte'; + import UpdateVariableModal from './updateVariableModal.svelte'; + import { Click, trackEvent } from '$lib/actions/analytics'; + + export let variables: Partial[] = []; + export let productLabel = 'site'; + export let docsLink = + 'https://appwrite.io/docs/products/sites/develop#accessing-environment-variables'; + export let analyticsSource = 'site_configuration'; + export let analyticsCreateSource = 'site_settings'; + export let isLoading = false; + + let showEditorModal = false; + let showImportModal = false; + let showSecretModal = false; + let showCreate = false; + let showUpdate = false; + let showDelete = false; + + let currentVariable: Partial; + + $: createSource = analyticsCreateSource || analyticsSource; + + + + + Set up environment variables to securely manage keys and settings for your project. + + + + + + + {#if variables?.length} + + {/if} + + + {#if isLoading && !variables?.length} + + + Key + Value + + + {#each Array(3) as _} + + + + + + + + + + + + {/each} + + {:else if variables?.length} + + {#snippet children(paginatedItems)} + + + Key + Value + + + {#each paginatedItems as variable} + + {variable.key} + + +
+ {#if variable.secret} + + + + This value is secret, you cannot see its + value. + + + {:else} + + {/if} +
+
+ +
+ + { + e.preventDefault(); + toggle(e); + }}> + + + + + + {#if !variable?.secret} + { + toggle(e); + currentVariable = variable; + showUpdate = true; + }}> + Update + + {/if} + {#if !variable?.secret} + { + toggle(e); + currentVariable = variable; + showSecretModal = true; + }}> + Secret + + {/if} + { + toggle(e); + currentVariable = variable; + showDelete = true; + }}> + Delete + + + + +
+
+
+ {/each} +
+ {/snippet} +
+ {:else} + (showCreate = true)}>Create variables to get started + {/if} +
+
+
+ +{#if showEditorModal} + +{/if} + +{#if showSecretModal} + +{/if} + +{#if showImportModal} + +{/if} + +{#if showCreate} + +{/if} +{#if showUpdate} + +{/if} + +{#if showDelete} + +{/if} diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/importSiteVariablesModal.svelte b/src/lib/components/variables/importVariablesModal.svelte similarity index 100% rename from src/routes/(console)/project-[region]-[project]/sites/create-site/importSiteVariablesModal.svelte rename to src/lib/components/variables/importVariablesModal.svelte diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/secretVariableModal.svelte b/src/lib/components/variables/secretVariableModal.svelte similarity index 100% rename from src/routes/(console)/project-[region]-[project]/sites/create-site/secretVariableModal.svelte rename to src/lib/components/variables/secretVariableModal.svelte diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/updateVariableModal.svelte b/src/lib/components/variables/updateVariableModal.svelte similarity index 94% rename from src/routes/(console)/project-[region]-[project]/sites/create-site/updateVariableModal.svelte rename to src/lib/components/variables/updateVariableModal.svelte index c678007f98..bf48d8b62f 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/updateVariableModal.svelte +++ b/src/lib/components/variables/updateVariableModal.svelte @@ -11,6 +11,7 @@ export let show = false; export let selectedVar: Partial; export let variables: Partial[]; + export let productLabel = 'site'; let pair = { $id: selectedVar?.$id, @@ -40,7 +41,8 @@ - Update the environment variable for your site. Global variables can be set in project settings[]; + export let docsLink = + 'https://appwrite.io/docs/products/sites/develop#accessing-environment-variables'; const editableVariables = variables.filter((variable) => !variable.secret); const secretVariables = variables.filter((variable) => variable.secret); @@ -122,11 +124,7 @@ {#if secretVariables?.length > 0} {secretVariables.length} secret variables are hidden from the editor. Their values will - remain unchanged. Learn more. + remain unchanged. Learn more. {/if} diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.svelte index 9a06f70dd6..a9233a3689 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/+page.svelte @@ -59,6 +59,45 @@ let detectingRuntime = true; + type DetectedVariable = { + key?: string; + name?: string; + value?: string; + secret?: boolean; + }; + + function normalizeDetectedVariables(detected: DetectedVariable[] = []) { + const normalized: Partial[] = []; + detected.forEach((variable) => { + const key = variable.key ?? variable.name; + if (!key) { + return; + } + normalized.push({ + key, + value: variable.value ?? '', + secret: variable.secret ?? false + }); + }); + return normalized; + } + + function mergeVariables( + existing: Partial[], + detected: Partial[] + ) { + const map = new Map(existing.map((variable) => [variable.key, variable])); + detected.forEach((variable) => { + if (!variable.key) { + return; + } + if (!map.has(variable.key)) { + map.set(variable.key, variable); + } + }); + return Array.from(map.values()); + } + onMount(async () => { installation.set(data.installation); repository.set(data.repository); @@ -82,6 +121,10 @@ entrypoint = detections.entrypoint; buildCommand = detections.commands; runtime = detections.runtime as Runtime; + const detectedVariables = normalizeDetectedVariables(detections?.variables); + if (detectedVariables.length) { + variables = mergeVariables(variables, detectedVariables); + } trackEvent(Submit.FrameworkDetect, { runtime, source: 'repository' }); } catch (error) { @@ -189,7 +232,11 @@ installationId={data.installation.$id} repositoryId={data.repository.id} /> - + diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/configuration.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/configuration.svelte index 8f3091f39e..90f413113c 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/configuration.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/repository-[repository]/configuration.svelte @@ -3,9 +3,13 @@ import { Link } from '$lib/elements'; import { InputText } from '$lib/elements/forms'; import { Accordion, Fieldset, Layout } from '@appwrite.io/pink-svelte'; + import type { Models } from '@appwrite.io/console'; + import EnvironmentVariables from '$lib/components/variables/environmentVariables.svelte'; export let buildCommand = ''; export let roles: string[] = []; + export let variables: Partial[] = []; + export let isVariablesLoading = false;
@@ -31,5 +35,12 @@ +
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 dc5d0a1403..97ddee3da8 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 @@ -1,38 +1,10 @@ @@ -96,7 +110,7 @@ type="button" size="s" disabled={newVariables.length === 1 && !pair.key && !pair.value} - on:click={() => removeVariable(i)}> + onclick={() => removeVariable(i)}> diff --git a/src/lib/components/variables/environmentVariables.svelte b/src/lib/components/variables/environmentVariables.svelte index 01a856a8c7..98d2584bf6 100644 --- a/src/lib/components/variables/environmentVariables.svelte +++ b/src/lib/components/variables/environmentVariables.svelte @@ -27,29 +27,46 @@ import VariableEditorModal from './variableEditorModal.svelte'; import SecretVariableModal from './secretVariableModal.svelte'; import ImportVariablesModal from './importVariablesModal.svelte'; - import CreateVariableModal from './createVariableModal.svelte'; + import CreateVariableModal, { type ProductLabel } from './createVariableModal.svelte'; import DeleteVariableModal from './deleteVariableModal.svelte'; import UpdateVariableModal from './updateVariableModal.svelte'; import { Click, trackEvent } from '$lib/actions/analytics'; - export let variables: Partial[] = []; - export let productLabel = 'site'; - export let docsLink = - 'https://appwrite.io/docs/products/sites/develop#accessing-environment-variables'; - export let analyticsSource = 'site_configuration'; - export let analyticsCreateSource = 'site_settings'; - export let isLoading = false; + const DOCS_LINKS: Record = { + site: 'https://appwrite.io/docs/products/sites/develop#accessing-environment-variables', + function: 'https://appwrite.io/docs/products/functions/develop#environment-variables' + }; - let showEditorModal = false; - let showImportModal = false; - let showSecretModal = false; - let showCreate = false; - let showUpdate = false; - let showDelete = false; + let { + variables = $bindable([]), + productLabel = 'site', + analyticsSource = 'site_configuration', + analyticsCreateSource = 'site_settings', + isLoading = false + }: { + variables: Partial[]; + productLabel?: ProductLabel; + analyticsSource?: string; + analyticsCreateSource?: string; + isLoading?: boolean; + } = $props(); - let currentVariable: Partial; + let showEditorModal = $state(false); + let showImportModal = $state(false); + let showSecretModal = $state(false); + let showCreate = $state(false); + let showUpdate = $state(false); + let showDelete = $state(false); + let currentVariable = $state>(undefined); - $: createSource = analyticsCreateSource || analyticsSource; + const createSource = $derived(analyticsCreateSource || analyticsSource); + const docsLink = $derived(DOCS_LINKS[productLabel]); + + const tableColumns = [ + { id: 'key', width: { min: 300 } }, + { id: 'value', width: { min: 280 } }, + { id: 'actions', width: 40 } + ]; @@ -61,7 +78,7 @@