Merge branch 'main' into init-3

This commit is contained in:
Jesse Winton
2025-04-24 09:40:24 -04:00
6 changed files with 166 additions and 68 deletions

View File

@@ -35,7 +35,7 @@
"@appwrite.io/console": "^0.6.4",
"@appwrite.io/pink": "~0.26.0",
"@appwrite.io/pink-icons": "~0.26.0",
"@appwrite.io/repo": "github:appwrite/appwrite#feat-multi-region-docs",
"@appwrite.io/repo": "github:appwrite/appwrite#1.6.x",
"@eslint/compat": "^1.2.7",
"@eslint/js": "^9.21.0",
"@fingerprintjs/fingerprintjs": "^4.5.1",

10
pnpm-lock.yaml generated
View File

@@ -31,8 +31,8 @@ importers:
specifier: ~0.26.0
version: 0.26.0
'@appwrite.io/repo':
specifier: github:appwrite/appwrite#feat-multi-region-docs
version: https://codeload.github.com/appwrite/appwrite/tar.gz/4d81a901cbc48b94a720392a2611da028ea934b9
specifier: github:appwrite/appwrite#1.6.x
version: https://codeload.github.com/appwrite/appwrite/tar.gz/ed8c39f649fc05973aefcddc7aad6a427cca02d5
'@eslint/compat':
specifier: ^1.2.7
version: 1.2.8(eslint@9.24.0(jiti@2.4.2))
@@ -287,8 +287,8 @@ packages:
'@appwrite.io/pink@0.26.0':
resolution: {integrity: sha512-iPeGE56pauzxuIXt15ZswjKCErwp3QdF3XOlJZfyYY7J2nirra85JNTL+3lWuFIf8yYWL7NbvCjhf8ig79TgwA==}
'@appwrite.io/repo@https://codeload.github.com/appwrite/appwrite/tar.gz/4d81a901cbc48b94a720392a2611da028ea934b9':
resolution: {tarball: https://codeload.github.com/appwrite/appwrite/tar.gz/4d81a901cbc48b94a720392a2611da028ea934b9}
'@appwrite.io/repo@https://codeload.github.com/appwrite/appwrite/tar.gz/ed8c39f649fc05973aefcddc7aad6a427cca02d5':
resolution: {tarball: https://codeload.github.com/appwrite/appwrite/tar.gz/ed8c39f649fc05973aefcddc7aad6a427cca02d5}
version: 0.0.0
'@asamuzakjp/css-color@3.1.2':
@@ -4238,7 +4238,7 @@ snapshots:
normalize.css: 8.0.1
the-new-css-reset: 1.11.3
'@appwrite.io/repo@https://codeload.github.com/appwrite/appwrite/tar.gz/4d81a901cbc48b94a720392a2611da028ea934b9': {}
'@appwrite.io/repo@https://codeload.github.com/appwrite/appwrite/tar.gz/ed8c39f649fc05973aefcddc7aad6a427cca02d5': {}
'@asamuzakjp/css-color@3.1.2':
dependencies:

View File

@@ -1,6 +1,6 @@
import { error } from '@sveltejs/kit';
import { OpenAPIV3 } from 'openapi-types';
import { Platform, type ServiceValue } from './references';
import { error } from '@sveltejs/kit';
export type SDKMethod = {
'rate-limit': number;
@@ -10,6 +10,7 @@ export type SDKMethod = {
title: string;
description: string;
demo: string;
group?: string;
parameters: Array<{
name: string;
description: string;
@@ -34,6 +35,7 @@ type SDKMethodModel = {
type AppwriteOperationObject = OpenAPIV3.OperationObject & {
'x-appwrite': {
method: string;
group?: string;
weight: number;
cookies: boolean;
type: string;
@@ -331,7 +333,8 @@ export async function getService(
data.methods.push({
id: operation['x-appwrite'].method,
demo: demo ?? '',
group: operation['x-appwrite'].group,
demo: typeof demo === 'string' ? demo : '',
title: operation.summary ?? '',
description: operation.description ?? '',
parameters: parameters ?? [],
@@ -344,6 +347,17 @@ export async function getService(
});
}
// Sort methods by weight from x-appwrite metadata
data.methods.sort((a, b) => {
const aPath = api.paths[a.url] as OpenAPIV3.PathItemObject;
const bPath = api.paths[b.url] as OpenAPIV3.PathItemObject;
const aMethod = a.method.toLowerCase() as Lowercase<OpenAPIV3.HttpMethods>;
const bMethod = b.method.toLowerCase() as Lowercase<OpenAPIV3.HttpMethods>;
const aWeight = (aPath?.[aMethod] as AppwriteOperationObject)?.['x-appwrite']?.weight ?? 0;
const bWeight = (bPath?.[bMethod] as AppwriteOperationObject)?.['x-appwrite']?.weight ?? 0;
return aWeight - bWeight;
});
return data;
}

View File

@@ -1,7 +1,7 @@
import { error } from '@sveltejs/kit';
import { getService } from '$lib/utils/specs';
import type { EntryGenerator, PageServerLoad } from './$types';
import { Platform, Service, type ServiceValue, versions } from '$lib/utils/references';
import { getService } from '$lib/utils/specs';
import { error } from '@sveltejs/kit';
import type { EntryGenerator, PageServerLoad } from './$types';
const services = Object.values(Service);
const platforms = Object.values(Platform);
@@ -19,8 +19,10 @@ export const entries: EntryGenerator = () => {
export const load: PageServerLoad = async ({ params }) => {
const { platform, service } = params;
const version = params.version === 'cloud' ? '1.6.x' : params.version;
if (!versions.includes(version)) error(404, 'Invalid version');
if (!services.includes(service as ServiceValue)) error(404, 'Invalid service');
if (!platforms.includes(platform as Platform)) error(404, 'Invalid platform');
if (!services.includes(service as ServiceValue)) error(404, 'Invalid service');
return getService(version, platform, service);
};

View File

@@ -34,6 +34,8 @@
const headings = getContext<LayoutContext>('headings');
let selected: string | undefined = $state(undefined);
let selectedMenuItem: HTMLElement;
headings.subscribe((n) => {
const noVisible = Object.values(n).every((n) => !n.visible);
if (selected && noVisible) {
@@ -42,7 +44,6 @@
for (const key in n) {
if (n[key].visible) {
selected = key;
break;
}
}
});
@@ -127,6 +128,62 @@
serviceDescription.substring(0, serviceDescription.indexOf('.') + 1)
);
/**
* Determines the order of operations based on the method title.
* For eg. Create account, Get account, List accounts, Update account, Delete account.
*/
function getOperationOrder(methodTitle: string): number {
const title = methodTitle.toLowerCase();
if (title.startsWith('create')) return 1;
if (title.startsWith('read') || title.startsWith('get') || title.startsWith('list'))
return 2;
if (title.startsWith('update')) return 3;
if (title.startsWith('delete')) return 4;
return 5; // Other operations
}
/**
* Sorts methods by their operation order and title
*/
function sortMethods(methods: any[]) {
return methods.sort((a, b) => {
const orderA = getOperationOrder(a.title);
const orderB = getOperationOrder(b.title);
if (orderA === orderB) {
return a.title.localeCompare(b.title);
}
return orderA - orderB;
});
}
/**
* Groups methods by their group attribute, null group goes to '' for ordering
*/
function groupMethodsByGroup(methods: any[]) {
return methods.reduce((acc, method) => {
const groupKey = method.group || '';
if (!acc[groupKey]) {
acc[groupKey] = [];
}
acc[groupKey].push(method);
return acc;
}, {});
}
function bindSelectedRef(node: HTMLElement, isSelected: boolean) {
if (isSelected) {
selectedMenuItem = node;
}
return {
update(newIsSelected: boolean) {
if (newIsSelected) {
selectedMenuItem = node;
}
}
};
}
let platformBindingForSelect = $derived(page.params.platform as Platform);
let platform = $derived(/**$preferredPlatform ?? */ page.params.platform as Platform);
let platformType = $derived(platform.startsWith('client-') ? 'CLIENT' : 'SERVER');
@@ -242,58 +299,62 @@
</div>
{/if}
</section>
{#each data.methods as method (method.id)}
<section class="web-article-content-grid-6-4">
<div class="web-article-content-grid-6-4-column-1 flex flex-col gap-8">
<header class="web-article-content-header">
<Heading id={method.id} level={2} inReferences>{method.title}</Heading>
</header>
<div class="flex flex-col gap-2">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html parse(method.description)}
{#each Object.entries(groupMethodsByGroup(data.methods)) as [group, methods]}
{#each sortMethods(methods) as method (method.id)}
<section class="web-article-content-grid-6-4">
<div class="web-article-content-grid-6-4-column-1 flex flex-col gap-8">
<header class="web-article-content-header">
<Heading id={method.id} level={2} inReferences
>{method.title}</Heading
>
</header>
<div class="flex flex-col gap-2">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html parse(method.description)}
</div>
<Accordion>
{#if method.parameters.length > 0}
<AccordionItem open={true} title="Request">
<Request {method} />
</AccordionItem>
{/if}
<AccordionItem title="Response">
<Response {method} />
</AccordionItem>
{#if method?.['rate-limit'] > 0 && method?.['rate-key']?.length > 0}
<AccordionItem title="Rate limits">
<RateLimits {method} {platformType} />
</AccordionItem>
{/if}
</Accordion>
</div>
<Accordion>
{#if method.parameters.length > 0}
<AccordionItem open={true} title="Request">
<Request {method} />
</AccordionItem>
{/if}
<AccordionItem title="Response">
<Response {method} />
</AccordionItem>
{#if method?.['rate-limit'] > 0 && method?.['rate-key']?.length > 0}
<AccordionItem title="Rate limits">
<RateLimits {method} {platformType} />
</AccordionItem>
{/if}
</Accordion>
</div>
<div class="web-article-content-grid-6-4-column-2 flex flex-col gap-8">
<div class="dark contents">
<div
class="sticky"
style="--inset-block-start:var(--p-grid-huge-navs-secondary-sticky-position);"
>
<Fence
language="text"
badge="Endpoint"
content="{method.method.toUpperCase()} {method.url}"
toCopy={method.url}
process
withLineNumbers={false}
/>
<div class="mt-6">
<div class="web-article-content-grid-6-4-column-2 flex flex-col gap-8">
<div class="dark contents">
<div
class="sticky"
style="--inset-block-start:var(--p-grid-huge-navs-secondary-sticky-position);"
>
<Fence
language={platform}
content={method.demo}
language="text"
badge="Endpoint"
content="{method.method.toUpperCase()} {method.url}"
toCopy={method.url}
process
withLineNumbers={false}
/>
<div class="mt-6">
<Fence
language={platform}
content={method.demo}
process
withLineNumbers={false}
/>
</div>
</div>
</div>
</div>
</div>
</section>
</section>
{/each}
{/each}
</div>
<aside
@@ -325,13 +386,27 @@
</button>
</div>
<ul class="web-references-menu-list">
{#each data.methods as method}
<li class="web-references-menu-item">
<a
href={`#${method.id}`}
class="web-references-menu-link text-caption"
class:is-selected={method.id === selected}>{method.title}</a
>
{#each Object.entries(groupMethodsByGroup(data.methods)) as [group, methods]}
<li class="web-references-menu-group">
{#if group !== ''}
<h6 class="text-micro text-greyscale-500 mb-2 uppercase">
{group}
</h6>
{/if}
<ul class="flex flex-col gap-2">
{#each sortMethods(methods) as method}
<li class="web-references-menu-item">
<a
href={`#${method.id}`}
class="web-references-menu-link text-caption"
class:is-selected={method.id === selected}
use:bindSelectedRef={method.id === selected}
>
{method.title}
</a>
</li>
{/each}
</ul>
</li>
{/each}
</ul>
@@ -352,4 +427,11 @@
.web-inline-code {
translate: 0 0.125rem;
}
.web-references-menu-group {
margin-bottom: 1.5rem;
&:last-child {
margin-bottom: 0;
}
}
</style>

View File

@@ -1,9 +1,9 @@
import dynamicImport from 'vite-plugin-dynamic-import';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
import { enhancedImages } from '@sveltejs/enhanced-img';
import { sveltekit } from '@sveltejs/kit/vite';
import dynamicImport from 'vite-plugin-dynamic-import';
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
import manifestSRI from 'vite-plugin-manifest-sri';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [