public playground warning

This commit is contained in:
Kyle Corbitt
2023-06-28 07:05:51 -07:00
parent f63c23f9fb
commit dc357d7611
6 changed files with 86 additions and 80 deletions

View File

@@ -11,18 +11,7 @@
# Prisma # Prisma
# https://www.prisma.io/docs/reference/database-reference/connection-urls#env # https://www.prisma.io/docs/reference/database-reference/connection-urls#env
DATABASE_URL="file:./db.sqlite" DATABASE_URL="postgresql://postgres:postgres@localhost:5432/prompt-lab?schema=public"
# Next Auth # OpenAI
# You can generate a new secret on the command line with:
# openssl rand -base64 32
# https://next-auth.js.org/configuration/options#secret
# NEXTAUTH_SECRET=""
NEXTAUTH_URL="http://localhost:3000"
# Next Auth Discord Provider
DISCORD_CLIENT_ID=""
DISCORD_CLIENT_SECRET=""
NODE_ENV="development"
OPENAI_API_KEY="" OPENAI_API_KEY=""

View File

@@ -19,6 +19,7 @@ FROM base as builder
# Include all NEXT_PUBLIC_* env vars here # Include all NEXT_PUBLIC_* env vars here
ARG NEXT_PUBLIC_POSTHOG_KEY ARG NEXT_PUBLIC_POSTHOG_KEY
ARG NEXT_PUBLIC_IS_PUBLIC_PLAYGROUND
WORKDIR /app WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules COPY --from=deps /app/node_modules ./node_modules

View File

@@ -0,0 +1,22 @@
import { Flex, Icon, Link, Text } from "@chakra-ui/react";
import { BsExclamationTriangleFill } from "react-icons/bs";
import { env } from "~/env.mjs";
export default function PublicPlaygroundWarning() {
console.log(env);
if (!env.NEXT_PUBLIC_IS_PUBLIC_PLAYGROUND) return null;
return (
<Flex bgColor="red.600" color="whiteAlpha.900" p={2} align="center">
<Icon boxSize={4} mr={2} as={BsExclamationTriangleFill} />
<Text>
Warning: this is a public playground. Anyone can see, edit or delete your experiments. For
private use,{" "}
<Link textDecor="underline" href="https://github.com/corbt/prompt-lab">
run a local copy
</Link>
.
</Text>
</Flex>
);
}

View File

@@ -16,6 +16,7 @@ import { RiFlaskLine } from "react-icons/ri";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import Link from "next/link"; import Link from "next/link";
import { useHandledAsyncCallback } from "~/utils/hooks"; import { useHandledAsyncCallback } from "~/utils/hooks";
import PublicPlaygroundWarning from "../PublicPlaygroundWarning";
const ExperimentLink = forwardRef<BoxProps & { active: boolean | undefined }, "a">( const ExperimentLink = forwardRef<BoxProps & { active: boolean | undefined }, "a">(
({ children, active, ...props }, ref) => ( ({ children, active, ...props }, ref) => (
@@ -51,59 +52,62 @@ export default function AppShell(props: { children: React.ReactNode; title?: str
}, [createMutation, router]); }, [createMutation, router]);
return ( return (
<Flex minH="100vh"> <VStack align="stretch" spacing={0} h="100vh">
<Head> <PublicPlaygroundWarning />
<title>{props.title ? `${props.title} | Prompt Lab` : "Prompt Lab"}</title> <Flex flex={1}>
</Head> <Head>
<Box bgColor="gray.100" flexShrink={0} width="220px" p={2}> <title>{props.title ? `${props.title} | Prompt Lab` : "Prompt Lab"}</title>
<VStack align="stretch"> </Head>
<HStack spacing={0}> <Box bgColor="gray.100" flexShrink={0} width="220px" p={2}>
<Image <VStack align="stretch">
src="/flask2.svg" <HStack spacing={0}>
alt="" <Image
w={6} src="/flask2.svg"
h={6} alt=""
// filter="drop-shadow(0 0 2px rgb(0 0 0 / 0.4))" w={6}
/> h={6}
<Heading size="md" p={2}> // filter="drop-shadow(0 0 2px rgb(0 0 0 / 0.4))"
Prompt Lab />
</Heading> <Heading size="md" p={2}>
</HStack> Prompt Lab
<Box h="1px" bgColor="gray.400" /> </Heading>
<HStack align="center" spacing={2} p={2} pb={0}> </HStack>
<Heading size="xs" textAlign="center"> <Box h="1px" bgColor="gray.400" />
Experiments <HStack align="center" spacing={2} p={2} pb={0}>
</Heading> <Heading size="xs" textAlign="center">
</HStack> Experiments
<VStack spacing={1} align="stretch"> </Heading>
{experiments?.data?.map((exp) => ( </HStack>
<VStack spacing={1} align="stretch">
{experiments?.data?.map((exp) => (
<ExperimentLink
key={exp.id}
as={Link}
active={exp.id === currentId}
href={{ pathname: "/experiments/[id]", query: { id: exp.id } }}
display="flex"
alignItems="center"
>
<Icon as={RiFlaskLine} boxSize={4} mr={2} />
{exp.label}
</ExperimentLink>
))}
<ExperimentLink <ExperimentLink
key={exp.id} onClick={createExperiment}
as={Link} active={false}
active={exp.id === currentId}
href={{ pathname: "/experiments/[id]", query: { id: exp.id } }}
display="flex" display="flex"
alignItems="center" alignItems="center"
> >
<Icon as={RiFlaskLine} boxSize={4} mr={2} /> <Icon as={BsPlusSquare} boxSize={4} mr={2} />
{exp.label} New Experiment
</ExperimentLink> </ExperimentLink>
))} </VStack>
<ExperimentLink
onClick={createExperiment}
active={false}
display="flex"
alignItems="center"
>
<Icon as={BsPlusSquare} boxSize={4} mr={2} />
New Experiment
</ExperimentLink>
</VStack> </VStack>
</VStack> </Box>
</Box> <Box flex={1} overflowX="auto" overflowY="auto" h="100vh">
<Box flex={1} overflowX="auto" overflowY="auto" h="100vh"> {props.children}
{props.children} </Box>
</Box> </Flex>
</Flex> </VStack>
); );
} }

