fork of hey-api/openapi-ts because I need some additional things
1<script setup lang="ts">
2import { ref } from 'vue';
3
4import { createClient } from './client/client';
5import { PetSchema } from './client/schemas.gen';
6import { addPet, getPetById, updatePet } from './client/sdk.gen';
7import type { Pet } from './client/types.gen';
8
9const pet = ref<Pet | undefined>();
10const petInput = ref({ name: '', category: '' });
11const isPetNameRequired = PetSchema.required.includes('name');
12
13const localClient = createClient({
14 baseUrl: 'https://petstore3.swagger.io/api/v3',
15 headers: {
16 Authorization: 'Bearer <token_from_local_client>',
17 },
18});
19
20localClient.interceptors.request.use((request, options) => {
21 if (options.url === '/pet/{petId}' && options.method === 'GET' && Math.random() < 0.5) {
22 request.headers.set('Authorization', 'Bearer <token_from_interceptor>');
23 }
24 return request;
25});
26
27localClient.interceptors.error.use((error) => {
28 console.error(error);
29 return error;
30});
31
32function randomInt(min: number, max: number) {
33 return Math.floor(Math.random() * (max - min + 1) + min);
34}
35
36async function setRandomPetId() {
37 const id = randomInt(1, 10);
38 const { data, error } = await getPetById({
39 client: localClient,
40 path: { petId: id },
41 });
42 if (error) {
43 console.error(error);
44 return;
45 }
46 pet.value = data!;
47}
48
49function buildPetBody(base?: Partial<Pet>) {
50 return {
51 category: {
52 id: base?.category?.id ?? 0,
53 name: petInput.value.category,
54 },
55 id: base?.id ?? 0,
56 name: petInput.value.name,
57 photoUrls: ['string'],
58 status: 'available' as const,
59 tags: [
60 {
61 id: 0,
62 name: 'string',
63 },
64 ],
65 };
66}
67
68async function handleAddPet() {
69 if (isPetNameRequired && !petInput.value.name) return;
70 const { data, error } = await addPet({ body: buildPetBody() });
71 if (error) {
72 console.error(error);
73 return;
74 }
75 pet.value = data!;
76}
77
78async function handleUpdatePet() {
79 if (!pet.value) return;
80 const { data, error } = await updatePet({
81 body: buildPetBody(pet.value),
82 headers: { Authorization: 'Bearer <token_from_method>' },
83 });
84 if (error) {
85 console.error(error);
86 return;
87 }
88 pet.value = data!;
89}
90</script>
91
92<template>
93 <div class="bg-[#18191b] py-12">
94 <div class="mx-auto flex max-w-md flex-col gap-12">
95 <div class="flex items-center">
96 <a class="shrink-0" href="https://heyapi.dev/" target="_blank">
97 <img
98 alt="Hey API logo"
99 class="size-16 transition duration-300 will-change-auto"
100 src="https://heyapi.dev/assets/raw/logo.png"
101 />
102 </a>
103
104 <h1 class="text-2xl font-bold text-white">@hey-api/openapi-ts 🤝 ofetch</h1>
105 </div>
106
107 <div class="flex flex-col gap-2">
108 <div
109 class="flex max-w-60 items-center gap-3 rounded border border-[#575e64] bg-[#1f2123] p-4"
110 >
111 <div
112 class="flex size-10 place-content-center place-items-center rounded-full bg-[#233057] text-lg font-medium text-[#9eb1ff]"
113 >
114 <span>
115 {{ pet?.name?.slice(0, 1) || 'N' }}
116 </span>
117 </div>
118
119 <div>
120 <p class="text-sm font-bold text-white">Name: {{ pet?.name || 'N/A' }}</p>
121
122 <p class="text-sm text-[#f1f7feb5]">Category: {{ pet?.category?.name || 'N/A' }}</p>
123 </div>
124 </div>
125
126 <button
127 class="rounded bg-[#3e63dd] p-1 text-sm font-medium text-white"
128 type="button"
129 @click="setRandomPetId"
130 >
131 Get Random Pet
132 </button>
133 </div>
134
135 <form class="flex flex-col gap-3" @submit.prevent="handleAddPet">
136 <div class="flex w-64 flex-col gap-1">
137 <label class="font-medium text-white" for="name">Name</label>
138
139 <input
140 v-model="petInput.name"
141 class="rounded border border-[#575e64] bg-[#121314] p-1 text-sm text-white placeholder:text-[#575e64]"
142 name="name"
143 placeholder="Kitty"
144 :required="isPetNameRequired"
145 />
146 </div>
147
148 <div class="flex w-64 flex-col gap-1">
149 <label class="font-medium text-white" for="category">Category</label>
150
151 <input
152 v-model="petInput.category"
153 class="rounded border border-[#575e64] bg-[#121314] p-1 text-sm text-white placeholder:text-[#575e64]"
154 name="category"
155 placeholder="Cats"
156 required
157 />
158 </div>
159
160 <div class="flex gap-2">
161 <button class="rounded bg-[#3e63dd] p-2 text-sm font-medium text-white" type="submit">
162 Add Pet
163 </button>
164
165 <button
166 class="rounded bg-[#3e63dd] p-2 text-sm font-medium text-white disabled:cursor-not-allowed"
167 :disabled="!pet"
168 type="button"
169 @click="handleUpdatePet"
170 >
171 Update Pet
172 </button>
173 </div>
174 </form>
175 </div>
176 </div>
177</template>