Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f044340
Add new badges to site domains
vermakhushboo Sep 12, 2025
6df5f66
Merge branch 'main' into feat-improve-domain-flows
vermakhushboo Sep 15, 2025
995ef38
Add badges and links to functions/projects tables
vermakhushboo Sep 16, 2025
8ddcc95
Merge branch 'main' into feat-improve-domain-flows
vermakhushboo Sep 16, 2025
bb6c951
Fix verification flows for sites/functions/api
vermakhushboo Sep 17, 2025
8602eb4
Merge branch 'main' into feat-improve-domain-flows
vermakhushboo Sep 17, 2025
bfe9c92
Simplify timeFromNowShort function
vermakhushboo Sep 19, 2025
2ee96d1
Merge branch 'main' into feat-improve-domain-flows
vermakhushboo Sep 19, 2025
15e56c3
Add CNAME flattening changes
vermakhushboo Sep 19, 2025
2b68cf9
Add comment to empty catch block
vermakhushboo Sep 22, 2025
ce61ac0
Comment addressal
vermakhushboo Sep 22, 2025
625273d
Merge branch 'main' into feat-improve-domain-flows
vermakhushboo Sep 23, 2025
2fcdf31
Handle TLDs with multiple dots
vermakhushboo Sep 23, 2025
18de91d
Create and verify domain in background
vermakhushboo Sep 24, 2025
37571a0
Merge branch 'main' into feat-improve-domain-flows
vermakhushboo Sep 26, 2025
ffbab00
Change links to quiet-muted
vermakhushboo Sep 26, 2025
f81d05e
Migrate to svelte 5 syntax
vermakhushboo Sep 26, 2025
bf84ce6
Show view logs link if logs are not empty
vermakhushboo Sep 26, 2025
f8c2629
Resolve merge conflicts
vermakhushboo Oct 8, 2025
e41a191
Make records copy dynamic based on presence/absence of CAA row
vermakhushboo Oct 9, 2025
1faadf9
Fix error that always showed domain verified notification even on fai…
vermakhushboo Oct 9, 2025
160e9c0
Merge branch 'main' into feat-improve-domain-flows
vermakhushboo Oct 9, 2025
cb45348
Show certificate logs for verified state too
vermakhushboo Oct 13, 2025
71b7997
Merge branch 'main' into feat-improve-domain-flows
vermakhushboo Oct 13, 2025
6abb277
Update table without having to refresh
vermakhushboo Oct 13, 2025
493ad69
No in line view logs for verified
vermakhushboo Oct 13, 2025
11f7c13
Attempt to add auto-refresh
vermakhushboo Oct 13, 2025
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
56 changes: 47 additions & 9 deletions src/lib/components/domains/cnameTable.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import { Link } from '$lib/elements';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
import { getSubdomain } from '$lib/helpers/tlds';
import {
Badge,
Layout,
Expand All @@ -11,10 +12,23 @@
} from '@appwrite.io/pink-svelte';
import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store';

export let domain: string;
export let verified = undefined;
let {
domain,
verified = undefined,
ruleStatus = undefined
}: {
domain: string;
verified?: boolean | undefined;
ruleStatus?: string | undefined;
} = $props();

let subdomain = domain.split('.').slice(0, -2).join('.');
const subdomain = $derived(getSubdomain(domain));

const caaText = $derived(
$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA?.includes(' ')
? $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA
: `0 issue "${$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}"`
);
Comment on lines +25 to +31
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Prevent runtime errors if regionalConsoleVariables is undefined.

Accessing properties on an undefined store value will throw. Guard with optional chaining and provide a safe fallback.

-    const caaText = $derived(
-        $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA?.includes(' ')
-            ? $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA
-            : `0 issue "${$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}"`
-    );
+    const caaText = $derived(
+        $regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA?.includes(' ')
+            ? $regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA ?? ''
+            : $regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA
+              ? `0 issue "${$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}"`
+              : ''
+    );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const subdomain = $derived(getSubdomain(domain));
const caaText = $derived(
$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA?.includes(' ')
? $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA
: `0 issue "${$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}"`
);
const subdomain = $derived(getSubdomain(domain));
const caaText = $derived(
$regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA?.includes(' ')
? $regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA ?? ''
: $regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA
? `0 issue "${$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}"`
: ''
);
🤖 Prompt for AI Agents
In src/lib/components/domains/cnameTable.svelte around lines 25 to 31, the code
reads properties from $regionalConsoleVariables directly which can be undefined
and cause runtime errors; update the expression to use optional chaining and a
safe fallback (e.g., treat undefined as an empty string) when calling includes
and when interpolating the value so the derived store always receives a string;
ensure the conditional becomes something like checking
($regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA ?? '') and fallback to a
default CAA string when empty so no property access occurs on undefined.

