Skip to content

Commit a24de52

Browse files
authored
Merge branch 'main' into main
2 parents 0fc082f + 324e21f commit a24de52

18 files changed

Lines changed: 1933 additions & 895 deletions

apps/docs/public/prisma-management-api.postman_collection.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

apps/site/content/changelog/2026-07-24.mdx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ slug: "2026-07-24"
66
headline: "Store files with Object Store buckets and see your workspace at a glance"
77
tags:
88
- "Prisma"
9-
- "Prisma Postgres"
109
- "Prisma Compute"
1110
- "Prisma Next"
1211
canonical: "/changelog#log2026-07-24"
@@ -73,12 +72,6 @@ App detection moved into the public SDK, and app URLs are now correct before you
7372
- **Improved** · The GitHub repository picker in the Prisma Console loads repositories page by page, so installations with more than 100 repositories can reach all of them, and switching accounts mid-load no longer briefly shows the wrong account's list.
7473
- **Fixed** · The app URL returned before your first deployment now names the domain your app will actually serve on. Previously it could point at the wrong region and never resolve.
7574

76-
## Prisma Postgres
77-
78-
One reliability improvement for databases waking from idle.
79-
80-
- **Improved** · Cold starts no longer run through a single per-region coordinator, so one degraded coordinator cannot block databases from waking across its region.
81-
8275
## Prisma docs
8376

8477
The prisma.io docs are now built for coding agents.

apps/site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@prisma/eclipse": "workspace:^",
2121
"@react-three/fiber": "^9.5.0",
2222
"cobe": "^2.0.1",
23+
"codehike": "^1.1.0",
2324
"cors": "^2.8.6",
2425
"fumadocs-core": "catalog:",
2526
"fumadocs-mdx": "catalog:",

apps/site/public/og/og-stack.png

-413 KB
Loading
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"use client";
2+
3+
import { cn } from "@/lib/cn";
4+
import { useRef, useState } from "react";
5+
6+
/**
7+
* The primary CTA: the scaffold command with a copy button. The command is
8+
* plain text in the DOM (crawlable, selectable); the button is labelled and
9+
* announces success politely.
10+
*/
11+
export function CopyCommand({ command, className }: { command: string; className?: string }) {
12+
const [copied, setCopied] = useState(false);
13+
const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
14+
15+
const copy = async () => {
16+
try {
17+
await navigator.clipboard.writeText(command);
18+
setCopied(true);
19+
clearTimeout(timer.current);
20+
timer.current = setTimeout(() => setCopied(false), 2000);
21+
} catch {
22+
// Clipboard can be unavailable (permissions, http); the text stays selectable.
23+
}
24+
};
25+
26+
return (
27+
<div
28+
className={cn(
29+
"flex items-center gap-3 rounded-square-high border border-stroke-neutral bg-background-neutral-weaker py-2.5 pl-4 pr-2.5",
30+
className,
31+
)}
32+
>
33+
<code className="font-mono text-sm text-foreground-neutral md:text-base">
34+
<span className="select-none text-foreground-neutral-weaker">$ </span>
35+
{command}
36+
</code>
37+
<button
38+
type="button"
39+
onClick={copy}
40+
aria-label={`Copy the command ${command}`}
41+
className="grid size-8 shrink-0 place-items-center rounded-square border border-stroke-neutral text-foreground-neutral-weak transition-colors hover:border-stroke-ppg hover:text-foreground-ppg"
42+
>
43+
<i className={copied ? "fa-regular fa-check" : "fa-regular fa-copy"} aria-hidden />
44+
</button>
45+
<span aria-live="polite" className="sr-only">
46+
{copied ? "Command copied to clipboard" : ""}
47+
</span>
48+
</div>
49+
);
50+
}

apps/site/src/app/stack/framework-carousel.tsx

