Small fork of @ts-rest/core
for use in the PubPub SDK.
Mainly exports a few types and allows forms to be uploaded in Node 18.
We aim to keep in sync with the main repo, only making non-breaking changes ideally.
The versioning is <main-version><incremental-digit>
.
So if @ts-rest/core
is at 3.30.5
, we'll be at 3.30.50
, 3.30.51
etc.
The main change is in libs/ts-rest/core/src/client.ts
, in the form upload section.
Basically if you submit arrays of things it now works.
client.upload({ files: [new File([''], 'test.txt')] });
and it allows you to specify a file like this:
client.upload({ files: { blob: new Blob([''], 'text/plain'), filename: 'test.txt' } });
This allows you to upload files using node
18, where File
is not defined.
git clone https://github.com/pubpub/ts-rest
pnpm i
Then make the modifications you want to make in /libs/ts-rest/core
.
When you're done, just run
pnpm publish-fork
This will publish @ts-rest/core
as a tag of this repo, saying something like
β success Package uploaded to https://github.com/pubpub/ts-rest with the name ts-rest-core-v<something>-gitpkg.
and you can then use it in your project like so:
npm i pubpub/ts-rest#ts-rest-core-v<something>-gitpkg
Original README below:
Incrementally adoptable RPC-like client and server helpers for a magical end to end typed experience πͺ
ts-rest offers a simple way to define a contract for your API, which can be both consumed and implemented by your application, giving you end to end type safety without the hassle or code generation.
- End-to-end type safety π
- RPC-like client side API β‘οΈ
- Small Bundle Size π
- No Code Generation πββοΈ
- Zod support for runtime validation π
- Full optional OpenAPI integration π
π Start reading the official Quickstart Guide π
Easily define your API contract somewhere shared
const contract = c.contract({
getPosts: {
method: 'GET',
path: '/posts',
query: z.object({
skip: z.number(),
take: z.number(),
}), // <-- Zod schema
responses: {
200: c.type<Post[]>(), // <-- OR normal TS types
},
headers: z.object({
'x-pagination-page': z.coerce.number().optional(),
}),
},
});
Fulfill the contract on your server, with a type-safe router:
const router = s.router(contract, {
getPosts: async ({ params: { id } }) => {
return {
status: 200,
body: prisma.post.findUnique({ where: { id } }),
};
},
});
Consume the api on the client with a RPC-like interface:
const result = await client.getPosts({
headers: { 'x-pagination-page': 1 },
query: { skip: 0, take: 10 },
// ^-- Fully typed!
});
Create a contract, implement it on your server then consume it in your client. Incrementally adopt, trial it with your team, then get shipping faster.
π Start reading the official Quickstart Guide π
MASSIVE Thanks to all of these wonderful people (emoji key), who have helped make ts-rest possible:
Since our first commit in 2022 we've been growing steadily. We're proud of our progress and we're excited about the future.