</script>

<Layout.Stack gap="xl">
Expand All @@ -23,15 +37,25 @@
<Typography.Text variant="l-500" color="--fgcolor-neutral-primary">
{domain}
</Typography.Text>
{#if verified === true}
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
Comment on lines +40 to 51
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle ruleStatus === 'verified' explicitly.

Show the success badge when status is verified even if verified flag isn’t set.

-            {:else if ruleStatus === 'unverified'}
+            {:else if ruleStatus === 'unverified'}
                 <Badge
                     variant="secondary"
                     type="error"
                     size="xs"
                     content="Certificate generation failed" />
-            {:else if verified === true}
+            {:else if ruleStatus === 'verified' || verified === true}
                 <Badge variant="secondary" type="success" size="xs" content="Verified" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if ruleStatus === 'verified' || verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
🤖 Prompt for AI Agents
In src/lib/components/domains/cnameTable.svelte around lines 40 to 51, the
current conditional omits handling for ruleStatus === 'verified' and only shows
the success badge when verified === true; update the conditional flow to
explicitly check for ruleStatus === 'verified' (render the success Badge) before
the final verified === true fallback so that a 'verified' status always shows
the success badge regardless of the verified flag, keeping the existing other
branches intact.

{:else if verified === false}
<Badge variant="secondary" type="warning" size="xs" content="Verification failed" />
{/if}
</Layout.Stack>
<Typography.Text variant="m-400">
Add the following record on your DNS provider. Note that DNS changes may take time to
propagate fully.
Add the following {$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA
? 'records'
: 'record'} on your DNS provider. Note that DNS changes may take up to 48 hours to propagate
fully.
</Typography.Text>
</Layout.Stack>

Expand All @@ -43,14 +67,28 @@
</svelte:fragment>
<Table.Row.Base {root}>
<Table.Cell {root}>CNAME</Table.Cell>
<Table.Cell {root}>{subdomain}</Table.Cell>
<Table.Cell {root}>{subdomain || '@'}</Table.Cell>
<Table.Cell {root}>
<InteractiveText
variant="copy"
isVisible
text={$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME} />
</Table.Cell>
</Table.Row.Base>
{#if $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}
<Table.Row.Base {root}>
<Table.Cell {root}>
<Layout.Stack gap="s" direction="row" alignItems="center">
<span>CAA</span>
<Badge variant="secondary" size="xs" content="Recommended" />
</Layout.Stack>
</Table.Cell>
<Table.Cell {root}>@</Table.Cell>
<Table.Cell {root}>
<InteractiveText variant="copy" isVisible text={caaText} />
</Table.Cell>
</Table.Row.Base>
{/if}
Comment on lines +78 to +91
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard CAA conditional and keep value consistent with the guard.

Use optional chaining in the {#if} and rely on the already-guarded caaText.

-        {#if $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}
+        {#if $regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA}
             <Table.Row.Base {root}>
                 <Table.Cell {root}>
                     <Layout.Stack gap="s" direction="row" alignItems="center">
                         <span>CAA</span>
                         <Badge variant="secondary" size="xs" content="Recommended" />
                     </Layout.Stack>
                 </Table.Cell>
                 <Table.Cell {root}>@</Table.Cell>
                 <Table.Cell {root}>
                     <InteractiveText variant="copy" isVisible text={caaText} />
                 </Table.Cell>
             </Table.Row.Base>
         {/if}
🤖 Prompt for AI Agents
In src/lib/components/domains/cnameTable.svelte around lines 76-89, the CAA
conditional should use optional chaining and the rendered value should rely on
the already-guarded caaText; update the {#if} to check
$regionalConsoleVariables?._APP_DOMAIN_TARGET_CAA (optional chaining) and ensure
the Table.Cell passes caaText (not re-reading the store) to InteractiveText so
the displayed value matches the guard.

</Table.Root>
<Layout.Stack gap="s" direction="row" alignItems="center">
<Icon icon={IconInfo} size="s" color="--fgcolor-neutral-secondary" />
Expand Down
5 changes: 5 additions & 0 deletions src/lib/components/domains/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { default as ViewLogsModal } from './viewLogsModal.svelte';
export { default as CnameTable } from './cnameTable.svelte';
export { default as DnsRecordsAction } from './dnsRecordsAction.svelte';
export { default as NameserverTable } from './nameserverTable.svelte';
export { default as RecordTable } from './recordTable.svelte';
25 changes: 20 additions & 5 deletions src/lib/components/domains/nameserverTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
import { Badge, Layout, Typography, Table, InteractiveText } from '@appwrite.io/pink-svelte';
export let domain: string;
export let verified = undefined;
let {
domain,
verified = undefined,
ruleStatus = undefined
}: {
domain: string;
verified?: boolean | undefined;
ruleStatus?: string | undefined;
} = $props();
const nameserverList = $regionalConsoleVariables?._APP_DOMAINS_NAMESERVERS
? $regionalConsoleVariables?._APP_DOMAINS_NAMESERVERS?.split(',')
Expand All @@ -16,10 +23,18 @@
<Typography.Text variant="l-500" color="--fgcolor-neutral-primary">
{domain}
</Typography.Text>
{#if verified === true}
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
Copy link
Member

Choose a reason for hiding this comment

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

is this correct? does ruleStatus === 'created mean it failed verification? is there no other status on rule?

Copy link
Member Author

Choose a reason for hiding this comment

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

As per backend, created = verification failed, verifying = 'generating certificate', unverified = 'certificate generation failed', verified = verified

{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
Copy link
Member

Choose a reason for hiding this comment

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

do we not use a warning [orange] variant in similar places for different states? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

Not as per new design, only in org > domains table

{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
Comment on lines +26 to 37
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle ruleStatus === 'verified' explicitly.

If callers pass only ruleStatus without toggling verified=true, the "Verified" badge won’t render. Add a branch for ruleStatus === 'verified'.

-        {:else if ruleStatus === 'unverified'}
+        {:else if ruleStatus === 'unverified'}
             <Badge
                 variant="secondary"
                 type="error"
                 size="xs"
                 content="Certificate generation failed" />
-        {:else if verified === true}
+        {:else if ruleStatus === 'verified' || verified === true}
             <Badge variant="secondary" type="success" size="xs" content="Verified" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if ruleStatus === 'verified' || verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{/if}
🤖 Prompt for AI Agents
In src/lib/components/domains/nameserverTable.svelte around lines 26 to 37, the
template lacks an explicit branch for ruleStatus === 'verified' so if callers
set ruleStatus to 'verified' but don't set verified=true the "Verified" badge
never renders; add an {:else if ruleStatus === 'verified'} branch (before the
final {:else if verified === true} or replace the final check) that renders the
same Badge as the verified=true case (variant="secondary" type="success"
size="xs" content="Verified"), ensuring the verified state is handled
consistently by ruleStatus alone.

{:else if verified === false}
<Badge variant="secondary" type="warning" size="xs" content="Verification failed" />
{/if}
</Layout.Stack>
<Typography.Text variant="m-400">
Expand Down
120 changes: 98 additions & 22 deletions src/lib/components/domains/recordTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,58 @@
Alert
} from '@appwrite.io/pink-svelte';
import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store';
import { isCloud } from '$lib/system';
import { getSubdomain } from '$lib/helpers/tlds';

export let domain: string;
export let verified = undefined;
export let variant: 'cname' | 'a' | 'aaaa';
export let service: 'sites' | 'general' = 'general';
let {
domain,
verified = undefined,
variant,
service = 'general',
ruleStatus = undefined,
onNavigateToNameservers = () => {},
onNavigateToA = () => {},
onNavigateToAAAA = () => {}
}: {
domain: string;
verified?: boolean | undefined;
variant: 'cname' | 'a' | 'aaaa';
service?: 'sites' | 'functions' | 'general';
ruleStatus?: string | undefined;
onNavigateToNameservers?: () => void;
onNavigateToA?: () => void;
onNavigateToAAAA?: () => void;
} = $props();

let subdomain = domain?.split('.')?.slice(0, -2)?.join('.');
const subdomain = $derived(getSubdomain(domain));

const aTabVisible = $derived(
!isCloud &&
Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) &&
$regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'
);
const aaaaTabVisible = $derived(
!isCloud &&
Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) &&
$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'
);
Comment on lines +35 to +46
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Guard store access with optional chaining.

Avoid potential runtime errors if regionalConsoleVariables is not yet available.

-    const subdomain = $derived(getSubdomain(domain));
+    const subdomain = $derived(getSubdomain(domain));

-    const aTabVisible = $derived(
-        !isCloud &&
-            Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) &&
-            $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'
-    );
-    const aaaaTabVisible = $derived(
-        !isCloud &&
-            Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) &&
-            $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'
-    );
+    const aTabVisible = $derived(
+        !isCloud &&
+            Boolean($regionalConsoleVariables?._APP_DOMAIN_TARGET_A) &&
+            $regionalConsoleVariables?._APP_DOMAIN_TARGET_A !== '127.0.0.1'
+    );
+    const aaaaTabVisible = $derived(
+        !isCloud &&
+            Boolean($regionalConsoleVariables?._APP_DOMAIN_TARGET_AAAA) &&
+            $regionalConsoleVariables?._APP_DOMAIN_TARGET_AAAA !== '::1'
+    );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const subdomain = $derived(getSubdomain(domain));
const aTabVisible = $derived(
!isCloud &&
Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_A) &&
$regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'
);
const aaaaTabVisible = $derived(
!isCloud &&
Boolean($regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) &&
$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'
);
const subdomain = $derived(getSubdomain(domain));
const aTabVisible = $derived(
!isCloud &&
Boolean($regionalConsoleVariables?._APP_DOMAIN_TARGET_A) &&
$regionalConsoleVariables?._APP_DOMAIN_TARGET_A !== '127.0.0.1'
);
const aaaaTabVisible = $derived(
!isCloud &&
Boolean($regionalConsoleVariables?._APP_DOMAIN_TARGET_AAAA) &&
$regionalConsoleVariables?._APP_DOMAIN_TARGET_AAAA !== '::1'
);
🤖 Prompt for AI Agents
In src/lib/components/domains/recordTable.svelte around lines 35 to 46, accesses
to regionalConsoleVariables are unguarded and may throw if the store value is
undefined; update the expressions to use optional chaining (e.g.,
$regionalConsoleVariables?._APP_DOMAIN_TARGET_A and
$regionalConsoleVariables?._APP_DOMAIN_TARGET_AAAA) and ensure Boolean checks
handle undefined safely so the derived values compute only when
regionalConsoleVariables is present.


const caaText = $derived(
$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA?.includes(' ')
? $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA
: `0 issue "${$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}"`
);

function setTarget() {
switch (variant) {
case 'cname':
return service === 'general'
? $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME
: $regionalConsoleVariables._APP_DOMAIN_SITES;
if (service === 'sites') {
return $regionalConsoleVariables._APP_DOMAIN_SITES;
} else if (service === 'functions') {
return $regionalConsoleVariables._APP_DOMAIN_FUNCTIONS;
} else {
return $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME;
}
case 'a':
return $regionalConsoleVariables._APP_DOMAIN_TARGET_A;
case 'aaaa':
Expand All @@ -37,15 +75,25 @@
<Typography.Text variant="l-500" color="--fgcolor-neutral-primary">
{domain}
</Typography.Text>
{#if verified === true}
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
Comment on lines +78 to +81
Copy link
Member

Choose a reason for hiding this comment

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

same as above

{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{:else if verified === false}
<Badge variant="secondary" type="warning" size="xs" content="Verification failed" />
{/if}
Comment on lines +78 to 90
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle ruleStatus === 'verified'.

Render success badge when status is verified even if verified flag isn’t true.

-            {:else if ruleStatus === 'unverified'}
+            {:else if ruleStatus === 'unverified'}
                 <Badge
                     variant="secondary"
                     type="error"
                     size="xs"
                     content="Certificate generation failed" />
-            {:else if verified === true}
+            {:else if ruleStatus === 'verified' || verified === true}
                 <Badge variant="secondary" type="success" size="xs" content="Verified" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{:else if verified === false}
<Badge variant="secondary" type="warning" size="xs" content="Verification failed" />
{/if}
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
{:else if ruleStatus === 'verified' || verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{/if}
🤖 Prompt for AI Agents
In src/lib/components/domains/recordTable.svelte around lines 74 to 86, the
template currently only renders the "Verified" success badge when the verified
flag is true, but the review requests handling ruleStatus === 'verified' too;
update the conditional so the success badge is shown when ruleStatus ===
'verified' OR verified === true (either by adding an else if branch for
ruleStatus === 'verified' before the final check, or by changing the final
condition to check ruleStatus === 'verified' || verified === true), ensuring the
"Verified" Badge renders for the 'verified' status even if the verified boolean
is false.

</Layout.Stack>
<Typography.Text variant="m-400">
Add the following record on your DNS provider. Note that DNS changes may take time to
propagate fully.
Add the following {$regionalConsoleVariables._APP_DOMAIN_TARGET_CAA
? 'records'
: 'record'} on your DNS provider. Note that DNS changes may take up to 48 hours to propagate
fully.
</Typography.Text>
</Layout.Stack>

Expand All @@ -62,17 +110,45 @@
<InteractiveText variant="copy" isVisible text={setTarget()} />
</Table.Cell>
</Table.Row.Base>
{#if $regionalConsoleVariables._APP_DOMAIN_TARGET_CAA}
<Table.Row.Base {root}>
<Table.Cell {root}>
<Layout.Stack gap="s" direction="row" alignItems="center">
<span>CAA</span>
<Badge variant="secondary" size="xs" content="Recommended" />
</Layout.Stack>
</Table.Cell>
<Table.Cell {root}>@</Table.Cell>
<Table.Cell {root}>
<InteractiveText variant="copy" isVisible text={caaText} />
</Table.Cell>
</Table.Row.Base>
{/if}
</Table.Root>
<Layout.Stack gap="s" direction="row" alignItems="center">
{#if variant === 'cname'}
<Alert.Inline>
If your domain uses CAA records, ensure certainly.com is authorized — otherwise, SSL
setup may fail. A list of all domain providers and their DNS setting is available <Link
variant="muted"
external
href="https://appwrite.io/docs/advanced/platform/custom-domains">here</Link
>.
</Alert.Inline>
{#if variant === 'cname' && !subdomain}
{#if isCloud}
<Alert.Inline>
Since <Badge variant="secondary" size="s" content={domain} /> is an apex domain,
CNAME record is only supported by certain providers. If yours doesn't, please verify
using
<Link variant="muted" on:click={onNavigateToNameservers}>nameservers</Link> instead.
</Alert.Inline>
{:else if aTabVisible || aaaaTabVisible}
<Alert.Inline>
Since <Badge variant="secondary" size="s" content={domain} /> is an apex domain,
CNAME record is only supported by certain providers. If yours doesn't, please verify
using
{#if aTabVisible}
<Link variant="muted" on:click={onNavigateToA}>A record</Link>
{#if aaaaTabVisible}
or <Link variant="muted" on:click={onNavigateToAAAA}>AAAA record</Link
>{/if}
{:else if aaaaTabVisible}
<Link variant="muted" on:click={onNavigateToAAAA}>AAAA record</Link>
{/if} instead.
</Alert.Inline>
{/if}
Comment on lines +129 to +151
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Migrate event handlers to Svelte 5 syntax.

Use onclick instead of on:click. This aligns with project-wide Svelte 5 migration. Based on learnings

-                    <Link variant="muted" on:click={onNavigateToNameservers}>nameservers</Link> instead.
+                    <Link variant="muted" onclick={onNavigateToNameservers}>nameservers</Link> instead.
...
-                        <Link variant="muted" on:click={onNavigateToA}>A record</Link>
+                        <Link variant="muted" onclick={onNavigateToA}>A record</Link>
-                            or <Link variant="muted" on:click={onNavigateToAAAA}>AAAA record</Link
+                            or <Link variant="muted" onclick={onNavigateToAAAA}>AAAA record</Link
                             >{/if}
-                    {:else if aaaaTabVisible}
-                        <Link variant="muted" on:click={onNavigateToAAAA}>AAAA record</Link>
+                    {:else if aaaaTabVisible}
+                        <Link variant="muted" onclick={onNavigateToAAAA}>AAAA record</Link>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{#if variant === 'cname' && !subdomain}
{#if isCloud}
<Alert.Inline>
Since <Badge variant="secondary" size="s" content={domain} /> is an apex domain,
CNAME record is only supported by certain providers. If yours doesn't, please verify
using
<Link variant="muted" on:click={onNavigateToNameservers}>nameservers</Link> instead.
</Alert.Inline>
{:else if aTabVisible || aaaaTabVisible}
<Alert.Inline>
Since <Badge variant="secondary" size="s" content={domain} /> is an apex domain,
CNAME record is only supported by certain providers. If yours doesn't, please verify
using
{#if aTabVisible}
<Link variant="muted" on:click={onNavigateToA}>A record</Link>
{#if aaaaTabVisible}
or <Link variant="muted" on:click={onNavigateToAAAA}>AAAA record</Link
>{/if}
{:else if aaaaTabVisible}
<Link variant="muted" on:click={onNavigateToAAAA}>AAAA record</Link>
{/if} instead.
</Alert.Inline>
{/if}
{#if variant === 'cname' && !subdomain}
{#if isCloud}
<Alert.Inline>
Since <Badge variant="secondary" size="s" content={domain} /> is an apex domain,
CNAME record is only supported by certain providers. If yours doesn't, please verify
using
<Link variant="muted" onclick={onNavigateToNameservers}>nameservers</Link> instead.
</Alert.Inline>
{:else if aTabVisible || aaaaTabVisible}
<Alert.Inline>
Since <Badge variant="secondary" size="s" content={domain} /> is an apex domain,
CNAME record is only supported by certain providers. If yours doesn't, please verify
using
{#if aTabVisible}
<Link variant="muted" onclick={onNavigateToA}>A record</Link>
{#if aaaaTabVisible}
or <Link variant="muted" onclick={onNavigateToAAAA}>AAAA record</Link
>{/if}
{:else if aaaaTabVisible}
<Link variant="muted" onclick={onNavigateToAAAA}>AAAA record</Link>
{/if} instead.
</Alert.Inline>
{/if}
🤖 Prompt for AI Agents
In src/lib/components/domains/recordTable.svelte around lines 123 to 145, the
event handlers use the Svelte 3 "on:click" syntax; migrate them to Svelte 5 by
replacing on:click={...} with the onclick={...} prop on the Link components
(apply to onNavigateToNameservers, onNavigateToA, and onNavigateToAAAA),
ensuring no other behavior changes and preserving existing casing and props.

{:else}
<Typography.Text variant="m-400" color="--fgcolor-neutral-secondary">
A list of all domain providers and their DNS setting is available <Link
Expand Down
1 change: 1 addition & 0 deletions src/lib/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@ export { default as RegionEndpoint } from './regionEndpoint.svelte';
export { default as ExpirationInput } from './expirationInput.svelte';
export { default as EstimatedCard } from './estimatedCard.svelte';
export { default as SortButton, type SortDirection } from './sortButton.svelte';
export * from './domains';
export { default as SendVerificationEmailModal } from './account/sendVerificationEmailModal.svelte';
15 changes: 15 additions & 0 deletions src/lib/helpers/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,21 @@ export function timeFromNow(datetime: string): string {
return dayjs().to(dayjs(datetime));
}

export function timeFromNowShort(datetime: string): string {
if (!datetime) {
return 'unknown time';
}
if (!isValidDate(datetime)) {
return 'invalid date';
}

const timeStr = dayjs().to(dayjs(datetime));
return timeStr
.replace('second', 'sec') // seconds > secs
.replace('minute', 'min') // minutes > mins
.replace('hour', 'hr'); // hours > hrs
}

export function hoursToDays(hours: number) {
if (hours > 24) {
return `${Math.floor(hours / 24)} days`;
Expand Down
13 changes: 11 additions & 2 deletions src/lib/helpers/tlds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { parse } from 'tldts';
* Returns the apex/root domain from a full domain string.
*/
export function getApexDomain(domain: string): string | null {
return parse(domain).domain;
return parse(domain, { allowPrivateDomains: true }).domain;
}

/**
Expand All @@ -13,8 +13,17 @@ export function getApexDomain(domain: string): string | null {
export function isASubdomain(domain: string | null): boolean {
if (!domain) return false;

const { domain: apex, subdomain } = parse(domain);
const { domain: apex, subdomain } = parse(domain, { allowPrivateDomains: true });
if (!apex) return false;

return !!subdomain;
}

/**
* Returns the subdomain part from a full domain string.
*/
export function getSubdomain(domain: string): string {
if (!domain) return '';

return parse(domain, { allowPrivateDomains: true }).subdomain || '';
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
Navigate to your domain provider and update the nameservers to <InlineCode
code="ns1.appwrite-dns.com"
size="s" /> and <InlineCode code="ns2.appwrite-dns.com" size="s" />.
Note that DNS changes may take time to propagate fully.
Note that DNS changes may take up to 48 hours to propagate fully.
</span>
<svelte:fragment slot="actions">
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script lang="ts">
import { onMount } from 'svelte';
import { page } from '$app/state';
import { realtime } from '$lib/stores/sdk';
import { Dependencies } from '$lib/constants';
import { invalidate } from '$app/navigation';
onMount(() => {
return realtime
.forProject(page.params.region, page.params.project)
.subscribe('console', (response) => {
if (
response.events.includes('proxy.rules.*.update') ||
response.events.includes('proxy.rules.*.create') ||
response.events.includes('proxy.rules.*.delete')
) {
if ((response.payload as any)?.deploymentResourceId === page.params.function) {

Check failure on line 17 in src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/+layout.svelte

View workflow job for this annotation

GitHub Actions / build

Unexpected any. Specify a different type
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Replace any with a specific type.

The explicit any cast bypasses type safety. Define an interface or use the appropriate type from the SDK.

Apply this diff to add type safety:

+    interface ProxyRulePayload {
+        deploymentResourceId?: string;
+        [key: string]: unknown;
+    }
+
     onMount(() => {
         return realtime
             .forProject(page.params.region, page.params.project)
             .subscribe('console', (response) => {
                 if (
                     response.events.includes('proxy.rules.*.update') ||
                     response.events.includes('proxy.rules.*.create') ||
                     response.events.includes('proxy.rules.*.delete')
                 ) {
-                    if ((response.payload as any)?.deploymentResourceId === page.params.function) {
+                    if ((response.payload as ProxyRulePayload)?.deploymentResourceId === page.params.function) {
                         invalidate(Dependencies.FUNCTION_DOMAINS);
                     }
                 }
             });
     });

As per static analysis.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ((response.payload as any)?.deploymentResourceId === page.params.function) {
<script lang="ts">
import { onMount } from 'svelte';
import { realtime, Dependencies } from '$lib/stores/sdk';
interface ProxyRulePayload {
deploymentResourceId?: string;
[key: string]: unknown;
}
onMount(() => {
return realtime
.forProject(page.params.region, page.params.project)
.subscribe('console', (response) => {
if (
response.events.includes('proxy.rules.*.update') ||
response.events.includes('proxy.rules.*.create') ||
response.events.includes('proxy.rules.*.delete')
) {
if ((response.payload as ProxyRulePayload)?.deploymentResourceId === page.params.function) {
invalidate(Dependencies.FUNCTION_DOMAINS);
}
}
});
});
</script>
🧰 Tools
🪛 ESLint

[error] 17-17: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🪛 GitHub Check: build

[failure] 17-17:
Unexpected any. Specify a different type

🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/+layout.svelte
around line 17, the code casts response.payload to any when checking
deploymentResourceId; replace the any with a concrete type by importing or
declaring an interface that includes deploymentResourceId (and any other used
fields) or use the SDK's payload type if available, then cast response.payload
to that type or narrow it with a type guard before the comparison so the check
becomes typesafe and avoids using any.

invalidate(Dependencies.FUNCTION_DOMAINS);
}
}
});
});
</script>

<slot />
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const load: PageLoad = async ({ depends, params, url, route, parent }) =>
Query.equal('trigger', RuleTrigger.MANUAL),
Query.limit(limit),
Query.offset(offset),
Query.orderDesc(''),
Query.orderDesc('$updatedAt'),
...parsedQueries.values()
],
search: search || undefined
Expand Down
Loading
Loading