Compare commits

...

25 Commits

Author SHA1 Message Date
Robert Soriano
07693009f8 release v0.2.2 2022-06-16 06:49:32 -07:00
Robert Soriano
dceade155c chore(deps): bump nuxt to 3.0.0-rc.4 2022-06-16 06:48:56 -07:00
Robert Soriano
4012249f09 chore(deps): bump h3 to 0.7.9 2022-06-16 06:48:20 -07:00
Robert Soriano
38eda2c4d6 chore(deps): bump @trpc/client to 9.25.2 2022-06-16 06:47:39 -07:00
Robert Soriano
9468af75f4 chore(deps): bump @trpc/server to 9.25.2 2022-06-16 06:47:18 -07:00
Robert Soriano
ea24a67a6d chore(deps): bump @nuxt/kit to 3.0.0-rc.4 2022-06-16 06:46:35 -07:00
Robert Soriano
5e8d04741c release v0.2.1 2022-06-13 18:51:41 -07:00
Robert Soriano
1032e65a0d refactor: remove unused import in playground 2022-06-13 18:51:35 -07:00
Robert Soriano
f261d3feeb Merge pull request #12 from cawa-93/patch-1
fix: auto-import `getQueryKey`
2022-06-13 18:49:07 -07:00
Alex Kozack
b1ca09e986 fix: auto-import getQueryKey 2022-06-13 12:06:03 +03:00
Robert Soriano
b804429fc0 update readme 2022-06-12 23:32:55 -07:00
Robert Soriano
7df64296ff update readme 2022-06-12 23:32:41 -07:00
Robert Soriano
a53d823f5e release v0.2.0 2022-06-12 23:30:07 -07:00
Robert Soriano
feef3dde6b update readme 2022-06-12 23:30:03 -07:00
Robert Soriano
82ee2ce672 refactor!: replace trpcURL option with endpoint 2022-06-12 23:29:28 -07:00
Robert Soriano
f62a13766a update readme 2022-06-12 23:19:55 -07:00
Robert Soriano
c7888e81ed refactor: use addAutoImport 2022-06-12 23:18:38 -07:00
Robert Soriano
c77eb68f5d refactor: rename endpoint option 2022-06-12 23:17:13 -07:00
Robert Soriano
333539569c refactor: lint 2022-06-12 23:16:01 -07:00
Robert Soriano
e5c40f183b Merge pull request #7 from cawa-93/feat/extract-get-query-key
feat: extract `getQueryKey` helper
2022-06-12 23:08:21 -07:00
Robert Soriano
977a9e1465 release v0.1.24 2022-06-05 17:05:34 -07:00
Robert Soriano
2620379e02 feat: allow changing of src dir 2022-06-05 17:05:13 -07:00
Robert Soriano
e4f42d5322 Merge pull request #10 from nicolesmileyface/feat/support-src-dir
use nuxt srcDir instead of rootDir
2022-06-05 17:02:41 -07:00
Cole Hollant
ad28a9124e use nuxt srcDir instead of rootDir 2022-06-05 11:55:25 -04:00
cawa-93
273bda980b feat: extract getQueryKey helper
This method will be useful to get a key that can be used to reset the internal nuxt cache
2022-05-31 15:20:21 +03:00
8 changed files with 1217 additions and 951 deletions

View File