View File

@@ -8,19 +8,7 @@ export const env = createEnv({
*/ */
server: { server: {
DATABASE_URL: z.string().url(), DATABASE_URL: z.string().url(),
NODE_ENV: z.enum(["development", "test", "production"]), NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
NEXTAUTH_SECRET:
process.env.NODE_ENV === "production" ? z.string().min(1) : z.string().min(1).optional(),
NEXTAUTH_URL: z.preprocess(
// This makes Vercel deployments not fail if you don't set NEXTAUTH_URL
// Since NextAuth.js automatically uses the VERCEL_URL if present.
(str) => process.env.VERCEL_URL ?? str,
// VERCEL_URL doesn't include `https` so it cant be validated as a URL
process.env.VERCEL ? z.string().min(1) : z.string().url()
),
// Add `.min(1) on ID and SECRET if you want to make sure they're not empty
DISCORD_CLIENT_ID: z.string(),
DISCORD_CLIENT_SECRET: z.string(),
OPENAI_API_KEY: z.string().min(1), OPENAI_API_KEY: z.string().min(1),
}, },
@@ -30,7 +18,12 @@ export const env = createEnv({
* `NEXT_PUBLIC_`. * `NEXT_PUBLIC_`.
*/ */
client: { client: {
NEXT_PUBLIC_POSTHOG_KEY: z.string(), NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(),
NEXT_PUBLIC_IS_PUBLIC_PLAYGROUND: z
.string()
.optional()
.default("false")
.transform((val) => val.toLowerCase() === "true"),
}, },
/** /**
@@ -40,12 +33,9 @@ export const env = createEnv({
runtimeEnv: { runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL, DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV, NODE_ENV: process.env.NODE_ENV,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
DISCORD_CLIENT_ID: process.env.DISCORD_CLIENT_ID,
DISCORD_CLIENT_SECRET: process.env.DISCORD_CLIENT_SECRET,
OPENAI_API_KEY: process.env.OPENAI_API_KEY, OPENAI_API_KEY: process.env.OPENAI_API_KEY,
NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY, NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY,
NEXT_PUBLIC_IS_PUBLIC_PLAYGROUND: process.env.NEXT_PUBLIC_IS_PUBLIC_PLAYGROUND,
}, },
/** /**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.

View File

@@ -35,7 +35,7 @@ export const api = createTRPCNext<AppRouter>({
links: [ links: [
loggerLink({ loggerLink({
enabled: (opts) => enabled: (opts) =>
process.env.NODE_ENV === "development" || (process.env.NODE_ENV ?? "development") === "development" ||
(opts.direction === "down" && opts.result instanceof Error), (opts.direction === "down" && opts.result instanceof Error),
}), }),
httpBatchLink({ httpBatchLink({