Compare commits

..

103 Commits

Author SHA1 Message Date
wobsoriano
4289dcbfab chore(release): v0.10.8 2023-08-20 22:30:24 -07:00
wobsoriano
dc317c2ded build: bump local deps 2023-08-20 21:57:59 -07:00
wobsoriano
3db0b31d31 refactor: use stand-alone getErrorShape 2023-08-20 21:55:25 -07:00
wobsoriano
f86ebcd6d6 docs: add handler param description 2023-08-20 21:48:39 -07:00
wobsoriano
252f6108cf refactor: use built-in getRequestURL from h3 instead of ufo 2023-08-20 21:41:57 -07:00
wobsoriano
3a395a7d4a build(deps): bump h3 to 1.8.0 2023-08-20 21:36:23 -07:00
wobsoriano
ec7e0255c2 chore(release): v0.10.7 2023-08-10 21:01:35 -07:00
Robert Soriano
1386832b4a Merge pull request #115 from Blechlawine/fix/usequery-nullable
fix: make useQuery return data nullable (#113)
2023-08-10 08:15:24 -07:00
Blechlawine
120ebc5760 fix: make useQuery return data nullable 2023-08-10 15:16:46 +02:00
Robert Soriano
adeb5a5afd Merge pull request #84 from Colonel-Sandvich/patch-1
docs: Update Server Side Calls docs
2023-08-03 13:07:20 -07:00
wobsoriano
6e47431f35 bump local deps 2023-07-20 22:16:57 -07:00
wobsoriano
7c9392b209 add examples to workspace 2023-07-12 10:47:53 -07:00
wobsoriano
117f7b791f bump local deps 2023-07-12 10:46:39 -07:00
wobsoriano
735e362958 remove prettier config 2023-07-12 10:46:20 -07:00
Robert Soriano
0738a133ca Merge pull request #108 from RyanPaulGannon/next
Example: Added a basic example with a product call
2023-07-12 10:44:56 -07:00
Robert Soriano
97ef8c90b8 Update CHANGELOG.md 2023-07-09 17:41:35 -07:00
wobsoriano
bec300b750 chore(release): v0.10.6 2023-07-09 17:38:40 -07:00
wobsoriano
7bbe767495 bump local deps 2023-07-09 17:38:07 -07:00
wobsoriano
811a634010 chore(deps): update ofetch to 1.1.1 2023-07-09 17:36:54 -07:00
wobsoriano
12d8c97f71 chore(deps): update h3 to 1.7.1 2023-07-09 17:36:23 -07:00
Ryan Gannon
3fc261d5e7 Example: Added a basic example with a product call 2023-06-13 15:00:38 +01:00
wobsoriano
ad85a78350 chore(release): v0.10.5 2023-05-27 06:13:49 -07:00
wobsoriano
892d167ff1 feat: pass input to watched sources if it's a ref 2023-05-27 06:13:45 -07:00
wobsoriano
e15ea6b5a3 chore(release): v0.10.4 2023-05-26 20:41:31 -07:00
wobsoriano
054fad952a feat: add reactive inputs 2023-05-26 20:41:22 -07:00
wobsoriano
e15a62a5b2 chore: remove engines property 2023-05-26 10:55:38 -07:00
wobsoriano
3f399f0c58 downgrade playground and docs nuxt version to 3.4.3 2023-05-26 10:54:59 -07:00
wobsoriano
247a6448cb set pnpm nuxt overrides to 3.5.0 2023-05-20 21:21:12 -07:00
wobsoriano
5301221148 reinstall docs 2023-05-20 21:20:11 -07:00
wobsoriano
7683499953 docs: update local deps 2023-05-20 20:06:48 -07:00
wobsoriano
2c28424ecd chore(release): v0.10.3 2023-05-20 11:11:11 -07:00
wobsoriano
18cd492ffd feat: export createH3ApiHandler for h3 apps 2023-05-20 11:11:07 -07:00
wobsoriano
c2ae94b4a7 chore(deps): bump h3 to 1.6.6 2023-05-20 11:09:04 -07:00
wobsoriano
94eb3c6257 replace bumpp with changelogen 2023-05-20 11:08:44 -07:00
wobsoriano
e55670169e remove unused imports in playground 2023-05-15 09:06:45 -07:00
wobsoriano
4f7fbbe108 chore: release v0.10.2 2023-05-15 09:03:34 -07:00
wobsoriano
c32fdf7893 feat: allow providing a transform output type 2023-05-15 09:00:04 -07:00
wobsoriano
10bc1d3a4d chore: release v0.10.1 2023-05-12 13:09:29 -07:00
wobsoriano
7bd62822d3 remove nuxt from peer deps 2023-05-12 13:09:24 -07:00
wobsoriano
967271089f fix docs build 2023-05-12 11:28:07 -07:00
wobsoriano
169c6aa534 chore: release v0.10.0 2023-05-12 11:26:02 -07:00
wobsoriano
2d025788ce feat(deps): add nuxt as a peer dependeny 2023-05-12 11:24:29 -07:00
wobsoriano
4af2b2ef3f feat(deps): bump @trpc/client and @trpc/server to 10.26.0 2023-05-12 11:20:45 -07:00
wobsoriano
ae0b7824f4 fix: asyncData types 2023-05-12 11:19:37 -07:00
wobsoriano
4339bf5059 fix: transform types 2023-05-12 11:07:44 -07:00
wobsoriano
252e2261e9 update pnpm nuxt overrides 2023-05-12 10:58:47 -07:00
wobsoriano
40eaf44f39 bump local deps 2023-05-12 10:42:46 -07:00
wobsoriano
ad827bb716 chore: release v0.9.0 2023-04-14 13:06:07 -07:00
wobsoriano
08125cbf0c fix types 2023-04-14 13:05:53 -07:00
wobsoriano
fb5723b071 feat(deps): bump @trpc/client and @trpc/server to 10.20.0 2023-04-14 11:13:38 -07:00
wobsoriano
8c35279cc2 bump local deps 2023-04-14 11:12:30 -07:00
Robert Soriano
61a5bcd2ee Merge pull request #88 from Colonel-Sandvich/next
Update `HTTPLinkOptions` import
2023-04-14 08:27:22 -07:00
Colonel-Sandvich
eaeab1565d Update HTTPLinkOptions import 2023-04-14 16:18:27 +01:00
Robert Soriano
e7453bfc70 Merge pull request #86 from danielroe/fix/github-module
fix: use latest `@nuxtlabs/github` module
2023-04-13 16:19:14 -07:00
Daniel Roe
54ef27d524 fix: use latest @nuxtlabs/github module 2023-04-13 23:54:49 +01:00
Colonel-Sandvich
1c638a8489 docs: Update Server Side Calls docs 2023-04-08 22:56:57 +01:00
Robert Soriano
38d83dac34 Merge pull request #83 from CRBroughton/trpc-10.19.1
chore: bump dependencies for nuxt 3.3.3 + devtools 0.3.2
2023-04-07 20:37:57 -07:00
CRBroughton
0f7e52248f chore: bump dependencies for nuxt 3.3.3 2023-04-07 21:38:55 +01:00
wobsoriano
be55641338 fix: trpc-nuxt docs 2023-04-03 16:04:08 -07:00
wobsoriano
6ba6e70b92 chore: release v0.8.0 2023-03-27 22:55:56 -07:00
wobsoriano
b710f809c7 bump local deps 2023-03-27 22:54:26 -07:00
Robert Soriano
4f647afa36 Merge pull request #80 from CRBroughton/nuxt-3.2.2-support 2023-03-27 21:25:00 -07:00
CRBroughton
1defbe5954 chore: upgrade dependencies for nuxt 3.2.2 2023-03-27 21:48:14 +01:00
Robert Soriano
fa6ba65d35 Merge pull request #76 from robinWongM/hotfix/subscribe-not-working
fix: pass all arguments to proxied trpc client method
2023-03-18 13:56:08 -07:00
Robert Soriano
d4af221e89 Merge pull request #75 from kedniko/patch-1
Update 2.recommended.md
2023-03-18 13:55:45 -07:00
Robin Wong
6595a1d306 fix: pass all arguments to proxied trpc client method 2023-03-18 03:15:49 +08:00
kedniko
b506cd5f14 Update 2.recommended.md 2023-03-10 18:31:26 +01:00
wobsoriano
7a69573fb9 chore: release v0.7.0 2023-02-20 09:18:07 -08:00
wobsoriano
8e26e781d4 fix type errors 2023-02-20 09:18:03 -08:00
wobsoriano
8efb63e70c bump tsup to 6.6.3 2023-02-20 09:09:10 -08:00
wobsoriano
4f6c07b0a1 feat(deps): require trpc >10.12.0 2023-02-20 09:08:44 -08:00
wobsoriano
aa3fe5527d feat(deps): bump ufo to 1.1.0 2023-02-20 09:07:44 -08:00
wobsoriano
6f17913eab feat(deps): bump ofetch to 1.0.1 2023-02-20 09:07:18 -08:00
wobsoriano
d6c60cb2b3 feat(deps): bump h3 to 1.5.0 2023-02-20 09:06:56 -08:00
wobsoriano
76fbd59525 chore: release v0.6.0 2023-02-04 21:01:26 -08:00
wobsoriano
57faf8749a feat(deps): bump h3 to 1.1.0 2023-02-04 21:00:25 -08:00
wobsoriano
9456342d58 remove unused deps 2023-02-04 20:59:51 -08:00
wobsoriano
f89c8e44ef feat(deps): bump @trpc/client and @trpc/server to 10.10.0 2023-02-04 20:59:39 -08:00
wobsoriano
7f156806d8 add Acknowledgements section 2023-02-01 08:49:10 -08:00
wobsoriano
bd33589d2f add funding.yml 2023-01-31 20:03:14 -08:00
Robert Soriano
16b6ed315a Merge pull request #68 from CodyBontecou/patch-1
Update 1.simple.md
2023-01-25 22:42:38 -05:00
Cody Bontecou
6e74e44233 Update 1.simple.md
Updated to use destructuring syntax.
2023-01-25 15:18:16 -10:00
Cody Bontecou
6485aa42a7 Update 1.simple.md
Walking through the setup with Nuxt v3.1.0 requires accessing `.value` within the template.
2023-01-25 13:00:50 -10:00
Robert Soriano
051d5bb325 Update 1.composables.md 2023-01-09 10:33:17 -08:00
Robert Soriano
b7d4dc7642 Update 1.composables.md 2023-01-09 10:33:07 -08:00
wobsoriano
abb351268a chore: release v0.5.0 2023-01-06 17:51:36 -08:00
wobsoriano
c1a791558e fix: link types 2023-01-06 17:32:16 -08:00
wobsoriano
14a18a783e chore: bump peerDependencies between @trpc/* packages 2023-01-06 16:53:42 -08:00
wobsoriano
209c28513d add getQueryKey doc 2022-12-27 17:12:31 -08:00
Robert Soriano
6157d51d59 Delete public directory 2022-12-26 01:21:06 -08:00
Robert Soriano
0effea5efc Update README.md 2022-12-26 01:20:42 -08:00
Robert Soriano
f6f79ddab4 Merge pull request #58 from therealokoro/next
feature-request: add logo, favicon and cover image to docs
2022-12-26 01:15:44 -08:00
Okoro Redemption
b4eea4393e docs: added logo, cover image, favicon 2022-12-23 21:01:25 +01:00
wobsoriano
ec576865c1 docs: update installation 2022-12-21 09:21:31 -08:00
wobsoriano
83aeeb7332 chore: update deps 2022-12-21 09:19:24 -08:00
wobsoriano
fd977982ec playground cleanup 2022-12-20 20:21:41 -08:00
Robert Soriano
e5178d1634 Update 1.installation.md 2022-12-19 21:49:38 -08:00
wobsoriano
6191a1f925 docs: update homepage 2022-12-19 20:43:23 -08:00
wobsoriano
c100ee171c playground: update build.transpile 2022-12-19 20:41:04 -08:00
wobsoriano
949e122be7 docs: update homepage 2022-12-19 20:40:00 -08:00
wobsoriano
410dcf8a11 docs: fix AppRouter import in simple usage 2022-12-19 20:24:54 -08:00
wobsoriano
a8138602a2 docs: update build.transpile instructions 2022-12-19 20:22:04 -08:00
wobsoriano
bb2d1ef8dd chore: update deps 2022-12-19 11:27:15 -08:00
40 changed files with 6481 additions and 3135 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
github: wobsoriano

99
CHANGELOG.md Normal file
View File

@@ -0,0 +1,99 @@
# Changelog
## v0.10.8
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.7...v0.10.8)
### 💅 Refactors
- Use built-in getRequestURL from h3 instead of ufo ([252f610](https://github.com/wobsoriano/trpc-nuxt/commit/252f610))
- Use stand-alone getErrorShape ([3db0b31](https://github.com/wobsoriano/trpc-nuxt/commit/3db0b31))
### 📖 Documentation
- Add handler param description ([f86ebcd](https://github.com/wobsoriano/trpc-nuxt/commit/f86ebcd))
### 📦 Build
- **deps:** Bump h3 to 1.8.0 ([3a395a7](https://github.com/wobsoriano/trpc-nuxt/commit/3a395a7))
- Bump local deps ([dc317c2](https://github.com/wobsoriano/trpc-nuxt/commit/dc317c2))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))
## v0.10.7
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.6...v0.10.7)
### 🩹 Fixes
- Make useQuery return data nullable ([120ebc5](https://github.com/wobsoriano/trpc-nuxt/commit/120ebc5))
### 📖 Documentation
- Update Server Side Calls docs ([1c638a8](https://github.com/wobsoriano/trpc-nuxt/commit/1c638a8))
### ❤️ Contributors
- Blechlawine <marczinser@gmx.de>
- Colonel-Sandvich
## v0.10.6
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.5...v0.10.6)
### 🏡 Chore
- **deps**:
- Bump h3 to 1.7.1 &nbsp;-&nbsp; by @wobsoriano [<samp>(12d8c)</samp>](https://github.com/wobsoriano/trpc-nuxt/commit/12d8c97f71bedb025b2e7914db13e69e5f62c8a2)
- Bump ofetch to 1.1.1 &nbsp;-&nbsp; by @wobsoriano [<samp>(811a6)</samp>](https://github.com/wobsoriano/trpc-nuxt/commit/811a6340107a2bea53f2cf488416bcec915f88b0)
## v0.10.5
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.4...v0.10.5)
### 🚀 Enhancements
- Pass input to watched sources if it's a ref ([892d167](https://github.com/wobsoriano/trpc-nuxt/commit/892d167))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))
## v0.10.4
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.3...v0.10.4)
### 🚀 Enhancements
- Add reactive inputs ([054fad9](https://github.com/wobsoriano/trpc-nuxt/commit/054fad9))
### 📖 Documentation
- Update local deps ([7683499](https://github.com/wobsoriano/trpc-nuxt/commit/7683499))
### 🏡 Chore
- Remove engines property ([e15a62a](https://github.com/wobsoriano/trpc-nuxt/commit/e15a62a))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))
## v0.10.3
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.2...v0.10.3)
### 🚀 Enhancements
- Export createH3ApiHandler for h3 apps ([18cd492](https://github.com/wobsoriano/trpc-nuxt/commit/18cd492))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))

View File

@@ -1,3 +1,9 @@
<p align="center">
<figure>
<img src="https://trpc-nuxt.vercel.app/cover.jpg" alt="trpc-nuxt cover image" />
</figure>
</p>
# tRPC-Nuxt
End-to-end typesafe APIs with [tRPC.io](https://trpc.io/) in Nuxt applications.
@@ -19,7 +25,11 @@ For version 3 of this module (tRPC v9, auto-imports, auto handlers), [go here](h
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
## Acknowledgements
Huge thanks to [Alex / KATT](https://github.com/KATT), the author of [tRPC](https://trpc.io/), for being the first sponsor of this project! 🎉
## License

View File

@@ -1,25 +1,38 @@
export default defineAppConfig({
docus: {
title: 'tRPC Nuxt',
image: 'https://og-image.vercel.app/tRPC-Nuxt',
alt: 'tRPC-Nuxt cover',
url: 'https://trpc-nuxt.vercel.app',
debug: false,
socials: {
github: 'wobsoriano/trpc-nuxt'
},
aside: {
level: 1
},
footer: {
credits: true,
icons: [
{
label: 'NuxtJS',
href: 'https://nuxtjs.org',
component: 'IconNuxt'
}
]
}
}
docus: {
title: "tRPC Nuxt",
description: "End-to-end typesafe APIs in Nuxt applications.",
image: "https://og-image.vercel.app/tRPC-Nuxt",
alt: "tRPC-Nuxt cover",
url: "https://trpc-nuxt.vercel.app",
debug: false,
socials: {
github: "wobsoriano/trpc-nuxt"
},
cover: {
src: "/cover.jpg",
alt: "tRPC-Nuxt module"
},
header: {
logo: true
},
aside: {
level: 1
},
footer: {
credits: {
icon: "IconDocus",
text: "Powered by Docus",
href: "https://docus.com"
},
iconLinks: [
{
label: "NuxtJS",
href: "https://nuxt.com",
// @ts-expect-error: IDK nuxt
component: "IconNuxtLabs"
}
]
}
}
})

99
docs/components/Logo.vue Normal file
View File

@@ -0,0 +1,99 @@
<template>
<div class="logo">
<div v-if="$colorMode.value == 'dark'">
<svg
width="40"
height="40"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 509 454.27"
>
<path
d="M363.3,307.79v.31l.28-.48Z"
fill="#fff"
stroke="#fff"
stroke-miterlimit="10"
stroke-width="9"
/>
<path
d="M16.88,307.79v.3l.27-.46ZM83.1,350.1l.15.25.14-.08Z"
fill="#fff"
stroke="#fff"
stroke-miterlimit="10"
stroke-width="9"
/>
<path
d="M433.22,259.49V139.58l-102-58.85V49.53L254.48,5.2,251.38,7,177.69,49.53V80.79L75.85,139.58V259.44L4.5,300.64v88.68l76.79,44.33,73.27-42.3,100,57.73,100-57.71,73.23,42.28,76.79-44.33V300.64ZM254.48,19.5l57.89,33.41L254,86.37C238.27,77,212.74,61.79,197.24,52.54Zm64.41,43.94v67.62l-58.22,33.61V96.81Zm-128.82-.75c13.83,8.23,44,26.24,58.22,34.69v67.29l-58.22-33.61ZM16.88,307.79l.27-.16-.27.46Zm58.22,108L16.88,382.16V313.8L75.1,348.49Zm5.7-78.29c.71.41-55.37-33-56.76-33.82L81.29,270.6,139.18,304Zm2.45,12.87-.15-.25.29.17Zm62.45,31.81-3.52,2-54.7,31.57V347.92l58.22-33.37Zm205.22-81.52v78.49l-96.39,55.65-96.45-55.69V300.64L88.23,260.32V146.73l89.46-51.65V138.2l76.79,44.33,76.79-44.33V95l89.57,51.71V260.27Zm12.66,7-.28.48v-.31Zm57.94,108.15-54.65-31.55-3.57-2.06V313.79l58.22,34.7Zm5.7-78.29-56.76-33.82,57.25-33.06L485.59,304Zm64.9,44.68L433.9,415.77V347.92l58.22-33.37Z"
fill="#fff"
stroke="#fff"
stroke-miterlimit="10"
stroke-width="9"
/>
<path
d="M83.1,350.1l.15.25.14-.08Zm0,0,.15.25.14-.08Zm0,0,.15.25.14-.08Z"
fill="#fff"
stroke="#fff"
stroke-miterlimit="10"
stroke-width="9"
/>
<path
d="M322.58,277.47l-34.44-57.86a9.2,9.2,0,0,0-3.4-3.3,9.47,9.47,0,0,0-12.67,3.3l-8.81,14.8L246,205.46c-3.46-6-12.61-6-16.07,0l-42.86,72a8.78,8.78,0,0,0,0,9,9.33,9.33,0,0,0,8,4.5h32.19c12.76,0,22.16-5.43,28.64-16,5.44-9.14,18.84-31.66,24.13-40.53l25.26,42.44H271.68L263.26,291h51.29C321.45,291.06,326.22,283.5,322.58,277.47Zm-79-10c-4.3,6.87-9.18,9.38-16.76,9.38H204.34L238,220.24l16.8,28.3Z"
fill="#fff"
stroke="#fff"
stroke-miterlimit="10"
stroke-width="9"
/>
</svg>
</div>
<div v-else>
<svg
width="40"
height="40"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 509 454.27"
>
<path
d="M363.3,307.79v.31l.28-.48Z"
stroke="#000"
stroke-miterlimit="10"
stroke-width="9"
/>
<path
d="M16.88,307.79v.3l.27-.46ZM83.1,350.1l.15.25.14-.08Z"
stroke="#000"
stroke-miterlimit="10"
stroke-width="9"
/>
<path
d="M433.22,259.49V139.58l-102-58.85V49.53L254.48,5.2,251.38,7,177.69,49.53V80.79L75.85,139.58V259.44L4.5,300.64v88.68l76.79,44.33,73.27-42.3,100,57.73,100-57.71,73.23,42.28,76.79-44.33V300.64ZM254.48,19.5l57.89,33.41L254,86.37C238.27,77,212.74,61.79,197.24,52.54Zm64.41,43.94v67.62l-58.22,33.61V96.81Zm-128.82-.75c13.83,8.23,44,26.24,58.22,34.69v67.29l-58.22-33.61ZM16.88,307.79l.27-.16-.27.46Zm58.22,108L16.88,382.16V313.8L75.1,348.49Zm5.7-78.29c.71.41-55.37-33-56.76-33.82L81.29,270.6,139.18,304Zm2.45,12.87-.15-.25.29.17Zm62.45,31.81-3.52,2-54.7,31.57V347.92l58.22-33.37Zm205.22-81.52v78.49l-96.39,55.65-96.45-55.69V300.64L88.23,260.32V146.73l89.46-51.65V138.2l76.79,44.33,76.79-44.33V95l89.57,51.71V260.27Zm12.66,7-.28.48v-.31Zm57.94,108.15-54.65-31.55-3.57-2.06V313.79l58.22,34.7Zm5.7-78.29-56.76-33.82,57.25-33.06L485.59,304Zm64.9,44.68L433.9,415.77V347.92l58.22-33.37Z"
stroke="#000"
stroke-miterlimit="10"
stroke-width="9"
/>
<path
d="M83.1,350.1l.15.25.14-.08Zm0,0,.15.25.14-.08Zm0,0,.15.25.14-.08Z"
stroke="#000"
stroke-miterlimit="10"
stroke-width="9"
/>
<path
d="M322.58,277.47l-34.44-57.86a9.2,9.2,0,0,0-3.4-3.3,9.47,9.47,0,0,0-12.67,3.3l-8.81,14.8L246,205.46c-3.46-6-12.61-6-16.07,0l-42.86,72a8.78,8.78,0,0,0,0,9,9.33,9.33,0,0,0,8,4.5h32.19c12.76,0,22.16-5.43,28.64-16,5.44-9.14,18.84-31.66,24.13-40.53l25.26,42.44H271.68L263.26,291h51.29C321.45,291.06,326.22,283.5,322.58,277.47Zm-79-10c-4.3,6.87-9.18,9.38-16.76,9.38H204.34L238,220.24l16.8,28.3Z"
stroke="#000"
stroke-miterlimit="10"
stroke-width="9"
/>
</svg>
</div>
<ProseStrong>tRPC Nuxt</ProseStrong>
</div>
</template>
<style scoped>
.logo {
display: flex;
align-items: center;
gap: 10px;
font-weight: 800;
}
</style>

View File

@@ -24,7 +24,7 @@ yarn add @trpc/server @trpc/client trpc-nuxt zod
```ts [nuxt.config.ts]
export default defineNuxtConfig({
build: {
transpile: ['trpc-nuxt/client']
transpile: ['trpc-nuxt']
}
})
```

View File

@@ -78,7 +78,7 @@ Create a strongly-typed plugin using your API's type signature.
```ts [plugins/client.ts]
import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client'
import type { AppRouter } from '~/server/trpc/routers'
import type { AppRouter } from '~/server/api/trpc/[trpc]'
export default defineNuxtPlugin(() => {
/**
@@ -107,12 +107,12 @@ export default defineNuxtPlugin(() => {
<script setup lang="ts">
const { $client } = useNuxtApp()
const hello = await $client.hello.useQuery({ text: 'client' })
const { data: hello } = await $client.hello.useQuery({ text: 'client' })
</script>
<template>
<div>
<p>{{ hello.data?.greeting }}</p>
<p>{{ hello?.greeting }}</p>
</div>
</template>
```

View File

@@ -96,7 +96,7 @@ import { inferAsyncReturnType } from '@trpc/server'
* Creates context for an incoming request
* @link https://trpc.io/docs/context
*/
export const createContext = () => {}
export const createContext = () => ({})
export type Context = inferAsyncReturnType<typeof createContext>;
```

View File

@@ -7,7 +7,7 @@ title: Composables
It is often useful to wrap functionality of your `@trpc/client` api within other functions. For this purpose, it's necessary to be able to infer input types and output types generated by your `@trpc/server` router.
::alert{type="info"}
[createTRPCNuxtClient](/get-started/client/create) adds a `useQuery` method built on top of [useAsyncData](https://nuxt.com/docs/api/composables/use-async-data/).
[createTRPCNuxtClient](/get-started/client/create) already adds a `useQuery` method built on top of [useAsyncData](https://nuxt.com/docs/api/composables/use-async-data/). You might not need this.
::
## Inference Helpers

View File

@@ -27,11 +27,11 @@ export const router = t.router({
```
```ts [server/api/greeting.ts]
import { router } from '@/server/trpc/trpc'
import { appRouter } from '@/server/trpc/routers'
export default eventHandler(async (event) => {
export default defineEventHandler(async (event) => {
const { name } = getQuery(event)
const caller = router.createCaller({})
const caller = appRouter.createCaller({})
const greeting = await caller.greeting({ name })
@@ -67,11 +67,11 @@ export const router = t.router({
```
```ts [server/api/post.ts]
import { router } from '@/server/trpc/trpc'
import { appRouter } from '@/server/trpc/routers'
export default eventHandler(async (event) => {
export default defineEventHandler(async (event) => {
const body = await getBody(event)
const caller = router.createCaller({})
const caller = appRouter.createCaller({})
const post = await caller.post.add(body.post)

View File

@@ -27,5 +27,6 @@ End-to-end typesafe APIs in Nuxt applications.
- Automatic typesafety
- Snappy DX
- Autocompletion on the client, for inputs, outputs and errors
- Leverages [useAsyncData](https://nuxt.com/docs/api/composables/use-async-data) and [$fetch](https://nuxt.com/docs/api/utils/dollarfetch)
::
::

View File

@@ -7,11 +7,9 @@
"generate": "nuxi build",
"preview": "nuxi preview"
},
"dependencies": {
"nuxt": "^3.0.0"
},
"devDependencies": {
"@nuxt-themes/docus": "^1.1.10",
"@nuxtlabs/github-module": "^1.5.4"
"@nuxt-themes/docus": "^1.14.3",
"@nuxtlabs/github-module": "^1.6.3",
"nuxt": "3.6.5"
}
}

BIN
docs/public/cover.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

23
examples/basic-example/.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
# Nuxt dev/build outputs
.output
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
.fleet
.idea
# Local env files
.env
.env.*
!.env.example

View File

@@ -0,0 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false

View File

@@ -0,0 +1,63 @@
# Nuxt 3 Minimal Starter
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install the dependencies:
```bash
# npm
npm install
# pnpm
pnpm install
# yarn
yarn install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
# npm
npm run dev
# pnpm
pnpm run dev
# yarn
yarn dev
```
## Production
Build the application for production:
```bash
# npm
npm run build
# pnpm
pnpm run build
# yarn
yarn build
```
Locally preview production build:
```bash
# npm
npm run preview
# pnpm
pnpm run preview
# yarn
yarn preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.

View File

@@ -0,0 +1,127 @@
<script setup lang="ts">
const { $client } = useNuxtApp()
const { data: product } = await $client.products.useQuery()
function formatPrice(num: number) {
return `£ ${num.toFixed(2)}`
}
</script>
<template>
<div class="product-page">
<header class="header">
<h1 class="header-title">
TRPC-Nuxt Basic Example
</h1>
</header>
<div class="card">
<div class="card-content">
<h3 class="card-title">
{{ product.title }}
</h3>
<p class="card-description">
{{ product.description }}
</p>
<p class="card-price">
{{ formatPrice(product.price) }}
</p>
<button class="card-button">
Add to Cart
</button>
</div>
</div>
</div>
</template>
<style>
body {
margin: 0;
}
.product-page {
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
}
.header {
width: 100%;
background-color: #41b883;
padding: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.header-title {
margin: 0;
font-size: 24px;
font-weight: bold;
color: #fff;
text-align: center;
font-family: 'Roboto', sans-serif;
}
.card {
width: 300px;
border: 1px solid #eaeaea;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-top: 16px;
}
.card-image {
width: 100%;
height: auto;
}
.card-content {
padding: 16px;
background-color: #f9f9f9;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.card-title {
margin: 0;
font-size: 20px;
color: #333;
font-family: 'Roboto', sans-serif;
}
.card-description {
margin: 8px 0;
font-size: 14px;
color: #666;
font-family: 'Roboto', sans-serif;
}
.card-price {
margin: 8px 0;
font-size: 18px;
font-weight: bold;
color: #333;
font-family: 'Roboto', sans-serif;
}
.card-button {
display: block;
width: 100%;
padding: 8px;
margin-top: 16px;
font-size: 16px;
font-weight: bold;
text-align: center;
color: #fff;
background-color: #41b883;
border: none;
border-radius: 4px;
cursor: pointer;
}
.card-button:hover {
background-color: #399d7d;
}
</style>

View File

@@ -0,0 +1,7 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
build: {
transpile: ['trpc-nuxt'],
},
})

