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