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

docs: @tanstack/vue-query vue example

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