Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"dependencies": {
"@ai-sdk/svelte": "^1.1.24",
"@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@297fbee",
"@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@41152f5",
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@df765cc",
"@appwrite.io/pink-legacy": "^1.0.3",
Expand Down
24 changes: 23 additions & 1 deletion src/lib/stores/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ const initialFormData = {
sites: {
root: false,
deploymentInactive: false
},
messaging: {
root: false,
messages: false
}
};

Expand Down Expand Up @@ -76,7 +80,11 @@ export const ResourcesFriendly = {
row: { singular: 'Row', plural: 'Rows' },
site: { singular: 'Site', plural: 'Sites' },
'site-deployment': { singular: 'Site Deployment', plural: 'Site Deployments' },
'site-variable': { singular: 'Site Variable', plural: 'Site Variables' }
'site-variable': { singular: 'Site Variable', plural: 'Site Variables' },
provider: { singular: 'Provider', plural: 'Providers' },
topic: { singular: 'Topic', plural: 'Topics' },
subscriber: { singular: 'Subscriber', plural: 'Subscribers' },
message: { singular: 'Message', plural: 'Messages' }
};

export const providerResources: ProviderResourceMap = {
Expand Down Expand Up @@ -132,6 +140,14 @@ export const migrationFormToResources = <P extends Provider>(
addResource(ResourceType.Sitedeployment);
}
}
if (formData.messaging.root) {
addResource(ResourceType.Provider);
addResource(ResourceType.Topic);
addResource(ResourceType.Subscriber);
}
if (formData.messaging.messages) {
addResource(ResourceType.Message);
}

return resources as ProviderResourceMap[P];
};
Expand Down Expand Up @@ -194,6 +210,12 @@ export const resourcesToMigrationForm = (resources: MigrationResource[]): Migrat
if (resources.includes(ResourceType.Sitedeployment)) {
formData.sites.deploymentInactive = true;
}
if (resources.includes(ResourceType.Provider)) {
formData.messaging.root = true;
}
if (resources.includes(ResourceType.Message)) {
formData.messaging.messages = true;
}

return formData;
};
Expand Down
7 changes: 6 additions & 1 deletion src/routes/(console)/(migration-wizard)/resource-form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@
return resources.includes(ResourceType.Site);
}

if (groupKey === 'messaging') {
return resources.includes(ResourceType.Provider);
}

const groupToResource: Record<string, MigrationResource> = {
users: ResourceType.User,
databases: ResourceType.Database
Expand All @@ -127,7 +131,8 @@
databases: 'database',
functions: 'function',
storage: 'bucket',
sites: 'site'
sites: 'site',
messaging: 'provider'
};
return map[groupKey] || groupKey;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
commands: installCommand || undefined,
scopes: selectedScopes?.length ? selectedScopes : undefined,
providerSilentMode: false,
specification: specification || undefined
buildSpecification: specification || undefined
});

// Add domain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
enabled: true,
entrypoint,
commands: buildCommand,
specification: specification || undefined
buildSpecification: specification || undefined
});

// Add domain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
providerBranch: branch,
providerSilentMode: silentMode,
providerRootDirectory: rootDir,
specification: specification || undefined
buildSpecification: specification || undefined
});

// Add domain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
providerBranch: branch,
providerSilentMode: silentMode,
providerRootDirectory: rootDir,
specification: specification || undefined
buildSpecification: specification || undefined
});

// Add domain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
providerBranch: func.providerBranch || undefined,
providerSilentMode: func.providerSilentMode || undefined,
providerRootDirectory: func.providerRootDirectory || undefined,
specification: func.specification || undefined
buildSpecification: func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
providerBranch: $func.providerBranch || undefined,
providerSilentMode: $func.providerSilentMode || undefined,
providerRootDirectory: $func.providerRootDirectory || undefined,
specification: $func.specification || undefined
buildSpecification: $func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
providerBranch: func.providerBranch || undefined,
providerSilentMode: func.providerSilentMode || undefined,
providerRootDirectory: func.providerRootDirectory || undefined,
specification: func.specification || undefined
buildSpecification: func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
providerBranch: $func.providerBranch || undefined,
providerSilentMode: $func.providerSilentMode || undefined,
providerRootDirectory: $func.providerRootDirectory || undefined,
specification: $func.specification || undefined
buildSpecification: $func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
providerBranch: $func.providerBranch || undefined,
providerSilentMode: $func.providerSilentMode || undefined,
providerRootDirectory: $func.providerRootDirectory || undefined,
specification: $func.specification || undefined
buildSpecification: $func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
export let func: Models.Function;
export let specs: Models.SpecificationList;