@@ -29,10 +29,10 @@ export default defineNuxtConfig({
modules: ['trpc-nuxt'], modules: ['trpc-nuxt'],
trpc: { trpc: {
baseURL: 'http://localhost:3000', // defaults to http://localhost:3000 baseURL: 'http://localhost:3000', // defaults to http://localhost:3000
trpcURL: '/api/trpc', // defaults to /api/trpc endpoint: '/trpc', // defaults to /trpc
}, },
typescript: { typescript: {
strict: true // set this to true to make input/output types work strict: true // required to make input/output types work
} }
}) })
``` ```
@@ -111,7 +111,7 @@ const { data: token } = await useAsyncQuery(['auth.login', { username, password
headers.value.Authorization = `Bearer ${token}` headers.value.Authorization = `Bearer ${token}`
// All client calls will now include the Authorization header. // All client calls will now include the Authorization header.
// For SSR, please follow this until I found a solution https://github.com/trpc/trpc/discussions/1686 // For SSR, please follow this link https://github.com/trpc/trpc/discussions/1686
``` ```
## Options ## Options

View File

@@ -1,7 +1,7 @@
{ {
"name": "trpc-nuxt", "name": "trpc-nuxt",
"type": "module", "type": "module",
"version": "0.1.23", "version": "0.2.2",
"packageManager": "pnpm@7.1.1", "packageManager": "pnpm@7.1.1",
"license": "MIT", "license": "MIT",
"main": "./dist/module.cjs", "main": "./dist/module.cjs",
@@ -32,13 +32,14 @@
"prepare": "nuxi prepare playground" "prepare": "nuxi prepare playground"
}, },
"dependencies": { "dependencies": {
"@nuxt/kit": "^3.0.0-rc.3", "@nuxt/kit": "^3.0.0-rc.4",
"@trpc/client": "^9.23.3", "@trpc/client": "^9.25.2",
"@trpc/server": "^9.23.2", "@trpc/server": "^9.25.2",
"@vueuse/core": "^8.5.0", "@vueuse/core": "^8.6.0",
"@vueuse/nuxt": "^8.5.0", "@vueuse/nuxt": "^8.6.0",
"dedent": "^0.7.0",
"defu": "^6.0.0", "defu": "^6.0.0",
"h3": "^0.7.8", "h3": "^0.7.9",
"pathe": "^0.3.0", "pathe": "^0.3.0",
"ufo": "^0.8.4" "ufo": "^0.8.4"
}, },
@@ -48,14 +49,16 @@
"@nuxt/module-builder": "latest", "@nuxt/module-builder": "latest",
"bumpp": "^7.1.1", "bumpp": "^7.1.1",
"eslint": "^8.14.0", "eslint": "^8.14.0",
"nuxt": "^3.0.0-rc.3", "nuxt": "3.0.0-rc.4",
"ohash": "^0.1.0", "ohash": "^0.1.0",
"pnpm": "^7.1.1", "pnpm": "^7.1.1",
"superjson": "^1.9.1",
"trpc-nuxt": "workspace:*", "trpc-nuxt": "workspace:*",
"zod": "^3.16.0" "zod": "^3.16.0"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "@antfu" "extends": "@antfu",
"rules": {
"no-console": "warn"
}
} }
} }

View File