View File

@@ -0,0 +1,22 @@
{
"name": "nuxt-app",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"devDependencies": {
"@nuxt/devtools": "latest",
"@types/node": "^20.4.2",
"nuxt": "^3.6.5"
},
"dependencies": {
"@trpc/client": "^10.35.0",
"@trpc/server": "^10.35.0",
"trpc-nuxt": "workspace:*",
"zod": "^3.21.4"
}
}

View File

@@ -0,0 +1,22 @@
import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client'
import type { AppRouter } from '~/server/trpc/routers'
export default defineNuxtPlugin(() => {
/**
* createTRPCNuxtClient adds a `useQuery` composable
* built on top of `useAsyncData`.
*/
const client = createTRPCNuxtClient<AppRouter>({
links: [
httpBatchLink({
url: '/api/trpc',
}),
],
})
return {
provide: {
client,
},
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,9 @@
import { createNuxtApiHandler } from 'trpc-nuxt'
import { appRouter } from '../../trpc/routers'
import { createContext } from '../../trpc/context'
// export API handler
export default createNuxtApiHandler({
router: appRouter,
createContext,
})

View File

@@ -0,0 +1,9 @@
import { inferAsyncReturnType } from '@trpc/server'
/**
* Creates context for an incoming request
* @link https://trpc.io/docs/context
*/
export const createContext = () => ({})
export type Context = inferAsyncReturnType<typeof createContext>

View File

@@ -0,0 +1,27 @@
import { z } from 'zod'
import { publicProcedure, router } from '../trpc'
export const appRouter = router({
hello: publicProcedure
.input(
z.object({
text: z.string().nullish(),
})
)
.query(({ input }) => {
console.log(input)
return {
greeting: `hello ${input?.text ?? 'world'}`,
}
}),
products: publicProcedure.query(async () => {
return {
title: 'TRPC Nuxt',
price: 12.0,
description: 'Check out the trpc-nuxt repo',
}
}),
})
// export type definition of API
export type AppRouter = typeof appRouter

View File

@@ -0,0 +1,20 @@
/**
* This is your entry point to setup the root configuration for tRPC on the server.
* - `initTRPC` should only be used once per app.
* - We export only the functionality that we use so we can enforce which base procedures should be used
*
* Learn how to create protected base procedures and other things below:
* @see https://trpc.io/docs/v10/router
* @see https://trpc.io/docs/v10/procedures
*/
import { initTRPC } from '@trpc/server'
import { Context } from '../trpc/context'
const t = initTRPC.context<Context>().create()
/**
* Unprotected procedure
**/
export const publicProcedure = t.procedure
export const router = t.router
export const middleware = t.middleware

View File

@@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}

View File

@@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}

View File

@@ -2,8 +2,8 @@
"name": "trpc-nuxt",
"description": "End-to-end typesafe APIs in Nuxt applications.",
"type": "module",
"packageManager": "pnpm@7.18.2",
"version": "0.4.4",
"packageManager": "pnpm@8.6.9",
"version": "0.10.8",
"license": "MIT",
"sideEffects": false,
"exports": {
@@ -25,33 +25,33 @@
"client.d.ts"
],
"scripts": {
"dev": "concurrently \"pnpm build -- --watch\" \"pnpm --filter playground dev\"",
"dev": "tsup --watch --onSuccess \"pnpm --filter playground dev\"",
"dev:prepare": "pnpm build && nuxt prepare playground",
"prepublishOnly": "pnpm build",
"build": "tsup",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"release": "bumpp && npm publish"
"release": "changelogen --release && npm publish && git push --follow-tags",
"update-deps": "taze -w && pnpm i"
},
"peerDependencies": {
"@trpc/client": "^10.0.0",
"@trpc/server": "^10.0.0"
"@trpc/client": "^10.26.0",
"@trpc/server": "^10.26.0"
},
"dependencies": {
"h3": "^1.0.2",
"ofetch": "^1.0.0",
"ohash": "^1.0.0",
"ufo": "^1.0.0"
"h3": "^1.8.0",
"ofetch": "^1.1.1",
"ohash": "^1.1.2"
},
"devDependencies": {
"@nuxt/eslint-config": "^0.1.1",
"@trpc/client": "^10.5.0",
"@trpc/server": "^10.5.0",
"bumpp": "^8.2.1",
"concurrently": "^7.5.0",
"eslint": "^8.25.0",
"tsup": "6.4.0",
"typescript": "^4.7.4"
"@trpc/client": "^10.37.1",
"@trpc/server": "^10.37.1",
"changelogen": "^0.5.4",
"eslint": "^8.45.0",
"taze": "^0.11.2",
"tsup": "7.2.0",
"typescript": "^5.1.6"
},
"eslintConfig": {
"extends": [
@@ -74,10 +74,9 @@
],
"pnpm": {
"overrides": {
"nuxt": "3.0.0"
"nuxt": "3.6.5",
"@trpc/client": "10.37.1",
"@trpc/server": "10.37.1"
}
},
"engines": {
"node": "^16.13.0 || ^18.12.0"
}
}
}