let specification = func.specification;
let originalSpecification = func.specification;
$: originalSpecification = func.specification;
let specification = func.buildSpecification;
let originalSpecification = func.buildSpecification;
$: originalSpecification = func.buildSpecification;

async function updateLogging() {
try {
Expand All @@ -45,7 +45,7 @@
providerBranch: func.providerBranch || undefined,
providerSilentMode: func.providerSilentMode || undefined,
providerRootDirectory: func.providerRootDirectory || undefined,
specification: specification || undefined
buildSpecification: specification || undefined
});

await invalidate(Dependencies.FUNCTION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
providerBranch: $func.providerBranch || undefined,
providerSilentMode: $func.providerSilentMode || undefined,
providerRootDirectory: $func.providerRootDirectory || undefined,
specification: $func.specification || undefined
buildSpecification: $func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
providerBranch: $func.providerBranch || undefined,
providerSilentMode: $func.providerSilentMode || undefined,
providerRootDirectory: $func.providerRootDirectory || undefined,
specification: $func.specification || undefined
buildSpecification: $func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
providerBranch: $func.providerBranch || undefined,
providerSilentMode: $func.providerSilentMode || undefined,
providerRootDirectory: $func.providerRootDirectory || undefined,
specification: $func.specification || undefined
buildSpecification: $func.buildSpecification || undefined
});
await invalidate(Dependencies.FUNCTION);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
providerBranch: $func.providerBranch || undefined,
providerSilentMode: $func.providerSilentMode || undefined,
providerRootDirectory: $func.providerRootDirectory || undefined,
specification: $func.specification || undefined
buildSpecification: $func.buildSpecification || undefined
Copy link
Contributor

@coderabbitai coderabbitai bot Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

In Appwrite SDK / Console 5.0.0, did the Functions.update payload field change from specificationtobuildSpecification?

💡 Result:

No. In Appwrite’s current Functions API (as reflected in the SDK reference examples), functions.update(...) still uses the payload field specification (described as “Runtime specification for the function and builds”), and there is no buildSpecification field shown for that endpoint. [1][2]

Sources: Appwrite Functions API reference (Node.js) shows specification in functions.update payload [1]; REST reference for PUT /functions/{functionId} also uses specification [2].


Revert buildSpecification to specification to match the Appwrite SDK contract.