Lines changed: 0 additions & 60 deletions
This file was deleted.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { BunMark } from "./bun-mark";
2+
import { PrismaMark } from "./prisma-mark";
3+
import styles from "./stack.module.css";
4+
5+
const heroLayers = [
6+
{
7+
id: "app",
8+
eyebrow: "You write",
9+
title: "Your application",
10+
icon: <i className="fa-regular fa-laptop" aria-hidden />,
11+
accent: "violet" as const,
12+
},
13+
{
14+
id: "orm",
15+
eyebrow: "Talks through",
16+
title: "Prisma ORM",
17+
icon: <PrismaMark className="size-[14px]" />,
18+
accent: "orm" as const,
19+
},
20+
{
21+
id: "postgres",
22+
eyebrow: "Stores in",
23+
title: "Prisma Postgres",
24+
icon: <i className="fa-regular fa-database" aria-hidden />,
25+
accent: "ppg" as const,
26+
},
27+
{
28+
id: "compute",
29+
eyebrow: "Runs on",
30+
title: "Prisma Compute + Bun",
31+
icon: <BunMark className="size-[15px]" />,
32+
accent: "ppg" as const,
33+
},
34+
];
35+
36+
/**
37+
* The hero's animated stack: the four layers enter staggered, then a request
38+
* pulse travels the connectors on a loop. The layers widen toward the base so
39+
* the visual previews the stack pyramid the reader meets one scroll later.
40+
* Pure CSS, server-rendered; under prefers-reduced-motion everything is
41+
* simply visible and static, so the relationship reads the same without
42+
* animation.
43+
*/
44+
export function HeroVisual() {
45+
return (
46+
<div className={styles["hero-visual"]} aria-hidden>
47+
{heroLayers.map((layer, index) => (
48+
<div
49+
key={layer.id}
50+
className={styles["hero-layer-slot"]}
51+
style={{ "--row": index } as React.CSSProperties}
52+
>
53+
{index > 0 && <span className={styles["hero-connector"]} />}
54+
<div
55+
className={`${styles["hero-layer"]} ${styles[`accent-${layer.accent}`]}`}
56+
style={{ animationDelay: `${index * 140}ms` }}
57+
>
58+
<span className={styles["hero-layer-icon"]}>{layer.icon}</span>
59+
<span className={styles["hero-layer-text"]}>
60+
<span className={styles["hero-layer-eyebrow"]}>{layer.eyebrow}</span>
61+
<span className={styles["hero-layer-title"]}>{layer.title}</span>
62+
</span>
63+
</div>
64+
</div>
65+
))}
66+
</div>
67+
);
68+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { prisma_highlighter } from "@/lib/shiki_prisma";
2+
import type { HighlightedCode } from "codehike/code";
3+
import type { CSSProperties } from "react";
4+
import { journeySteps, type JourneyStep } from "./journey-steps";
5+
6+
/** Code Hike token: plain text, or [text, color, style?]. */
7+
type CodeToken = string | [string, string, CSSProperties?];
8+
9+
/**
10+
* Tokenize with the site's shiki `prisma-dark` theme (CSS-variable colors, so
11+
* it adapts to both themes) and re-shape into Code Hike's token format. Tokens
12+
* are split per word because Code Hike's transitions move tokens
13+
* independently; coarser tokens make the animation lurch.
14+
*/
15+
function toCodeTokens(text: string, color: string, out: CodeToken[]) {
16+
for (const part of text.split(/(\s+)/)) {
17+
if (!part) continue;
18+
if (/^\s+$/.test(part)) {
19+
out.push(part);
20+
} else {
21+
out.push([part, color]);
22+
}
23+
}
24+
}
25+
26+
async function highlightStep(code: string, lang: JourneyStep["lang"]): Promise<HighlightedCode> {
27+
const tokens: CodeToken[] = [];
28+
if (lang === "text") {
29+
// Plain-text steps (the project tree): names in the normal code color,
30+
// trailing `# …` annotations dimmed like comments.
31+
code.split("\n").forEach((line, index) => {
32+
if (index > 0) tokens.push("\n");
33+
const hash = line.indexOf("# ");
34+
if (hash > -1) {
35+
toCodeTokens(line.slice(0, hash), "var(--color-foreground-neutral-weak)", tokens);
36+
toCodeTokens(line.slice(hash), "var(--color-disabled)", tokens);
37+
} else {
38+
toCodeTokens(line, "var(--color-foreground-neutral-weak)", tokens);
39+
}
40+
});
41+
} else {
42+
const highlighter = await prisma_highlighter();
43+
const lines = highlighter.codeToTokensBase(code, {
44+
lang,
45+
theme: highlighter.getTheme("prisma-dark"),
46+
});
47+
lines.forEach((line, index) => {
48+
if (index > 0) tokens.push("\n");
49+
for (const token of line) {
50+
toCodeTokens(token.content, token.color ?? "currentColor", tokens);
51+
}
52+
});
53+
}
54+
return {
55+
tokens,
56+
code,
57+
lang,
58+
meta: "",
59+
themeName: "prisma-dark",
60+
style: {},
61+
annotations: [],
62+
} as unknown as HighlightedCode;
63+
}
64+
65+
/** Highlight every journey step on the server; the player receives plain data. */
66+
export async function highlightJourney(): Promise<HighlightedCode[]> {
67+
return Promise.all(journeySteps.map((step) => highlightStep(step.code, step.lang)));
68+
}

0 commit comments

Comments
 (0)