View File

@@ -1,6 +1,6 @@
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
build: {
transpile: ['trpc-nuxt/client']
transpile: ['trpc-nuxt']
}
})

View File

@@ -9,13 +9,14 @@
"postinstall": "nuxt prepare"
},
"dependencies": {
"@trpc/client": "^10.5.0",
"@trpc/server": "^10.5.0",
"superjson": "^1.11.0",
"@trpc/client": "^10.37.1",
"@trpc/server": "^10.37.1",
"superjson": "^1.13.1",
"trpc-nuxt": "workspace:*",
"zod": "^3.19.1"
"zod": "^3.21.4"
},
"devDependencies": {
"nuxt": "^3.0.0"
"@types/node": "^20.4.2",
"nuxt": "3.6.5"
}
}

View File

@@ -0,0 +1,27 @@
<script setup lang="ts">
const route = useRoute()
const { $client } = useNuxtApp()
const id = ref(1)
// const { data: todo, pending, error } = await useAsyncData(() => $client.todo.getTodo.query(id.value), {
// watch: [id]
// })
const { data: todo, pending, error, refresh } = await $client.todo.getTodo.useQuery(id)
</script>
<template>
<div v-if="pending">
Loading...
</div>
<div v-else-if="error?.data?.code">
Error: {{ error.data.code }}
</div>
<div v-else>
ID: {{ todo?.id }} <br>
Title: {{ todo?.title }} <br>
Completed: {{ todo?.completed }}
</div>
<button @click="id++">
Next Todo
</button>
</template>

