make trpc-nuxt flexible by exporting server and client functions instead of nuxt modules

This commit is contained in:
Robert Soriano
2022-10-29 21:50:27 -07:00
parent bad2de134b
commit ae920a37fd
20 changed files with 713 additions and 780 deletions

View File

@@ -1,8 +1,5 @@
import Module from '../src/module'
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
modules: [Module],
runtimeConfig: {
baseURL: '',
},

View File

@@ -1,4 +1,18 @@
{
"name": "playground",
"private": true
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"trpc-nuxt": "workspace:*",
"zod": "^3.19.1"
},
"devDependencies": {
"nuxt": "3.0.0-rc.12"
}
}

View File

@@ -1,7 +1,6 @@
<script setup lang="ts">
const { $client } = useNuxtApp()
// const headers = useClientHeaders()
// const { data: todos, pending, error, refresh } = await useAsyncQuery(['getTodos'])
// const addHeader = () => {
// headers.value.authorization = 'Bearer abcdefghijklmnop'
@@ -13,7 +12,7 @@ const addTodo = async () => {
try {
const result = await $client.todo.addTodo.mutate({
id: 69,
id: Date.now(),
userId: 69,
title,
completed: false,
@@ -26,7 +25,7 @@ const addTodo = async () => {
}
}
const { data: todos, pending, error, refresh } = await $client.getTodos.query()
const { data: todos, pending, error, refresh } = await $client.todo.getTodos.query()
</script>
<template>

View File

@@ -1,12 +1,12 @@
import { httpBatchLink } from '@trpc/client'
import { createTRPCNuxtProxyClient } from 'trpc-nuxt/client'
import type { AppRouter } from '~~/server/trpc'
import type { AppRouter } from '~~/server/trpc/routers'
export default defineNuxtPlugin(() => {
const client = createTRPCNuxtProxyClient<AppRouter>({
links: [
httpBatchLink({
url: 'http://localhost:3000/trpc',
url: 'http://localhost:3000/api/trpc',
}),
],
})

View File

@@ -0,0 +1,12 @@
import { createNuxtApiHandler } from 'trpc-nuxt'
import { appRouter } from '../../trpc/routers'
export default createNuxtApiHandler({
router: appRouter,
createContext: async () => {
return {}
},
onError({ error }) {
console.log('Error', error)
},
})

View File

@@ -1,69 +1,25 @@
import { initTRPC } from '@trpc/server'
import { z } from 'zod'
import type { H3Event } from 'h3'
import type { inferAsyncReturnType } from '@trpc/server'
const baseURL = 'https://jsonplaceholder.typicode.com'
const t = initTRPC.context<any>().create()
const TodoShape = z.object({
userId: z.number(),
id: z.number(),
title: z.string(),
completed: z.boolean(),
})
export type Todo = z.infer<typeof TodoShape>
const t = initTRPC.context<Context>().create()
// We explicitly export the methods we use here
// This allows us to create reusable & protected base procedures
export const middleware = t.middleware
/**
* Create a router
* @see https://trpc.io/docs/v10/router
*/
export const router = t.router
/**
* Create an unprotected procedure
* @see https://trpc.io/docs/v10/procedures
**/
export const publicProcedure = t.procedure
const anotherRouter = router({
getTodo: publicProcedure
.input(z.number())
.query((req) => {
return $fetch<Todo>(`${baseURL}/todos/${req.input}`)
}),
addTodo: publicProcedure
.input(TodoShape)
.mutation((req) => {
return $fetch<Todo>(`${baseURL}/todos`, {
method: 'POST',
body: req.input,
})
}),
})
/**
* @see https://trpc.io/docs/v10/middlewares
*/
export const middleware = t.middleware
export const appRouter = router({
todo: anotherRouter,
getTodos: publicProcedure.query(() => {
return $fetch<Todo[]>(`${baseURL}/todos`)
}),
getTodo: publicProcedure
.input(z.number())
.query((req) => {
console.log('REQ', req)
return $fetch<Todo>(`${baseURL}/todos/${req.input}`)
}),
})
export type AppRouter = typeof appRouter
export async function createContext(event: H3Event) {
// Create your context based on the request object
// Will be available as `ctx` in all your resolvers
// This is just an example of something you'd might want to do in your ctx fn
// const x = useCookies(event)
console.log(event.req.headers)
return {
}
}
type Context = inferAsyncReturnType<typeof createContext>
/**
* @see https://trpc.io/docs/v10/merging-routers
*/
export const mergeRouters = t.mergeRouters

View File

@@ -0,0 +1,10 @@
import { router } from '..'
import { todoRouter } from './todo'
import { userRouter } from './user'
export const appRouter = router({
todo: todoRouter,
user: userRouter,
})
export type AppRouter = typeof appRouter

View File

@@ -0,0 +1,33 @@
import { z } from 'zod'
import { publicProcedure, router } from '..'
const baseURL = 'https://jsonplaceholder.typicode.com'
const TodoShape = z.object({
userId: z.number(),
id: z.number(),
title: z.string(),
completed: z.boolean(),
})
export type Todo = z.infer<typeof TodoShape>
export const todoRouter = router({
getTodos: publicProcedure
.query(() => {
return $fetch<Todo[]>(`${baseURL}/todos`)
}),
getTodo: publicProcedure
.input(z.number())
.query((req) => {
return $fetch<Todo>(`${baseURL}/todos/${req.input}`)
}),
addTodo: publicProcedure
.input(TodoShape)
.mutation((req) => {
return $fetch<Todo>(`${baseURL}/todos`, {
method: 'POST',
body: req.input,
})
}),
})

View File

@@ -0,0 +1,33 @@
import { z } from 'zod'
import { publicProcedure, router } from '..'
const baseURL = 'https://jsonplaceholder.typicode.com'
const UserShape = z.object({
id: z.number(),
name: z.string(),
username: z.string(),
email: z.string(),
})
export type User = z.infer<typeof UserShape>
export const userRouter = router({
getUsers: publicProcedure
.query(() => {
return $fetch<User[]>(`${baseURL}/users`)
}),
getUser: publicProcedure
.input(z.number())
.query((req) => {
return $fetch<User>(`${baseURL}/users/${req.input}`)
}),
addUser: publicProcedure
.input(UserShape)
.mutation((req) => {
return $fetch<User>(`${baseURL}/users`, {
method: 'POST',
body: req.input,
})
}),
})

4
playground/tsconfig.json Normal file
View File

@@ -0,0 +1,4 @@
{
// https://v3.nuxtjs.org/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}