diff --git a/bun-tests/fake-snippets-api/routes/packages/list_latest.test.ts b/bun-tests/fake-snippets-api/routes/packages/list_latest.test.ts index 809bef746..46ed82e39 100644 --- a/bun-tests/fake-snippets-api/routes/packages/list_latest.test.ts +++ b/bun-tests/fake-snippets-api/routes/packages/list_latest.test.ts @@ -12,6 +12,7 @@ test("list latest packages", async () => { owner_github_username: "user1", creator_account_id: "creator1", created_at: "2023-01-01T00:00:00Z", + owner_tscircuit_handle: "user1", updated_at: "2023-01-01T00:00:00Z", description: "Description 1", ai_description: "AI Description 1", @@ -28,6 +29,7 @@ test("list latest packages", async () => { owner_github_username: "user2", creator_account_id: "creator2", created_at: "2023-01-02T00:00:00Z", + owner_tscircuit_handle: "user2", updated_at: "2023-01-02T00:00:00Z", description: "Description 2", ai_description: "AI Description 2", @@ -44,6 +46,7 @@ test("list latest packages", async () => { owner_github_username: "user3", creator_account_id: "creator3", created_at: "2023-01-03T00:00:00Z", + owner_tscircuit_handle: "user3", updated_at: "2023-01-03T00:00:00Z", description: "Description 3", ai_description: "AI Description 3", @@ -61,6 +64,7 @@ test("list latest packages", async () => { owner_github_username: "user4", creator_account_id: "creator4", created_at: "2023-01-04T00:00:00Z", + owner_tscircuit_handle: "user4", updated_at: "2023-01-04T00:00:00Z", description: "Snippet Description", ai_description: "AI Description", diff --git a/fake-snippets-api/lib/db/db-client.ts b/fake-snippets-api/lib/db/db-client.ts index f6b875aa0..f168660a4 100644 --- a/fake-snippets-api/lib/db/db-client.ts +++ b/fake-snippets-api/lib/db/db-client.ts @@ -347,6 +347,7 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({ > & { creator_account_id?: string github_repo_full_name?: string + owner_org_id?: string branch_name?: string commit_message?: string commit_author?: string @@ -362,7 +363,7 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({ const newPackage = { package_id: `pkg_${nextId}`, creator_account_id: snippet.creator_account_id ?? snippet.owner_name, // Using owner_name as account_id since we don't have context - owner_org_id: "", // Empty string instead of null to match type + owner_org_id: snippet.owner_org_id ?? "", owner_github_username: snippet.owner_name, is_source_from_github: false, description: snippet.description || "", @@ -1162,7 +1163,7 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({ return false } return ( - account.github_username.toLowerCase().includes(lowercaseQuery) || + account.github_username?.toLowerCase().includes(lowercaseQuery) || (account.tscircuit_handle?.toLowerCase().includes(lowercaseQuery) ?? false) ) @@ -1362,12 +1363,13 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({ _package: Omit< z.input, "package_id" | "github_repo_full_name" - >, + > & { + github_repo_full_name?: string | null + }, ): Package => { const timestamp = Date.now() const newPackage = { package_id: `package_${timestamp}`, - github_repo_full_name: null, latest_pcb_preview_image_url: _package.latest_pcb_preview_image_url ?? `/api/packages/images/${_package.name}`, @@ -1377,6 +1379,7 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({ latest_sch_preview_image_url: _package.latest_sch_preview_image_url ?? `/api/packages/images/${_package.name}`, + github_repo_full_name: _package.github_repo_full_name ?? null, ..._package, } set((state) => ({ @@ -1711,7 +1714,6 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({ }, auth?: { account_id?: string }, ) => { - console.log(filters) let orgs = get().organizations if (filters?.owner_account_id) { orgs = orgs.filter( @@ -1727,9 +1729,12 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({ }) } if (filters?.tscircuit_handle) { - orgs = orgs.filter( - (org) => org.tscircuit_handle === filters.tscircuit_handle, - ) + orgs = orgs.filter((org) => { + const account = get().accounts.find( + (account) => account.account_id === org.owner_account_id, + ) + return account?.tscircuit_handle === filters.tscircuit_handle + }) } if (filters?.name) { orgs = orgs.filter( diff --git a/fake-snippets-api/lib/db/schema.ts b/fake-snippets-api/lib/db/schema.ts index 4b3493042..9df4b9533 100644 --- a/fake-snippets-api/lib/db/schema.ts +++ b/fake-snippets-api/lib/db/schema.ts @@ -69,7 +69,7 @@ export const shippingInfoSchema = z.object({ }) export const accountSchema = z.object({ account_id: z.string(), - github_username: z.string(), + github_username: z.string().nullable(), tscircuit_handle: z.string().nullable(), shippingInfo: shippingInfoSchema.optional(), personal_org_id: z.string().nullable(), diff --git a/fake-snippets-api/lib/db/seed.ts b/fake-snippets-api/lib/db/seed.ts index 22ddbb952..50d74a44a 100644 --- a/fake-snippets-api/lib/db/seed.ts +++ b/fake-snippets-api/lib/db/seed.ts @@ -592,6 +592,7 @@ export default () => ( creator_account_id: account_id, owner_org_id: "org-1234", owner_github_username: "testuser", + github_repo_full_name: "testuser/test", description: "A test package for development", created_at: new Date().toISOString(), updated_at: new Date().toISOString(), @@ -729,6 +730,7 @@ export const TestComponent = ({ name }: { name: string }) => ( db.addSnippet({ name: "seveibar/a555timer", unscoped_name: "a555timer", + owner_org_id: "org-1234", owner_name: "seveibar", code: ` export const A555Timer = ({ name }: { name: string }) => ( @@ -1260,6 +1262,7 @@ exports.A555Timer = A555Timer; name: "testuser/a555timer-square-wave", unscoped_name: "a555timer-square-wave", owner_name: "testuser", + owner_org_id: "org-1234", branch_name: "main", commit_message: "Attempted build of a555timer-square-wave package", commit_author: "testuser", diff --git a/fake-snippets-api/lib/middleware/with-session-auth.ts b/fake-snippets-api/lib/middleware/with-session-auth.ts index 8c8c12dfd..daab30ef5 100644 --- a/fake-snippets-api/lib/middleware/with-session-auth.ts +++ b/fake-snippets-api/lib/middleware/with-session-auth.ts @@ -13,7 +13,7 @@ export const withSessionAuth: Middleware< type: "session" account_id: string personal_org_id: string - github_username: string + github_username: string | null tscircuit_handle: string | null session_id: string orgs: Array<{ diff --git a/fake-snippets-api/routes/api/accounts/get.ts b/fake-snippets-api/routes/api/accounts/get.ts index a1b2f885b..9f9cd1765 100644 --- a/fake-snippets-api/routes/api/accounts/get.ts +++ b/fake-snippets-api/routes/api/accounts/get.ts @@ -11,6 +11,7 @@ export default withRouteSpec({ auth: "session", commonParams: z.object({ github_username: z.string().optional(), + tscircuit_handle: z.string().optional(), }), jsonResponse: z.object({ account: publicAccountSchema.extend({ @@ -19,8 +20,13 @@ export default withRouteSpec({ }), })(async (req, ctx) => { let account: Account | undefined - const { github_username } = req.commonParams - if (github_username) { + const { github_username, tscircuit_handle } = req.commonParams + if (tscircuit_handle) { + account = ctx.db.accounts.find( + (acc: Account) => + acc.tscircuit_handle?.toLowerCase() === tscircuit_handle.toLowerCase(), + ) + } else if (github_username) { const foundAccount = ctx.db.accounts.find( (acc: Account) => acc.github_username?.toLowerCase() === github_username.toLowerCase(), diff --git a/fake-snippets-api/routes/api/github/installations/create_new_installation_redirect.ts b/fake-snippets-api/routes/api/github/installations/create_new_installation_redirect.ts index f78e79f2a..6993350ac 100644 --- a/fake-snippets-api/routes/api/github/installations/create_new_installation_redirect.ts +++ b/fake-snippets-api/routes/api/github/installations/create_new_installation_redirect.ts @@ -39,7 +39,7 @@ export default withRouteSpec({ github_installation_id: githubInstallationId, account_id: ctx.auth.account_id, installation_id: mockInstallationId, - github_username: account.github_username, + github_username: account.github_username as string, created_at: new Date().toISOString(), updated_at: new Date().toISOString(), is_active: true, diff --git a/fake-snippets-api/routes/api/orgs/list.ts b/fake-snippets-api/routes/api/orgs/list.ts index 59f2afb99..ec3605549 100644 --- a/fake-snippets-api/routes/api/orgs/list.ts +++ b/fake-snippets-api/routes/api/orgs/list.ts @@ -22,7 +22,7 @@ export default withRouteSpec({ message: "You must provide filtering parameters", }) } - console.log(2, github_handle, tscircuit_handle) + const orgs = ctx.db.getOrgs( { github_handle, diff --git a/fake-snippets-api/routes/api/packages/create.ts b/fake-snippets-api/routes/api/packages/create.ts index a5031ffb4..f79ec32a5 100644 --- a/fake-snippets-api/routes/api/packages/create.ts +++ b/fake-snippets-api/routes/api/packages/create.ts @@ -55,13 +55,15 @@ export default withRouteSpec({ } if (!owner_segment) { - owner_segment = org_id ? org!.org_name : ctx.auth.github_username + owner_segment = org_id + ? (org!.org_name ?? "") + : (ctx.auth.github_username ?? "") } const final_name = name ?? `${owner_segment}/${unscoped_name}` const requested_owner_lower = owner_segment.toLowerCase() - const personal_owner_lower = ctx.auth.github_username.toLowerCase() + const personal_owner_lower = ctx.auth.github_username?.toLowerCase() let owner_org_id = ctx.auth.personal_org_id let owner_github_username = ctx.auth.github_username diff --git a/fake-snippets-api/routes/api/packages/list.ts b/fake-snippets-api/routes/api/packages/list.ts index 22a3a7a07..6ec8f0e44 100644 --- a/fake-snippets-api/routes/api/packages/list.ts +++ b/fake-snippets-api/routes/api/packages/list.ts @@ -12,6 +12,7 @@ export default withRouteSpec({ owner_org_id: z.string().optional(), name: z.string().optional(), limit: z.number().int().min(1).optional(), + starred_by: z.string().optional(), }), jsonResponse: z.object({ ok: z.boolean(), @@ -34,6 +35,7 @@ export default withRouteSpec({ is_writable, owner_org_id, limit, + starred_by, } = req.commonParams const auth = "auth" in ctx && ctx.auth ? ctx.auth : null @@ -81,6 +83,24 @@ export default withRouteSpec({ if (owner_org_id) { packages = packages.filter((p) => p.owner_org_id === owner_org_id) } + if (starred_by) { + const starredByAccount = ctx.db.accounts.find( + (acc) => acc.github_username?.toLowerCase() === starred_by.toLowerCase(), + ) + if (starredByAccount) { + const starredPackageIds = new Set( + ctx.db.accountPackages + .filter( + (ap) => + ap.account_id === starredByAccount.account_id && ap.is_starred, + ) + .map((ap) => ap.package_id), + ) + packages = packages.filter((p) => starredPackageIds.has(p.package_id)) + } else { + packages = [] + } + } if (limit) { packages = packages.slice(0, limit) } diff --git a/fake-snippets-api/routes/api/snippets/create.ts b/fake-snippets-api/routes/api/snippets/create.ts index 461d276e9..7a66a35ee 100644 --- a/fake-snippets-api/routes/api/snippets/create.ts +++ b/fake-snippets-api/routes/api/snippets/create.ts @@ -173,6 +173,7 @@ export default withRouteSpec({ return ctx.json({ ok: true, + // @ts-expect-error depreceated snippets routes snippet: snippetResponse, }) } catch (error) { diff --git a/fake-snippets-api/routes/api/snippets/list.ts b/fake-snippets-api/routes/api/snippets/list.ts index 756af35df..cf39c5982 100644 --- a/fake-snippets-api/routes/api/snippets/list.ts +++ b/fake-snippets-api/routes/api/snippets/list.ts @@ -40,7 +40,8 @@ export default withRouteSpec({ if (starred_by) { starredByAccount = ctx.db.accounts.find( - (acc) => acc.github_username.toLowerCase() === starred_by.toLowerCase(), + (acc) => + acc.github_username?.toLowerCase() === starred_by.toLowerCase(), ) || null if (starredByAccount) { diff --git a/src/components/CmdKMenu.tsx b/src/components/CmdKMenu.tsx index 805767351..dbf5eed5f 100644 --- a/src/components/CmdKMenu.tsx +++ b/src/components/CmdKMenu.tsx @@ -67,7 +67,7 @@ const CmdKMenu = () => { useImportComponentDialog() const { importComponent: importJlcpcbComponent } = useJlcpcbComponentImport() const session = useGlobalStore((s) => s.session) - const currentUser = session?.github_username + const currentUser = session?.tscircuit_handle const jlcpcbProxyRequestHeaders = useMemo( () => session?.token @@ -198,7 +198,7 @@ const CmdKMenu = () => { .map((account: Account) => { const { score, matches } = fuzzyMatch( searchQuery, - account.github_username, + account.tscircuit_handle ?? account.github_username ?? "", ) return { ...account, score, matches } }) @@ -213,7 +213,7 @@ const CmdKMenu = () => { if (!currentUser) return [] try { const response = await axios.post(`/packages/list`, { - owner_github_username: currentUser, + owner_tscircuit_handle: currentUser, limit: 5, }) return response.data.packages || [] diff --git a/src/components/ProfileRouter.tsx b/src/components/ProfileRouter.tsx index bd55d910e..29730a4d2 100644 --- a/src/components/ProfileRouter.tsx +++ b/src/components/ProfileRouter.tsx @@ -16,11 +16,15 @@ const ProfileRouter: React.FC = () => { return } - if (isLoading && !isFetched) { + if (isLoading || !isFetched) { return } - if (organization && !organization.is_personal_org && !error) { + if (error || !organization) { + return + } + + if (!organization.is_personal_org) { return } diff --git a/src/components/UserCard.tsx b/src/components/UserCard.tsx index 0fda0aa04..c756f17e4 100644 --- a/src/components/UserCard.tsx +++ b/src/components/UserCard.tsx @@ -24,7 +24,7 @@ export const UserCard: React.FC = ({ if (onClick) { onClick(account) } else if (!withLink) { - window.location.href = `/${account.github_username}` + window.location.href = `/${account.tscircuit_handle}` } } @@ -53,11 +53,11 @@ export const UserCard: React.FC = ({

- {account.github_username} + {account.tscircuit_handle}

- @{account.github_username} + @{account.tscircuit_handle}

@@ -67,8 +67,8 @@ export const UserCard: React.FC = ({ if (withLink) { return ( onClick(account) : undefined} > {cardContent} diff --git a/src/components/organization/OrganizationMembers.tsx b/src/components/organization/OrganizationMembers.tsx index 64b634088..878eb960a 100644 --- a/src/components/organization/OrganizationMembers.tsx +++ b/src/components/organization/OrganizationMembers.tsx @@ -61,35 +61,37 @@ export const OrganizationMembers: React.FC = ({ return (
{member.github_username - .split(" ") - .map((word) => word[0]) - .join("") - .toUpperCase() - .slice(0, 2)} + ? member.github_username + .split(" ") + .map((word) => word[0]) + .join("") + .toUpperCase() + .slice(0, 2) + : "U"}

- {member.github_username} + {member.github_username || "Unknown User"}

- @{member.github_username} + @{member.github_username || "unknown"}

diff --git a/src/hooks/use-global-store.ts b/src/hooks/use-global-store.ts index e7e96e4dc..efaf955aa 100644 --- a/src/hooks/use-global-store.ts +++ b/src/hooks/use-global-store.ts @@ -7,6 +7,8 @@ export type Store = { account_id: string session_id: string github_username: string + tscircuit_handle: string + personal_org_id: string } | null setSession: (session: Store["session"]) => any should_onboarding_tips_be_closed: boolean diff --git a/src/pages/authorize.tsx b/src/pages/authorize.tsx index e7107bd4f..9628555e6 100644 --- a/src/pages/authorize.tsx +++ b/src/pages/authorize.tsx @@ -53,6 +53,8 @@ const AuthenticatePageInnerContent = () => { github_username: "testuser", token: "1234", session_id: "session-1234", + tscircuit_handle: "testuser", + personal_org_id: "org-1234", }) handleRedirect(redirect, () => setLocation("/")) diff --git a/src/pages/dev-login.tsx b/src/pages/dev-login.tsx index 861e5751d..5ee33b0f0 100644 --- a/src/pages/dev-login.tsx +++ b/src/pages/dev-login.tsx @@ -38,6 +38,8 @@ export const DevLoginPage = () => { account_id: data.session.account_id, session_id: data.session.session_id, github_username: username, + tscircuit_handle: username, + personal_org_id: "org-1234", }) // Redirect to home page diff --git a/src/pages/search.tsx b/src/pages/search.tsx index b7110b7b6..962fd2ef2 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -141,7 +141,7 @@ export const SearchPage = () => { .map((account: Account) => { const { score, matches } = fuzzyMatch( searchQuery, - account.github_username, + account.github_username ?? account.tscircuit_handle ?? "", ) return { ...account, score, matches } }) diff --git a/src/pages/user-profile.tsx b/src/pages/user-profile.tsx index 50bac7b76..6b5f606a5 100644 --- a/src/pages/user-profile.tsx +++ b/src/pages/user-profile.tsx @@ -8,9 +8,12 @@ import { Input } from "@/components/ui/input" import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs" import { useAxios } from "@/hooks/use-axios" import { useGlobalStore } from "@/hooks/use-global-store" -import { useApiBaseUrl } from "@/hooks/use-packages-base-api-url" import { GitHubLogoIcon } from "@radix-ui/react-icons" -import type { Package, PublicOrgSchema } from "fake-snippets-api/lib/db/schema" +import type { + Account, + Package, + PublicOrgSchema, +} from "fake-snippets-api/lib/db/schema" import type React from "react" import { useState } from "react" import { useQuery } from "react-query" @@ -43,13 +46,14 @@ export const UserProfilePage = () => { isLoading: isLoadingAccount, isFetched: isFetchedAccount, } = useQuery< - { account: { github_username: string } }, + { + account: Account + }, Error & { status: number } >( ["account", username], async () => { const response = await axios.post("/accounts/get", { - github_username: username, tscircuit_handle: username, }) return response.data @@ -60,9 +64,10 @@ export const UserProfilePage = () => { }, ) - // use the username stored in the database so the correct case is displayed const githubUsername = account?.account?.github_username || username - const isCurrentUserProfile = githubUsername === session?.github_username + const tscircuitHandle = account?.account?.tscircuit_handle || username + const isCurrentUserProfile = + account?.account?.account_id === session?.account_id const { Dialog: DeleteDialog, openDialog: openDeleteDialog } = useConfirmDeletePackageDialog() @@ -73,15 +78,15 @@ export const UserProfilePage = () => { isLoading: isLoadingUserPackages, refetch: refetchUserPackages, } = useQuery( - ["userPackages", githubUsername], + ["userPackages", tscircuitHandle], async () => { const response = await axios.post(`/packages/list`, { - owner_github_username: githubUsername, + owner_org_id: account?.account?.personal_org_id, }) return response.data.packages }, { - enabled: Boolean(githubUsername), + enabled: Boolean(account?.account), refetchOnWindowFocus: false, }, ) @@ -100,9 +105,6 @@ export const UserProfilePage = () => { refetchOnWindowFocus: false, }, ) - - const baseUrl = useApiBaseUrl() - if (!isFetchedAccount) { return null }