fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at feat/use-query-options 212 lines 6.2 kB view raw
1<script lang="ts" setup> 2import type { Pet } from '@/client'; 3import type { RequestOptions } from '@/client/client'; 4import { PiniaColadaDevtools } from '@pinia/colada-devtools'; 5import { createClient } from '@/client/client'; 6import { PetSchema } from '@/client/schemas.gen'; 7import { addPetMutation, getPetByIdQuery, updatePetMutation } from '@/client/@pinia/colada.gen'; 8import { useQuery, useMutation, useQueryCache } from '@pinia/colada'; 9import { ref, watch } from 'vue'; 10 11const localClient = createClient({ 12 // set default base url for requests made by this client 13 baseUrl: 'https://petstore3.swagger.io/api/v3', 14 /** 15 * Set default headers only for requests made by this client. This is to 16 * demonstrate local clients and their configuration taking precedence over 17 * internal service client. 18 */ 19 headers: { 20 Authorization: 'Bearer <token_from_local_client>', 21 }, 22}); 23 24localClient.interceptors.request.use((request: Request, options: RequestOptions) => { 25 // Middleware is great for adding authorization tokens to requests made to 26 // protected paths. Headers are set randomly here to allow surfacing the 27 // default headers, too. 28 if (options.url === '/pet/{petId}' && options.method === 'GET' && Math.random() < 0.5) { 29 request.headers.set('Authorization', 'Bearer <token_from_interceptor>'); 30 } 31 return request; 32}); 33 34const isPetNameRequired = PetSchema.required.includes('name'); 35 36const petId = ref<number | undefined>(); 37const petInput = ref({ name: '', category: '' }); 38 39const { data: pet, error } = useQuery(() => ({ 40 ...getPetByIdQuery({ 41 path: { 42 petId: petId.value as number, 43 }, 44 }), 45 enabled: petId.value !== undefined, 46})); 47const { mutateAsync: createPet } = useMutation(addPetMutation()); 48const { mutateAsync: updatePet } = useMutation(updatePetMutation()); 49 50const queryCache = useQueryCache(); 51async function invalidateCurrentPet() { 52 const { key } = getPetByIdQuery({ 53 path: { 54 petId: petId.value as number, 55 }, 56 }); 57 await queryCache.invalidateQueries({ key, exact: true }); 58} 59 60async function updatePetIdAndInvalidate(newId: number | undefined) { 61 if (newId !== undefined) { 62 petId.value = newId; 63 } 64 65 if (petId.value !== undefined) { 66 await invalidateCurrentPet(); 67 } 68} 69 70async function handleAddPet() { 71 if (isPetNameRequired && !petInput.value.name) return; 72 73 const result = await createPet({ body: buildPetBody() }); 74 if (!result) return; 75 76 await updatePetIdAndInvalidate(result.id); 77} 78 79async function handleUpdatePet() { 80 if (!pet.value) return; 81 82 const result = await updatePet({ 83 body: buildPetBody(pet.value), 84 headers: { 85 Authorization: 'Bearer <token_from_method>', 86 }, 87 }); 88 if (!result) return; 89 90 await updatePetIdAndInvalidate(result.id); 91} 92 93function randomInt(min: number, max: number) { 94 return Math.floor(Math.random() * (max - min + 1) + min); 95} 96 97function setRandomPetId() { 98 petId.value = randomInt(1, 10); 99} 100 101function buildPetBody(base?: Partial<Pet>) { 102 return { 103 category: { 104 id: base?.category?.id ?? 0, 105 name: petInput.value.category, 106 }, 107 id: base?.id ?? 0, 108 name: petInput.value.name, 109 photoUrls: ['string'], 110 status: 'available' as const, 111 tags: [ 112 { 113 id: 0, 114 name: 'string', 115 }, 116 ], 117 }; 118} 119 120watch(error, (error) => { 121 console.error(error); 122}); 123</script> 124 125<template> 126 <div class="bg-[#18191b] py-12"> 127 <div class="mx-auto flex max-w-md flex-col gap-12"> 128 <div class="flex items-center"> 129 <a class="shrink-0" href="https://heyapi.dev/" target="_blank"> 130 <img 131 alt="Hey API logo" 132 class="size-16 transition duration-300 will-change-auto" 133 src="https://heyapi.dev/assets/raw/logo.png" 134 /> 135 </a> 136 137 <h1 class="text-2xl font-bold text-white">@hey-api/openapi-ts 🤝 Pinia Colada</h1> 138 </div> 139 140 <div class="flex flex-col gap-2"> 141 <div 142 class="flex max-w-60 items-center gap-3 rounded border border-[#575e64] bg-[#1f2123] p-4" 143 > 144 <div 145 class="flex size-10 place-content-center place-items-center rounded-full bg-[#233057] text-lg font-medium text-[#9eb1ff]" 146 > 147 <span> 148 {{ pet?.name?.slice(0, 1) || 'N' }} 149 </span> 150 </div> 151 152 <div> 153 <p class="text-sm font-bold text-white">Name: {{ pet?.name || 'N/A' }}</p> 154 155 <p class="text-sm text-[#f1f7feb5]">Category: {{ pet?.category?.name || 'N/A' }}</p> 156 </div> 157 </div> 158 159 <button 160 class="rounded bg-[#3e63dd] p-1 text-sm font-medium text-white" 161 type="button" 162 @click="setRandomPetId" 163 > 164 Get Random Pet 165 </button> 166 </div> 167 168 <form class="flex flex-col gap-3" @submit.prevent="handleAddPet"> 169 <div class="flex w-64 flex-col gap-1"> 170 <label class="font-medium text-white" for="name">Name</label> 171 172 <input 173 v-model="petInput.name" 174 class="rounded border border-[#575e64] bg-[#121314] p-1 text-sm text-white placeholder:text-[#575e64]" 175 name="name" 176 placeholder="Kitty" 177 required 178 /> 179 </div> 180 181 <div class="flex w-64 flex-col gap-1"> 182 <label class="font-medium text-white" for="category">Category</label> 183 184 <input 185 v-model="petInput.category" 186 class="rounded border border-[#575e64] bg-[#121314] p-1 text-sm text-white placeholder:text-[#575e64]" 187 name="category" 188 placeholder="Cats" 189 required 190 /> 191 </div> 192 193 <div class="flex gap-2"> 194 <button class="rounded bg-[#3e63dd] p-2 text-sm font-medium text-white" type="submit"> 195 Add Pet 196 </button> 197 198 <button 199 class="rounded bg-[#3e63dd] p-2 text-sm font-medium text-white disabled:cursor-not-allowed" 200 :disabled="!pet" 201 type="button" 202 @click="handleUpdatePet" 203 > 204 Update Pet 205 </button> 206 </div> 207 </form> 208 </div> 209 </div> 210 211 <pinia-colada-devtools /> 212</template>