@@ -2,7 +2,6 @@ import * as trpc from '@trpc/server'
import type { inferAsyncReturnType } from '@trpc/server' import type { inferAsyncReturnType } from '@trpc/server'
import { z } from 'zod' import { z } from 'zod'
import type { CompatibilityEvent } from 'h3' import type { CompatibilityEvent } from 'h3'
import { useCookies } from 'h3'
const baseURL = 'https://jsonplaceholder.typicode.com' const baseURL = 'https://jsonplaceholder.typicode.com'
@@ -30,6 +29,7 @@ export const router = trpc.router<Context>()
.mutation('addTodo', { .mutation('addTodo', {
input: TodoShape, input: TodoShape,
async resolve(req) { async resolve(req) {
console.log(req.input)
return await $fetch<Todo>(`${baseURL}/todos`, { return await $fetch<Todo>(`${baseURL}/todos`, {
method: 'POST', method: 'POST',
body: req.input, body: req.input,

2078
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,14 @@
import { fileURLToPath } from 'url' import { fileURLToPath } from 'url'
import { join, resolve } from 'pathe' import { join, resolve } from 'pathe'
import { defu } from 'defu' import { defu } from 'defu'
// @ts-expect-error: No types
import dedent from 'dedent'
import { addPlugin, addServerHandler, addTemplate, defineNuxtModule } from '@nuxt/kit' import { addAutoImport, addPlugin, addServerHandler, addTemplate, defineNuxtModule } from '@nuxt/kit'
export interface ModuleOptions { export interface ModuleOptions {
baseURL: string baseURL: string
trpcURL: string endpoint: string
} }
export default defineNuxtModule<ModuleOptions>({ export default defineNuxtModule<ModuleOptions>({
@@ -16,14 +18,14 @@ export default defineNuxtModule<ModuleOptions>({
}, },
defaults: { defaults: {
baseURL: 'http://localhost:3000', baseURL: 'http://localhost:3000',
trpcURL: '/api/trpc', endpoint: '/trpc',
}, },
async setup(options, nuxt) { async setup(options, nuxt) {
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url)) const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
nuxt.options.build.transpile.push(runtimeDir, '#build/trpc-handler') nuxt.options.build.transpile.push(runtimeDir, '#build/trpc-handler')
const handlerPath = join(nuxt.options.buildDir, 'trpc-handler.ts') const handlerPath = join(nuxt.options.buildDir, 'trpc-handler.ts')
const trpcOptionsPath = join(nuxt.options.rootDir, 'server/trpc') const trpcOptionsPath = join(nuxt.options.srcDir, 'server/trpc')
// Add vueuse // Add vueuse
nuxt.options.modules.push('@vueuse/nuxt') nuxt.options.modules.push('@vueuse/nuxt')
@@ -31,19 +33,18 @@ export default defineNuxtModule<ModuleOptions>({
// Final resolved configuration // Final resolved configuration
const finalConfig = nuxt.options.runtimeConfig.public.trpc = defu(nuxt.options.runtimeConfig.public.trpc, { const finalConfig = nuxt.options.runtimeConfig.public.trpc = defu(nuxt.options.runtimeConfig.public.trpc, {
baseURL: options.baseURL, baseURL: options.baseURL,
trpcURL: options.trpcURL, endpoint: options.endpoint,
}) })
nuxt.hook('autoImports:extend', (imports) => { addAutoImport([
imports.push( { name: 'useClient', from: join(runtimeDir, 'client') },
{ name: 'useClient', from: join(runtimeDir, 'client') }, { name: 'useAsyncQuery', from: join(runtimeDir, 'client') },
{ name: 'useAsyncQuery', from: join(runtimeDir, 'client') }, { name: 'useClientHeaders', from: join(runtimeDir, 'client') },
{ name: 'useClientHeaders', from: join(runtimeDir, 'client') }, { name: 'getQueryKey', from: join(runtimeDir, 'client') },
) ])
})
addServerHandler({ addServerHandler({
route: `${finalConfig.trpcURL}/*`, route: `${finalConfig.endpoint}/*`,
handler: handlerPath, handler: handlerPath,
}) })
@@ -53,13 +54,13 @@ export default defineNuxtModule<ModuleOptions>({
filename: 'trpc-handler.ts', filename: 'trpc-handler.ts',
write: true, write: true,
getContents() { getContents() {
return ` return dedent`
import { createTRPCHandler } from 'trpc-nuxt/api' import { createTRPCHandler } from 'trpc-nuxt/api'
import * as functions from '${trpcOptionsPath}' import * as functions from '${trpcOptionsPath}'
export default createTRPCHandler({ export default createTRPCHandler({
...functions, ...functions,
trpcURL: '${finalConfig.trpcURL}' endpoint: '${finalConfig.endpoint}'
}) })
` `
}, },

View File

@@ -42,13 +42,13 @@ export function createTRPCHandler<Router extends AnyRouter>({
createContext, createContext,
responseMeta, responseMeta,
onError, onError,
trpcURL, endpoint,
}: { }: {
router: Router router: Router
createContext?: CreateContextFn<Router> createContext?: CreateContextFn<Router>
responseMeta?: ResponseMetaFn<Router> responseMeta?: ResponseMetaFn<Router>
onError?: OnErrorFn<Router> onError?: OnErrorFn<Router>
trpcURL: string endpoint: string
}) { }) {
return defineEventHandler(async (event) => { return defineEventHandler(async (event) => {
const { const {
@@ -56,17 +56,17 @@ export function createTRPCHandler<Router extends AnyRouter>({
res, res,
} = event } = event
const $url = createURL(req.url) const $url = createURL(req.url!)
const httpResponse = await resolveHTTPResponse({ const httpResponse = await resolveHTTPResponse({
router, router,
req: { req: {
method: req.method, method: req.method!,
headers: req.headers, headers: req.headers,
body: isMethod(event, 'GET') ? null : await useBody(event), body: isMethod(event, 'GET') ? null : await useBody(event),
query: $url.searchParams, query: $url.searchParams,
}, },
path: $url.pathname.substring(trpcURL.length + 1), path: $url.pathname.substring(endpoint.length + 1),
createContext: async () => createContext?.(event), createContext: async () => createContext?.(event),
responseMeta, responseMeta,
onError: (o) => { onError: (o) => {
@@ -81,8 +81,8 @@ export function createTRPCHandler<Router extends AnyRouter>({
res.statusCode = status res.statusCode = status
Object.keys(headers).forEach((key) => { headers && Object.keys(headers).forEach((key) => {
res.setHeader(key, headers[key]) res.setHeader(key, headers[key]!)
}) })
return body return body

View File

@@ -31,6 +31,16 @@ export type TError = TRPCClientErrorLike<AppRouter>
export type TQueryValues = inferProcedures<AppRouter['_def']['queries']> export type TQueryValues = inferProcedures<AppRouter['_def']['queries']>
/**
* Calculates the key used for `useAsyncData` call
* @param pathAndInput
*/
export function getQueryKey<
TPath extends keyof TQueryValues & string,
>(pathAndInput: [path: TPath, ...args: inferHandlerInput<TQueries[TPath]>]) {
return `${pathAndInput[0]}-${objectHash(pathAndInput[1] ? JSON.stringify(pathAndInput[1]) : '')}`
}
export async function useAsyncQuery< export async function useAsyncQuery<
TPath extends keyof TQueryValues & string, TPath extends keyof TQueryValues & string,
TOutput extends TQueryValues[TPath]['output'] = TQueryValues[TPath]['output'], TOutput extends TQueryValues[TPath]['output'] = TQueryValues[TPath]['output'],
@@ -41,7 +51,7 @@ export async function useAsyncQuery<
options: AsyncDataOptions<TOutput, Transform, PickKeys> = {}, options: AsyncDataOptions<TOutput, Transform, PickKeys> = {},
): Promise<AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, TError>> { ): Promise<AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, TError>> {
const { $client } = useNuxtApp() const { $client } = useNuxtApp()
const key = `${pathAndInput[0]}-${objectHash(pathAndInput[1] ? JSON.stringify(pathAndInput[1]) : '')}` const key = getQueryKey(pathAndInput)
const serverError = useState<TError | null>(`error-${key}`, () => null) const serverError = useState<TError | null>(`error-${key}`, () => null)
const { error, data, ...rest } = await useAsyncData( const { error, data, ...rest } = await useAsyncData(
key, key,

View File

@@ -11,7 +11,7 @@ export default defineNuxtPlugin((nuxtApp) => {
const headers = useRequestHeaders() const headers = useRequestHeaders()
const otherHeaders = useClientHeaders() const otherHeaders = useClientHeaders()
const client = trpc.createTRPCClient<AppRouter>({ const client = trpc.createTRPCClient<AppRouter>({
url: `${config.baseURL}${config.trpcURL}`, url: `${config.baseURL}${config.endpoint}`,
headers: () => { headers: () => {
return { return {
...unref(otherHeaders), ...unref(otherHeaders),