Skip to content

Commit 6b4c835

Browse files
Merge branch 'main' into docs/deno-spawn-apis
2 parents 4979581 + 4d98977 commit 6b4c835

File tree

14 files changed

+306
-10
lines changed

14 files changed

+306
-10
lines changed

_components/CopyPage.tsx

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
export default function CopyPage({ file }: { file: string | undefined }) {
2+
if (!file || file.includes("[")) return null;
3+
4+
const markdownUrl = `https://docs.deno.com${file}`;
5+
const claudeUrl = `https://claude.ai/new?q=${
6+
encodeURIComponent(
7+
`Read this page from the Deno docs: ${markdownUrl} and answer questions about the content.`,
8+
)
9+
}`;
10+
11+
return (
12+
<div class="copy-page-split inline-flex shrink-0 rounded-full border-2 border-foreground-primary dark:border-background-tertiary">
13+
{/* Primary: directly copies the URL */}
14+
<button
15+
type="button"
16+
class="copy-page-main-btn flex items-center gap-2 px-4 py-2 text-sm font-semibold text-foreground-primary bg-transparent hover:bg-header-highlight dark:hover:text-background-primary rounded-l-full transition-colors cursor-pointer select-none"
17+
>
18+
<svg
19+
xmlns="http://www.w3.org/2000/svg"
20+
aria-hidden="true"
21+
fill="currentColor"
22+
width="12"
23+
height="12"
24+
viewBox="0 0 16 16"
25+
>
26+
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z" />
27+
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z" />
28+
</svg>
29+
<span class="copy-page-main-label">Copy page</span>
30+
</button>
31+
32+
{/* Visual divider between the two halves */}
33+
<span
34+
class="self-stretch w-0.5 bg-foreground-primary dark:bg-background-tertiary shrink-0"
35+
aria-hidden="true"
36+
>
37+
</span>
38+
39+
{/* Chevron: opens the popover panel */}
40+
<button
41+
type="button"
42+
class="copy-page-toggle-btn flex items-center px-3 py-2 text-foreground-primary bg-transparent hover:bg-header-highlight dark:hover:text-background-primary rounded-r-full transition-colors cursor-pointer select-none"
43+
popovertarget="copy-page-menu"
44+
aria-label="More copy options"
45+
aria-haspopup="menu"
46+
>
47+
<svg
48+
class="copy-page-chevron transition-transform duration-200"
49+
xmlns="http://www.w3.org/2000/svg"
50+
aria-hidden="true"
51+
fill="currentColor"
52+
width="12"
53+
height="12"
54+
viewBox="0 0 16 16"
55+
>
56+
<path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z" />
57+
</svg>
58+
</button>
59+
60+
{/* Popover panel — lives in top layer, positioned via JS */}
61+
<div id="copy-page-menu" popover="auto" class="copy-page-panel">
62+
<a
63+
href={file}
64+
target="_blank"
65+
class="no-underline flex items-start gap-3 px-4 py-3 hover:bg-background-secondary dark:hover:bg-gray-800 transition-colors"
66+
>
67+
<svg
68+
xmlns="http://www.w3.org/2000/svg"
69+
aria-hidden="true"
70+
fill="currentColor"
71+
width="16"
72+
height="16"
73+
viewBox="0 0 16 16"
74+
class="mt-0.5 shrink-0"
75+
>
76+
<path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z" />
77+
</svg>
78+
<span>
79+
<span class="block text-sm font-medium">View Page as Markdown</span>
80+
<span class="block text-xs text-foreground-secondary mt-0.5">
81+
Open the Markdown file in a new tab
82+
</span>
83+
</span>
84+
</a>
85+
<a
86+
href={claudeUrl}
87+
target="_blank"
88+
class="no-underline flex items-start gap-3 px-4 py-3 border-t border-foreground-tertiary hover:bg-background-secondary dark:hover:bg-gray-800 transition-colors"
89+
>
90+
<svg
91+
xmlns="http://www.w3.org/2000/svg"
92+
aria-hidden="true"
93+
fill="currentColor"
94+
width="16"
95+
height="16"
96+
viewBox="0 0 24 24"
97+
class="mt-0.5 shrink-0"
98+
>
99+
<path d="M12 0C12 0 10.5 10.5 0 12C10.5 12 12 24 12 24C12 24 13.5 13.5 24 12C13.5 12 12 0 12 0Z" />
100+
</svg>
101+
<span>
102+
<span class="block text-sm font-medium">Open in Claude</span>
103+
<span class="block text-xs text-foreground-secondary mt-0.5">
104+
Ask Claude about this page
105+
</span>
106+
</span>
107+
</a>
108+
</div>
109+
</div>
110+
);
111+
}

