diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/createGit.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/createGit.svelte
index 1ea7fffbd7..e9ee60e75b 100644
--- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/createGit.svelte
+++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/(modals)/createGit.svelte
@@ -90,7 +90,10 @@
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: $installation.$id || undefined,
providerRepositoryId: selectedRepository || undefined,
- providerBranch: branch || undefined
+ providerBranch: branch || undefined,
+ providerSilentMode: $func.providerSilentMode ?? undefined,
+ providerRootDirectory: $func.providerRootDirectory ?? undefined,
+ buildSpecification: $func.buildSpecification || undefined
});
}
if (commit) {
diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/disconnectRepo.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/disconnectRepo.svelte
index 9ba31a85a1..fc27ddfe93 100644
--- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/disconnectRepo.svelte
+++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/disconnectRepo.svelte
@@ -40,7 +40,8 @@
providerRepositoryId: '',
providerBranch: '',
providerSilentMode: true,
- providerRootDirectory: ''
+ providerRootDirectory: '',
+ buildSpecification: $func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
dispatch('success');
diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateRepository.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateRepository.svelte
index 1a2412dfeb..c091ffe530 100644
--- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateRepository.svelte
+++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateRepository.svelte
@@ -91,7 +91,8 @@
providerRepositoryId: func.providerRepositoryId || undefined,
providerBranch: selectedBranch,
providerSilentMode: silentMode,
- providerRootDirectory: selectedDir
+ providerRootDirectory: selectedDir,
+ buildSpecification: func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
addNotification({
@@ -129,7 +130,21 @@
selectedDir !== func?.providerRootDirectory;
async function connect(selectedInstallationId: string, selectedRepository: string) {
+ let nextBranch = func?.providerBranch ?? 'main';
try {
+ const branchList = await sdk
+ .forProject(page.params.region, page.params.project)
+ .vcs.listRepositoryBranches({
+ installationId: selectedInstallationId,
+ providerRepositoryId: selectedRepository
+ });
+ const sorted = sortBranches(branchList.branches);
+ nextBranch =
+ sorted.find((branch) => branch.name === func?.providerBranch)?.name ??
+ sorted.find((branch) => branch.name === 'main' || branch.name === 'master')?.name ??
+ sorted[0]?.name ??
+ nextBranch;
+
if (!isValueOfStringEnum(Runtime, func.runtime)) {
throw new Error(`Invalid runtime: ${func.runtime}`);
}
@@ -148,7 +163,10 @@
scopes: (func.scopes as Scopes[]) || undefined,
installationId: selectedInstallationId,
providerRepositoryId: selectedRepository,
- providerBranch: 'main'
+ providerBranch: nextBranch,
+ providerSilentMode: func.providerSilentMode ?? undefined,
+ providerRootDirectory: func.providerRootDirectory ?? undefined,
+ buildSpecification: func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
} catch {
@@ -275,7 +293,7 @@
{#if showSelectRoot}
{/if}
diff --git a/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte b/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte
index 35b0ddf23b..7309623b52 100644
--- a/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte
+++ b/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte
@@ -31,7 +31,11 @@
import { isCloud } from '$lib/system';
import { Button } from '$lib/elements/forms';
import { symmetricDifference } from '$lib/helpers/array';
- import { cloudOnlyBackupScopes, type ScopeDefinition } from '$lib/constants';
+ import {
+ cloudOnlyBackupScopes,
+ scopes as localScopes,
+ type ScopeDefinition
+ } from '$lib/constants';
import { sdk } from '$lib/stores/sdk';
import { Accordion, Alert, Badge, Divider, Layout, Selector } from '@appwrite.io/pink-svelte';
import type { Scopes } from '@appwrite.io/console';
@@ -41,39 +45,68 @@
let allScopesList: ScopeDefinition[] = $state([]);
let mounted = $state(false);
let loadError: string | null = $state(null);
+ const effectiveScopes = $derived(getEffectiveScopes(scopes));
+
+ const categoryAliasMap: Record = {
+ Database: 'Databases'
+ };
enum Category {
+ Project = 'Project',
Auth = 'Auth',
- Database = 'Database',
+ Databases = 'Databases',
Functions = 'Functions',
Messaging = 'Messaging',
Sites = 'Sites',
Storage = 'Storage',
+ Domains = 'Domains',
Other = 'Other'
}
- const categories = [
+ const categoryOrder = [
+ Category.Project,
Category.Auth,
- Category.Database,
+ Category.Databases,
Category.Functions,
Category.Storage,
Category.Messaging,
Category.Sites,
+ Category.Domains,
Category.Other
];
+ function normalizeCategory(category: string): string {
+ return categoryAliasMap[category] ?? category;
+ }
+
const filteredScopes = $derived.by(() => {
const databasesWriteIndex = allScopesList.findIndex((s) => s.scope === 'databases.write');
if (isCloud && databasesWriteIndex !== -1) {
return [
...allScopesList.slice(0, databasesWriteIndex + 1),
- ...cloudOnlyBackupScopes,
+ ...cloudOnlyBackupScopes.map((scope) => ({
+ ...scope,
+ category: normalizeCategory(scope.category)
+ })),
...allScopesList.slice(databasesWriteIndex + 1)
];
}
return allScopesList;
});
+ const categories = $derived.by(() => {
+ const availableCategories = new Set(
+ filteredScopes.map((scope) => normalizeCategory(scope.category))
+ );
+
+ return [
+ ...categoryOrder.filter((category) => availableCategories.has(category)),
+ ...Array.from(availableCategories).filter(
+ (category) => !categoryOrder.includes(category as Category)
+ )
+ ];
+ });
+
const scopeCatalog = $derived(
new Set([
...filteredScopes.map((s) => s.scope),
@@ -95,16 +128,29 @@
onMount(async () => {
try {
const result = await sdk.forConsole.console.listProjectScopes();
- allScopesList = result.scopes.map((s) => ({
- scope: s.$id,
- description: s.description,
- category: s.category,
- deprecated: s.deprecated,
- icon: ''
- }));
+ const scopesById = new Map();
+
+ for (const scope of localScopes) {
+ scopesById.set(scope.scope, {
+ ...scope,
+ category: normalizeCategory(scope.category)
+ });
+ }
+
+ for (const scope of result.scopes) {
+ scopesById.set(scope.$id, {
+ scope: scope.$id,
+ description: scope.description,
+ category: normalizeCategory(scope.category),
+ deprecated: scope.deprecated,
+ icon: ''
+ });
+ }
+
+ allScopesList = Array.from(scopesById.values());
for (const s of filteredScopes) {
- activeScopes[s.scope] = scopes.includes(s.scope as Scopes);
+ activeScopes[s.scope] = effectiveScopes.includes(s.scope);
}
mounted = true;
} catch (e) {
@@ -129,8 +175,9 @@
function categoryState(category: string, s: string[]): boolean | 'indeterminate' {
const scopesByCategory = filteredScopes.filter((n) => n.category === category);
+ const scopeSet = new Set(getEffectiveScopes(s));
const activeInCategory = scopesByCategory.filter((scopeItem) =>
- s.includes(scopeItem.scope as Scopes)
+ scopeSet.has(scopeItem.scope)
);
if (activeInCategory.length === 0) {
@@ -142,7 +189,7 @@
return 'indeterminate';
}
- function onCategoryChange(event: CustomEvent, category: Category) {
+ function onCategoryChange(event: CustomEvent, category: string) {
const { detail } = event;
if (detail === 'indeterminate') return;
filteredScopes.forEach((s) => {
@@ -177,7 +224,7 @@
{@const checked = categoryState(category, scopes)}
{@const isLastItem = index === categories.length - 1}
{@const scopesLength = filteredScopes.filter(
- (n) => n.category === category && scopes.includes(n.scope as Scopes)
+ (n) => n.category === category && effectiveScopes.includes(n.scope)
).length}