View File

@@ -8,8 +8,8 @@ const { data: todo, pending, error } = await useAsyncData(() => $client.todo.get
<div v-if="pending">
Loading...
</div>
<div v-else-if="error?.data?.code">
{{ error.data.code }}
<div v-else-if="error">
{{ error.message }} - {{ error.cause }}
</div>
<div v-else>
ID: {{ todo?.id }} <br>

View File

@@ -12,7 +12,7 @@ export function createContext (
event: H3Event
) {
// for API-response caching see https://trpc.io/docs/caching
console.log('cookies', parseCookies(event))
// console.log('cookies', parseCookies(event))
return {}
}

8790
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,4 @@
packages:
- playground
- examples/*
- docs

View File

@@ -4,10 +4,20 @@ import { createFlatProxy, createRecursiveProxy } from '@trpc/server/shared'
import { hash } from 'ohash'
import { type DecoratedProcedureRecord } from './types'
// @ts-expect-error: Nuxt auto-imports
import { getCurrentInstance, onScopeDispose, useAsyncData } from '#imports'
import { getCurrentInstance, onScopeDispose, useAsyncData, unref, isRef } from '#imports'
/**
* Calculates the key used for `useAsyncData` call
* Calculates the key used for `useAsyncData` call.
*
* @example
*
* ```ts
* import { getQueryKey } from 'trpc-nuxt/client'
*
* $client.todo.getTodo(1)
*
* const queryKey = getQueryKey('todo.getTodo', 1)
* ```
*/
export function getQueryKey (
path: string,
@@ -44,14 +54,17 @@ export function createNuxtProxyDecoration<TRouter extends AnyRouter> (name: stri
controller = typeof AbortController !== 'undefined' ? new AbortController() : {} as AbortController
}
const queryKey = getQueryKey(path, input)
return useAsyncData(queryKey, () => (client as any)[path].query(input, {
const queryKey = getQueryKey(path, unref(input))
return useAsyncData(queryKey, () => (client as any)[path].query(unref(input), {
signal: controller?.signal,
...trpc
}), asyncDataOptions)
}), {
...asyncDataOptions,
watch: isRef(input) ? [...(asyncDataOptions.watch || []), input] : asyncDataOptions.watch
})
}
return (client as any)[path][lastArg](input)
return (client as any)[path][lastArg](...args)
})
}
@@ -59,7 +72,7 @@ export function createTRPCNuxtClient<TRouter extends AnyRouter> (opts: CreateTRP
const client = createTRPCProxyClient<TRouter>(opts)
const decoratedClient = createFlatProxy((key) => {
return createNuxtProxyDecoration(key, client)
return createNuxtProxyDecoration(key, client as any)
}) as DecoratedProcedureRecord<TRouter['_def']['record'], TRouter>
return decoratedClient

View File

@@ -3,9 +3,10 @@ import { type AnyRouter } from '@trpc/server'
import { FetchError } from 'ofetch'
// @ts-expect-error: Nuxt auto-imports
import { useRequestHeaders } from '#imports'
import { type HTTPLinkOptions as _HTTPLinkOptions } from '@trpc/client/dist/links/internals/httpUtils'
import { type HTTPLinkOptions as _HTTPLinkOptions } from '@trpc/client/dist/links/httpLink'
import { type FetchEsque } from '@trpc/client/dist/internals/types'
function customFetch(input: RequestInfo | URL, init?: RequestInit) {
function customFetch(input: RequestInfo | URL, init?: RequestInit & { method: 'GET' }) {
return globalThis.$fetch.raw(input.toString(), init)
.catch((e) => {
if (e instanceof FetchError && e.response) { return e.response }
@@ -43,7 +44,7 @@ export function httpLink<TRouter extends AnyRouter>(opts?: HTTPLinkOptions) {
headers () {
return headers
},
fetch: customFetch,
fetch: customFetch as FetchEsque,
...opts,
})
}
@@ -69,10 +70,11 @@ export function httpBatchLink<TRouter extends AnyRouter>(opts?: HttpBatchLinkOpt
return _httpBatchLink<TRouter>({
url: '/api/trpc',
// @ts-expect-error: Missing property from batchLink. Fix this later.
headers () {
return headers
},
fetch: customFetch,
fetch: customFetch as FetchEsque,
...opts,
})
}

View File

@@ -1,5 +1,5 @@
import type { TRPCClientErrorLike, TRPCRequestOptions as _TRPCRequestOptions } from '@trpc/client'
import { type TRPCSubscriptionObserver } from '@trpc/client/dist/internals/TRPCClient'
import { type TRPCSubscriptionObserver } from '@trpc/client/dist/internals/TRPCUntypedClient'
import type {
AnyMutationProcedure,
AnyProcedure,
@@ -16,10 +16,10 @@ import { inferTransformedProcedureOutput } from '@trpc/server/shared'
import type {
AsyncData,
AsyncDataOptions,
KeyOfRes,
KeysOf,
PickFrom,
_Transform
} from 'nuxt/dist/app/composables/asyncData'
import type { Ref } from 'vue'
interface TRPCRequestOptions extends _TRPCRequestOptions {
abortOnUnmount?: boolean
@@ -45,19 +45,22 @@ type SubscriptionResolver<
]
) => Unsubscribable
type MaybeRef<T> = T | Ref<T>
type DecorateProcedure<
TProcedure extends AnyProcedure,
TRouter extends AnyRouter,
> = TProcedure extends AnyQueryProcedure
? {
useQuery: <
TData = inferTransformedProcedureOutput<TProcedure>,
Transform extends _Transform<TData> = _Transform<TData, TData>,
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>,
ResT = inferTransformedProcedureOutput<TProcedure>,
DataE = TRPCClientErrorLike<TProcedure>,
DataT = ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
>(
input: inferProcedureInput<TProcedure>,
opts?: AsyncDataOptions<TData, Transform, PickKeys> & { trpc?: TRPCRequestOptions },
) => AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, TRPCClientErrorLike<TProcedure>>,
input: MaybeRef<inferProcedureInput<TProcedure>>,
opts?: AsyncDataOptions<ResT, DataT, PickKeys> & { trpc?: TRPCRequestOptions },
) => AsyncData<PickFrom<DataT, PickKeys> | null, DataE>,
query: Resolver<TProcedure>
} : TProcedure extends AnyMutationProcedure ? {
mutate: Resolver<TProcedure>

View File

@@ -9,10 +9,10 @@ import type {
import {
TRPCError
} from '@trpc/server'
import { createURL } from 'ufo'
import type { H3Event } from 'h3'
import { createError, defineEventHandler, isMethod, readBody } from 'h3'
import { createError, defineEventHandler, getRequestURL, isMethod, readBody } from 'h3'
import type { TRPCResponse } from '@trpc/server/rpc'
import { getErrorShape } from '@trpc/server/shared'
type MaybePromise<T> = T | Promise<T>
@@ -40,9 +40,25 @@ export interface OnErrorPayload<TRouter extends AnyRouter> {
export type OnErrorFn<TRouter extends AnyRouter> = (opts: OnErrorPayload<TRouter>) => void
export interface ResolveHTTPRequestOptions<TRouter extends AnyRouter> {
/**
* The tRPC router to use.
* @see https://trpc.io/docs/router
*/
router: TRouter
/**
* An async function that returns the tRPC context.
* @see https://trpc.io/docs/context
*/
createContext?: CreateContextFn<TRouter>
/**
* A function that returns the response meta.
* @see https://trpc.io/docs/caching#using-responsemeta-to-cache-responses
*/
responseMeta?: ResponseMetaFn<TRouter>
/**
* A function that is called when an error occurs.
* @see https://trpc.io/docs/error-handling#handling-errors
*/
onError?: OnErrorFn<TRouter>
batching?: {
enabled: boolean
@@ -50,9 +66,13 @@ export interface ResolveHTTPRequestOptions<TRouter extends AnyRouter> {
}
function getPath (event: H3Event): string | null {
if (typeof event.context.params.trpc === 'string') { return event.context.params.trpc }
const { params } = event.context
if (Array.isArray(event.context.params.trpc)) { return event.context.params.trpc.join('/') }
if (typeof params?.trpc === 'string') { return params.trpc }
if (params?.trpc && Array.isArray(params.trpc)) {
return (params.trpc as string[]).join('/')
}
return null
}
@@ -70,15 +90,16 @@ export function createNuxtApiHandler<TRouter extends AnyRouter> ({
res
} = event.node
const $url = createURL(req.url!)
const $url = getRequestURL(event)
const path = getPath(event)
if (path === null) {
const error = router.getErrorShape({
const error = getErrorShape({
config: router._def._config,
error: new TRPCError({
message:
'Param "trpc" not found - is the file named `[trpc]`.ts or `[...trpc].ts`?',
'Query "trpc" not found - is the file named `[trpc]`.ts or `[...trpc].ts`?',
code: 'INTERNAL_SERVER_ERROR'
}),
type: 'unknown',
@@ -124,3 +145,5 @@ export function createNuxtApiHandler<TRouter extends AnyRouter> ({
return body
})
}
export const createH3ApiHandler = createNuxtApiHandler