The Appwrite Functions API uses specification (not buildSpecification) as the payload field for functions.update(). Using the wrong field name will prevent the timeout from being persisted correctly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/routes/`(console)/project-[region]-[project]/functions/function-[function]/settings/updateTimeout.svelte
at line 45, The payload uses the wrong field name: replace buildSpecification
with specification in the update payload so the Appwrite SDK's
functions.update() receives the correct field; locate the assignment
(buildSpecification: $func.buildSpecification || undefined) and change it to use
$func.specification (or $func.specification || undefined) so the field name and
value match the Appwrite Functions API contract.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using SDK 5.0.0 which was generated from 1.8.x after PR #11448 merged the specification → buildSpecification / runtimeSpecification split. The functions.update() signature in SDK 5.0.0 accepts buildSpecification, not specification. See: https://github.com/appwrite/appwrite/blob/2afec80a2570/src/Appwrite/Utopia/Response/Model/Site.php#L176-L185

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@premtsd-code, thank you for the clarification! You're right — my original comment was based on the public Appwrite docs which still reflect the older specification field. Since this PR uses the internal @appwrite.io/console SDK at version 5.0.0 (targeting Appwrite 1.8.x, post-#11448), which introduced the specification → buildSpecification rename, the change here is correct.

The consistent rename across all function and site settings files in this PR aligns perfectly with that SDK breaking change. I apologize for the incorrect flag.


✏️ Learnings added
Learnt from: premtsd-code
Repo: appwrite/console PR: 2913
File: src/routes/(console)/project-[region]-[project]/functions/function-[function]/settings/updateTimeout.svelte:45-45
Timestamp: 2026-03-12T10:07:55.347Z
Learning: In the Appwrite Console repository (`appwrite/console`), the internal SDK `appwrite.io/console` at version 5.0.0 (targeting Appwrite server 1.8.x, introduced after appwrite/appwrite#11448) renamed the `specification` field to `buildSpecification` in all `functions.update()` and `sites.update()` API payloads. Do not flag usages of `buildSpecification` in these SDK calls as incorrect — it is the correct field name for SDK 5.0.0+. The older public Appwrite docs/SDKs (e.g., sdk-for-node, sdk-for-web) may still show `specification`, but the internal console SDK uses `buildSpecification`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2722
File: src/lib/components/backupDatabaseAlert.svelte:19-27
Timestamp: 2026-01-27T05:58:36.012Z
Learning: In the Appwrite Console codebase, assume that organization.billingPlanDetails is always present on loaded organization objects. Do not use optional chaining on billingPlanDetails itself. Instead, use optional chaining only for the final property: organization?.billingPlanDetails.backupsEnabled. If billingPlanDetails is missing, treat it as a backend issue. This guideline applies to Svelte component files (e.g., any src/**/*.svelte) where the organization object is accessed to read backupsEnabled.

Learnt from: ItzNotABug
Repo: appwrite/console PR: 2722
File: src/lib/layout/shell.svelte:156-164
Timestamp: 2026-01-27T06:13:21.829Z
Learning: billingPlanDetails is cloud-only in the Appwrite Console. When accessing billing-related properties in any Svelte file, guard with isCloud or use defensive access (e.g., optional chaining or explicit null checks) to support both cloud and self-hosted deployments. Prefer guards around billingPlanDetails access and avoid assuming presence; implement pattern like if (isCloud) { ... } or use billingPlanDetails?.property with appropriate fallbacks.

Learnt from: ItzNotABug
Repo: appwrite/console PR: 2722
File: src/lib/components/cardContainer.svelte:12-18
Timestamp: 2026-01-28T10:13:02.917Z
Learning: In src/lib/components/cardContainer.svelte, the service prop is route-scoped and does not change after the component mounts. Since navigating to a different URL provides a new service, initializing serviceId once (e.g., const serviceId = service as PlanServices) is intentional and no reactive derivation is needed. For code reviews, approve this pattern for this file, and avoid adding unnecessary $: reactive derivations tied to service. If future routing changes could update service without remounting, consider validating whether service changes are reflected and adjust accordingly.

});
await invalidate(Dependencies.FUNCTION);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
sites: {
root: 'Sites',
deploymentInactive: 'Include inactive deployments'
},
messaging: {
root: 'Messaging',
messages: 'Include messages'
}
};

Expand All @@ -48,6 +52,10 @@
sites: {
root: 'Import all sites and their active deployment',
deploymentInactive: 'Import all deployments that are not currently active'
},
messaging: {
root: 'Import all messaging providers, topics and subscribers',
messages: 'Import all messages'
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@
Scopes.BucketsRead,
Scopes.FunctionsRead,
Scopes.ExecutionRead,
Scopes.SitesRead,
Scopes.ProvidersRead,
Scopes.TopicsRead,
Scopes.SubscribersRead,
Scopes.MessagesRead,
Scopes.LocaleRead,
Scopes.AvatarsRead,
Scopes.HealthRead
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
providerBranch: nextBranch,
providerSilentMode: data.site?.providerSilentMode ?? undefined,
providerRootDirectory: data.site?.providerRootDirectory ?? undefined,
specification: data.site?.specification || undefined
buildSpecification: data.site?.buildSpecification || undefined
});
invalidate(Dependencies.SITE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export const load = async ({ params, depends, parent }) => {
});

const enabledSpecs = specificationsList?.specifications?.filter((s) => s.enabled) ?? [];
if (!enabledSpecs.some((s) => s.slug === site.specification)) {
site.specification = enabledSpecs[0]?.slug;
if (!enabledSpecs.some((s) => s.slug === site.buildSpecification)) {
site.buildSpecification = enabledSpecs[0]?.slug;
}

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@
site.adapter = adapter;
}
if (specs && specs.specifications?.length) {
if (!specs.specifications.some((s) => s.slug === site.specification)) {
site.specification = specs.specifications[0].slug;
if (!specs.specifications.some((s) => s.slug === site.buildSpecification)) {
site.buildSpecification = specs.specifications[0].slug;
}
}
}
Expand All @@ -128,10 +128,10 @@
}
// only allow enabled specsification for it
const enabledSpecs = specs?.specifications?.filter((s) => s.enabled) ?? [];
let specToSend = enabledSpecs.some((s) => s.slug === site.specification)
? site.specification
let specToSend = enabledSpecs.some((s) => s.slug === site.buildSpecification)
? site.buildSpecification
: enabledSpecs[0]?.slug;
site.specification = specToSend;
site.buildSpecification = specToSend;
try {
await sdk.forProject(page.params.region, page.params.project).sites.update({
siteId: site.$id,
Expand All @@ -151,7 +151,7 @@
providerBranch: site.providerBranch || undefined,
providerSilentMode: site.providerSilentMode || undefined,
providerRootDirectory: site.providerRootDirectory || undefined,
specification: specToSend || undefined
buildSpecification: specToSend || undefined
});
await invalidate(Dependencies.SITE);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
providerBranch: site?.providerBranch || undefined,
providerSilentMode: site?.providerSilentMode || undefined,
providerRootDirectory: site?.providerRootDirectory || undefined,
specification: site?.specification || undefined
buildSpecification: site?.buildSpecification || undefined
});
await invalidate(Dependencies.SITE);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
providerBranch: site?.providerBranch || undefined,
providerSilentMode: site?.providerSilentMode || undefined,
providerRootDirectory: site?.providerRootDirectory || undefined,
specification: site?.specification || undefined
buildSpecification: site?.buildSpecification || undefined
});
await invalidate(Dependencies.SITE);
addNotification({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
providerBranch: selectedBranch || undefined,
providerSilentMode: silentMode || undefined,
providerRootDirectory: selectedDir || undefined,
specification: site?.specification || undefined
buildSpecification: site?.buildSpecification || undefined
});
await invalidate(Dependencies.SITE);
addNotification({
Expand Down Expand Up @@ -152,7 +152,7 @@
providerBranch: nextBranch,
providerSilentMode: site?.providerSilentMode ?? undefined,
providerRootDirectory: site?.providerRootDirectory ?? undefined,
specification: site?.specification || undefined
buildSpecification: site?.buildSpecification || undefined
});

invalidate(Dependencies.SITE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
export let site: Models.Site;
export let specs: Models.SpecificationList;

let specification = site.specification;
let originalSpecification = site.specification;
let specification = site.buildSpecification;
let originalSpecification = site.buildSpecification;

async function updateLogging() {
try {
Expand All @@ -40,7 +40,7 @@
providerBranch: site?.providerBranch || undefined,
providerSilentMode: site?.providerSilentMode || undefined,
providerRootDirectory: site?.providerRootDirectory || undefined,
specification: specification || undefined
buildSpecification: specification || undefined
});
await invalidate(Dependencies.SITE);
originalSpecification = specification;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
providerBranch: site?.providerBranch || undefined,
providerSilentMode: site?.providerSilentMode || undefined,
providerRootDirectory: site?.providerRootDirectory || undefined,
specification: site?.specification || undefined
buildSpecification: site?.buildSpecification || undefined
});
await invalidate(Dependencies.SITE);
addNotification({
Expand Down
Loading
Loading