Skip to content

Commit 6efce19

Browse files
authored
Add v7/v6 docs separation (#1379)
1 parent d6c8164 commit 6efce19

File tree

10 files changed

+1135
-80
lines changed

10 files changed

+1135
-80
lines changed

docs/src/components/LeftSidebar/LeftSidebar.astro

+234-78
Original file line numberDiff line numberDiff line change
@@ -4,102 +4,258 @@ type Props = {
44
};
55
66
const { currentPage } = Astro.props;
7-
const currentPageMatch = currentPage.endsWith("/") ? currentPage.slice(1, -1) : currentPage.slice(1);
87
9-
interface Link {
10-
url: string;
11-
text: string;
8+
const base = Astro.site?.pathname ?? "/";
9+
10+
const pathname = currentPage.endsWith("/")
11+
? currentPage.slice(0, -1)
12+
: currentPage;
13+
14+
function isCurrentPage(url: string) {
15+
return `/${url}` === pathname ? "page" : undefined;
1216
}
1317
14-
const sidebar: Record<string, Link[]> = {
15-
"openapi-typescript": [
16-
{ text: "Introduction", url: "introduction" },
17-
{ text: "CLI", url: "cli" },
18-
{ text: "Node.js API", url: "node" },
19-
{ text: "Advanced", url: "advanced" },
20-
{ text: "About", url: "about" },
21-
],
22-
"openapi-fetch": [
23-
{ text: "Introduction", url: "openapi-fetch" },
24-
{ text: "API", url: "openapi-fetch/api" },
25-
{ text: "Examples", url: "openapi-fetch/examples" },
26-
{ text: "About", url: "openapi-fetch/about" },
27-
],
18+
const v = pathname.includes("/v6") ? 6 : 7;
19+
20+
const url = {
21+
introduction: `${v === 6 ? "v6/" : ""}introduction`,
22+
cli: `${v === 6 ? "v6/" : ""}cli`,
23+
node: `${v === 6 ? "v6/" : ""}node`,
24+
advanced: `${v === 6 ? "v6/" : ""}advanced`,
25+
about: `${v === 6 ? "v6/" : ""}about`,
2826
};
2927
---
3028

3129
<nav aria-labelledby="grid-left">
3230
<ul class="nav-groups">
33-
{
34-
Object.entries(sidebar).map(([header, children]) => (
35-
<li class="nav-group">
36-
<h2 class="nav-group-title">{header}</h2>
37-
<ul class="nav-group-subnav">
38-
{children.map((child) => {
39-
const url = Astro.site?.pathname + child.url;
40-
return (
41-
<li class="nav-link">
42-
<a class="link" href={url} aria-current={currentPageMatch === child.url ? "page" : false}>
43-
{child.text}
44-
</a>
45-
</li>
46-
);
47-
})}
48-
</ul>
31+
<li class="nav-group">
32+
<h2 class="nav-group-title">openapi-typescript</h2>
33+
<fieldset class="version-switcher">
34+
<label
35+
class="version"
36+
for="v6"
37+
>
38+
<input
39+
id="v6"
40+
checked={v === 6 || undefined}
41+
name="version"
42+
type="radio"
43+
/>
44+
v6
45+
</label>
46+
<label
47+
class="version"
48+
for="v7"
49+
>
50+
<input
51+
id="v7"
52+
checked={v === 7 || undefined}
53+
name="version"
54+
type="radio"
55+
/>
56+
v7 (beta)</label
57+
>
58+
</fieldset>
59+
<ul class="nav-group-subnav">
60+
<li class="nav-link">
61+
<a
62+
class="link"
63+
href={`${base}${url.introduction}`}
64+
aria-current={isCurrentPage(url.introduction)}
65+
>
66+
Introduction
67+
</a>
4968
</li>
50-
))
51-
}
69+
<li class="nav-link">
70+
<a
71+
class="link"
72+
href={`${base}${url.cli}`}
73+
aria-current={isCurrentPage(url.cli)}
74+
>
75+
CLI
76+
</a>
77+
</li>
78+
<li class="nav-link">
79+
<a
80+
class="link"
81+
href={`${base}${url.node}`}
82+
aria-current={isCurrentPage(url.node)}
83+
>
84+
Node.js API
85+
</a>
86+
</li>
87+
<li class="nav-link">
88+
<a
89+
class="link"
90+
href={`${base}${url.advanced}`}
91+
aria-current={isCurrentPage(url.advanced)}
92+
>
93+
Advanced
94+
</a>
95+
</li>
96+
<li class="nav-link">
97+
<a
98+
class="link"
99+
href={`${base}migration-guide`}
100+
aria-current={isCurrentPage("/migration-guide")}
101+
>
102+
Migrating
103+
</a>
104+
</li>
105+
<li class="nav-link">
106+
<a
107+
class="link"
108+
href={`${base}${url.about}`}
109+
aria-current={isCurrentPage(url.about)}
110+
>
111+
About
112+
</a>
113+
</li>
114+
</ul>
115+
</li>
116+
<li class="nav-group">
117+
<h2 class="nav-group-title">openapi-fetch</h2>
118+
<ul class="nav-group-subnav">
119+
<li class="nav-link">
120+
<a
121+
class="link"
122+
href={`${base}openapi-fetch`}
123+
aria-current={isCurrentPage("/openapi-fetch")}
124+
>
125+
Introduction
126+
</a>
127+
</li>
128+
<li class="nav-link">
129+
<a
130+
class="link"
131+
href={`${base}openapi-fetch/api`}
132+
aria-current={isCurrentPage("/openapi-fetch/api")}
133+
>
134+
API
135+
</a>
136+
</li>
137+
<li class="nav-link">
138+
<a
139+
class="link"
140+
href={`${base}openapi-fetch/examples`}
141+
aria-current={isCurrentPage("/openapi-fetch/examples")}
142+
>
143+
Examples
144+
</a>
145+
</li>
146+
<li class="nav-link">
147+
<a
148+
class="link"
149+
href={`${base}openapi-fetch/about`}
150+
aria-current={isCurrentPage("/openapi-fetch/about")}
151+
>
152+
About
153+
</a>
154+
</li>
155+
</ul>
156+
</li>
52157
</ul>
53-
</nav>
54158

55-
<script is:inline>
56-
window.addEventListener("DOMContentLoaded", () => {
57-
var target = document.querySelector('[aria-current="page"]');
58-
if (target && target.offsetTop > window.innerHeight - 100) {
59-
document.querySelector(".nav-groups").scrollTop = target.offsetTop;
60-
}
61-
});
62-
</script>
63-
64-
<style lang="scss">
65-
@use '../../tokens' as *;
66-
67-
nav {
68-
padding-top: 1rem;
69-
width: 100%;
70-
}
71-
72-
.nav-groups {
73-
display: flex;
74-
flex-direction: column;
75-
gap: 1rem;
76-
height: 100%;
77-
margin: 0;
78-
max-height: 100vh;
79-
overflow-y: auto;
80-
padding: 0;
81-
82-
@media (min-width: 50em) {
159+
<script is:inline>
160+
window.addEventListener("DOMContentLoaded", () => {
161+
var target = document.querySelector('[aria-current="page"]');
162+
if (target && target.offsetTop > window.innerHeight - 100) {
163+
document.querySelector(".nav-groups").scrollTop = target.offsetTop;
164+
}
165+
});
166+
167+
document.getElementById("v6").addEventListener("change", (evt) => {
168+
if (window.location.pathname === "/migration-guide") {
169+
return; // no /v6 version
170+
}
171+
if (evt.target.checked) {
172+
window.location.href = "/v6" + window.location.pathname;
173+
}
174+
});
175+
176+
document.getElementById("v7").addEventListener("change", (evt) => {
177+
if (evt.target.checked) {
178+
window.location.href = window.location.pathname.replace("/v6/", "/");
179+
}
180+
});
181+
</script>
182+
183+
<style lang="scss">
184+
@use "../../tokens" as *;
185+
@use "../../styles/util" as *;
186+
187+
nav {
188+
padding-top: 1rem;
189+
width: 100%;
190+
}
191+
192+
.nav-groups {
193+
display: flex;
194+
flex-direction: column;
195+
gap: 1rem;
196+
height: 100%;
197+
margin: 0;
198+
max-height: 100vh;
199+
overflow-y: auto;
83200
padding: 0;
201+
202+
@media (min-width: 50em) {
203+
padding: 0;
204+
}
84205
}
85-
}
86206

87-
.nav-link {
88-
margin: 0;
89-
}
207+
.nav-link {
208+
margin: 0;
209+
}
90210

91-
.nav-group {
92-
margin-top: 1rem;
211+
.nav-group {
212+
margin-top: 1rem;
93213

94-
&:first-of-type {
95-
margin-top: 0;
214+
&:first-of-type {
215+
margin-top: 0;
216+
}
96217
}
97-
}
98218

99-
.nav-group-subnav {
100-
margin-top: 0.5rem;
101-
}
219+
.nav-group-subnav {
220+
margin-top: 0.5rem;
221+
}
102222

223+
.nav-group-title {
224+
align-items: center;
225+
display: flex;
226+
gap: 0.5rem;
227+
white-space: nowrap;
228+
}
103229

104-
</style>
230+
.version {
231+
align-items: center;
232+
cursor: pointer;
233+
display: flex;
234+
font-size: 0.875rem;
235+
gap: 0.25rem;
105236

237+
input,
238+
label {
239+
cursor: pointer;
240+
}
241+
242+
&:hover,
243+
&:focus-within {
244+
background-color: token("color.blue.95");
245+
246+
@include darkMode {
247+
background-color: token("color.blue.25");
248+
}
249+
}
250+
}
251+
252+
.version-switcher {
253+
align-items: center;
254+
border: none;
255+
display: flex;
256+
gap: 0.5rem;
257+
margin: 0;
258+
padding: 0;
259+
}
260+
</style>
261+
</nav>

docs/src/content/docs/about.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ description: Additional info about this project
1818
- [**Relevance AI**](https://github.com/RelevanceAI/relevance-js-sdk): build and deploy AI chains
1919
- [**Revolt**](https://github.com/revoltchat/api): open source user-first chat platform
2020
- [**Spacebar**](https://github.com/spacebarchat): a free, open source, self-hostable Discord-compatible chat/voice/video platform
21+
- [\*\*Supabase](https://github.com/supabase/supabase): The open source Firebase alternative.
2122
- [**Twitter API**](https://github.com/twitterdev/twitter-api-typescript-sdk): Official SDK for the Twitter API
2223

2324
## Project goals

docs/src/content/docs/introduction.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ _Note: OpenAPI 2.x is supported with versions `5.x` and previous_
2727
This library requires the latest version of <a href="https://nodejs.org/en" target="_blank" rel="noopener noreferrer">Node.js</a> installed (20.x or higher recommended). With that present, run the following in your project:
2828

2929
```bash
30-
npm i -D openapi-typescript
30+
npm i -D openapi-typescript@next
3131
```
3232

3333
> **Highly recommended**: enable [noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess) in your `tsconfig.json` ([docs](/advanced#enable-nouncheckedindexaccess-in-your-tsconfigjson))
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: Migration Guide
3+
description: Migrating between openapi-typescript versions
4+
---
5+
6+
## v6 → v7
7+
8+
The v7 release only has a few minor breaking changes to be aware of:
9+
10+
### TypeScript AST
11+
12+
v7 introduces the TypeScript AST rather than simple string transformations. This applies to the core Node.js API, which now returns a TypeScript AST, as well as the options `transform()` and `postTransform()`. [The Node.js API docs have been updated with relevant examples to help](./node).
13+
14+
### Globbing replaced with Redocly config
15+
16+
v7 can still generate multiple schemas at once, but rather than globbing, a `redocly.config.yaml` file must be created instead that lists out every input schema, and where the output types should be saved. [See the updated docs for more info](./cli#redoc-config).
17+
18+
### Node.js API input types
19+
20+
Input types were made more predictable in v7. Inputting a partial filepath as a string was removed because it was somewhat nondeterministic—it would either succeed or fail based on where the Node.js API was called from. Now, to load a schema from a filepath or remote URL, use a proper `URL` like so:
21+
22+
```diff
23+
- openapiTS('./path/to/schema.json');
24+
+ openapiTS(new URL('./path/to/schema.json', import.meta.url'));
25+
```
26+
27+
_Note: `import.meta.url` is only needed for local files; you can simply point to a URL for remote schemas_
28+
29+
This is more predictable, and works in more environments.
30+
31+
In addition, the `string` input is now more robust. v6 didn’t support inputting a full YAML spec as a string, but v7 can handle a dynamic YAML and/or JSON string just fine (JSON in object form is still accepted, too).
32+
33+
[See the updated docs for more info](./node#usage).
34+
35+
[See the full CHANGELOG](https://github.com/drwpow/openapi-typescript/blob/6.x/packages/openapi-typescript/CHANGELOG.md)

docs/src/content/docs/node.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ The Node API may be useful if dealing with dynamically-created schemas, or you
88
## Setup
99

1010
```bash
11-
npm i --save-dev openapi-typescript
11+
npm i --save-dev openapi-typescript@next
1212
```
1313

1414
> **Recommended**: For the best experience, use Node ESM by adding `"type": "module"` to `package.json` ([docs](https://nodejs.org/api/esm.html#enabling))

0 commit comments

Comments
 (0)