Merge branch 'main' into fix/fix-relationship-set-and-view

# Conflicts:
#	package.json
#	pnpm-lock.yaml
This commit is contained in:
ernstmul
2025-05-23 10:46:27 +02:00
31 changed files with 226 additions and 136 deletions
+3 -2
View File
@@ -27,7 +27,7 @@
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "^2.0.0-RC.1",
"@appwrite.io/pink-legacy": "^1.0.3",
"@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@510c1a7",
"@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@12707b9",
"@popperjs/core": "^2.11.8",
"@sentry/sveltekit": "^8.38.0",
"@stripe/stripe-js": "^3.5.0",
@@ -83,7 +83,8 @@
"typescript": "^5.8.2",
"typescript-eslint": "^8.30.1",
"vite": "^6.2.3",
"vitest": "^3.0.0"
"vitest": "^3.0.0",
"tldts": "^7.0.7"
},
"pnpm": {
"onlyBuiltDependencies": [
+38 -21
View File
@@ -22,13 +22,13 @@ importers:
version: 0.25.0
'@appwrite.io/pink-icons-svelte':
specifier: ^2.0.0-RC.1
version: 2.0.0-RC.1(svelte@5.25.3)
version: https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-icons-svelte@12707b9(svelte@5.25.3)
'@appwrite.io/pink-legacy':
specifier: ^1.0.3
version: 1.0.3
'@appwrite.io/pink-svelte':
specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@510c1a7
version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@510c1a7(svelte@5.25.3)
specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@12707b9
version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@12707b9(svelte@5.25.3)
'@popperjs/core':
specifier: ^2.11.8
version: 2.11.8
@@ -177,6 +177,9 @@ importers:
svelte-sequential-preprocessor:
specifier: ^2.0.2
version: 2.0.2
tldts:
specifier: ^7.0.7
version: 7.0.7
tslib:
specifier: ^2.8.1
version: 2.8.1
@@ -258,13 +261,14 @@ packages:
resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@1959}
version: 1.5.2
'@appwrite.io/pink-icons-svelte@2.0.0-RC.1':
resolution: {integrity: sha512-iLFlV55hj8mGuAbmxJGenxN5RaZMmVT4GJb9dv/MP1xBAtYibFq7JvBcxm18qV2KU8c31Rntf+Ub4GL7HwqTYg==}
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@12707b95033c5822745ec6a2250a9cd0de10a498':
resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@12707b95033c5822745ec6a2250a9cd0de10a498}
version: 2.0.0-RC.1
peerDependencies:
svelte: ^4.0.0
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@510c1a70bb1a11aa8a58177e657dec6199215595':
resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@510c1a70bb1a11aa8a58177e657dec6199215595}
'@appwrite.io/pink-icons-svelte@https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-icons-svelte@12707b9':
resolution: {tarball: https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-icons-svelte@12707b9}
version: 2.0.0-RC.1
peerDependencies:
svelte: ^4.0.0
@@ -278,8 +282,8 @@ packages:
'@appwrite.io/pink-legacy@1.0.3':
resolution: {integrity: sha512-GGde5fmPhs+s6/3aFeMPc/kKADG/gTFkYQSy6oBN8pK0y0XNCLrZZgBv+EBbdhwdtqVEWXa0X85Mv9w7jcIlwQ==}
'@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@510c1a7':
resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@510c1a7}
'@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@12707b9':
resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@12707b9}
version: 2.0.0-RC.2
peerDependencies:
svelte: ^4.0.0
@@ -1340,8 +1344,8 @@ packages:
'@types/prop-types@15.7.14':
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
'@types/react@18.3.20':
resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==}
'@types/react@18.3.22':
resolution: {integrity: sha512-vUhG0YmQZ7kL/tmKLrD3g5zXbXXreZXB3pmROW8bg3CnLnpjkRVwUlLne7Ufa2r9yJ8+/6B73RzhAek5TBKh2Q==}
'@types/remarkable@2.0.8':
resolution: {integrity: sha512-eKXqPZfpQl1kOADjdKchHrp2gwn9qMnGXhH/AtZe0UrklzhGJkawJo/Y/D0AlWcdWoWamFNIum8+/nkAISQVGg==}
@@ -2852,8 +2856,8 @@ packages:
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
engines: {node: '>=0.4.0'}
property-information@7.0.0:
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
property-information@7.1.0:
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@@ -3239,10 +3243,17 @@ packages:
tldts-core@6.1.85:
resolution: {integrity: sha512-DTjUVvxckL1fIoPSb3KE7ISNtkWSawZdpfxGxwiIrZoO6EbHVDXXUIlIuWympPaeS+BLGyggozX/HTMsRAdsoA==}
tldts-core@7.0.7:
resolution: {integrity: sha512-ECqb8imSroX1UmUuhRBNPkkmtZ8mHEenieim80UVxG0M5wXVjY2Fp2tYXCPvk+nLy1geOhFpeD5YQhM/gF63Jg==}
tldts@6.1.85:
resolution: {integrity: sha512-gBdZ1RjCSevRPFix/hpaUWeak2/RNUZB4/8frF1r5uYMHjFptkiT0JXIebWvgI/0ZHXvxaUDDJshiA0j6GdL3w==}
hasBin: true
tldts@7.0.7:
resolution: {integrity: sha512-ETNXj36ql5BXDa4VVJk3wgqansg8TI1Yqo217twSAPjyDnh/b2T+XzrI0ftn6EnzVPbXpMTZHOWj5s3a8/uGPA==}
hasBin: true
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -3617,11 +3628,11 @@ snapshots:
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@1959': {}
'@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)':
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@12707b95033c5822745ec6a2250a9cd0de10a498(svelte@5.25.3)':
dependencies:
svelte: 5.25.3
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@510c1a70bb1a11aa8a58177e657dec6199215595(svelte@5.25.3)':
'@appwrite.io/pink-icons-svelte@https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-icons-svelte@12707b9(svelte@5.25.3)':
dependencies:
svelte: 5.25.3
@@ -3634,9 +3645,9 @@ snapshots:
'@appwrite.io/pink-icons': 1.0.0
the-new-css-reset: 1.11.3
'@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@510c1a7(svelte@5.25.3)':
'@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@12707b9(svelte@5.25.3)':
dependencies:
'@appwrite.io/pink-icons-svelte': https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@510c1a70bb1a11aa8a58177e657dec6199215595(svelte@5.25.3)
'@appwrite.io/pink-icons-svelte': https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@12707b95033c5822745ec6a2250a9cd0de10a498(svelte@5.25.3)
'@floating-ui/dom': 1.6.13
'@melt-ui/pp': 0.3.2(@melt-ui/svelte@0.86.6(svelte@5.25.3))(svelte@5.25.3)
'@melt-ui/svelte': 0.86.6(svelte@5.25.3)
@@ -4777,7 +4788,7 @@ snapshots:
'@types/prop-types@15.7.14': {}
'@types/react@18.3.20':
'@types/react@18.3.22':
dependencies:
'@types/prop-types': 15.7.14
csstype: 3.1.3
@@ -5879,7 +5890,7 @@ snapshots:
hast-util-whitespace: 3.0.0
html-void-elements: 3.0.0
mdast-util-to-hast: 13.2.0
property-information: 7.0.0
property-information: 7.1.0
space-separated-tokens: 2.0.2
stringify-entities: 4.0.4
zwitch: 2.0.4
@@ -6412,7 +6423,7 @@ snapshots:
progress@2.0.3: {}
property-information@7.0.0: {}
property-information@7.1.0: {}
proxy-from-env@1.1.0: {}
@@ -6725,7 +6736,7 @@ snapshots:
svelte-motion@0.12.2(svelte@5.25.3):
dependencies:
'@types/react': 18.3.20
'@types/react': 18.3.22
framesync: 6.1.2
popmotion: 11.0.5
style-value-types: 5.1.2
@@ -6834,10 +6845,16 @@ snapshots:
tldts-core@6.1.85: {}
tldts-core@7.0.7: {}
tldts@6.1.85:
dependencies:
tldts-core: 6.1.85
tldts@7.0.7:
dependencies:
tldts-core: 7.0.7
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
@@ -17,7 +17,7 @@
{domain}
</Typography.Text>
{#if verified}
<Badge variant="secondary" type="success" content="Verified" />
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{:else if verified === false}
<Badge variant="secondary" type="warning" size="xs" content="Pending verification" />
{/if}
@@ -38,9 +38,9 @@
{domain}
</Typography.Text>
{#if verified}
<Badge variant="secondary" type="success" content="Verified" />
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{:else if verified === false}
<Badge variant="secondary" type="error" content="Verification failed" />
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else}
<Badge
variant="secondary"
+20 -4
View File
@@ -1,23 +1,39 @@
<script lang="ts">
import { setContext, onMount } from 'svelte';
import { Card } from '@appwrite.io/pink-svelte';
import { createMenubar, melt } from '@melt-ui/svelte';
import { menuOpen } from '$lib/components/menu/store';
import { activeMenuId, menuOpen } from '$lib/components/menu/store';
const menuId = Math.random().toString(36).slice(2);
const {
elements: { menubar },
builders: { createMenu }
} = createMenubar();
const {
elements: { trigger: trigger, menu: menu, separator: separator },
states: { open }
elements: { trigger, menu, separator },
states: { open },
builders // for submenu for same toggle state
} = createMenu();
function toggle() {
open.update((state) => !state);
}
$: menuOpen.set($open);
open.subscribe((state) => {
if (state) activeMenuId.set(menuId);
else activeMenuId.update((current) => (current === menuId ? null : current));
});
onMount(() => {
return activeMenuId.subscribe((id) => {
if (id !== menuId) open.set(false);
});
});
$: menuOpen.set($open as boolean);
setContext('menuBuilder', { builders, separator });
</script>
<div use:melt={$menubar}>
+14
View File
@@ -1,3 +1,17 @@
import { writable } from 'svelte/store';
import type { createMenubar } from '@melt-ui/svelte';
export const menuOpen = writable(false);
export const activeMenuId = writable<string | null>(null);
/**
* Full menu context passed to submenus
* includes `builders` and shared `separator`.
*/
export type MenuContext = {
separator: ReturnType<
ReturnType<typeof createMenubar>['builders']['createMenu']
>['elements']['separator'];
builders: ReturnType<ReturnType<typeof createMenubar>['builders']['createMenu']>['builders'];
};
+6 -9
View File
@@ -1,15 +1,12 @@
<script lang="ts">
import { getContext } from 'svelte';
import { melt } from '@melt-ui/svelte';
import type { MenuContext } from './store';
import { Card } from '@appwrite.io/pink-svelte';
import { createMenubar, melt } from '@melt-ui/svelte';
const {
builders: { createMenu }
} = createMenubar();
const {
elements: { separator: separator },
builders: { createSubmenu: createSubmenu }
} = createMenu();
// get parent builder for toggle state!
const { builders, separator } = getContext<MenuContext>('menuBuilder');
const { createSubmenu } = builders;
const {
elements: { subMenu: subMenu, subTrigger: subTrigger }
+1 -1
View File
@@ -49,7 +49,7 @@
{pattern}
on:input
on:invalid={handleInvalid}
type="email"
type="text"
helper={error}
state={error ? 'error' : 'default'}
autofocus={autofocus || undefined}
+21
View File
@@ -0,0 +1,21 @@
import { parse } from 'tldts';
/**
* Returns the apex/root domain from a full domain string.
*/
export function getApexDomain(domain: string): string | null {
return parse(domain).domain;
}
/**
* Checks whether the given domain is a subdomain.
*/
export function isASubdomain(domain: string | null): boolean {
if (!domain) return false;
const { domain: apex, subdomain } = parse(domain);
if (!apex) return false;
if (subdomain === 'www') return false;
return !!subdomain;
}
+2
View File
@@ -338,6 +338,8 @@ export type Plan = {
backupPolicies: number;
emailBranding: boolean;
supportsCredits: boolean;
buildSize: number; // in MB
deploymentSize: number; // in MB
};
export type PlanList = {
@@ -1,27 +1,31 @@
<script lang="ts">
import { sdk } from '$lib/stores/sdk';
import { addNotification } from '$lib/stores/notifications';
import { invalidate } from '$app/navigation';
import { goto, invalidate } from '$app/navigation';
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
import { Dependencies } from '$lib/constants';
import { Confirm } from '$lib/components';
import type { Domain } from '$lib/sdk/domains';
import { base } from '$app/paths';
import { page } from '$app/state';
export let show = false;
export let selectedDomain: Domain;
let error = '';
let domainsList = `${base}/organization-${page.params.organization}/domains`;
async function deleteDomain() {
try {
await sdk.forConsole.domains.delete(selectedDomain.$id);
await invalidate(Dependencies.DOMAINS);
show = false;
addNotification({
type: 'success',
message: `${selectedDomain.domain} has been deleted`
});
trackEvent(Submit.DomainDelete);
await goto(domainsList);
await invalidate(Dependencies.DOMAINS);
} catch (e) {
error = e.message;
trackError(e, Submit.DomainDelete);
@@ -14,8 +14,7 @@
canSeeProjects,
canSeeTeams,
isBilling,
isOwner,
scopes
isOwner
} from '$lib/stores/roles';
import { GRACE_PERIOD_OVERRIDE, isCloud } from '$lib/system';
import { IconGithub, IconPlus } from '@appwrite.io/pink-icons-svelte';
@@ -33,7 +32,6 @@
$: avatars = $members.memberships?.map((m) => m.userName || m.userEmail) ?? [];
$: organizationId = page.params.organization;
$: path = `${base}/organization-${organizationId}`;
$: console.log($scopes);
$: tabs = [
{
href: path,
@@ -12,7 +12,6 @@
import {
Alert,
Avatar,
Badge,
Card,
Divider,
Icon,
@@ -151,12 +150,12 @@
<Typography.Text color="--fgcolor-neutral-primary">
<Layout.Stack direction="row" gap="xs" alignItems="center">
{runtimeDetail?.name}
{#if runtimeDetail?.name?.toLowerCase() === 'deno'}
<Badge
variant="secondary"
size="xs"
content="New" />
{/if}
<!--{#if runtimeDetail?.name?.toLowerCase() === 'deno'}-->
<!-- <Badge-->
<!-- variant="secondary"-->
<!-- size="xs"-->
<!-- content="New" />-->
<!--{/if}-->
</Layout.Stack>
</Typography.Text>
</Layout.Stack>
@@ -86,7 +86,7 @@
if (page.url.searchParams.has('runtime')) {
runtime = page.url.searchParams.get('runtime') as Runtime;
} else {
runtime = matchingRuntimes[0];
runtime = matchingRuntimes[0] as Runtime;
}
}
});
@@ -4,14 +4,14 @@
import { Repositories } from '$lib/components/git';
import { Dependencies } from '$lib/constants';
import { Link } from '$lib/elements';
import { Button, InputCheckbox, InputSelect } from '$lib/elements/forms';
import { Button, InputCheckbox } from '$lib/elements/forms';
import { timeFromNow } from '$lib/helpers/date';
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
import { installation, repository, sortBranches } from '$lib/stores/vcs';
import { Runtime, VCSDeploymentType, type Models } from '@appwrite.io/console';
import { IconGithub } from '@appwrite.io/pink-icons-svelte';
import { Icon, Layout, Skeleton, Typography } from '@appwrite.io/pink-svelte';
import { Icon, Input, Layout, Skeleton, Typography } from '@appwrite.io/pink-svelte';
import { func } from '../store';
import { page } from '$app/state';
@@ -120,6 +120,14 @@
error = e.message;
}
}
$: if (!show) {
error = '';
branch = null;
commit = null;
activate = true;
hasRepository = !!$func?.providerRepositoryId;
}
</script>
<Modal title="Create Git deployment" bind:show onSubmit={createDeployment} bind:error>
@@ -179,13 +187,13 @@
</Typography.Caption>
</Layout.Stack>
</Card>
<InputSelect
required={true}
<Input.ComboBox
required
id="branch"
label="Production branch"
placeholder="Select branch"
bind:value={branch}
isSearchable
bind:value={branch}
on:select={(event) => {
branch = event.detail.value;
}}
@@ -11,12 +11,22 @@
import { Icon, Layout, Tooltip, Typography, Upload } from '@appwrite.io/pink-svelte';
import { func } from '../store';
import { page } from '$app/state';
import { consoleVariables } from '$routes/(console)/store';
import { currentPlan } from '$lib/stores/organization';
import { isCloud } from '$lib/system';
export let show = false;
let files: FileList;
let error: string = '';
$: maxSize =
isCloud && $currentPlan
? $currentPlan?.deploymentSize === 0
? 0
: $currentPlan?.deploymentSize * 1000000
: $consoleVariables._APP_COMPUTE_SIZE_LIMIT; // already in MB
async function create() {
try {
await sdk
@@ -69,7 +79,7 @@
<Upload.Dropzone
extensions={['gz', 'tar']}
bind:files
maxSize={10000000}
{maxSize}
required
on:invalid={handleInvalid}>
<Layout.Stack alignItems="center" gap="s">
@@ -36,7 +36,7 @@
invalidate(Dependencies.DEPLOYMENTS);
if (redirect) {
goto(
`${base}/project-${page.params.region}-${page.params.project}/functions/function-${$func.$id}/deployments/deployment-${deployment.$id}`
`${base}/project-${page.params.region}-${page.params.project}/functions/function-${$func.$id}/deployment-${deployment.$id}`
);
}
show = false;
@@ -20,6 +20,7 @@
import { isValueOfStringEnum } from '$lib/helpers/types.js';
import { isCloud } from '$lib/system';
import { project } from '$routes/(console)/project-[region]-[project]/store';
import { getApexDomain } from '$lib/helpers/tlds';
const routeBase = `${base}/project-${page.params.region}-${page.params.project}/functions/function-${page.params.function}/domains`;
@@ -47,14 +48,12 @@
});
async function addDomain() {
let domain = data.domains?.domains.find((d) => d.domain === domainName);
const apexDomain = getApexDomain(domainName);
let domain = data.domains?.domains.find((d) => d.domain === apexDomain);
if (!domain && isCloud) {
if (apexDomain && !domain && isCloud) {
try {
domain = await sdk.forConsole.domains.create(
$project.teamId,
domainName.toLocaleLowerCase()
);
domain = await sdk.forConsole.domains.create($project.teamId, apexDomain);
} catch (error) {
addNotification({
type: 'error',
@@ -20,6 +20,7 @@
import Wizard from '$lib/layout/wizard.svelte';
import { base } from '$app/paths';
import { writable } from 'svelte/store';
import { isASubdomain } from '$lib/helpers/tlds';
import { consoleVariables } from '$routes/(console)/store';
import NameserverTable from '$lib/components/domains/nameserverTable.svelte';
import RecordTable from '$lib/components/domains/recordTable.svelte';
@@ -27,7 +28,7 @@
let { data } = $props();
const ruleId = page.url.searchParams.get('rule');
let isSubDomain = $derived(page.params.domain?.split('.')?.length >= 3);
const isSubDomain = $derived.by(() => isASubdomain(page.params.domain));
let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>('nameserver');
$effect(() => {
@@ -126,7 +127,7 @@
Nameservers
</Tabs.Item.Button>
{/if}
{#if !!$consoleVariables._APP_DOMAIN_TARGET_A && $consoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'}
{#if !isCloud && !!$consoleVariables._APP_DOMAIN_TARGET_A && $consoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'}
<Tabs.Item.Button
{root}
on:click={() => (selectedTab = 'a')}
@@ -134,7 +135,7 @@
A
</Tabs.Item.Button>
{/if}
{#if !!$consoleVariables._APP_DOMAIN_TARGET_AAAA && $consoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'}
{#if !isCloud && !!$consoleVariables._APP_DOMAIN_TARGET_AAAA && $consoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'}
<Tabs.Item.Button
{root}
on:click={() => (selectedTab = 'aaaa')}
@@ -1,23 +1,17 @@
import { sdk } from '$lib/stores/sdk';
import { Dependencies } from '$lib/constants.js';
import { isCloud } from '$lib/system';
import type { Domain, DomainsList } from '$lib/sdk/domains.js';
import { Dependencies } from '$lib/constants.js';
import type { DomainsList } from '$lib/sdk/domains.js';
export const load = async ({ depends, params }) => {
export const load = async ({ depends }) => {
depends(Dependencies.DOMAINS);
let domain: Domain;
let domainsList: DomainsList;
if (isCloud) {
domainsList = await sdk.forConsole.domains.list();
const domainId = domainsList.domains.find(
(domain: Domain) => domain.domain === params.domain
).$id;
domain = await sdk.forConsole.domains.get(domainId);
}
return {
domain,
domainsList
};
};
@@ -11,6 +11,7 @@
import { onMount } from 'svelte';
import { isCloud } from '$lib/system';
import { project } from '$routes/(console)/project-[region]-[project]/store';
import { getApexDomain } from '$lib/helpers/tlds';
const routeBase = `${base}/project-${page.params.region}-${page.params.project}/settings/domains`;
@@ -27,14 +28,12 @@
});
async function addDomain() {
let domain = data.domains?.domains.find((d) => d.domain === domainName);
const apexDomain = getApexDomain(domainName);
let domain = data.domains?.domains.find((d) => d.domain === apexDomain);
if (!domain && isCloud) {
if (apexDomain && !domain && isCloud) {
try {
domain = await sdk.forConsole.domains.create(
$project.teamId,
domainName.toLocaleLowerCase()
);
domain = await sdk.forConsole.domains.create($project.teamId, apexDomain);
} catch (error) {
addNotification({
type: 'error',
@@ -48,7 +47,7 @@
try {
const rule = await sdk
.forProject(page.params.region, page.params.project)
.proxy.createAPIRule(domainName);
.proxy.createAPIRule(domainName.toLocaleLowerCase());
if (rule?.status === 'verified') {
await goto(routeBase);
await invalidate(Dependencies.DOMAINS);
@@ -20,6 +20,7 @@
import Wizard from '$lib/layout/wizard.svelte';
import { base } from '$app/paths';
import { writable } from 'svelte/store';
import { isASubdomain } from '$lib/helpers/tlds';
import { consoleVariables } from '$routes/(console)/store';
import NameserverTable from '$lib/components/domains/nameserverTable.svelte';
import RecordTable from '$lib/components/domains/recordTable.svelte';
@@ -27,7 +28,7 @@
let { data } = $props();
const ruleId = page.url.searchParams.get('rule');
let isSubDomain = $derived(page.params.domain?.split('.')?.length >= 3);
const isSubDomain = $derived.by(() => isASubdomain(page.params.domain));
let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>('nameserver');
$effect(() => {
@@ -125,7 +126,7 @@
Nameservers
</Tabs.Item.Button>
{/if}
{#if !!$consoleVariables._APP_DOMAIN_TARGET_A && $consoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'}
{#if !isCloud && !!$consoleVariables._APP_DOMAIN_TARGET_A && $consoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'}
<Tabs.Item.Button
{root}
on:click={() => (selectedTab = 'a')}
@@ -133,7 +134,7 @@
A
</Tabs.Item.Button>
{/if}
{#if !!$consoleVariables._APP_DOMAIN_TARGET_AAAA && $consoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'}
{#if !isCloud && !!$consoleVariables._APP_DOMAIN_TARGET_AAAA && $consoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'}
<Tabs.Item.Button
{root}
on:click={() => (selectedTab = 'aaaa')}
@@ -1,23 +1,17 @@
import { sdk } from '$lib/stores/sdk';
import { Dependencies } from '$lib/constants.js';
import { isCloud } from '$lib/system';
import type { Domain, DomainsList } from '$lib/sdk/domains.js';
import { Dependencies } from '$lib/constants.js';
import type { DomainsList } from '$lib/sdk/domains.js';
export const load = async ({ depends, params }) => {
export const load = async ({ depends }) => {
depends(Dependencies.DOMAINS);
let domain: Domain;
let domainsList: DomainsList;
if (isCloud) {
domainsList = await sdk.forConsole.domains.list();
const domainId = domainsList.domains.find(
(domain: Domain) => domain.domain === params.domain
).$id;
domain = await sdk.forConsole.domains.get(domainId);
}
return {
domain,
domainsList
};
};
@@ -11,8 +11,7 @@
import { onMount } from 'svelte';
import { project } from '../store';
import { canWriteProjects } from '$lib/stores/roles';
const endpoint = sdk.forConsole.client.config.endpoint;
import { getProjectEndpoint } from '$lib/helpers/project';
let name: string = null;
@@ -45,7 +44,7 @@
Access Appwrite services using this project's API Endpoint and Project ID.
<svelte:fragment slot="aside">
<CopyInput label="Project ID" value={$project.$id} />
<CopyInput label="API Endpoint" value={endpoint} />
<CopyInput label="API Endpoint" value={getProjectEndpoint()} />
</svelte:fragment>
<svelte:fragment slot="actions">
<Button
@@ -5,7 +5,7 @@
import { Repositories } from '$lib/components/git';
import { Dependencies } from '$lib/constants';
import { Link } from '$lib/elements';
import { Button, InputCheckbox, InputSelect } from '$lib/elements/forms';
import { Button, InputCheckbox } from '$lib/elements/forms';
import { timeFromNow } from '$lib/helpers/date';
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
@@ -18,7 +18,7 @@
type Models
} from '@appwrite.io/console';
import { IconGithub } from '@appwrite.io/pink-icons-svelte';
import { Icon, Layout, Skeleton, Typography } from '@appwrite.io/pink-svelte';
import { Icon, Input, Layout, Skeleton, Typography } from '@appwrite.io/pink-svelte';
export let show = false;
export let site: Models.Site;
@@ -125,6 +125,14 @@
error = e.message;
}
}
$: if (!show) {
error = '';
branch = null;
commit = null;
activate = true;
hasRepository = !!site?.providerRepositoryId;
}
</script>
<Modal title="Create Git deployment" bind:show onSubmit={createDeployment} bind:error>
@@ -184,13 +192,13 @@
</Typography.Caption>
</Layout.Stack>
</Card>
<InputSelect
required={true}
<Input.ComboBox
required
id="branch"
label="Production branch"
placeholder="Select branch"
bind:value={branch}
isSearchable
bind:value={branch}
on:select={(event) => {
branch = event.detail.value;
}}
@@ -9,6 +9,9 @@
import type { Models } from '@appwrite.io/console';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
import { Icon, Layout, Tooltip, Typography, Upload } from '@appwrite.io/pink-svelte';
import { isCloud } from '$lib/system';
import { currentPlan } from '$lib/stores/organization';
import { consoleVariables } from '$routes/(console)/store';
export let show = false;
export let site: Models.Site;
@@ -16,6 +19,13 @@
let files: FileList;
let error: string = '';
$: maxSize =
isCloud && $currentPlan
? $currentPlan?.deploymentSize === 0
? 0
: $currentPlan?.deploymentSize * 1000000
: $consoleVariables._APP_COMPUTE_SIZE_LIMIT; // already in MB
async function createDeployment() {
try {
uploader.uploadSiteDeployment(site.$id, files[0]);
@@ -63,7 +73,7 @@
<Upload.Dropzone
extensions={['gz', 'tar']}
bind:files
maxSize={10000000}
{maxSize}
required
on:invalid={handleInvalid}>
<Layout.Stack alignItems="center" gap="s">
@@ -29,8 +29,8 @@
let showDelete = $state(false);
let showCancel = $state(false);
onMount(async () => {
sdk.forConsole.client.subscribe(
onMount(() => {
return sdk.forConsole.client.subscribe(
'console',
async (response: RealtimeResponseEvent<Models.Deployment>) => {
if (
@@ -38,7 +38,7 @@
`sites.${page.params.site}.deployments.${page.params.deployment}.update`
)
) {
invalidate(Dependencies.DEPLOYMENTS);
await invalidate(Dependencies.DEPLOYMENT);
}
}
);
@@ -25,6 +25,7 @@
import { ConnectRepoModal } from '$lib/components/git/index.js';
import { project } from '$routes/(console)/project-[region]-[project]/store';
import { isCloud } from '$lib/system';
import { getApexDomain } from '$lib/helpers/tlds';
const routeBase = `${base}/project-${page.params.region}-${page.params.project}/sites/site-${page.params.site}/domains`;
@@ -52,14 +53,12 @@
});
async function addDomain() {
let domain = data.domains?.domains.find((d) => d.domain === domainName);
const apexDomain = getApexDomain(domainName);
let domain = data.domains?.domains.find((d) => d.domain === apexDomain);
if (!domain && isCloud) {
if (apexDomain && !domain && isCloud) {
try {
domain = await sdk.forConsole.domains.create(
$project.teamId,
domainName.toLocaleLowerCase()
);
domain = await sdk.forConsole.domains.create($project.teamId, apexDomain);
} catch (error) {
addNotification({
type: 'error',
@@ -175,13 +174,17 @@
value: branch.name
}))}
<Layout.Stack gap="s">
<InputSelect
{options}
label="Production branch"
id="branch"
<Input.ComboBox
required
id="branch"
label="Production branch"
placeholder="Select branch"
isSearchable
bind:value={branch}
placeholder="Select branch" />
on:select={(event) => {
branch = event.detail.value;
}}
{options} />
{#if !data.branches?.total}
<Input.Helper state="default">
No branches found in the selected repository. Create a
@@ -20,6 +20,7 @@
import Wizard from '$lib/layout/wizard.svelte';
import { base } from '$app/paths';
import { writable } from 'svelte/store';
import { isASubdomain } from '$lib/helpers/tlds';
import { consoleVariables } from '$routes/(console)/store';
import NameserverTable from '$lib/components/domains/nameserverTable.svelte';
import RecordTable from '$lib/components/domains/recordTable.svelte';
@@ -27,9 +28,10 @@
let { data } = $props();
const ruleId = page.url.searchParams.get('rule');
let isSubDomain = $derived(page.params.domain?.split('.')?.length >= 3);
const isSubDomain = $derived.by(() => isASubdomain(page.params.domain));
let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>('nameserver');
$effect(() => {
if ($consoleVariables._APP_DOMAIN_TARGET_CNAME && isSubDomain) {
selectedTab = 'cname';
@@ -127,7 +129,7 @@
Nameservers
</Tabs.Item.Button>
{/if}
{#if !!$consoleVariables._APP_DOMAIN_TARGET_A && $consoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'}
{#if !isCloud && !!$consoleVariables._APP_DOMAIN_TARGET_A && $consoleVariables._APP_DOMAIN_TARGET_A !== '127.0.0.1'}
<Tabs.Item.Button
{root}
on:click={() => (selectedTab = 'a')}
@@ -135,7 +137,7 @@
A
</Tabs.Item.Button>
{/if}
{#if !!$consoleVariables._APP_DOMAIN_TARGET_AAAA && $consoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'}
{#if !isCloud && !!$consoleVariables._APP_DOMAIN_TARGET_AAAA && $consoleVariables._APP_DOMAIN_TARGET_AAAA !== '::1'}
<Tabs.Item.Button
{root}
on:click={() => (selectedTab = 'aaaa')}
@@ -150,10 +152,10 @@
<NameserverTable domain={page.params.domain} {verified} />
{:else}
<RecordTable
domain={page.params.domain}
{verified}
service="sites"
variant={selectedTab}
service="sites" />
domain={page.params.domain} />
{/if}
<Divider />
<Layout.Stack direction="row" justifyContent="flex-end">
@@ -1,26 +1,20 @@
import { sdk } from '$lib/stores/sdk';
import { isCloud } from '$lib/system';
import { Dependencies } from '$lib/constants.js';
import type { Domain, DomainsList } from '$lib/sdk/domains.js';
import type { DomainsList } from '$lib/sdk/domains';
export const load = async ({ parent, depends, params }) => {
export const load = async ({ parent, depends }) => {
const { site } = await parent();
depends(Dependencies.SITES_DOMAINS);
let domain: Domain;
let domainsList: DomainsList;
if (isCloud) {
domainsList = await sdk.forConsole.domains.list();
const domainId = domainsList.domains.find(
(domain: Domain) => domain.domain === params.domain
).$id;
domain = await sdk.forConsole.domains.get(domainId);
}
return {
site,
domain,
domainsList
};
};
@@ -11,6 +11,7 @@
import { consoleVariables } from '$routes/(console)/store';
import { isCloud } from '$lib/system';
import { page } from '$app/state';
import { isASubdomain } from '$lib/helpers/tlds';
import NameserverTable from '$lib/components/domains/nameserverTable.svelte';
import RecordTable from '$lib/components/domains/recordTable.svelte';
@@ -22,9 +23,7 @@
selectedDomain: Models.ProxyRule;
} = $props();
let isSubDomain = $derived.by(() =>
selectedDomain?.domain?.length ? selectedDomain?.domain?.split('.')?.length >= 3 : false
);
const isSubDomain = $derived.by(() => isASubdomain(selectedDomain?.domain));
let selectedTab = $state<'cname' | 'nameserver' | 'a' | 'aaaa'>('nameserver');
$effect(() => {