_components/TableOfContents.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default function TableOfContents({ data, toc, hasSubNav }: {
1212

1313
return (
1414
<ul
15-
className={`toc-list hidden sticky p-4 pr-0 h-screen-minus-header overflow-y-auto border-l border-l-foreground-tertiary lg:block lg:w-full ${topClasses}`}
15+
className={`toc-list hidden sticky ${topClasses} h-screen-minus-header overflow-y-auto border-l border-l-foreground-tertiary p-4 pr-0 lg:flex lg:flex-col lg:w-full`}
1616
id="toc"
1717
>
1818
{toc.map((item: TableOfContentsItem_) => (

_config.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,24 @@ site.addEventListener("afterBuild", async () => {
190190
/* NOTE: we used to get gfm.css from the jsr.io CDN, but now we simply have a local copy. This is because it needs to be placed on a CSS layer, which isn't possible with an imported file. */
191191
// Deno.writeTextFileSync(site.dest("gfm.css"), GFM_CSS);
192192

193+
// Copy lint rule markdown source files to _site so they're served at /lint/rules/*.md.
194+
// These files are excluded from Lume's processing pipeline (site.ignore) because
195+
// lint_rule.page.tsx handles page generation, but we still want the raw .md accessible.
196+
try {
197+
await Deno.mkdir(site.dest("lint/rules"), { recursive: true });
198+
for await (const entry of Deno.readDir("lint/rules")) {
199+
if (entry.isFile && entry.name.endsWith(".md")) {
200+
await Deno.copyFile(
201+
`lint/rules/${entry.name}`,
202+
site.dest(`lint/rules/${entry.name}`),
203+
);
204+
}
205+
}
206+
log.info("Copied lint rule markdown files to _site/lint/rules/");
207+
} catch (error) {
208+
log.error("Error copying lint rule markdown files: " + error);
209+
}
210+
193211
// Generate LLMs documentation files directly to _site directory
194212
if (Deno.env.get("BUILD_TYPE") == "FULL") {
195213
try {

_includes/doc.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,17 @@ export default function Doc(data: Lume.Data, helpers: Lume.Helpers) {
6969
class="markdown-body mt-6 sm:mt-6"
7070
>
7171
{!(isReference && !isApiLandingPage) && (
72-
<h1
73-
dangerouslySetInnerHTML={{
74-
__html: helpers.md(data.title!, true),
75-
}}
76-
>
77-
</h1>
72+
<header class="flex items-start justify-between gap-4">
73+
<h1
74+
dangerouslySetInnerHTML={{
75+
__html: helpers.md(data.title!, true),
76+
}}
77+
>
78+
</h1>
79+
{file && !file.includes("[") && file.endsWith(".md") && (
80+
<data.comp.CopyPage file={file} />
81+
)}
82+
</header>
7883
)}
7984
{data.available_since && (
8085
<div class="bg-gray-200 rounded-md text-sm py-3 px-4 mb-4 font-semibold">

_includes/layout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export default function Layout(data: Lume.Data) {
7777
<script type="module" defer src="/js/copy.js"></script>
7878
<script type="module" defer src="/js/tabs.js"></script>
7979
<script type="module" defer src="/js/feedback.js"></script>
80+
<script type="module" defer src="/js/copy-page.js"></script>
8081
<script type="module" defer src="/js/search.js"></script>
8182
<script
8283
async

js/copy-page.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Primary "Copy page" button — directly copies URL
2+
document.querySelectorAll<HTMLButtonElement>(".copy-page-main-btn").forEach(
3+
(btn) => {
4+
btn.addEventListener("click", () => {
5+
navigator?.clipboard?.writeText(window.location.href).then(() => {
6+
const label = btn.querySelector<HTMLElement>(".copy-page-main-label");
7+
if (label) {
8+
const original = label.textContent;
9+
label.textContent = "Copied!";
10+
setTimeout(() => {
11+
label.textContent = original;
12+
}, 2000);
13+
}
14+
}).catch(() => {
15+
const label = btn.querySelector<HTMLElement>(".copy-page-main-label");
16+
if (label) {
17+
const original = label.textContent;
18+
label.textContent = "Copy failed";
19+
setTimeout(() => {
20+
label.textContent = original;
21+
}, 2000);
22+
}
23+
});
24+
});
25+
},
26+
);
27+
28+
// Popover panel — position below the chevron button + rotate chevron
29+
const panel = document.getElementById("copy-page-menu") as HTMLElement | null;
30+
const toggleBtn = document.querySelector<HTMLButtonElement>(
31+
".copy-page-toggle-btn",
32+
);
33+
34+
panel?.addEventListener("toggle", (event) => {
35+
const e = event as ToggleEvent;
36+
const chevron = toggleBtn?.querySelector<SVGElement>(".copy-page-chevron");
37+
38+
if (e.newState === "open" && toggleBtn) {
39+
const rect = toggleBtn.getBoundingClientRect();
40+
panel.style.top = `${rect.bottom + 4}px`;
41+
panel.style.right = `${window.innerWidth - rect.right}px`;
42+
}
43+
if (chevron) {
44+
chevron.style.transform = e.newState === "open" ? "rotate(180deg)" : "";
45+
}
46+
});

markdown-it/codeblock-copy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default function codeblockCopyPlugin(md: any) {
2222
<svg class="copy-icon" width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
2323
<rect x="2" y="2" width="7" height="7" fill="none"/>
2424
<rect x="6" y="6" width="7" height="7" fill="none"/>
25-
<path d="M1.55566 2.7C1.55566 2.03726 2.09292 1.5 2.75566 1.5H8.75566C9.41841 1.5 9.95566 2.03726 9.95566 2.7V5.1H12.3557C13.0184 5.1 13.5557 5.63726 13.5557 6.3V12.3C13.5557 12.9627 13.0184 13.5 12.3557 13.5H6.35566C5.69292 13.5 5.15566 12.9627 5.15566 12.3V9.9H2.75566C2.09292 9.9 1.55566 9.36274 1.55566 8.7V2.7ZM6.35566 9.9V12.3H12.3557V6.3H9.95566V8.7C9.95566 9.36274 9.41841 9.9 8.75566 9.9H6.35566ZM8.75566 8.7V2.7H2.75566V8.7H8.75566Z" fill="hsla(var(--foreground-secondary))"/>
25+
<path d="M1.55566 2.7C1.55566 2.03726 2.09292 1.5 2.75566 1.5H8.75566C9.41841 1.5 9.95566 2.03726 9.95566 2.7V5.1H12.3557C13.0184 5.1 13.5557 5.63726 13.5557 6.3V12.3C13.5557 12.9627 13.0184 13.5 12.3557 13.5H6.35566C5.69292 13.5 5.15566 12.9627 5.15566 12.3V9.9H2.75566C2.09292 9.9 1.55566 9.36274 1.55566 8.7V2.7ZM6.35566 9.9V12.3H12.3557V6.3H9.95566V8.7C9.95566 9.36274 9.41841 9.9 8.75566 9.9H6.35566ZM8.75566 8.7V2.7H2.75566V8.7H8.75566Z" fill="currentColor"/>
2626
</svg>
2727
<svg class="check-icon hidden" width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
2828
<path d="M3 7.5L6.5 11L12 3" stroke="green" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>

replacements.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"CLI_VERSION": "2.7.2"
2+
"CLI_VERSION": "2.7.4"
33
}

runtime/fundamentals/modules.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,45 @@ When using a `package.json` file, dev dependencies can be added to the separate
563563
}
564564
```
565565

566+
### JSR packages in package.json
567+
568+
You can depend on JSR packages directly from `package.json` using the `jsr:`
569+
scheme, without needing a separate `deno.json`:
570+
571+
```json title="package.json"
572+
{
573+
"dependencies": {
574+
"@std/path": "jsr:^1.0.9"
575+
}
576+
}
577+
```
578+
579+
This works with `deno install` and brings JSR packages to any project that uses
580+
`package.json` for dependency management.
581+
582+
### Dependency overrides
583+
584+
The `overrides` field in `package.json` lets you control transitive dependency
585+
versions throughout your dependency tree. This is useful for applying security
586+
patches, fixing version compatibility issues, or replacing packages:
587+
588+
```json title="package.json"
589+
{
590+
"dependencies": {
591+
"express": "^4.18.0"
592+
},
593+
"overrides": {
594+
"cookie": "0.7.0",
595+
"express": {
596+
"qs": "6.13.0"
597+
}
598+
}
599+
}
600+
```
601+
602+
In this example, `cookie` is pinned globally to `0.7.0`, while `qs` is
603+
overridden only when required by `express`.
604+
566605
### Why does Deno not have a `devImports` field?
567606

568607
To understand why Deno does not separate out dev dependencies in the package

runtime/getting_started/installation.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ oldUrl:
99

1010
Deno works on macOS, Linux, and Windows. Deno is a single binary executable. It
1111
has no external dependencies. On macOS, both M1 (arm64) and Intel (x64)
12-
executables are provided. On Linux and Windows, only x64 is supported.
12+
executables are provided. On Windows, both ARM64 and x64 are supported. On
13+
Linux, only x64 is supported.
1314

1415
## Download and install
1516

0 commit comments

Comments
 (0)