Skip to content

Commit b02546f

Browse files
authored
Merge pull request #2341 from hey-api/feat/zod-4
docs: add Zod 4 page
2 parents 30b17ae + 9954bcf commit b02546f

File tree

3,010 files changed

+32485
-1801
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,010 files changed

+32485
-1801
lines changed

.changeset/mighty-eels-care.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
'@hey-api/openapi-ts': minor
3+
---
4+
5+
feat(zod): add support for Zod 4 and Zod Mini
6+
7+
### Added Zod 4 and Zod Mini
8+
9+
This release adds support for Zod 4 and Zod Mini. By default, the `zod` plugin will generate output for Zod 4. If you want to preserve the previous output for Zod 3 or use Zod Mini, set `compatibilityVersion` to `3` or `mini`.
10+
11+
```js
12+
export default {
13+
input: 'https://get.heyapi.dev/hey-api/backend',
14+
output: 'src/client',
15+
plugins: [
16+
// ...other plugins
17+
{
18+
name: 'zod',
19+
compatibilityVersion: 3,
20+
},
21+
],
22+
};
23+
```
24+
25+
```js
26+
export default {
27+
input: 'https://get.heyapi.dev/hey-api/backend',
28+
output: 'src/client',
29+
plugins: [
30+
// ...other plugins
31+
{
32+
name: 'zod',
33+
compatibilityVersion: 'mini',
34+
},
35+
],
36+
};
37+
```

docs/.vitepress/config/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ import shared from './shared';
66
export default defineConfig({
77
...shared,
88
locales: {
9+
...shared.locales,
910
root: { label: 'English', ...en },
1011
},
12+
vite: {
13+
...shared.vite,
14+
resolve: {
15+
...shared.vite?.resolve,
16+
preserveSymlinks: true,
17+
},
18+
},
1119
});

docs/.vitepress/theme/Layout.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<script setup>
1+
<script setup lang="ts">
22
import DefaultTheme from 'vitepress/theme';
33
44
const { Layout } = DefaultTheme;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<div class="container">
3+
<slot />
4+
</div>
5+
</template>
6+
7+
<style scoped>
8+
.container {
9+
align-items: center;
10+
column-gap: 1rem;
11+
display: flex;
12+
}
13+
</style>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script setup lang="ts">
2+
const props = defineProps<{
3+
value: string;
4+
}>();
5+
</script>
6+
7+
<template>
8+
<div class="container">
9+
<div class="control">
10+
<div class="value-container">
11+
{{ props.value }}
12+
</div>
13+
</div>
14+
</div>
15+
</template>
16+
17+
<style scoped>
18+
.container {
19+
box-sizing: border-box;
20+
position: relative;
21+
width: var(--vs-width);
22+
}
23+
24+
.control {
25+
align-items: center;
26+
background-color: var(--vs-background-color);
27+
border-radius: var(--vs-border-radius);
28+
border: var(--vs-border);
29+
display: flex;
30+
flex-wrap: wrap;
31+
justify-content: space-between;
32+
min-height: var(--vs-min-height);
33+
}
34+
35+
.value-container {
36+
align-items: center;
37+
display: grid;
38+
flex: 1 1 0%;
39+
overflow: hidden;
40+
padding: var(--vs-padding-y) calc(var(--vs-padding-x) * 1.4)
41+
var(--vs-padding-y) var(--vs-padding-x);
42+
position: relative;
43+
}
44+
</style>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<script setup lang="ts">
2+
import { ref } from 'vue';
3+
import { useRoute, useRouter } from 'vitepress';
4+
import VueSelect from 'vue3-select-component';
5+
6+
type Option = {
7+
label: string;
8+
short?: string;
9+
value: string;
10+
};
11+
12+
const props = defineProps<{
13+
default: string;
14+
values: Array<Option>;
15+
}>();
16+
17+
const route = useRoute();
18+
const router = useRouter();
19+
20+
const selected = ref(getCurrentVersion(route.path));
21+
22+
function getCurrentVersion(path: string) {
23+
const segments = path.replace(/(^\/|\/$)/g, '').split('/');
24+
const versionValues = props.values.map((v) => v.value);
25+
const last = segments[segments.length - 1];
26+
return versionValues.includes(last) ? last : props.default;
27+
}
28+
29+
function switchVersion(option: Option) {
30+
const path = route.path;
31+
const segments = path.replace(/(^\/|\/$)/g, '').split('/');
32+
const versionValues = props.values.map((v) => v.value);
33+
const last = segments[segments.length - 1];
34+
if (versionValues.includes(last)) {
35+
segments.pop();
36+
}
37+
if (option.value !== props.default) {
38+
segments.push(option.value);
39+
}
40+
const nextPath = `/${segments.filter(Boolean).join('/')}`;
41+
if (nextPath !== route.path) {
42+
router.go(nextPath);
43+
}
44+
}
45+
</script>
46+
47+
<template>
48+
<VueSelect
49+
v-model="selected"
50+
:isClearable="false"
51+
:options="props.values"
52+
@option-selected="switchVersion"
53+
>
54+
<template #value="{ option }">
55+
{{ option.short || option.label }}
56+
</template>
57+
</VueSelect>
58+
</template>

