mirror of
https://github.com/ArthurDanjou/trpc-nuxt.git
synced 2026-01-14 12:14:40 +01:00
update playground
This commit is contained in:
@@ -1,18 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
const { data, pending, error } = await useAsyncQuery(['getUser', { username: 'jcena' }], {
|
||||
lazy: false,
|
||||
transform: data => data || null,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="pending">
|
||||
Loading...
|
||||
</div>
|
||||
<div v-else-if="error">
|
||||
Error: {{ JSON.stringify(error, null, 2) }}
|
||||
</div>
|
||||
<div v-else>
|
||||
User {{ JSON.stringify(data, null, 2) }}
|
||||
<div>
|
||||
<NuxtPage />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
34
playground/pages/index.vue
Normal file
34
playground/pages/index.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
const { data: todos, pending, error, refresh } = await useAsyncQuery(['getTodos'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="pending">
|
||||
Loading...
|
||||
</div>
|
||||
<div v-else-if="error?.data?.code">
|
||||
Error: {{ error.data.code }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<ul>
|
||||
<li v-for="t in todos.slice(0, 10)" :key="t.id">
|
||||
<NuxtLink :class="{ completed: t.completed }" :to="`/todo/${t.id}`">
|
||||
Title: {{ t.title }}
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
<button @click="() => refresh()">
|
||||
Refresh
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.completed {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
</style>
|
||||
18
playground/pages/todo/[id].vue
Normal file
18
playground/pages/todo/[id].vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
const { data: todo, pending, error } = await useAsyncQuery(['getTodo', Number(route.params.id)])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="pending">
|
||||
Loading...
|
||||
</div>
|
||||
<div v-else-if="error?.data?.code">
|
||||
{{ error.data.code }}
|
||||
</div>
|
||||
<div v-else>
|
||||
ID: {{ todo.id }} <br>
|
||||
Title: {{ todo.title }} <br>
|
||||
Completed: {{ todo.completed }}
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,82 +1,24 @@
|
||||
// ~/server/trpc/index.ts
|
||||
import { ZodError, z } from 'zod'
|
||||
import * as trpc from '@trpc/server'
|
||||
import type { inferAsyncReturnType } from '@trpc/server'
|
||||
import type { CompatibilityEvent } from 'h3'
|
||||
import type { ResponseMetaFnPayload } from 'trpc-nuxt/api'
|
||||
// import superjson from 'superjson'
|
||||
import { z } from 'zod'
|
||||
|
||||
const fakeUsers = [
|
||||
{ id: 1, username: 'jcena' },
|
||||
{ id: 2, username: 'dbatista' },
|
||||
{ id: 3, username: 'jbiden' },
|
||||
]
|
||||
|
||||
export const router = trpc
|
||||
.router<inferAsyncReturnType<typeof createContext>>()
|
||||
.formatError(({ shape, error }) => {
|
||||
return {
|
||||
...shape,
|
||||
data: {
|
||||
...shape.data,
|
||||
zodError:
|
||||
error.code === 'BAD_REQUEST'
|
||||
&& error.cause instanceof ZodError
|
||||
? error.cause.flatten()
|
||||
: null,
|
||||
},
|
||||
}
|
||||
})
|
||||
.query('getUsers', {
|
||||
resolve() {
|
||||
return fakeUsers
|
||||
},
|
||||
})
|
||||
.query('getUser', {
|
||||
// validate input with Zod
|
||||
input: z.object({
|
||||
username: z.string().min(5),
|
||||
}),
|
||||
resolve(req) {
|
||||
return fakeUsers.find(i => i.username === req.input.username) ?? null
|
||||
},
|
||||
})
|
||||
.mutation('createUser', {
|
||||
input: z.object({ username: z.string().min(5) }),
|
||||
resolve(req) {
|
||||
const newUser = {
|
||||
id: fakeUsers.length + 1,
|
||||
username: req.input.username,
|
||||
}
|
||||
fakeUsers.push(newUser)
|
||||
return newUser
|
||||
},
|
||||
})
|
||||
|
||||
export const createContext = (event: CompatibilityEvent) => {
|
||||
event.res.setHeader('x-ssr', 1)
|
||||
return {}
|
||||
export interface Todo {
|
||||
userId: number
|
||||
id: number
|
||||
title: string
|
||||
completed: boolean
|
||||
}
|
||||
|
||||
export const responseMeta = (opts: ResponseMetaFnPayload<any>) => {
|
||||
// const nuxtApp = useNuxtApp()
|
||||
// const client = useClient()
|
||||
// console.log(opts)
|
||||
const baseURL = 'https://jsonplaceholder.typicode.com'
|
||||
|
||||
// if (nuxtApp.nuxtState) {
|
||||
// nuxtApp.nuxtState.trpc = client.runtime.transformer.serialize({
|
||||
// ctx: opts.ctx,
|
||||
// errors: opts.errors,
|
||||
// })
|
||||
// }
|
||||
// else {
|
||||
// nuxtApp.nuxtState = {
|
||||
// trpc: client.runtime.transformer.serialize({
|
||||
// ctx: opts.ctx,
|
||||
// errors: opts.errors,
|
||||
// }),
|
||||
// }
|
||||
// }
|
||||
|
||||
return {}
|
||||
}
|
||||
export const router = trpc.router()
|
||||
.query('getTodos', {
|
||||
async resolve() {
|
||||
return await $fetch<Todo[]>(`${baseURL}/todos`)
|
||||
},
|
||||
})
|
||||
.query('getTodo', {
|
||||
input: z.number(),
|
||||
async resolve(req) {
|
||||
return await $fetch<Todo>(`${baseURL}/todos/${req.input}`)
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user