-
Notifications
You must be signed in to change notification settings - Fork 187
SER-287 Add new badges to site domains #2364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
ConsoleProject ID: Sites (2)
Note You can use Avatars API to generate QR code for any text or URLs. |
WalkthroughAdds a new exported helper Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal). Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte (1)
41-41
: Fix type: selectedProxyRule should allow null.Prevents a TS error with the initial null assignment.
-let selectedProxyRule: Models.ProxyRule = $state(null); +let selectedProxyRule: Models.ProxyRule | null = $state(null);
🧹 Nitpick comments (4)
src/lib/helpers/date.ts (1)
209-227
: Make unit-shortening locale-agnostic and handle future times; dedupe validation.Current string replaces miss “in x minutes/seconds/hours” and depend on English phrasing; also duplicates validation from timeFromNow. Replace with regex-based unit swaps and reuse timeFromNow.
-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(' seconds ago', ' secs ago') - .replace(' second ago', ' sec ago') - .replace(' minutes ago', ' mins ago') - .replace(' minute ago', ' min ago') - .replace(' hours ago', ' hrs ago') - .replace(' hour ago', ' hr ago') - .replace(' days ago', ' days ago') - .replace(' day ago', ' day ago'); -} +export function timeFromNowShort(datetime: string): string { + const base = timeFromNow(datetime); + if (base === 'unknown time' || base === 'invalid date') return base; + return base + .replace(/\bseconds\b/g, 'secs') + .replace(/\bsecond\b/g, 'sec') + .replace(/\bminutes\b/g, 'mins') + .replace(/\bminute\b/g, 'min') + .replace(/\bhours\b/g, 'hrs') + .replace(/\bhour\b/g, 'hr'); +}Note: if the app ever localizes dayjs relativeTime, these swaps should be disabled or made locale-aware.
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte (3)
93-108
: Gate “View logs” by rule.logs to avoid empty modal.Row UI always shows “View logs”, while the action menu hides it when logs are absent. Make them consistent.
- <Link - size="s" - on:click={(e) => { - e.preventDefault(); - selectedProxyRule = rule; - showLogs = true; - }}> - View logs - </Link> + {#if rule.logs} + <Link + size="s" + on:click={(e) => { + e.preventDefault(); + selectedProxyRule = rule; + showLogs = true; + }}> + View logs + </Link> + {/if}
110-125
: Apply the same logs gating for the unverified branch.Mirror the condition used in the action menu.
- <Link - size="s" - on:click={(e) => { - e.preventDefault(); - selectedProxyRule = rule; - showLogs = true; - }}> - View logs - </Link> + {#if rule.logs} + <Link + size="s" + on:click={(e) => { + e.preventDefault(); + selectedProxyRule = rule; + showLogs = true; + }}> + View logs + </Link> + {/if}
130-145
: Avoid inline styles; use a class for the updated-time text.Keeps styling consistent and easier to theme.
- <Typography.Text - variant="m-400" - color="--fgcolor-neutral-tertiary" - style="font-size: 0.875rem;"> + <Typography.Text + variant="m-400" + color="--fgcolor-neutral-tertiary" + class="updated-cell">Add to the file’s <style>:
.updated-cell { font-size: 0.875rem; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/lib/helpers/date.ts
(1 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts
(1 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte
(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: e2e
🔇 Additional comments (3)
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts (1)
20-25
: Add a visible, accessible header: "Updated".Blank headers harm accessibility and sorting; set the title and confirm whether this column should be sortable. Apply:
- title: '', + title: 'Updated',Also confirm whether this column should be sortable; if not, set the appropriate flag on Column to prevent confusing sort UI (depends on your Column type).
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte (2)
28-28
: LGTM: import of timeFromNowShort.
76-92
: Confirm status mapping: created → “Verification failed”.“created” typically reads as an initial state; showing “Verification failed” might be misleading. Verify backend status semantics before shipping the copy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte (1)
33-35
: Type mismatch: initializing string state withnull
.
let redirect: string = $state(null);
(andbranch
) violates the declared type.-let redirect: string = $state(null); -let branch: string = $state(null); +let redirect = $state(''); // or: let redirect: string | null = $state(null); +let branch = $state(''); // or: let branch: string | null = $state(null);src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte (1)
41-41
: Type: allow null in reactive state.
$state(null)
conflicts withModels.ProxyRule
type. Use a union to avoid TS errors under strict mode.-let selectedProxyRule: Models.ProxyRule = $state(null); +let selectedProxyRule: Models.ProxyRule | null = $state(null);
🧹 Nitpick comments (17)
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte (2)
55-58
: Use locale‑independent lowercasing for domains.
toLocaleLowerCase()
can miscase in some locales (e.g., Turkish). UsetoLowerCase()
for DNS labels.- .proxy.createAPIRule({ domain: domainName.toLocaleLowerCase() }); + .proxy.createAPIRule({ domain: domainName.toLowerCase() });
62-70
: URL‑encode dynamic path/query parts in redirect.Safer when domains include wildcards or unusual chars; also encode
rule.$id
.- let redirect = `${routeBase}/add-domain/verify-${domainName}?rule=${rule.$id}`; + const encodedDomain = encodeURIComponent(domainName); + let redirect = `${routeBase}/add-domain/verify-${encodedDomain}?rule=${encodeURIComponent(rule.$id)}`;src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte (2)
104-111
: Encode redirect URL and avoid shadowingredirect
state.The local
redirect
string shadows the boundredirect
field and the domain/rule aren’t encoded. Rename and encode.- let redirect = `${routeBase}/add-domain/verify-${domainName}?rule=${rule.$id}`; + const encodedDomain = encodeURIComponent(domainName); + let verificationUrl = `${routeBase}/add-domain/verify-${encodedDomain}?rule=${encodeURIComponent(rule.$id)}`; - if (isCloud && domain?.$id) { - redirect += `&domain=${domain.$id}`; - } + if (isCloud && domain?.$id) { + verificationUrl += `&domain=${domain.$id}`; + } - await goto(redirect); + await goto(verificationUrl);
78-99
: Normalize domain before rule creation.For consistency and to avoid case‑sensitive mismatches, lower‑case the domain in all create calls.
- domain: domainName, + domain: domainName.toLowerCase(), @@ - domain: domainName, + domain: domainName.toLowerCase(), @@ - domain: domainName, + domain: domainName.toLowerCase(),src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/store.ts (1)
20-25
: Add an accessible header for the Updated column.Empty titles can hurt a11y. Prefer a visible or visually‑hidden label.
- title: '', + title: 'Updated',src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte (3)
93-107
: Gate “View logs” links on log availability (matches action menu logic).Action menu checks
proxyRule.logs
, but inline links don’t. Avoid opening an empty modal.- {:else if proxyRule.status === 'verifying'} + {:else if proxyRule.status === 'verifying' && proxyRule.logs} @@ - {:else if proxyRule.status === 'unverified'} + {:else if proxyRule.status === 'unverified' && proxyRule.logs}Also applies to: 109-124
83-91
: A11y: interactive “Link” without href.Provide
href="#"
(with preventDefault) or switch to a button‑styled component to maintain semantics.- <Link + <Link href="#" size="s" on:click={(e) => { e.preventDefault(); selectedProxyRule = proxyRule; showRetry = true; }}> @@ - <Link + <Link href="#" size="s" on:click={(e) => { e.preventDefault(); selectedProxyRule = proxyRule; showLogs = true; }}> @@ - <Link + <Link href="#" size="s" on:click={(e) => { e.preventDefault(); selectedProxyRule = proxyRule; showLogs = true; }}>Also applies to: 100-107, 116-124
27-29
: Prefer importing DnsRecordsAction from the barrel for consistency.Minor consistency tweak with
ViewLogsModal
import.-import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte'; +import { DnsRecordsAction } from '$lib/components';src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte (3)
85-91
: Instrument “Retry” and “View logs” clicks for analytics.Deletion is tracked; these new actions aren’t. Add tracking for observability.
Example:
selectedProxyRule = rule; showRetry = true; +trackEvent(Click.DomainRetryClick, { source: 'sites_domain_overview' });
selectedProxyRule = rule; showLogs = true; +trackEvent(Click.DomainViewLogsClick, { source: 'sites_domain_overview' });
Also applies to: 101-107, 117-124
153-165
: Icon‑only button needs an accessible name.Add
aria-label
(and optionallytitle
) to the kebab menu trigger for screen readers.-<Button +<Button text icon + aria-label="More actions" + title="More actions" on:click={(e) => {
130-146
: Guard rule.$updatedAt (handle nullish dates); 'updated' column confirmed
- Confirmed: columns store includes { id: 'updated' } — src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts.
- Action: avoid "Invalid date" by rendering only when rule.$updatedAt is present. Suggested tweak:
-{#if rule.status !== 'verified'} +{#if rule.status !== 'verified' && rule.$updatedAt} ... - {#if rule.status === 'created'} + {#if rule.status === 'created'} Checked {timeFromNowShort(rule.$updatedAt)}src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte — apply change around the existing updated column render.
src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte (6)
48-55
: Columns: width and updated column—OK; add sortability if desired.If users sort by "updated", consider wiring sort metadata.
134-149
: Updated column: add nullish guard.Prevent rendering when
domain.$updatedAt
is falsy to avoid bad output.-{#if domain.status !== 'verified'} +{#if domain.status !== 'verified' && domain.$updatedAt}
169-178
: Action menu logs gating: good; also add analytics.Track "View logs" selections for parity with delete.
selectedDomain = domain; showLogs = true; toggle(e); +trackEvent(Click.DomainViewLogsClick, { source: 'settings_domain_overview' });
180-190
: Retry action: add analytics.selectedDomain = domain; showRetry = true; toggle(e); +trackEvent(Click.DomainRetryClick, { source: 'settings_domain_overview' });
231-235
: CSS nit: align divider styles across pages.Sites table also adds vertical padding; consider keeping styles consistent.
.action-menu-divider { - margin-inline: -1rem; + margin-inline: -1rem; + padding-block-start: 0.25rem; + padding-block-end: 0.25rem; }
156-165
: Add accessible name to kebab button.Icon‑only button needs an
aria-label
(andtitle
) for SR users.-<Button +<Button text icon + aria-label="More actions" + title="More actions" on:click={(e) => {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/lib/components/domains/index.ts
(1 hunks)src/lib/components/index.ts
(1 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte
(1 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/store.ts
(1 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte
(7 hunks)src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte
(1 hunks)src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte
(8 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts
(1 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/store.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: e2e
🔇 Additional comments (14)
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte (1)
64-70
: Good guard on appending domain param only when present.The added
isCloud && domain?.$id
check prevents bogus&domain=
query strings. LGTM.src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/store.ts (1)
10-11
: Wider domain column looks right.The increased min width improves readability for long hostnames.
src/lib/components/index.ts (1)
90-90
: Barrel re‑export added.Makes domain components available via
$lib/components
. Ensure no name collisions with existing exports.src/lib/components/domains/index.ts (1)
1-5
: Barrel for domain components looks good.Straightforward re‑exports; helps consumers consolidate imports.
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/table.svelte (3)
6-16
: Imports: OK.Added
IconTerminal
,Divider
,ViewLogsModal
, andtimeFromNowShort
are appropriate for the new UI.
75-125
: Confirm backend→UI status mapping.You’re rendering:
- created → “Verification failed” + Retry
- verifying → “Generating certificate” + View logs
- unverified → “Certificate generation failed” + View logs
Please confirm these labels align with server semantics so we don’t show “failed” on initial create.
129-146
: Updated column rendering looks solid.Clear, concise relative times via
timeFromNowShort
. Good right‑alignment for visual scanning.src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte (5)
6-11
: LGTM on icon imports.
39-39
: State for logs modal: OK.No issues spotted.
27-27
: timeFromNowShort import/use looks good. Returns 'unknown time' for falsy input and 'invalid date' when isValidDate(datetime) fails — no changes required.
24-24
: Verified: ViewLogsModal is exported as a named export.Found in src/lib/components/domains/index.ts:
export { default as ViewLogsModal } from './viewLogsModal.svelte';
226-229
: Prop name & type confirmed — no change required.src/lib/components/domains/viewLogsModal.svelte exports selectedProxyRule: Models.ProxyRule and uses selectedProxyRule.logs; passing selectedProxyRule={selectedDomain} is correct.
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte (2)
24-24
: ViewLogsModal correctly re-exported.
Confirmed in src/lib/components/domains/index.ts:export { default as ViewLogsModal } from './viewLogsModal.svelte';
76-126
: Align status copy, gate "View logs", and prefer Button for actionsFile: src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/table.svelte Lines: 76-126
- 'created' currently renders "Verification failed" — if
created
means "not verified yet"/pending, change the copy:- content="Verification failed" + content="Verification pending"
- Gate inline "View logs" the same way the ActionMenu does (only show when
rule.logs
):- <Link + {#if rule.logs} + <Link size="s" on:click={(e) => { e.preventDefault(); selectedProxyRule = rule; showLogs = true; }}> - View logs - </Link> + View logs + </Link> + {/if}
- Actions look like buttons. If
Link
renders an anchor, prefer a Button (text) for a11y or add appropriate role/aria attributes:-<Link size="s" on:click={...}>Retry</Link> +<Button text size="s" on:click={...} aria-label="Retry verification">Retry</Button>
@@ -28,6 +36,7 @@ | |||
|
|||
let showDelete = $state(false); | |||
let showRetry = $state(false); | |||
let showLogs = $state(false); | |||
let selectedDomain: Models.ProxyRule = $state(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type: allow null in reactive state.
Same as sites table; fix union type.
-let selectedDomain: Models.ProxyRule = $state(null);
+let selectedDomain: Models.ProxyRule | null = $state(null);
📝 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.
let selectedDomain: Models.ProxyRule = $state(null); | |
let selectedDomain: Models.ProxyRule | null = $state(null); |
🤖 Prompt for AI Agents
In src/routes/(console)/project-[region]-[project]/settings/domains/table.svelte
around line 40, the reactive state variable selectedDomain is typed as
Models.ProxyRule but initialized to null; update its type to a union allowing
null (Models.ProxyRule | null) so the compiler and runtime accept the initial
null value and adjust any downstream usage to handle the null case as needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a big thing but makes sense @vermakhushboo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
{#if domain.status === 'created'} | ||
<Layout.Stack direction="row" gap="xs" alignItems="center"> | ||
<Badge | ||
variant="secondary" | ||
type="error" | ||
content="Verification failed" | ||
size="xs" /> | ||
<Link | ||
size="s" | ||
on:click={(e) => { | ||
e.preventDefault(); | ||
selectedDomain = domain; | ||
showRetry = true; | ||
}}> | ||
Retry | ||
</Link> | ||
</Layout.Stack> | ||
{:else if domain.status === 'verifying'} | ||
<Layout.Stack direction="row" gap="xs" alignItems="center"> | ||
<Badge | ||
variant="secondary" | ||
content="Generating certificate" | ||
size="xs" /> | ||
<Link | ||
size="s" | ||
on:click={(e) => { | ||
e.preventDefault(); | ||
selectedDomain = domain; | ||
showLogs = true; | ||
}}> | ||
View logs | ||
</Link> | ||
</Layout.Stack> | ||
{:else if domain.status === 'unverified'} | ||
<Layout.Stack direction="row" gap="xs" alignItems="center"> | ||
<Badge | ||
variant="secondary" | ||
type="error" | ||
content="Certificate generation failed" | ||
size="xs" /> | ||
<Link | ||
size="s" | ||
on:click={(e) => { | ||
e.preventDefault(); | ||
selectedDomain = domain; | ||
showLogs = true; | ||
}}> | ||
View logs | ||
</Link> | ||
</Layout.Stack> | ||
{/if} | ||
</Layout.Stack> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Status mapping, logs gating, and a11y: mirror fixes from sites table.
- "Verification failed" for
domain.status === 'created'
is likely incorrect—please confirm and fix copy. - Gate inline "View logs" on
domain.logs
(or make modal handle empty state). - Prefer Button (text) for action triggers, or add appropriate aria attributes to Link if it renders as anchor without href.
Apply analogous diffs as suggested in the sites table for these blocks.
@@ -15,8 +21,10 @@ | |||
} from '@appwrite.io/pink-svelte'; | |||
import DeleteDomainModal from './deleteDomainModal.svelte'; | |||
import RetryDomainModal from './retryDomainModal.svelte'; | |||
import { ViewLogsModal } from '$lib/components'; | |||
import { regionalProtocol } from '../../store'; | |||
import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't components/domains
have a barrel file now? index.ts
which is also exported via parent index.ts
?
@@ -28,6 +36,7 @@ | |||
|
|||
let showDelete = $state(false); | |||
let showRetry = $state(false); | |||
let showLogs = $state(false); | |||
let selectedDomain: Models.ProxyRule = $state(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a big thing but makes sense @vermakhushboo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/lib/components/domains/recordTable.svelte (1)
76-85
: Replace hard‑coded CA vendor with Let's Encrypt (or neutral copy)File: src/lib/components/domains/recordTable.svelte (lines 76–85) — replace the Alert copy so it references Let's Encrypt (letsencrypt.org) for Appwrite‑managed TLS, or use vendor‑neutral text ("the certificate authority used by Appwrite"). Keep the existing Link to the custom‑domains docs.
Search for other occurrences before committing:
rg -n -C2 -i 'certainly\.com|caa|letsencrypt|sectigo|digicert' src || truesrc/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte (1)
128-131
:isSubmitting
is not bound; submit button won’t reflect submission state.Use two‑way binding like other pages to prevent double submits and align UX.
- <Form onSubmit={verify} {isSubmitting}> + <Form onSubmit={verify} bind:isSubmitting>
🧹 Nitpick comments (38)
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts (3)
10-13
: Return a 400 using SvelteKit’s error helper instead of throwing a generic ErrorImproves status codes and error handling paths.
Apply:
- if (!ruleId) { - throw new Error('Rule ID is required'); - } + if (!ruleId) { + throw error(400, 'Rule ID is required'); + }Add import (outside this hunk):
import { error } from '@sveltejs/kit';
6-6
: Type the loader with PageLoad for stricter inference and safer data typingLocks the return shape into route $types and catches regressions.
Apply:
-export const load = async ({ params, parent, depends, url }) => { +export const load: PageLoad = async ({ params, parent, depends, url }) => {Add import (outside this hunk):
import type { PageLoad } from './$types';
16-22
: Optional: fetch in parallel to shave latency
domains.list
andproxy.getRule
are independent; run concurrently.One way:
const proxyRulePromise = sdk.forProject(params.region, params.project).proxy.getRule({ ruleId }); const domainsListPromise: Promise<Models.DomainsList | undefined> = isCloud ? sdk.forConsole.domains.list({ queries: [Query.equal('teamId', organization.$id)] }) : Promise.resolve(undefined); const [proxyRule, domainsList] = await Promise.all([proxyRulePromise, domainsListPromise]);src/lib/components/domains/cnameTable.svelte (3)
15-16
: NarrowruleStatus
type and include explicit'verified'
branch.Use a string‑literal union to prevent typos and handle the
'verified'
state directly (today it depends onverified === true
only).Apply:
-export let verified: boolean | undefined = undefined; -export let ruleStatus: string | undefined = undefined; +type RuleStatus = 'created' | 'verifying' | 'verified' | 'unverified'; +export let verified: boolean | undefined = undefined; +export let ruleStatus: RuleStatus | undefined = undefined;
27-39
: Status-to-badge mapping likely inverted; add a pending state and treat'unverified'
as verification failure.Current copy shows “Verification failed” for
'created'
. Suggest:
'verified'
→ “Verified”'verifying'
→ “Generating certificate”'unverified'
→ “Verification failed”'created'
→ “Awaiting verification” (or similar)Apply:
-{#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} +{#if ruleStatus === 'verified' || verified === true} <Badge variant="secondary" type="success" size="xs" content="Verified" /> +{:else if ruleStatus === 'verifying'} + <Badge variant="secondary" size="xs" content="Generating certificate" /> +{:else if ruleStatus === 'unverified'} + <Badge variant="secondary" type="error" size="xs" content="Verification failed" /> +{:else if ruleStatus === 'created'} + <Badge variant="secondary" size="xs" content="Awaiting verification" /> {/if}
55-56
: Show “@” for apex domains.
subdomain
is empty for apex records; render “@” for clarity (as done in recordTable).Apply:
-<Table.Cell {root}>{subdomain}</Table.Cell> +<Table.Cell {root}>{subdomain || '@'}</Table.Cell>src/lib/components/domains/nameserverTable.svelte (2)
7-8
: ConstrainruleStatus
to known values.Prevents accidental strings and aligns with other components.
Apply:
-export let verified: boolean | undefined = undefined; -export let ruleStatus: string | undefined = undefined; +type RuleStatus = 'created' | 'verifying' | 'verified' | 'unverified'; +export let verified: boolean | undefined = undefined; +export let ruleStatus: RuleStatus | undefined = undefined;
20-31
: Align badge copy with lifecycle and include'verified'
.Same mapping suggestion as cnameTable.
Apply:
-{#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} +{#if ruleStatus === 'verified' || verified === true} <Badge variant="secondary" type="success" size="xs" content="Verified" /> +{:else if ruleStatus === 'verifying'} + <Badge variant="secondary" size="xs" content="Generating certificate" /> +{:else if ruleStatus === 'unverified'} + <Badge variant="secondary" type="error" size="xs" content="Verification failed" /> +{:else if ruleStatus === 'created'} + <Badge variant="secondary" size="xs" content="Awaiting verification" /> {/if}src/lib/components/domains/recordTable.svelte (2)
14-18
: Type safety forruleStatus
.Use a union and keep
variant
consistent.Apply:
-export let verified: boolean | undefined = undefined; +export let verified: boolean | undefined = undefined; export let variant: 'cname' | 'a' | 'aaaa'; export let service: 'sites' | 'general' = 'general'; -export let ruleStatus: string | undefined = undefined; +type RuleStatus = 'created' | 'verifying' | 'verified' | 'unverified'; +export let ruleStatus: RuleStatus | undefined = undefined;
41-53
: Fix status mapping and include'verified'
.Mirror the same lifecycle mapping used across components.
Apply:
-{#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} +{#if ruleStatus === 'verified' || verified === true} <Badge variant="secondary" type="success" size="xs" content="Verified" /> +{:else if ruleStatus === 'verifying'} + <Badge variant="secondary" size="xs" content="Generating certificate" /> +{:else if ruleStatus === 'unverified'} + <Badge variant="secondary" type="error" size="xs" content="Verification failed" /> +{:else if ruleStatus === 'created'} + <Badge variant="secondary" size="xs" content="Awaiting verification" /> {/if}src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte (1)
45-45
: PrefertoLowerCase()
for domain normalization.
toLocaleLowerCase()
can be locale‑sensitive; domains should be ASCII‑lowercased.Apply:
- .proxy.createAPIRule({ domain: domainName.toLocaleLowerCase() }); + .proxy.createAPIRule({ domain: domainName.toLowerCase() });src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte (2)
30-41
: Avoid resetting the user’s selected tab on reactive changes.The
$effect
will overwrite manual tab picks if dependencies change. Consider setting default only on open.Apply:
-$effect(() => { - if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) { + $effect(() => { + if (!show) return; // only when opening + if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) { selectedTab = 'cname'; } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { selectedTab = 'a'; } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { selectedTab = 'aaaa'; } else { selectedTab = 'nameserver'; } });
113-125
: Consistent “verified” rendering across components.Once components accept
'verified'
inruleStatus
, we can rely onselectedProxyRule.status
and drop the separateverified
prop.After updating the components, simplify to:
<NameserverTable domain={selectedProxyRule.domain} ruleStatus={selectedProxyRule.status} /> <!-- and --> <RecordTable service="general" variant={selectedTab} domain={selectedProxyRule.domain} ruleStatus={selectedProxyRule.status} />src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte (3)
47-54
: Success toast can be misleading when status !== 'verified'.Toast always says “has been verified” even if the rule remains verifying/failed.
- show = false; - verified = domain.status === 'verified'; + show = false; + verified = domain.status === 'verified'; await invalidate(Dependencies.DOMAINS); addNotification({ type: 'success', - message: `${selectedDomain.domain} has been verified` + message: + domain.status === 'verified' + ? `${selectedDomain.domain} verified` + : `Verification retried for ${selectedDomain.domain}. We’ll keep checking.` });
61-64
: Type‑narrow the caught error.
e
isunknown
in TS; accessinge.message
can error.- } catch (e) { - error = - e.message ?? - 'Domain verification failed. Please check your domain settings or try again later'; - trackError(e, Submit.DomainUpdateVerification); + } catch (e) { + const message = + e instanceof Error && e.message + ? e.message + : 'Domain verification failed. Please check your domain settings or try again later'; + error = message; + trackError(e, Submit.DomainUpdateVerification); }
76-112
: De‑duplicate tab logic by deriving an allowed‑tabs list.Keeps selection/render rules in one place and avoids future drift.
Example:
const availableTabs = $derived(() => { const tabs: Array<'cname'|'nameserver'|'a'|'aaaa'> = []; const hasCname = isSubDomain && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost'; const hasA = !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'; const hasAaaa = !isCloud && !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'; if (hasCname) tabs.push('cname'); if (isCloud) tabs.push('nameserver'); else tabs.push('nameserver'); // always include if (hasA) tabs.push('a'); if (hasAaaa) tabs.push('aaaa'); return tabs; }); $effect(() => { selectedTab = availableTabs[0] ?? 'nameserver'; });src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts (3)
10-13
: Use SvelteKit’s error helper for bad input.Return a 400 instead of throwing a generic Error.
+import { error } from '@sveltejs/kit'; ... - if (!ruleId) { - throw new Error('Rule ID is required'); - } + if (!ruleId) { + error(400, 'Rule ID is required'); + }
15-21
: domainsList may be undefined on self‑hosted.Type and initialize accordingly to avoid implicit undefined.
-let domainsList: Models.DomainsList; +let domainsList: Models.DomainsList | undefined;
17-19
: Optional: region‑aware console SDK.If console endpoints are region‑scoped, prefer
sdk.forConsoleIn(params.region)
.src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts (3)
10-13
: Use SvelteKit’s error helper for bad input.Return a 400 instead of throwing.
+import { error } from '@sveltejs/kit'; ... - if (!ruleId) { - throw new Error('Rule ID is required'); - } + if (!ruleId) { + error(400, 'Rule ID is required'); + }
15-21
: domainsList can be undefined outside cloud.Adjust type to avoid uninitialized variable.
-let domainsList: Models.DomainsList; +let domainsList: Models.DomainsList | undefined;
17-19
: Optional: region‑aware console SDK.Prefer
sdk.forConsoleIn(params.region)
if applicable.src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte (2)
99-101
: Optional: perform nameserver update before navigation.Running it pre-
goto
reduces the chance of cancellation on route change.
103-107
: Type‑narrow error in notification.
error
isunknown
; guard before accessing.message
.- } catch (error) { - addNotification({ - type: 'error', - message: error.message - }); + } catch (error) { + addNotification({ + type: 'error', + message: error instanceof Error ? error.message : 'Failed to add domain' + }); }src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte (2)
42-44
: TS nullability mismatch forredirect
andbranch
.Declared as
string
but initialized withnull
. Make the types explicit to satisfy strict TS and avoid runtime surprises in bound inputs.- let redirect: string = $state(null); - let branch: string = $state(null); + let redirect = $state<string | null>(null); + let branch = $state<string | null>(null);
58-71
: Follow-up: domain ID discovery for retries (optional).If create returns domain_already_exists, consider resolving the existing domain ID (e.g., list + filter) so the later nameserver update can still run. This will improve success rate after “verified” short-circuit.
Do you want me to wire a fallback lookup via
sdk.forConsole.domains.list({ search: apexDomain, teamId: $project.teamId })
when create says “already exists”?src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte (3)
69-69
: Emptycatch
blocks hide actionable failures and break CI.Replace silent catches with targeted handling for
domain_already_exists
and user-facing notifications for unexpected errors.- } catch (error) {} + } catch (error: any) { + if (error?.type !== 'domain_already_exists') { + addNotification({ type: 'warning', message: error?.message ?? 'Failed to create apex domain' }); + } + } ... - } catch (error) {} + } catch (error: any) { + addNotification({ type: 'warning', message: error?.message ?? 'Failed to update nameservers' }); + }Also applies to: 86-86
72-75
: Possible undefineddata.domainsList
.
data.domainsList
may be absent outside cloud or on load failures. Use optional chaining to avoid crashes.- const domain = data.domainsList.domains.find( + const domain = data.domainsList?.domains?.find( (d: Models.Domain) => d.domain === apexDomain );
90-95
: Guard missingruleId
.
ruleId
can be null if the page is hit directly. Add a guard to prevent a 400 and guide the user.- const ruleData = await sdk + if (!ruleId) { + throw new Error('Missing rule ID. Please restart domain verification.'); + } + const ruleData = await sdk .forProject(page.params.region, page.params.project) .proxy.updateRuleVerification({ ruleId });src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte (5)
50-51
: AlignisSubmitting
store shape with other pages.Use the same
$state(writable(false))
pattern for consistency with bindings.- const isSubmitting = writable(false); + let isSubmitting = $state(writable(false));
56-56
: Remove stray console.log.Leftover debug log will leak to users’ consoles.
- console.log('apexDomain', apexDomain); + // no-op
69-69
: Emptycatch
blocks.Same issue as other verify pages; replace with minimal handling to satisfy CI and improve debuggability.
- } catch (error) {} + } catch (error: any) { + if (error?.type !== 'domain_already_exists') { + addNotification({ type: 'warning', message: error?.message ?? 'Failed to create apex domain' }); + } + } ... - } catch (error) {} + } catch (error: any) { + addNotification({ type: 'warning', message: error?.message ?? 'Failed to update nameservers' }); + }Also applies to: 86-86
72-75
: Optional chaining on domains list.Prevent crashes if
domainsList
is missing.- const domain = data.domainsList.domains.find( + const domain = data.domainsList?.domains?.find( (d: Models.Domain) => d.domain === apexDomain );
90-98
: GuardruleId
before verification.Avoid calling the API with
null
and show a clear error.- const ruleData = await sdk + if (!ruleId) { + throw new Error('Missing rule ID. Please restart domain verification.'); + } + const ruleData = await sdk .forProject(page.params.region, page.params.project) .proxy.updateRuleVerification({ ruleId });src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte (4)
46-47
: Inconsistentverified
typing.Other pages use
boolean
. Keep consistent unless components truly need tri‑state.- let verified: boolean | undefined = $state(undefined); + let verified = $state(false);
67-67
: Emptycatch
blocks.Mirror the handling used in other verify pages to avoid CI failure and improve UX.
- } catch (error) {} + } catch (error: any) { + if (error?.type !== 'domain_already_exists') { + addNotification({ type: 'warning', message: error?.message ?? 'Failed to create apex domain' }); + } + } ... - } catch (error) {} + } catch (error: any) { + addNotification({ type: 'warning', message: error?.message ?? 'Failed to update nameservers' }); + }Also applies to: 84-84
70-73
: Optional chaining ondomainsList
.Prevent runtime errors when the list is unavailable.
- const domain = data.domainsList.domains.find( + const domain = data.domainsList?.domains?.find( (d: Models.Domain) => d.domain === apexDomain );
88-95
: Guard missingruleId
.Avoid API call with
null
and provide clear remediation.- const ruleData = await sdk + if (!ruleId) { + throw new Error('Missing rule ID. Please restart domain verification.'); + } + const ruleData = await sdk .forProject(page.params.region, page.params.project) .proxy.updateRuleVerification({ ruleId });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
src/lib/components/domains/cnameTable.svelte
(2 hunks)src/lib/components/domains/nameserverTable.svelte
(2 hunks)src/lib/components/domains/recordTable.svelte
(2 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte
(2 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte
(6 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts
(2 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte
(3 hunks)src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte
(2 hunks)src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte
(6 hunks)src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts
(1 hunks)src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte
(3 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte
(2 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte
(6 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts
(1 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts (3)
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts (1)
load
(6-29)src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts (1)
load
(6-29)src/lib/stores/sdk.ts (1)
sdk
(142-165)
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts (4)
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts (1)
load
(6-29)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts (1)
load
(6-29)src/lib/system.ts (1)
isCloud
(24-24)src/lib/stores/sdk.ts (1)
sdk
(142-165)
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts (5)
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts (1)
load
(6-29)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts (1)
load
(6-29)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/+page.ts (1)
load
(10-50)src/routes/(console)/project-[region]-[project]/functions/function-[function]/store.ts (1)
func
(7-7)src/lib/stores/sdk.ts (1)
sdk
(142-165)
🪛 GitHub Check: build
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte
[failure] 59-59:
Empty block statement
[failure] 96-96:
Empty block statement
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte
[failure] 84-84:
Empty block statement
[failure] 67-67:
Empty block statement
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte
[failure] 69-69:
Empty block statement
[failure] 106-106:
Empty block statement
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte
[failure] 86-86:
Empty block statement
[failure] 69-69:
Empty block statement
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte
[failure] 39-39:
Empty block statement
[failure] 52-52:
Empty block statement
🪛 GitHub Actions: Tests
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte
[error] 59-59: ESLint: Empty block statement (no-empty). Step: pnpm run lint
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: e2e
🔇 Additional comments (9)
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts (3)
22-22
: LGTM: per‑project proxy rule fetch aligns with new ruleStatus plumbing
8-8
: Dependencies.DOMAINS is correct for this project-level verify page — no change needed. Matches other project domain routes (src/routes/(console)/project-[region]-[project]/settings/domains/+page.ts and add-domain/+page.ts) and the verify Svelte invalidates the same key.
15-20
: domainsList may be undefined when isCloud is false — make the type optional or initialize itdomainsList is declared but only assigned inside the
if (isCloud)
branch, so it can be unassigned (undefined) for self‑hosted runs; change the type or provide a default/guard before use.File: src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts — lines 15–20 (also applies to 24–27)
Suggested change:
-let domainsList: Models.DomainsList; +let domainsList: Models.DomainsList | undefined;If callers expect a non‑null value, either initialize to an empty list/object or guard in the loader/UI before using domainsList.
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte (1)
54-56
: Route usesdomainName
as typed; ensure consistent normalization.If normalization is required (lowercase), apply the same when building the verify URL.
Do you want this to be
verify-${domainName.toLowerCase()}
to match the create call?src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte (1)
114-125
: Props handoff looks correct.Passing
domain
,verified
, andruleStatus
into NameserverTable/RecordTable aligns with the new domains UI.src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte (1)
114-124
: LGTM on new prop wiring.
ruleStatus={selectedProxyRule.status}
is consistent across both tables.If not already covered by types, confirm both components export
export let ruleStatus: string | undefined;
.src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.ts (1)
26-27
: Return shape clarity.Returning
domainsList
as possibly undefined is fine if consumers handle it; otherwise default tonull
for explicitness.Search consumers of
data.domainsList
on this route to ensure undefined is handled.src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.ts (1)
24-28
: Return payload LGTM.Naming
function: func
avoids reserved word collisions; inclusion ofproxyRule
aligns with the UI.src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte (1)
65-68
: Team/Org ID source inconsistent — confirm equivalenceSearch shows create calls use different ID sources: some use $project.teamId while verify/org flows use $organization.$id or page.params.organization. Confirm $project.teamId === $organization.$id in all console contexts or unify to a single source to avoid accidental cross-org writes.
Uses $project.teamId:
- src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte (lines ~65–67)
- src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte (lines ~55–57)
- src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte (lines ~35–37)
Uses $organization.$id or page.params.organization:
- src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte (teamId: $organization.$id)
- src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte (teamId: $organization.$id)
- src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte (teamId: $organization.$id)
- src/routes/(console)/organization-[organization]/domains/add-domain/+page.svelte (teamId: page.params.organization)
If these IDs are not guaranteed equal, switch to a single canonical org-id source (or explicitly map project.teamId → organization id) before calling sdk.forConsole.domains.create.
let domain: Models.Domain; | ||
|
||
if (apexDomain && !domain && isCloud) { | ||
if (isCloud && apexDomain) { | ||
try { | ||
domain = await sdk.forConsole.domains.create({ | ||
teamId: $project.teamId, | ||
domain: apexDomain | ||
}); | ||
} catch (error) { | ||
// apex might already be added on organization level, skip. | ||
const alreadyAdded = error?.type === 'domain_already_exists'; | ||
if (!alreadyAdded) { | ||
addNotification({ | ||
type: 'error', | ||
message: error.message | ||
}); | ||
return; | ||
} | ||
} | ||
} catch (error) {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty catch triggers lint failure and hides real errors; also domain
may remain uninitialized.
Replace the try/catch with a safe promise .catch
and make domain
nullable.
- let domain: Models.Domain;
-
- if (isCloud && apexDomain) {
- try {
- domain = await sdk.forConsole.domains.create({
- teamId: $project.teamId,
- domain: apexDomain
- });
- } catch (error) {}
- }
+ let domain: Models.Domain | null = null;
+ if (isCloud && apexDomain) {
+ domain = await sdk.forConsole.domains
+ .create({ teamId: $project.teamId, domain: apexDomain })
+ .catch(() => null); // Domain may already exist; safe to ignore
+ }
📝 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.
let domain: Models.Domain; | |
if (apexDomain && !domain && isCloud) { | |
if (isCloud && apexDomain) { | |
try { | |
domain = await sdk.forConsole.domains.create({ | |
teamId: $project.teamId, | |
domain: apexDomain | |
}); | |
} catch (error) { | |
// apex might already be added on organization level, skip. | |
const alreadyAdded = error?.type === 'domain_already_exists'; | |
if (!alreadyAdded) { | |
addNotification({ | |
type: 'error', | |
message: error.message | |
}); | |
return; | |
} | |
} | |
} catch (error) {} | |
} | |
let domain: Models.Domain | null = null; | |
if (isCloud && apexDomain) { | |
domain = await sdk.forConsole.domains | |
.create({ teamId: $project.teamId, domain: apexDomain }) | |
.catch(() => null); // Domain may already exist; safe to ignore | |
} |
🧰 Tools
🪛 GitHub Check: build
[failure] 59-59:
Empty block statement
🪛 GitHub Actions: Tests
[error] 59-59: ESLint: Empty block statement (no-empty). Step: pnpm run lint
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte
around lines 51 to 60, the empty catch both silences errors and can leave
`domain` uninitialized; change `domain` to be nullable (e.g., Models.Domain |
null) and replace the try/catch with the promise form using `.catch(...)` so any
error is handled explicitly (log or surface it) and set `domain = null` on
failure; additionally, adjust any downstream code to handle the nullable
`domain` case safely.
return; | ||
} | ||
} | ||
} catch (error) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Fix pipeline: remove empty catch blocks.
These exact lines are failing ESLint (no-empty
). The diffs above resolve both occurrences.
Run to confirm no empty catch blocks remain:
Also applies to: 96-96
🏁 Script executed:
#!/bin/bash
rg -nP "catch\s*\([^)]*\)\s*\{\s*\}" -S || true
Length of output: 1764
Fix pipeline: remove empty catch blocks.
ESLint no-empty
failures found at:
- src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte:39
- src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte:52
- src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte:69
- src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte:86
- src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte:69
- src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte:106
- src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte:69
- src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte:86
- src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte:59
- src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte:96
- src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte:67
- src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte:84
Replace empty catch bodies with proper handling (log, rethrow, or an explicit justified eslint-disable comment).
🧰 Tools
🪛 GitHub Check: build
[failure] 59-59:
Empty block statement
🪛 GitHub Actions: Tests
[error] 59-59: ESLint: Empty block statement (no-empty). Step: pnpm run lint
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte
around line 59, there is an empty catch block; replace it with proper error
handling by capturing the caught error (e.g., catch (error)) and either log it
(console.error/processLogger.error) and surface a user-friendly message/state
update, rethrow the error if it must propagate, or if suppression is intentional
add a single-line eslint-disable comment with a justification; ensure any added
logging includes the error object for debugging and preserve original control
flow.
if (isCloud) { | ||
try { | ||
await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id }); | ||
} catch (error) {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard updateNameservers
and avoid empty catch.
Prevent null deref on domain
and remove empty catch.
- if (isCloud) {
- try {
- await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id });
- } catch (error) {}
- }
+ if (isCloud && domain?.$id) {
+ await sdk.forConsole.domains
+ .updateNameservers({ domainId: domain.$id })
+ .catch(() => {}); // Non-blocking best-effort
+ }
📝 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.
if (isCloud) { | |
try { | |
await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id }); | |
} catch (error) {} | |
} | |
if (isCloud && domain?.$id) { | |
await sdk.forConsole.domains | |
.updateNameservers({ domainId: domain.$id }) | |
.catch(() => void 0); // Non-blocking best-effort | |
} |
🧰 Tools
🪛 GitHub Check: build
[failure] 96-96:
Empty block statement
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/+page.svelte
around lines 93-97, avoid potential null dereference of domain and remove the
empty catch: ensure you only call updateNameservers when domain and domain.$id
are present and when the method exists (use a guard/optional chaining on
sdk.forConsole.domains.updateNameservers), and replace the empty catch with
proper error handling (e.g., log the error and/or surface a user-facing message
or rethrow) so failures are not silently ignored.
let verified = $state(false); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialize verified
from the selected rule to render correct badges before retry.
Currently shows unverified until after retry completes.
Apply:
-let verified = $state(false);
+let verified = $state(selectedProxyRule?.status === '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.
let verified = $state(false); | |
let verified = $state(selectedProxyRule?.status === 'verified'); |
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte
around lines 43-44, the local verified variable is initialized to false which
causes the UI to show unverified badges until a retry completes; change the
initialization to derive verified from the currently selected rule (e.g., read
selectedRule.verified or equivalent property from the component prop or store)
so the badge reflects the rule's actual verification state on render; ensure the
value updates if selectedRule changes (use reactive assignment or subscribe to
the store) and keep fallback to false if the selected rule is undefined.
try { | ||
await sdk | ||
const domain = await sdk | ||
.forProject(page.params.region, page.params.project) | ||
.proxy.updateRuleVerification({ ruleId: selectedProxyRule.$id }); | ||
await invalidate(Dependencies.FUNCTION_DOMAINS); | ||
|
||
show = false; | ||
verified = domain.status === 'verified'; | ||
await invalidate(Dependencies.FUNCTION_DOMAINS); | ||
|
||
addNotification({ | ||
type: 'success', | ||
message: `${selectedProxyRule.domain} has been verified` | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Success toast always claims “verified” even when status isn’t verified.
Use the returned status to tailor the message.
Apply:
- show = false;
- verified = domain.status === 'verified';
- await invalidate(Dependencies.FUNCTION_DOMAINS);
-
- addNotification({
- type: 'success',
- message: `${selectedProxyRule.domain} has been verified`
- });
+ show = false;
+ verified = domain.status === 'verified';
+ await invalidate(Dependencies.FUNCTION_DOMAINS);
+
+ addNotification({
+ type: 'success',
+ message:
+ domain.status === 'verified'
+ ? `${selectedProxyRule.domain} has been verified`
+ : `Verification retried for ${selectedProxyRule.domain} (status: ${domain.status})`
+ });
📝 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.
try { | |
await sdk | |
const domain = await sdk | |
.forProject(page.params.region, page.params.project) | |
.proxy.updateRuleVerification({ ruleId: selectedProxyRule.$id }); | |
await invalidate(Dependencies.FUNCTION_DOMAINS); | |
show = false; | |
verified = domain.status === 'verified'; | |
await invalidate(Dependencies.FUNCTION_DOMAINS); | |
addNotification({ | |
type: 'success', | |
message: `${selectedProxyRule.domain} has been verified` | |
}); | |
try { | |
const domain = await sdk | |
.forProject(page.params.region, page.params.project) | |
.proxy.updateRuleVerification({ ruleId: selectedProxyRule.$id }); | |
show = false; | |
verified = domain.status === 'verified'; | |
await invalidate(Dependencies.FUNCTION_DOMAINS); | |
addNotification({ | |
type: 'success', | |
message: | |
domain.status === 'verified' | |
? `${selectedProxyRule.domain} has been verified` | |
: `Verification retried for ${selectedProxyRule.domain} (status: ${domain.status})` | |
}); |
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte
around lines 46–58, the success notification always says "verified" regardless
of the returned domain.status; update the toast to use the actual status
returned by the API. After awaiting sdk...updateRuleVerification and setting
verified = domain.status === 'verified', build the notification message from
domain.status (e.g., `${selectedProxyRule.domain} has been ${domain.status}`) or
conditionally choose wording for known statuses, then call addNotification with
that message so the toast reflects the real verification result.
return; | ||
} | ||
} | ||
} catch (error) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix build failure: empty block statements.
Fill the catch blocks with logging/notifications as suggested above to resolve CI.
Also applies to: 52-52
🧰 Tools
🪛 GitHub Check: build
[failure] 39-39:
Empty block statement
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte
around lines 39 and 52, there are empty catch blocks causing build failures;
replace each empty catch with proper error handling: catch the error as unknown
(e.g., catch (error: unknown)), log it (console.error or processLogger) and
surface a user-facing notification or set an error state so the UI shows the
failure (use the existing toast/notification helper in the project or import
one), and optionally rethrow or return after handling; ensure imports for any
notification utilities are added.
try { | ||
await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id }); | ||
} catch (error) {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid null dereference on domain.$id
and surface errors.
domain
can be null if creation failed/skipped. Also, the empty catch eats real issues.
Apply:
- if (isCloud) {
- try {
- await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id });
- } catch (error) {}
- }
+ if (isCloud && apexDomain && domain?.$id) {
+ try {
+ await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id });
+ } catch (error) {
+ console.warn('updateNameservers failed for', apexDomain, error);
+ addNotification({
+ type: 'warning',
+ message: `Nameserver update skipped: ${apexDomain}`
+ });
+ }
+ }
📝 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.
try { | |
await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id }); | |
} catch (error) {} | |
} | |
if (isCloud && apexDomain && domain?.$id) { | |
try { | |
await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id }); | |
} catch (error) { | |
console.warn('updateNameservers failed for', apexDomain, error); | |
addNotification({ | |
type: 'warning', | |
message: `Nameserver update skipped: ${apexDomain}` | |
}); | |
} | |
} |
🧰 Tools
🪛 GitHub Check: build
[failure] 52-52:
Empty block statement
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte
around lines 50–53, avoid dereferencing domain.$id when domain may be null and
stop swallowing errors in the catch block: first guard that domain and
domain.$id exist (e.g., if (!domain?.$id) return or display an appropriate
error/validation message to the user) before calling
sdk.forConsole.domains.updateNameservers, and replace the empty catch with error
handling that surfaces the problem (log to console, show a user-facing
toast/alert, or rethrow) so real failures are visible to developers and users.
$effect(() => { | ||
if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) { | ||
selectedTab = 'cname'; | ||
} else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { | ||
selectedTab = 'a'; | ||
} else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { | ||
selectedTab = 'aaaa'; | ||
} else { | ||
selectedTab = 'nameserver'; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initial tab selection can target a non-rendered tab (mismatch with UI conditions).
The $effect
doesn’t mirror the render-time exclusions for localhost/loopback targets. It can auto-select a
/aaaa
/cname
even when those tabs are hidden, leaving content out of sync with the visible tabs.
Apply this diff to align selection with render conditions:
$effect(() => {
- if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) {
- selectedTab = 'cname';
- } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) {
- selectedTab = 'a';
- } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) {
- selectedTab = 'aaaa';
- } else {
- selectedTab = 'nameserver';
- }
+ const hasCname =
+ isSubDomain &&
+ !!$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME &&
+ $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost';
+ const hasA =
+ !isCloud &&
+ !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A &&
+ $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1';
+ const hasAaaa =
+ !isCloud &&
+ !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA &&
+ $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1';
+
+ if (hasCname) selectedTab = 'cname';
+ else if (hasA) selectedTab = 'a';
+ else if (hasAaaa) selectedTab = 'aaaa';
+ else selectedTab = 'nameserver';
});
📝 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.
$effect(() => { | |
if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) { | |
selectedTab = 'cname'; | |
} else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { | |
selectedTab = 'a'; | |
} else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { | |
selectedTab = 'aaaa'; | |
} else { | |
selectedTab = 'nameserver'; | |
} | |
}); | |
$effect(() => { | |
const hasCname = | |
isSubDomain && | |
!!$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && | |
$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost'; | |
const hasA = | |
!isCloud && | |
!!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && | |
$regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'; | |
const hasAaaa = | |
!isCloud && | |
!!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && | |
$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'; | |
if (hasCname) selectedTab = 'cname'; | |
else if (hasA) selectedTab = 'a'; | |
else if (hasAaaa) selectedTab = 'aaaa'; | |
else selectedTab = 'nameserver'; | |
}); |
if (isCloud && apexDomain && !isSiteDomain) { | ||
try { | ||
domain = await sdk.forConsole.domains.create({ | ||
teamId: $project.teamId, | ||
domain: apexDomain | ||
}); | ||
} catch (error) { | ||
// apex might already be added on organization level, skip. | ||
const alreadyAdded = error?.type === 'domain_already_exists'; | ||
if (!alreadyAdded) { | ||
addNotification({ | ||
type: 'error', | ||
message: error.message | ||
}); | ||
return; | ||
} | ||
} | ||
} catch (error) {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Over-eager apex domain creation and swallowed errors.
- Removing the
!domain
guard triggers a create attempt on every add (cloud + apex), causing noisydomain_already_exists
errors. - The empty
catch
hides real failures and trips CI (“Empty block statement”).
Handle the known duplicate gracefully and report unexpected errors.
Apply this diff:
- if (isCloud && apexDomain && !isSiteDomain) {
- try {
- domain = await sdk.forConsole.domains.create({
- teamId: $project.teamId,
- domain: apexDomain
- });
- } catch (error) {}
- }
+ if (isCloud && apexDomain && !isSiteDomain) {
+ try {
+ domain = await sdk.forConsole.domains.create({
+ teamId: $project.teamId,
+ domain: apexDomain
+ });
+ } catch (error: any) {
+ // Ignore "already exists", surface anything else.
+ if (error?.type !== 'domain_already_exists') {
+ addNotification({
+ type: 'error',
+ message: error?.message ?? 'Failed to create apex domain'
+ });
+ return;
+ }
+ }
+ }
📝 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.
if (isCloud && apexDomain && !isSiteDomain) { | |
try { | |
domain = await sdk.forConsole.domains.create({ | |
teamId: $project.teamId, | |
domain: apexDomain | |
}); | |
} catch (error) { | |
// apex might already be added on organization level, skip. | |
const alreadyAdded = error?.type === 'domain_already_exists'; | |
if (!alreadyAdded) { | |
addNotification({ | |
type: 'error', | |
message: error.message | |
}); | |
return; | |
} | |
} | |
} catch (error) {} | |
} | |
if (isCloud && apexDomain && !isSiteDomain) { | |
try { | |
domain = await sdk.forConsole.domains.create({ | |
teamId: $project.teamId, | |
domain: apexDomain | |
}); | |
} catch (error: any) { | |
// Ignore "already exists", surface anything else. | |
if (error?.type !== 'domain_already_exists') { | |
addNotification({ | |
type: 'error', | |
message: error?.message ?? 'Failed to create apex domain' | |
}); | |
return; | |
} | |
} | |
} |
🧰 Tools
🪛 GitHub Check: build
[failure] 69-69:
Empty block statement
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte
around lines 63–70, reintroduce the guard so we only attempt creating the apex
domain when no domain object exists (e.g., keep/check !domain) and avoid
creating on every add; wrap the create call in a try/catch that does not swallow
errors—detect the known duplicate case (error code/message like
"domain_already_exists") and ignore or handle it silently, but for any other
error log/report it to the UI or rethrow so CI/monitoring sees it (do not leave
an empty catch block).
if (isCloud) { | ||
try { | ||
await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id }); | ||
} catch (error) {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential runtime crash: domain
may be undefined when calling updateNameservers
.
domain
is only set on successful create. If creation fails (e.g., domain_already_exists) and is swallowed, domain
stays undefined and domain.$id
throws. Guard this call and surface actionable feedback.
Apply this diff:
- if (isCloud) {
- try {
- await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id });
- } catch (error) {}
- }
+ if (isCloud && domain?.$id) {
+ try {
+ await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id });
+ } catch (error: any) {
+ addNotification({
+ type: 'warning',
+ message: 'Failed to update nameservers for apex domain. You can retry from Domains → View logs.'
+ });
+ }
+ }
📝 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.
if (isCloud) { | |
try { | |
await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id }); | |
} catch (error) {} | |
} | |
if (isCloud && domain?.$id) { | |
try { | |
await sdk.forConsole.domains.updateNameservers({ domainId: domain.$id }); | |
} catch (error: any) { | |
addNotification({ | |
type: 'warning', | |
message: 'Failed to update nameservers for apex domain. You can retry from Domains → View logs.' | |
}); | |
} | |
} |
🧰 Tools
🪛 GitHub Check: build
[failure] 106-106:
Empty block statement
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/+page.svelte
around lines 103-107, the code calls sdk.forConsole.domains.updateNameservers({
domainId: domain.$id }) without ensuring domain is defined and swallows any
error; change this to check that domain !== undefined (or domain?.$id) before
calling updateNameservers, and in the catch block do not silently ignore
errors—capture and surface an actionable error (log it and/or show a user-facing
message) so failures are handled safely and provide feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte (1)
52-56
: Success toast fires even when verification didn’t succeed.You always notify success after
updateRuleVerification
, regardless ofdomain.status
. Gate the toast on success; otherwise show an info/error.- show = false; - verified = domain.status === 'verified'; - await invalidate(Dependencies.SITES_DOMAINS); - - addNotification({ - type: 'success', - message: `${selectedProxyRule.domain} has been verified` - }); + show = false; + verified = domain.status === 'verified'; + await invalidate(Dependencies.SITES_DOMAINS); + if (verified) { + addNotification({ + type: 'success', + message: `${selectedProxyRule.domain} has been verified` + }); + } else { + addNotification({ + type: 'info', + message: `Verification retried. Current status: ${domain.status}` + }); + }
♻️ Duplicate comments (3)
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte (2)
40-41
: Initialize verified from the selected rule.Prevents incorrect “unverified” badges before retry completes.
-let verified = $state(false); +let verified = $state(selectedProxyRule?.status === 'verified');
52-55
: Toast claims “verified” even when status isn’t verified.Use the returned status in the message.
addNotification({ type: 'success', - message: `${selectedProxyRule.domain} has been verified` + message: + domain.status === 'verified' + ? `${selectedProxyRule.domain} has been verified` + : `Verification retried for ${selectedProxyRule.domain} (status: ${domain.status})` });src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte (1)
27-37
: Initial tab can target a hidden tab. Mirror render conditions.Prevents selecting CNAME/A/AAAA when they’re filtered (localhost/loopback) and avoiding Nameservers on self‑hosted.
$effect(() => { - if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { - selectedTab = 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - selectedTab = 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - selectedTab = 'aaaa'; - } else { - selectedTab = 'nameserver'; - } + const hasCname = + !!$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && + $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost'; + const hasNameserver = isCloud; + const hasA = + !isCloud && + !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && + $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'; + const hasAaaa = + !isCloud && + !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && + $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'; + + if (hasCname) selectedTab = 'cname'; + else if (hasNameserver) selectedTab = 'nameserver'; + else if (hasA) selectedTab = 'a'; + else if (hasAaaa) selectedTab = 'aaaa'; + else selectedTab = 'cname'; });
🧹 Nitpick comments (23)
src/lib/components/domains/cnameTable.svelte (2)
27-39
: Double‑check status→badge mapping ("created" => "Verification failed" looks off).Confirm backend enum→UI copy. Today:
- created → "Verification failed"
- verifying → "Generating certificate"
- unverified → "Certificate generation failed"
If "created" is initial/new, showing "failed" is misleading. Consider a small mapper + default branch to avoid incorrect badges for unknown states.
Apply a mapper inline:
- {#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" /> + {#if ruleStatus} + {#if ruleStatus === 'verifying'} + <Badge variant="secondary" size="xs" content="Generating certificate" /> + {:else if ruleStatus === 'unverified' || ruleStatus === 'failed'} + <Badge variant="secondary" type="error" size="xs" content="Certificate generation failed" /> + {:else if ruleStatus === 'created'} + <Badge variant="secondary" size="xs" content="Verification pending" /> + {/if} {:else if verified === true} <Badge variant="secondary" type="success" size="xs" content="Verified" /> {/if}
63-81
: CAA row UX: clarify value format for common cases.Nice addition. Minor polish: add a short hint that multiple CAA tags (issue, issuewild) may be needed, and that the provided value is a recommended baseline.
src/lib/components/domains/recordTable.svelte (4)
54-66
: Same status→badge mapping concerns as cnameTable.Align copy and handle unknown states via a mapper to avoid showing a "failed" badge for "created".
Apply the same diff pattern used in cnameTable here.
25-33
: Make A/AAAA tab visibility reactive (or explicitly constant).These are computed once. If regionalConsoleVariables can change (region switch), this won’t update. Either:
- mark as intentional (constant per session), or
- make them reactive (
$:
) so UI updates when the store changes.
108-130
: Apex detection uses a naive subdomain check; use getApexDomain for correctness.
!subdomain
assumes two‑label apex (fails for e.g., example.co.uk). Use TLD helper for apex detection and subdomain derivation.Apply this diff locally for the condition:
- {#if variant === 'cname' && !subdomain} + {#if variant === 'cname' && domain === getApexDomain(domain)}And add at top:
+ import { getApexDomain } from '$lib/helpers/tlds';
Outside this hunk, update subdomain derivation to be TLD‑aware (example):
// replace current subdomain logic const apex = getApexDomain(domain); const subdomain = domain && apex && domain.endsWith(`.${apex}`) ? domain.slice(0, -(apex.length + 1)) : '';
87-105
: CAA row: same minor UX hint as cnameTable.Consider a brief caption or help icon noting when to use issue vs issuewild and that multiple CAA records can coexist.
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte (4)
35-45
: Default tab gating inconsistent with tab visibility.You gate the CNAME tab button on
_APP_DOMAIN_TARGET_CNAME !== 'localhost'
, but the default‑selection effect doesn’t. Result: default selects a hidden tab. Align both.Apply this diff:
- if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { + if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost') { selectedTab = 'cname';Also applies to: 151-159
52-87
: Apex‑domain pre‑verification: silent catches hide actionable failures.Swallowing errors twice makes troubleshooting hard. At minimum, log or track them; ideally, surface a non‑blocking info notification.
Add lightweight logging:
- } catch (error) {} + } catch (error) { + console.warn('Apex domain create/verify skipped:', error); + } ... - } catch (error) {} + } catch (error) { + console.warn('Apex domain nameserver update skipped:', error); + }
107-114
: Type‑safe error handling in catch.
error
isunknown
in TS. Accessingerror.message
can break type‑checks. Normalize safely.Apply this diff:
- } catch (error) { + } catch (error: unknown) { verified = false; isSubmitting.set(false); addNotification({ type: 'error', - message: error.message + message: error instanceof Error ? error.message : String(error) }); }
123-124
: URL‑encode the domain query param.Avoid issues with IDNs/punycode or special chars.
Apply this diff:
- await goto(`${routeBase}/add-domain?domain=${data.proxyRule.domain}`); + await goto(`${routeBase}/add-domain?domain=${encodeURIComponent(data.proxyRule.domain)}`);src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte (4)
35-44
: Default tab gating inconsistent with tab visibility (same as Sites).Add the
!== 'localhost'
guard to the default‑selection effect.- if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { + if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost') { selectedTab = 'cname';Also applies to: 149-157
52-86
: Apex‑domain pre‑verification: avoid empty catches.Mirror Sites page advice: at least log warnings so support can trace issues.
- } catch (error) {} + } catch (error) { + console.warn('Apex domain create/verify skipped:', error); + } ... - } catch (error) {} + } catch (error) { + console.warn('Apex domain nameserver update skipped:', error); + }
105-112
: Type‑safe error handling in catch.Normalize
unknown
errors before reading.message
.- } catch (error) { + } catch (error: unknown) { verified = false; isSubmitting.set(false); addNotification({ type: 'error', - message: error.message + message: error instanceof Error ? error.message : String(error) }); }
121-122
: URL‑encode the domain query param on back.- await goto(`${routeBase}/add-domain?domain=${data.proxyRule.domain}`); + await goto(`${routeBase}/add-domain?domain=${encodeURIComponent(data.proxyRule.domain)}`);src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte (1)
28-36
: Default tab gating inconsistent with visibility (localhost case).Align the effect with the tab button guard to avoid defaulting to a hidden CNAME tab.
- if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { + if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost') { selectedTab = 'cname';Also applies to: 75-83
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte (3)
27-37
: Align default tab selection with what’s actually rendered.Effect can select CNAME/A/AAAA even when hidden (localhost/loopback), or fall back to Nameservers on self‑hosted. Mirror render conditions.
$effect(() => { - if ($regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME) { - selectedTab = 'cname'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_A) { - selectedTab = 'a'; - } else if (!isCloud && $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA) { - selectedTab = 'aaaa'; - } else { - selectedTab = 'nameserver'; - } + const hasCname = + !!$regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME && + $regionalConsoleVariables._APP_DOMAIN_TARGET_CNAME !== 'localhost'; + const hasNameserver = isCloud; + const hasA = + !isCloud && + !!$regionalConsoleVariables._APP_DOMAIN_TARGET_A && + $regionalConsoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'; + const hasAaaa = + !isCloud && + !!$regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA && + $regionalConsoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'; + + if (hasCname) selectedTab = 'cname'; + else if (hasNameserver) selectedTab = 'nameserver'; + else if (hasA) selectedTab = 'a'; + else if (hasAaaa) selectedTab = 'aaaa'; + else selectedTab = 'cname'; });
58-61
: Handle unknown error type safely.Avoid assuming
e.message
.- error = - e.message ?? - 'Domain verification failed. Please check your domain settings or try again later'; + const msg = + e instanceof Error + ? e.message + : (typeof e === 'string' ? e : null); + error = + msg ?? + 'Domain verification failed. Please check your domain settings or try again later';
52-55
: Optional: notification type by status.Success for verified; info otherwise.
-addNotification({ - type: 'success', - message: - domain.status === 'verified' - ? `${selectedProxyRule.domain} has been verified` - : `Verification retried for ${selectedProxyRule.domain} (status: ${domain.status})` -}); +addNotification({ + type: domain.status === 'verified' ? 'success' : 'info', + message: + domain.status === 'verified' + ? `${selectedProxyRule.domain} has been verified` + : `Verification retried for ${selectedProxyRule.domain} (status: ${domain.status})` +});src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte (5)
18-23
: Default bindable show to false for consistency.Prevents an accidental undefined initial state.
- let { - show = $bindable(), + let { + show = $bindable(false), selectedDomain
40-41
: Initialize verified from the selected domain status.Ensures correct badges before retry.
-let verified = $state(false); +let verified = $state(selectedDomain?.status === 'verified');
52-55
: Toast claims “verified” regardless of result.Reflect actual
domain.status
.addNotification({ type: 'success', - message: `${selectedDomain.domain} has been verified` + message: + domain.status === 'verified' + ? `${selectedDomain.domain} has been verified` + : `Verification retried for ${selectedDomain.domain} (status: ${domain.status})` });
58-61
: Harden error handling for non-Error throws.Avoids
any
/unknown pitfalls.- error = - e.message ?? - 'Domain verification failed. Please check your domain settings or try again later'; + const msg = + e instanceof Error + ? e.message + : (typeof e === 'string' ? e : null); + error = + msg ?? + 'Domain verification failed. Please check your domain settings or try again later';
52-55
: Optional: notification type by status.Use success for verified; info otherwise.
-addNotification({ - type: 'success', - message: - domain.status === 'verified' - ? `${selectedDomain.domain} has been verified` - : `Verification retried for ${selectedDomain.domain} (status: ${domain.status})` -}); +addNotification({ + type: domain.status === 'verified' ? 'success' : 'info', + message: + domain.status === 'verified' + ? `${selectedDomain.domain} has been verified` + : `Verification retried for ${selectedDomain.domain} (status: ${domain.status})` +});
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/lib/components/domains/cnameTable.svelte
(3 hunks)src/lib/components/domains/recordTable.svelte
(3 hunks)src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte
(1 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte
(7 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/retryDomainModal.svelte
(3 hunks)src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte
(7 hunks)src/routes/(console)/project-[region]-[project]/settings/domains/retryDomainModal.svelte
(3 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte
(7 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte
(3 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/routes/(console)/organization-[organization]/domains/domain-[domain]/+page.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
- src/routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: e2e
- GitHub Check: build
🔇 Additional comments (1)
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/retryDomainModal.svelte (1)
111-115
: Props passthrough LGTM.Passing ruleStatus to child tables is consistent with the new badge logic; navigation callbacks are wired correctly.
Please sanity‑check that NameserverTable uses ruleStatus the same way as the Record/CNAME tables do.
Also applies to: 120-124
const ruleData = await sdk | ||
.forProject(page.params.region, page.params.project) | ||
.proxy.updateRuleVerification({ ruleId }); | ||
|
||
verified = ruleData.status === 'verified'; | ||
if (!verified) { | ||
throw new Error( | ||
'Domain verification failed. Please check your domain settings or try again later' | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard missing ruleId during verify.
Avoid passing null/undefined to the SDK.
- const ruleData = await sdk
+ if (!ruleId) {
+ throw new Error('Missing rule id. Please restart the verification flow.');
+ }
+ const ruleData = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId });
📝 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.
const ruleData = await sdk | |
.forProject(page.params.region, page.params.project) | |
.proxy.updateRuleVerification({ ruleId }); | |
verified = ruleData.status === 'verified'; | |
if (!verified) { | |
throw new Error( | |
'Domain verification failed. Please check your domain settings or try again later' | |
); | |
if (!ruleId) { | |
throw new Error('Missing rule id. Please restart the verification flow.'); | |
} | |
const ruleData = await sdk | |
.forProject(page.params.region, page.params.project) | |
.proxy.updateRuleVerification({ ruleId }); | |
verified = ruleData.status === 'verified'; | |
if (!verified) { | |
throw new Error( | |
'Domain verification failed. Please check your domain settings or try again later' | |
); |
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/functions/function-[function]/domains/add-domain/verify-[domain]/+page.svelte
around lines 87 to 95, the code calls updateRuleVerification with ruleId without
guarding against null/undefined; add a guard that checks ruleId (from
page.params or where it's derived) and handle the missing case before calling
the SDK—either throw a clear error or return early—so you never pass a
null/undefined ruleId into sdk.forProject(...).proxy.updateRuleVerification.
const ruleData = await sdk | ||
.forProject(page.params.region, page.params.project) | ||
.proxy.updateRuleVerification({ ruleId }); | ||
|
||
verified = ruleData.status === 'verified'; | ||
if (!verified) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard missing ruleId before verifying.
ruleId
can be null; passing it into the SDK will likely throw. Fail fast with a clear message.
Apply this diff:
- const ruleData = await sdk
+ if (!ruleId) {
+ throw new Error('Missing rule id. Please restart the verification flow.');
+ }
+ const ruleData = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId });
📝 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.
const ruleData = await sdk | |
.forProject(page.params.region, page.params.project) | |
.proxy.updateRuleVerification({ ruleId }); | |
verified = ruleData.status === 'verified'; | |
if (!verified) { | |
if (!ruleId) { | |
throw new Error('Missing rule id. Please restart the verification flow.'); | |
} | |
const ruleData = await sdk | |
.forProject(page.params.region, page.params.project) | |
.proxy.updateRuleVerification({ ruleId }); | |
verified = ruleData.status === 'verified'; | |
if (!verified) { |
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/sites/site-[site]/domains/add-domain/verify-[domain]/+page.svelte
around lines 89 to 94, the code calls
sdk.forProject(...).proxy.updateRuleVerification({ ruleId }) without ensuring
ruleId is present; guard against null/undefined by checking ruleId immediately
before the SDK call and fail fast with a clear error/return path (e.g., throw or
set an error state and return) so the SDK is never invoked with an invalid
ruleId.
What does this PR do?
a. Fix add-domain and verify domain flows
verification failed
->generating certificate
->certificate generation failed
view logs
,retry
links nexts to badgesview logs
in functions + projects domains dropdownlistDomains
for cloudupdated
column in each domains tableb. Update verification flows for sites/ functions/ projects tables
Test Plan
(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)
Related PRs and Issues
(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)
Have you read the Contributing Guidelines on issues?
(Write your answer here.)
Summary by CodeRabbit
New Features
Style / Layout
Behavior