docs/.vitepress/theme/custom.css

Lines changed: 88 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,27 @@ html.dark {
3131
--vp-home-hero-image-filter: blur(144px);
3232
}
3333

34+
html.mac {
35+
--vs-background-color: var(--vp-input-switch-bg-color);
36+
--vs-border: 1px solid var(--vp-input-border-color);
37+
--vs-menu-border: 1px solid var(--vp-input-border-color);
38+
--vs-menu-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
39+
--vs-option-background-color: var(--vp-sidebar-bg-color);
40+
--vs-option-disabled-background-color: var(--vp-sidebar-bg-color);
41+
--vs-option-focused-background-color: var(--vp-sidebar-bg-color);
42+
--vs-option-focused-text-color: var(--vp-c-brand-1);
43+
--vs-option-hover-background-color: var(--vp-sidebar-bg-color);
44+
--vs-option-hover-text-color: var(--vp-c-brand-1);
45+
--vs-option-selected-background-color: var(--vp-sidebar-bg-color);
46+
--vs-option-selected-text-color: var(--vp-c-brand-1);
47+
--vs-option-text-color: var(--vp-c-text-2);
48+
--vs-padding-x: 8px;
49+
--vs-padding-y: 4px;
50+
--vs-padding: var(--vs-padding-y) var(--vs-padding-x);
51+
--vs-text-color: var(--vp-c-text-1);
52+
--vs-width: auto;
53+
}
54+
3455
[data-soon] {
3556
background-color: var(--vp-button-brand-bg);
3657
border-radius: 1em;
@@ -48,6 +69,24 @@ iframe {
4869
margin: 0;
4970
}
5071

72+
.VPFeatures.VPHomeFeatures > .container {
73+
max-width: initial;
74+
}
75+
76+
.VPFeatures.VPHomeFeatures > .container > .items {
77+
gap: 1rem;
78+
justify-content: center;
79+
margin: 0;
80+
padding: 0.2rem 0;
81+
}
82+
83+
.VPFeatures.VPHomeFeatures > .container > .items > .item {
84+
flex-shrink: 0;
85+
max-width: 390px;
86+
padding: 0;
87+
width: 100%;
88+
}
89+
5190
.authors-list {
5291
display: flex;
5392
flex-wrap: wrap;
@@ -244,10 +283,6 @@ html.dark .sponsors-list li {
244283
text-transform: lowercase;
245284
}
246285

247-
.VPFeatures.VPHomeFeatures > .container {
248-
max-width: initial;
249-
}
250-
251286
.migration {
252287
background-color: var(--vp-c-brand-3);
253288
border-radius: 10px;
@@ -270,18 +305,60 @@ a.migration:focus {
270305
border-color: var(--vp-c-brand-1);
271306
}
272307

273-
.VPFeatures.VPHomeFeatures > .container > .items {
274-
gap: 1rem;
275-
justify-content: center;
276-
margin: 0;
277-
padding: 0.2rem 0;
278-
}
279-
280308
.contributors-list ul {
281309
margin-bottom: 1.3rem;
282310
margin-top: 1.3rem;
283311
}
284312

313+
.vue-select .control {
314+
cursor: pointer;
315+
transition: border-color 0.25s;
316+
}
317+
318+
.vue-select .control:hover {
319+
border-color: var(--vp-c-brand-1);
320+
}
321+
322+
.vue-select .control .indicators-container {
323+
padding: 0;
324+
}
325+
326+
.vue-select .control .value-container.has-value:has(.single-value) {
327+
padding-inline-end: 0;
328+
}
329+
330+
.vue-select .control .indicators-container button.dropdown-icon {
331+
height: 100%;
332+
padding: var(--vs-padding);
333+
width: calc(
334+
var(--vs-indicator-icon-size) + var(--vs-padding-x) + var(--vs-padding-x)
335+
);
336+
}
337+
338+
.vue-select .menu {
339+
width: fit-content !important;
340+
}
341+
342+
.vue-select .menu .menu-option {
343+
border-left: 2px solid transparent;
344+
border-right: 2px solid transparent;
345+
white-space: nowrap;
346+
transition:
347+
background-color 0.25s,
348+
border-color 0.25s,
349+
color 0.25s,
350+
opacity 0.25s;
351+
}
352+
353+
.vue-select .menu:hover .menu-option.focused:not(:hover) {
354+
border-left: 2px solid transparent;
355+
}
356+
357+
.vue-select .menu .menu-option:hover,
358+
.vue-select .menu:not(:hover) .menu-option.focused {
359+
border-left: 2px solid var(--vp-c-brand-1);
360+
}
361+
285362
@media (min-width: 640px) {
286363
.VPFeatures.VPHomeFeatures > .container > .items {
287364
gap: 1rem;
@@ -315,10 +392,3 @@ a.migration:focus {
315392
background-color: var(--vp-sidebar-bg-color);
316393
}
317394
}
318-
319-
.VPFeatures.VPHomeFeatures > .container > .items > .item {
320-
flex-shrink: 0;
321-
max-width: 390px;
322-
padding: 0;
323-
width: 100%;
324-
}

docs/.vitepress/theme/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@ import DefaultTheme from 'vitepress/theme';
66
import './custom.css';
77

88
import AuthorsList from './components/AuthorsList.vue';
9+
import Heading from './components/Heading.vue';
10+
import VersionLabel from './components/VersionLabel.vue';
11+
import VersionSwitcher from './components/VersionSwitcher.vue';
912
import Layout from './Layout.vue';
1013

1114
export default {
1215
Layout,
1316
enhanceApp: ({ app }) => {
1417
app.component('AuthorsList', AuthorsList);
18+
app.component('Heading', Heading);
19+
app.component('VersionLabel', VersionLabel);
20+
app.component('VersionSwitcher', VersionSwitcher);
1521
},
1622
extends: DefaultTheme,
1723
} satisfies Theme;

docs/openapi-ts/clients.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Clients
33
description: REST clients for Hey API. Compatible with all our features.
44
---
55

6-
<script setup>
6+
<script setup lang="ts">
77
import { embedProject } from '../embed'
88
</script>
99

docs/openapi-ts/clients/axios.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ title: Axios client
33
description: Axios client for Hey API. Compatible with all our features.
44
---
55

6-
<script setup>
6+
<script setup lang="ts">
77
import { embedProject } from '../../embed'
88
</script>
99

10-
# Axios
10+
<Heading>
11+
<h1>Axios</h1>
12+
<VersionLabel value="v1" />
13+
</Heading>
1114

1215
::: warning
1316
Axios client is currently in beta. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues).

0 commit comments

Comments
 (0)