Skip to content
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

feat: add rewrites and upserts for gateway.new #2779

Merged
merged 1 commit into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions apps/dashboard/app/(app)/apis/create-api-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,28 @@ import { Button } from "@unkey/ui";
import { Plus } from "lucide-react";
import { useRouter } from "next/navigation";
import type React from "react";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";

const formSchema = z.object({
name: z.string().trim().min(3, "Name must be at least 3 characters long").max(50),
});

export const CreateApiButton = ({ ...rest }: React.ButtonHTMLAttributes<HTMLButtonElement>) => {
type Props = {
defaultOpen?: boolean;
};

export const CreateApiButton = ({
defaultOpen,
...rest
}: React.ButtonHTMLAttributes<HTMLButtonElement> & Props) => {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
});

const [open, setOpen] = useState(defaultOpen ?? false);

const create = trpc.api.create.useMutation({
async onSuccess(res) {
toast.success("Your API has been created");
Expand All @@ -49,7 +59,7 @@ export const CreateApiButton = ({ ...rest }: React.ButtonHTMLAttributes<HTMLButt

return (
<>
<Dialog>
<Dialog open={open} onOpenChange={(o) => setOpen(o)}>
<DialogTrigger asChild>
<Button variant="primary" {...rest}>
<Plus />
Expand Down
11 changes: 9 additions & 2 deletions apps/dashboard/app/(app)/apis/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import { ApiList } from "./client";
export const dynamic = "force-dynamic";
export const runtime = "edge";

export default async function ApisOverviewPage() {
type Props = {
searchParams: { new?: boolean };
};

export default async function ApisOverviewPage(props: Props) {
const tenantId = getTenantId();
const workspace = await db.query.workspaces.findFirst({
where: (table, { and, eq, isNull }) =>
Expand Down Expand Up @@ -48,7 +52,10 @@ export default async function ApisOverviewPage() {
<Navbar.Breadcrumbs.Link href="/apis">APIs</Navbar.Breadcrumbs.Link>
</Navbar.Breadcrumbs>
<Navbar.Actions>
<CreateApiButton key="createApi" />
<CreateApiButton
key="createApi"
defaultOpen={apis.length === 0 || props.searchParams.new}
/>
</Navbar.Actions>
</Navbar>
<PageContent>
Expand Down
35 changes: 35 additions & 0 deletions apps/dashboard/app/(app)/gateway-new/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* This route creates a shortcut for onboarding
*
* We need this for compliance of our gateway.new domain.
* 1. A user will enter "gateway.new" in the browser
* 2. Vercel will detect the host and rewrite the request to this page
* 3. A workspace is upserted
* 4. The user is redirected to create their API
*/

import { getTenantId } from "@/lib/auth";
import { db, schema } from "@/lib/db";
import { newId } from "@unkey/id";
import { redirect } from "next/navigation";

export default async function Page() {
const tenantId = getTenantId();

const ws = await db.query.workspaces.findFirst({
where: (table, { eq, isNull, and }) =>
and(eq(table.tenantId, tenantId), isNull(table.deletedAt)),
});

if (!ws) {
await db.insert(schema.workspaces).values({
id: newId("workspace"),
name: "Personal Workspace",
tenantId,
betaFeatures: {},
features: {},
});
}

return redirect("/apis?new=true");
}
1 change: 1 addition & 0 deletions apps/dashboard/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const config = {
"/success",
"/success/(.*)",
"/auth/(.*)",
"/gateway-new",
"/(api|trpc)(.*)",
"/((?!.+\\.[\\w]+$|_next).*)",
"/((?!_next/static|_next/image|images|favicon.ico|$).*)",
Expand Down
12 changes: 11 additions & 1 deletion apps/dashboard/next.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/** @type {import('next').NextConfig} */

const securityHeaders = [
{
key: "X-Frame-Options",
Expand Down Expand Up @@ -51,6 +50,17 @@ const nextConfig = {
source: "/engineering/:match*",
destination: "https://unkey-engineering.mintlify.dev/engineering/:match*",
},
// Powers our gateway.new compliant domain
{
source: "/:path",
has: [
{
type: "host",
value: "gateway.new",
},
],
destination: "/gateway-new",
},
],
};

Expand Down
Loading