From 083cee754bf43cf5cb48bb344f46c30e2c0bbe84 Mon Sep 17 00:00:00 2001 From: riccardoperra Date: Wed, 30 Oct 2024 19:15:08 +0100 Subject: [PATCH] refactor folder structure to fix extracted serverfns --- packages/app/app.config.ts | 13 ++-- .../Home/CurrentUser/CurrentUser.tsx | 9 ++- packages/app/src/components/Home/Home.tsx | 60 ++++++------------- packages/app/src/lib/scratchApi.ts | 38 +++--------- packages/app/src/lib/server/appwrite.ts | 33 +--------- packages/app/src/lib/server/session.ts | 33 ++++------ packages/app/src/lib/session.ts | 40 +++++++++++++ packages/app/src/routes/api/oauth.ts | 6 +- 8 files changed, 90 insertions(+), 142 deletions(-) create mode 100644 packages/app/src/lib/session.ts diff --git a/packages/app/app.config.ts b/packages/app/app.config.ts index 6a47488..7582189 100644 --- a/packages/app/app.config.ts +++ b/packages/app/app.config.ts @@ -1,20 +1,17 @@ import {defineConfig, ViteCustomizableConfig} from '@solidjs/start/config'; import {vanillaExtractPlugin} from '@vanilla-extract/vite-plugin'; -import viteTsConfigPaths from 'vite-tsconfig-paths'; -import {mergeConfig} from 'vite'; import remarkFrontmatter from 'remark-frontmatter'; +import {mergeConfig} from 'vite'; +import viteTsConfigPaths from 'vite-tsconfig-paths'; // @ts-expect-error missing types import pkg from '@vinxi/plugin-mdx'; const {default: vinxiMdx} = pkg; -import rehypeRaw from 'rehype-raw'; import {nodeTypes} from '@mdx-js/mdx'; -import remarkGfm from 'remark-gfm'; -import remarkExpressiveCode, { - ExpressiveCodeTheme, -} from 'remark-expressive-code'; -import rehypeSlug from 'rehype-slug'; import rehypeAutoLinkHeadings from 'rehype-autolink-headings'; +import rehypeRaw from 'rehype-raw'; +import rehypeSlug from 'rehype-slug'; +import remarkGfm from 'remark-gfm'; import {rehypeBlockquote} from './rehype-custom/rehypeCustomBlockquote'; diff --git a/packages/app/src/components/Home/CurrentUser/CurrentUser.tsx b/packages/app/src/components/Home/CurrentUser/CurrentUser.tsx index 5dce118..080dd10 100644 --- a/packages/app/src/components/Home/CurrentUser/CurrentUser.tsx +++ b/packages/app/src/components/Home/CurrentUser/CurrentUser.tsx @@ -1,7 +1,3 @@ -import {createAsync, useAction, useSubmission} from '@solidjs/router'; -import {loggedInUser, logout} from '~/lib/server/session'; -import {Show} from 'solid-js'; -import {badge, currentUser} from './CurrentUser.css'; import {Icon} from '#ui/components/Icon'; import { Button, @@ -10,8 +6,11 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from '@codeui/kit'; -import {signupWithGithub} from '~/lib/server/appwrite'; +import {useAction, useSubmission} from '@solidjs/router'; import type {Models} from 'appwrite'; +import {Show} from 'solid-js'; +import {logout, signupWithGithub} from '~/lib/session'; +import {badge, currentUser} from './CurrentUser.css'; export interface CurrentUserBarProps { user: Models.User | null; } diff --git a/packages/app/src/components/Home/Home.tsx b/packages/app/src/components/Home/Home.tsx index 8004690..eedac88 100644 --- a/packages/app/src/components/Home/Home.tsx +++ b/packages/app/src/components/Home/Home.tsx @@ -5,15 +5,9 @@ import { useSearchParams, useSubmission, } from '@solidjs/router'; -import { - createMemo, - createResource, - ErrorBoundary, - Show, - Suspense, -} from 'solid-js'; +import {ErrorBoundary, Show, Suspense, useTransition} from 'solid-js'; import {getGithubData} from '~/lib/githubApi'; -import {loggedInUser} from '~/lib/server/session'; +import {loggedInUser} from '~/lib/session'; import {createScratch} from '../../lib/scratchApi'; import {CurrentUserBar} from './CurrentUser/CurrentUser'; import {HomeFooter} from './Footer/Footer'; @@ -33,40 +27,15 @@ import {RepoSearch} from './RepoSearch/RepoSearch'; import {ScratchList} from './ScratchList/ScratchList'; export const searchRepo = cache( - async (path: string) => getGithubData(path), + async (path: string | null) => (path ? getGithubData(path) : null), 'search-repo', ); -export const route = { - preload: () => { - const [params] = useSearchParams(); - if (params.repo && typeof params.repo === 'string') { - return searchRepo(params.repo); - } - return null; - }, -}; - export function Home() { const user = createAsync(() => loggedInUser()); const isCreatingScratch = useSubmission(createScratch); const [params] = useSearchParams(); - - const [repo] = createResource( - () => params.repo, - repo => { - if (!repo || !(typeof repo === 'string')) { - return null; - } - return searchRepo(repo); - }, - ); - - const canViewList = createMemo(() => { - const loading = repo.loading; - const data = repo.latest; - return !loading && data; - }); + const repo = createAsync(() => searchRepo(params.repo as string | null)); return (
@@ -84,15 +53,22 @@ export function Home() { {repo.error?.message}
} + fallback={(err, reset) => ( +
{err.message}
+ )} > }> - - - - - - + + {repo => { + const [pendingTask] = useTransition(); + pendingTask(); + return ( + + ); + }} diff --git a/packages/app/src/lib/scratchApi.ts b/packages/app/src/lib/scratchApi.ts index 92b00ae..1ec2a1d 100644 --- a/packages/app/src/lib/scratchApi.ts +++ b/packages/app/src/lib/scratchApi.ts @@ -1,20 +1,9 @@ -import { - Client, - Databases, - ID, - Models, - Permission, - Query, - Role, -} from 'node-appwrite'; import {action, cache, json, redirect} from '@solidjs/router'; -import { - createAdminClient, - createSessionClient, - getLoggedInUser, -} from './server/appwrite'; +import {Permission, Role, Query, ID, Models} from 'appwrite'; import {adjectives, colors, uniqueNamesGenerator} from 'unique-names-generator'; import type {EditorParsedRepository} from '../components/Editor/editor.context'; +import {createAdminClient, createSessionClient} from './server/appwrite'; +import {loggedInUser} from './session'; function getScratchAppwriteVars() { 'use server'; @@ -26,21 +15,12 @@ function getScratchAppwriteVars() { export const updateScratch = action(async (id: string, newCode: string) => { 'use server'; - const projectId = process.env.APPWRITE_CLOUD_PROJECT_ID!; - const endpoint = process.env.APPWRITE_CLOUD_URL!; const {databaseId, scratchCollectionId} = getScratchAppwriteVars(); - const user = await getLoggedInUser(); + const user = await loggedInUser(); if (!user) { return; } - - const client = new Client() - .setProject(projectId) - .setEndpoint(endpoint) - .setSelfSigned(true) - .setSession(user.$id); - - const database = new Databases(client); + const {database} = await createSessionClient(); return database.updateDocument(databaseId, scratchCollectionId, id, { code: newCode, @@ -50,7 +30,7 @@ export const updateScratch = action(async (id: string, newCode: string) => { export const createScratch = action(async () => { 'use server'; const {databaseId, scratchCollectionId} = getScratchAppwriteVars(); - const user = await getLoggedInUser(); + const user = await loggedInUser(); if (!user) { return; @@ -121,7 +101,7 @@ export const createScratchFork = action( ) => { 'use server'; const {databaseId, scratchCollectionId} = getScratchAppwriteVars(); - const user = await getLoggedInUser(); + const user = await loggedInUser(); if (!user) { return; } @@ -169,7 +149,7 @@ export const createScratchFork = action( export const deleteScratch = action(async scratchId => { 'use server'; - const user = await getLoggedInUser(); + const user = await loggedInUser(); if (!user) { return; } @@ -200,7 +180,7 @@ export type ScratchesListResponse = Models.DocumentList; export const listUserScratches = cache(async () => { 'use server'; - const user = await getLoggedInUser(); + const user = await loggedInUser(); if (!user) { return {documents: [], total: 0}; } diff --git a/packages/app/src/lib/server/appwrite.ts b/packages/app/src/lib/server/appwrite.ts index e3b55db..37e17db 100644 --- a/packages/app/src/lib/server/appwrite.ts +++ b/packages/app/src/lib/server/appwrite.ts @@ -1,8 +1,7 @@ -'use server'; +import {action, redirect} from '@solidjs/router'; import {Account, Client, Databases, OAuthProvider} from 'node-appwrite'; import {getHeaders} from 'vinxi/http'; import {getSession} from './session'; -import {action, cache, redirect} from '@solidjs/router'; export async function createSessionClient() { 'use server'; @@ -26,15 +25,6 @@ export async function createSessionClient() { }; } -export async function getLoggedInUser() { - try { - const {account} = await createSessionClient(); - return await account.get(); - } catch (error) { - return null; - } -} - export async function createAdminClient() { 'use server'; const apiKey = process.env.APPWRITE_CLOUD_FULL_ACCESS_API_KEY!; @@ -55,24 +45,3 @@ export async function createAdminClient() { }, }; } - -export const signupWithGithub = action(async () => { - 'use server'; - const {account} = await createAdminClient(); - - const origin = getHeaders().origin; - const successUrl = `${origin}/api/oauth`; - const failureUrl = `${origin}/`; - - try { - const redirectUrl = await account.createOAuth2Token( - OAuthProvider.Github, - successUrl, - failureUrl, - ); - return redirect(redirectUrl); - } catch (e) { - console.error(e); - return redirect('error'); - } -}, 'signup-with-github'); diff --git a/packages/app/src/lib/server/session.ts b/packages/app/src/lib/server/session.ts index e8489fa..8349030 100644 --- a/packages/app/src/lib/server/session.ts +++ b/packages/app/src/lib/server/session.ts @@ -1,8 +1,6 @@ -'use server'; -import {action, cache, redirect} from '@solidjs/router'; -import {Models as NodeModels} from 'node-appwrite'; +import type {Models as NodeModels} from 'node-appwrite'; import {useSession} from 'vinxi/http'; -import {getLoggedInUser} from './appwrite'; +import {createSessionClient} from './appwrite'; export function getSession() { return useSession<{ @@ -12,21 +10,16 @@ export function getSession() { }); } -async function getUser(): Promise | null> { - const session = await getSession(); - const userId = session.data.session?.userId; - if (!userId) return null; - return getLoggedInUser(); +export async function getLoggedInUser() { + try { + const {account} = await createSessionClient(); + return await account.get(); + } catch (error) { + return null; + } } -export const loggedInUser = cache(async () => { - const session = await getSession(); - const userId = session.data.session?.userId; - if (!userId) return null; - return getLoggedInUser(); -}, 'logged_user'); - -async function logoutSession() { +export async function logoutSession() { try { const session = await getSession(); await session.update(d => { @@ -37,9 +30,3 @@ async function logoutSession() { console.error('error removing session'); } } - -export const logout = action(async () => { - 'use server'; - await logoutSession(); - return redirect('/'); -}, 'logout'); diff --git a/packages/app/src/lib/session.ts b/packages/app/src/lib/session.ts new file mode 100644 index 0000000..a55c8aa --- /dev/null +++ b/packages/app/src/lib/session.ts @@ -0,0 +1,40 @@ +import {action, cache, redirect} from '@solidjs/router'; +import {OAuthProvider} from 'node-appwrite'; +import {getHeaders} from 'vinxi/http'; +import {createAdminClient} from './server/appwrite'; +import {getLoggedInUser, getSession, logoutSession} from './server/session'; + +export const loggedInUser = cache(async () => { + 'use server'; + const session = await getSession(); + const userId = session.data.session?.userId; + if (!userId) return null; + return getLoggedInUser(); +}, 'currentUser'); + +export const signupWithGithub = action(async () => { + 'use server'; + const {account} = await createAdminClient(); + + const origin = getHeaders().origin; + const successUrl = `${origin}/api/oauth`; + const failureUrl = `${origin}/`; + + try { + const redirectUrl = await account.createOAuth2Token( + OAuthProvider.Github, + successUrl, + failureUrl, + ); + return redirect(redirectUrl); + } catch (e) { + console.error(e); + return redirect('error'); + } +}, 'signup-with-github'); + +export const logout = action(async () => { + 'use server'; + await logoutSession(); + return redirect('/'); +}, 'logout'); diff --git a/packages/app/src/routes/api/oauth.ts b/packages/app/src/routes/api/oauth.ts index 7454632..5986f3b 100644 --- a/packages/app/src/routes/api/oauth.ts +++ b/packages/app/src/routes/api/oauth.ts @@ -1,7 +1,7 @@ -import type {APIEvent} from '@solidjs/start/server'; -import {createAdminClient} from '../../lib/server/appwrite'; -import {getSession} from '../../lib/server/session'; import {redirect} from '@solidjs/router'; +import type {APIEvent} from '@solidjs/start/server'; +import {createAdminClient} from '~/lib/server/appwrite'; +import {getSession} from '~/lib/server/session'; export async function GET({request}: APIEvent) { const req = new Request(request);