├── playgrounds ├── nuxt │ ├── public │ │ ├── robots.txt │ │ └── favicon.ico │ ├── server │ │ ├── routes │ │ │ ├── api │ │ │ │ └── index.ts │ │ │ └── rpc │ │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ ├── schemas │ │ │ └── auth.ts │ │ ├── routers │ │ │ ├── index.ts │ │ │ └── sse.ts │ │ ├── playground-client.ts │ │ └── orpc.ts │ ├── .vscode │ │ └── settings.json │ ├── tsconfig.json │ ├── nuxt.config.ts │ ├── app │ │ ├── app.vue │ │ └── components │ │ │ └── orpc-stream.vue │ ├── .gitignore │ └── README.md ├── svelte-kit │ ├── .npmrc │ ├── src │ │ ├── hooks.server.ts │ │ ├── lib │ │ │ └── index.ts │ │ ├── schemas │ │ │ └── auth.ts │ │ ├── app.d.ts │ │ ├── app.html │ │ ├── routers │ │ │ ├── index.ts │ │ │ └── sse.ts │ │ ├── routes │ │ │ └── orpc-stream.svelte │ │ ├── playground-client.ts │ │ └── orpc.ts │ ├── .vscode │ │ └── settings.json │ ├── static │ │ └── favicon.png │ ├── .gitignore │ ├── vite.config.ts │ └── README.md ├── astro │ ├── .vscode │ │ └── settings.json │ ├── src │ │ ├── shared │ │ │ └── query.ts │ │ ├── schemas │ │ │ └── auth.ts │ │ ├── orpc.ts │ │ ├── routers │ │ │ ├── index.ts │ │ │ └── sse.ts │ │ ├── middlewares │ │ │ └── auth.ts │ │ ├── components │ │ │ └── orpc-stream.tsx │ │ ├── pages │ │ │ └── index.astro │ │ └── playground-client.ts │ ├── astro.config.mjs │ ├── tsconfig.json │ ├── .gitignore │ └── README.md ├── electron │ ├── .vscode │ │ └── settings.json │ ├── .gitignore │ ├── src │ │ ├── preload │ │ │ └── index.d.ts │ │ ├── main │ │ │ ├── schemas │ │ │ │ └── auth.ts │ │ │ ├── orpc.ts │ │ │ └── routers │ │ │ │ ├── index.ts │ │ │ │ └── sse.ts │ │ └── renderer │ │ │ ├── src │ │ │ ├── main.tsx │ │ │ ├── components │ │ │ │ └── orpc-stream.tsx │ │ │ ├── App.tsx │ │ │ └── playground-client.ts │ │ │ └── index.html │ ├── README.md │ ├── tsconfig.node.json │ └── electron.vite.config.ts ├── nest │ ├── .vscode │ │ └── settings.json │ ├── tsconfig.build.json │ ├── src │ │ ├── schemas │ │ │ └── auth.ts │ │ ├── main.ts │ │ ├── contract │ │ │ ├── sse.ts │ │ │ └── index.ts │ │ ├── playground-client.ts │ │ └── other │ │ │ └── other.controller.ts │ ├── nest-cli.json │ ├── build.config.ts │ └── README.md ├── next │ ├── .vscode │ │ └── settings.json │ ├── src │ │ ├── app │ │ │ ├── favicon.ico │ │ │ ├── loading.tsx │ │ │ ├── error.tsx │ │ │ ├── providers.tsx │ │ │ ├── orpc-stream.tsx │ │ │ └── layout.tsx │ │ ├── instrumentation.ts │ │ ├── schemas │ │ │ └── auth.ts │ │ ├── orpc.ts │ │ ├── routers │ │ │ ├── index.ts │ │ │ └── sse.ts │ │ └── playground-client.ts │ ├── public │ │ ├── vercel.svg │ │ ├── file.svg │ │ └── window.svg │ ├── next.config.ts │ └── README.md ├── solid-start │ ├── src │ │ ├── global.d.ts │ │ ├── entry-client.tsx │ │ ├── schemas │ │ │ └── auth.ts │ │ ├── routes │ │ │ ├── api │ │ │ │ └── index.ts │ │ │ ├── rpc │ │ │ │ └── index.ts │ │ │ ├── orpc-stream.tsx │ │ │ └── index.tsx │ │ ├── routers │ │ │ ├── index.ts │ │ │ └── sse.ts │ │ ├── playground-client.ts │ │ ├── orpc.ts │ │ └── entry-server.tsx │ ├── .vscode │ │ └── settings.json │ ├── public │ │ └── favicon.ico │ ├── app.config.ts │ ├── .gitignore │ ├── tsconfig.json │ └── README.md ├── cloudflare-worker │ ├── src │ │ ├── vite-env.d.ts │ │ ├── main.tsx │ │ └── components │ │ │ └── orpc-stream.tsx │ ├── .vscode │ │ └── settings.json │ ├── worker │ │ ├── schemas │ │ │ └── auth.ts │ │ ├── dos │ │ │ └── publisher.ts │ │ ├── routers │ │ │ ├── message-v2.ts │ │ │ └── sse.ts │ │ └── orpc.ts │ ├── vite.config.ts │ ├── index.html │ ├── .gitignore │ ├── tsconfig.json │ └── README.md ├── browser-extension │ ├── .vscode │ │ └── settings.json │ ├── public │ │ └── icon │ │ │ ├── 16.png │ │ │ ├── 32.png │ │ │ ├── 48.png │ │ │ ├── 96.png │ │ │ └── 128.png │ ├── entrypoints │ │ ├── content.ts │ │ ├── background │ │ │ ├── schemas │ │ │ │ └── auth.ts │ │ │ ├── orpc.ts │ │ │ ├── index.ts │ │ │ └── routers │ │ │ │ ├── index.ts │ │ │ │ └── sse.ts │ │ └── popup │ │ │ ├── index.html │ │ │ ├── main.tsx │ │ │ ├── components │ │ │ └── orpc-stream.tsx │ │ │ ├── App.tsx │ │ │ ├── lib │ │ │ └── orpc.ts │ │ │ └── playground-client.ts │ ├── tsconfig.json │ ├── wxt.config.ts │ ├── .gitignore │ └── README.md ├── contract-first │ ├── .vscode │ │ └── settings.json │ ├── .gitignore │ └── src │ │ ├── schemas │ │ └── auth.ts │ │ ├── contract │ │ ├── sse.ts │ │ └── index.ts │ │ ├── routers │ │ ├── sse.ts │ │ ├── index.ts │ │ └── auth.ts │ │ ├── playground-client.ts │ │ └── lib │ │ └── orpc.ts ├── tanstack-start │ ├── .vscode │ │ └── settings.json │ ├── src │ │ ├── schemas │ │ │ └── auth.ts │ │ ├── orpc.ts │ │ ├── routers │ │ │ ├── index.ts │ │ │ └── sse.ts │ │ ├── components │ │ │ └── orpc-stream.tsx │ │ └── playground-client.ts │ ├── .gitignore │ ├── vite.config.ts │ ├── tsconfig.json │ └── README.md └── bun-websocket-otel │ ├── src │ ├── consts.ts │ ├── schemas │ │ └── auth.ts │ ├── orpc.ts │ ├── routers │ │ ├── sse.ts │ │ └── index.ts │ ├── index.html │ ├── playground-client.ts │ └── lib │ │ └── orpc.ts │ ├── bun-env.d.ts │ └── .gitignore ├── apps └── content │ ├── .vitepress │ └── .gitignore │ ├── public │ ├── og.jpg │ ├── logo.webp │ ├── robots.txt │ ├── code-dark.png │ ├── code-light.png │ ├── images │ │ └── opentelemetry-integration-preview.png │ ├── icon.svg │ └── _redirects │ ├── tsconfig.json │ └── .gitignore ├── vitest.jsdom.ts ├── packages ├── arktype │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── .gitignore ├── publisher │ ├── src │ │ ├── index.ts │ │ └── index.test.ts │ ├── tsconfig.json │ └── .gitignore ├── trpc │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── .gitignore ├── valibot │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── .gitignore ├── hey-api │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── .gitignore ├── openapi-client │ ├── src │ │ ├── index.ts │ │ ├── adapters │ │ │ ├── fetch │ │ │ │ └── index.ts │ │ │ └── standard │ │ │ │ ├── index.ts │ │ │ │ └── utils.ts │ │ └── helpers │ │ │ ├── index.ts │ │ │ └── index.test.ts │ ├── .gitignore │ └── tsconfig.json ├── otel │ ├── src │ │ ├── index.ts │ │ └── consts.ts │ ├── build.config.ts │ ├── tsconfig.json │ └── .gitignore ├── openapi │ ├── src │ │ ├── plugins │ │ │ └── index.ts │ │ ├── adapters │ │ │ ├── fetch │ │ │ │ ├── index.ts │ │ │ │ └── openapi-handler.test.ts │ │ │ ├── node │ │ │ │ └── index.ts │ │ │ ├── aws-lambda │ │ │ │ └── index.ts │ │ │ ├── fastify │ │ │ │ ├── index.ts │ │ │ │ └── index.test.ts │ │ │ └── standard │ │ │ │ ├── index.ts │ │ │ │ └── utils.test.ts │ │ └── index.ts │ ├── .gitignore │ └── tsconfig.json ├── server │ ├── src │ │ ├── adapters │ │ │ ├── standard-peer │ │ │ │ └── index.ts │ │ │ ├── bun-ws │ │ │ │ └── index.ts │ │ │ ├── ws │ │ │ │ └── index.ts │ │ │ ├── aws-lambda │ │ │ │ └── index.ts │ │ │ ├── crossws │ │ │ │ └── index.ts │ │ │ ├── fastify │ │ │ │ ├── index.ts │ │ │ │ └── index.test.ts │ │ │ ├── websocket │ │ │ │ └── index.ts │ │ │ ├── message-port │ │ │ │ └── index.ts │ │ │ ├── fetch │ │ │ │ ├── index.ts │ │ │ │ └── plugin.test-d.ts │ │ │ ├── node │ │ │ │ ├── index.ts │ │ │ │ └── plugin.test-d.ts │ │ │ └── standard │ │ │ │ ├── index.ts │ │ │ │ ├── utils.test.ts │ │ │ │ ├── utils.ts │ │ │ │ └── utils.test-d.ts │ │ ├── helpers │ │ │ └── index.ts │ │ ├── hibernation │ │ │ └── index.ts │ │ ├── config.test.ts │ │ ├── plugins │ │ │ └── index.ts │ │ ├── context.test.ts │ │ ├── link-utils.test-d.ts │ │ ├── router-hidden.test.ts │ │ ├── config.ts │ │ ├── context.ts │ │ ├── procedure.test.ts │ │ └── lazy.test.ts │ ├── .gitignore │ ├── tests │ │ └── advanced.test.ts │ └── tsconfig.json ├── pino │ ├── src │ │ ├── index.ts │ │ ├── index.test.ts │ │ ├── context.test.ts │ │ └── context.ts │ ├── tsconfig.json │ └── .gitignore ├── durable-iterator │ ├── src │ │ ├── error.ts │ │ ├── client │ │ │ ├── index.ts │ │ │ └── index.test.ts │ │ ├── index.test.ts │ │ ├── index.ts │ │ ├── durable-object │ │ │ ├── index.ts │ │ │ └── index.test.ts │ │ ├── consts.ts │ │ └── object.ts │ ├── build.config.ts │ ├── .gitignore │ ├── tsconfig.test.json │ └── tsconfig.json ├── client │ ├── src │ │ ├── adapters │ │ │ ├── websocket │ │ │ │ └── index.ts │ │ │ ├── fetch │ │ │ │ ├── index.ts │ │ │ │ └── plugin.test-d.ts │ │ │ ├── message-port │ │ │ │ └── index.ts │ │ │ └── standard │ │ │ │ └── index.ts │ │ ├── consts.ts │ │ ├── plugins │ │ │ └── index.ts │ │ └── error.test-d.ts │ ├── build.config.ts │ ├── .gitignore │ └── tsconfig.json ├── react │ ├── src │ │ ├── hooks │ │ │ └── index.ts │ │ └── index.ts │ ├── .gitignore │ └── tsconfig.json ├── contract │ ├── src │ │ ├── plugins │ │ │ ├── index.ts │ │ │ └── index.test.ts │ │ ├── types.ts │ │ ├── meta.ts │ │ ├── meta.test.ts │ │ ├── config.test.ts │ │ ├── link-utils.test-d.ts │ │ ├── procedure-client.ts │ │ ├── schema.test.ts │ │ ├── schema-utils.ts │ │ └── router-client.test-d.ts │ ├── tsconfig.json │ └── .gitignore ├── zod │ ├── src │ │ ├── zod4 │ │ │ ├── index.ts │ │ │ ├── coercer.rest.test.ts │ │ │ └── converter.rest.test.ts │ │ ├── schemas │ │ │ ├── url.test.ts │ │ │ ├── regexp.test.ts │ │ │ ├── blob.test.ts │ │ │ ├── url.ts │ │ │ ├── blob.ts │ │ │ └── regexp.ts │ │ └── index.ts │ ├── .gitignore │ └── tsconfig.json ├── ratelimit │ ├── src │ │ ├── index.ts │ │ ├── index.test.ts │ │ ├── adapters │ │ │ ├── cloudflare-ratelimit.ts │ │ │ └── cloudflare-ratelimit.test.ts │ │ └── types.ts │ ├── .gitignore │ └── tsconfig.json ├── standard-server │ ├── src │ │ ├── batch │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── event-iterator │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── errors.ts │ │ └── hibernation.test.ts │ ├── tsconfig.json │ └── .gitignore ├── json-schema │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── .gitignore │ └── tsconfig.json ├── standard-server-node │ ├── src │ │ ├── method.ts │ │ ├── method.test.ts │ │ ├── index.ts │ │ ├── signal.ts │ │ ├── headers.ts │ │ ├── headers.test.ts │ │ ├── url.ts │ │ └── types.ts │ ├── tsconfig.json │ └── .gitignore ├── ai-sdk │ ├── src │ │ ├── index.test.ts │ │ └── index.ts │ ├── tsconfig.json │ └── .gitignore ├── interop │ ├── src │ │ └── compression │ │ │ ├── index.ts │ │ │ └── index.test.ts │ ├── build.config.ts │ ├── tsconfig.json │ └── .gitignore ├── react-swr │ ├── src │ │ ├── index.test.ts │ │ ├── index.ts │ │ └── utils.ts │ ├── tests │ │ └── shared.tsx │ ├── tsconfig.json │ └── .gitignore ├── tanstack-query │ ├── src │ │ ├── index.test.ts │ │ ├── index.ts │ │ └── key.ts │ ├── tsconfig.json │ ├── .gitignore │ └── tests │ │ └── shared.tsx ├── standard-server-fastify │ ├── src │ │ ├── index.ts │ │ └── index.test.ts │ ├── .gitignore │ └── tsconfig.json ├── publisher-durable-object │ ├── src │ │ ├── index.ts │ │ ├── types.ts │ │ └── index.test.ts │ ├── build.config.ts │ ├── .gitignore │ ├── tsconfig.test.json │ └── tsconfig.json ├── standard-server-peer │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── .gitignore ├── standard-server-fetch │ ├── src │ │ └── index.ts │ ├── playground │ │ ├── event-source.http │ │ └── event-source-client.ts │ ├── tsconfig.json │ └── .gitignore ├── shared │ ├── src │ │ ├── consts.ts │ │ ├── uri.ts │ │ ├── chain.ts │ │ ├── args.test.ts │ │ ├── args.ts │ │ ├── error.test.ts │ │ ├── json.test-d.ts │ │ ├── error.ts │ │ ├── array.ts │ │ ├── json.ts │ │ ├── uri.test.ts │ │ ├── buffer.ts │ │ ├── id.ts │ │ ├── value.test.ts │ │ ├── value.ts │ │ ├── buffer.test.ts │ │ ├── array.test.ts │ │ └── args.test-d.ts │ ├── tsconfig.json │ ├── build.config.ts │ └── .gitignore ├── standard-server-aws-lambda │ ├── src │ │ ├── url.ts │ │ ├── types.test-d.ts │ │ ├── url.test.ts │ │ └── index.ts │ ├── .gitignore │ └── tsconfig.json ├── nest │ ├── build.config.ts │ ├── tsconfig.test.json │ └── .gitignore ├── vue-colada │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ ├── .gitignore │ └── tests │ │ └── shared.tsx ├── svelte-query │ ├── tsconfig.json │ ├── .gitignore │ ├── src │ │ └── index.ts │ └── tests │ │ └── shared.tsx ├── vue-query │ ├── tsconfig.json │ ├── .gitignore │ ├── tests │ │ └── shared.tsx │ └── src │ │ └── index.ts ├── react-query │ ├── tsconfig.json │ ├── .gitignore │ ├── src │ │ └── index.ts │ └── tests │ │ └── shared.tsx └── solid-query │ ├── tsconfig.json │ ├── .gitignore │ ├── src │ └── index.ts │ └── tests │ └── shared.tsx ├── knip.json ├── vitest.javascript.ts ├── .npmrc ├── .env.example ├── pnpm-workspace.yaml ├── tsconfig.lib.json ├── .github └── ISSUE_TEMPLATE │ └── config.yml ├── .gitignore └── SECURITY.md /playgrounds/nuxt/public/robots.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/content/.vitepress/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | cache 3 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /vitest.jsdom.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/dom' 2 | -------------------------------------------------------------------------------- /packages/arktype/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './converter' 2 | -------------------------------------------------------------------------------- /packages/publisher/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './publisher' 2 | -------------------------------------------------------------------------------- /packages/trpc/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './to-orpc-router' 2 | -------------------------------------------------------------------------------- /packages/valibot/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './converter' 2 | -------------------------------------------------------------------------------- /packages/hey-api/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './to-orpc-client' 2 | -------------------------------------------------------------------------------- /packages/openapi-client/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | -------------------------------------------------------------------------------- /packages/otel/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './instrumentation' 2 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/hooks.server.ts: -------------------------------------------------------------------------------- 1 | import './lib/orpc.server' 2 | -------------------------------------------------------------------------------- /packages/openapi/src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openapi-reference' 2 | -------------------------------------------------------------------------------- /packages/openapi/src/adapters/fetch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openapi-handler' 2 | -------------------------------------------------------------------------------- /packages/openapi/src/adapters/node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openapi-handler' 2 | -------------------------------------------------------------------------------- /packages/server/src/adapters/standard-peer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utils' 2 | -------------------------------------------------------------------------------- /playgrounds/nuxt/server/routes/api/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './[...]' 2 | -------------------------------------------------------------------------------- /playgrounds/nuxt/server/routes/rpc/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './[...]' 2 | -------------------------------------------------------------------------------- /packages/openapi-client/src/adapters/fetch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openapi-link' 2 | -------------------------------------------------------------------------------- /packages/openapi/src/adapters/aws-lambda/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openapi-handler' 2 | -------------------------------------------------------------------------------- /packages/openapi/src/adapters/fastify/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openapi-handler' 2 | -------------------------------------------------------------------------------- /playgrounds/astro/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/electron/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/nest/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/next/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/nuxt/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/global.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/pino/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './context' 2 | export * from './handler-plugin' 3 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /playgrounds/solid-start/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /apps/content/public/og.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/apps/content/public/og.jpg -------------------------------------------------------------------------------- /packages/durable-iterator/src/error.ts: -------------------------------------------------------------------------------- 1 | export class DurableIteratorError extends Error { 2 | } 3 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/contract-first/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/nuxt/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /apps/content/public/logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/apps/content/public/logo.webp -------------------------------------------------------------------------------- /apps/content/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | 4 | Sitemap: https://orpc.dev/sitemap.xml 5 | -------------------------------------------------------------------------------- /packages/durable-iterator/src/client/index.ts: -------------------------------------------------------------------------------- 1 | export * from './iterator' 2 | export * from './plugin' 3 | -------------------------------------------------------------------------------- /packages/server/src/adapters/bun-ws/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './rpc-handler' 3 | -------------------------------------------------------------------------------- /packages/server/src/adapters/ws/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './rpc-handler' 3 | -------------------------------------------------------------------------------- /playgrounds/contract-first/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | pnpm-lock.yaml 3 | package-lock.json 4 | yarn.lock -------------------------------------------------------------------------------- /playgrounds/electron/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | out 4 | .DS_Store 5 | .eslintcache 6 | *.log* 7 | -------------------------------------------------------------------------------- /apps/content/public/code-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/apps/content/public/code-dark.png -------------------------------------------------------------------------------- /knip.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/knip@latest/schema.json", 3 | "ignore": ["*/*/*.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/client/src/adapters/websocket/index.ts: -------------------------------------------------------------------------------- 1 | export * from './link-client' 2 | export * from './rpc-link' 3 | -------------------------------------------------------------------------------- /packages/server/src/adapters/aws-lambda/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './rpc-handler' 3 | -------------------------------------------------------------------------------- /packages/server/src/adapters/crossws/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './rpc-handler' 3 | -------------------------------------------------------------------------------- /packages/server/src/adapters/fastify/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './rpc-handler' 3 | -------------------------------------------------------------------------------- /packages/server/src/adapters/websocket/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './rpc-handler' 3 | -------------------------------------------------------------------------------- /apps/content/public/code-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/apps/content/public/code-light.png -------------------------------------------------------------------------------- /packages/client/src/adapters/fetch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './link-fetch-client' 2 | export * from './rpc-link' 3 | -------------------------------------------------------------------------------- /packages/openapi-client/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export { getIssueMessage, parseFormData } from '../adapters/standard' 2 | -------------------------------------------------------------------------------- /packages/react/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './optimistic-server-action' 2 | export * from './server-action' 3 | -------------------------------------------------------------------------------- /packages/server/src/adapters/message-port/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './rpc-handler' 3 | -------------------------------------------------------------------------------- /playgrounds/next/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/next/src/app/favicon.ico -------------------------------------------------------------------------------- /playgrounds/next/src/app/loading.tsx: -------------------------------------------------------------------------------- 1 | export default function Loading() { 2 | return
Loading...
3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/nuxt/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/nuxt/public/favicon.ico -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/lib/index.ts: -------------------------------------------------------------------------------- 1 | // place files you want to import through the `$lib` alias in this folder. 2 | -------------------------------------------------------------------------------- /packages/contract/src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | export * from './request-validation' 2 | export * from './response-validation' 3 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/src/consts.ts: -------------------------------------------------------------------------------- 1 | export const OTEL_TRACE_EXPORTER_URL = 'http://localhost:4318/v1/traces' 2 | -------------------------------------------------------------------------------- /vitest.javascript.ts: -------------------------------------------------------------------------------- 1 | import { ORPCInstrumentation } from './packages/otel/src' 2 | 3 | void new ORPCInstrumentation() 4 | -------------------------------------------------------------------------------- /packages/zod/src/zod4/index.ts: -------------------------------------------------------------------------------- 1 | export * from './coercer' 2 | export * from './converter' 3 | export * from './registries' 4 | -------------------------------------------------------------------------------- /playgrounds/next/src/instrumentation.ts: -------------------------------------------------------------------------------- 1 | export async function register() { 2 | await import('./lib/orpc.server') 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/svelte-kit/static/favicon.png -------------------------------------------------------------------------------- /packages/ratelimit/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler-plugin' 2 | export * from './middleware' 3 | export * from './types' 4 | -------------------------------------------------------------------------------- /packages/standard-server/src/batch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './request' 2 | export * from './response' 3 | export * from './signal' 4 | -------------------------------------------------------------------------------- /playgrounds/solid-start/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/solid-start/public/favicon.ico -------------------------------------------------------------------------------- /packages/json-schema/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './coercer' 2 | export * from './smart-coercion-plugin' 3 | export * from './types' 4 | -------------------------------------------------------------------------------- /packages/contract/src/types.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-restricted-imports */ 2 | export type { OpenAPIV3_1 as OpenAPI } from 'openapi-types' 3 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/public/icon/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/browser-extension/public/icon/16.png -------------------------------------------------------------------------------- /playgrounds/browser-extension/public/icon/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/browser-extension/public/icon/32.png -------------------------------------------------------------------------------- /playgrounds/browser-extension/public/icon/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/browser-extension/public/icon/48.png -------------------------------------------------------------------------------- /playgrounds/browser-extension/public/icon/96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/browser-extension/public/icon/96.png -------------------------------------------------------------------------------- /playgrounds/nuxt/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /playgrounds/astro/src/shared/query.ts: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/react-query' 2 | 3 | export const queryClient = new QueryClient() 4 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/public/icon/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/playgrounds/browser-extension/public/icon/128.png -------------------------------------------------------------------------------- /packages/client/src/adapters/message-port/index.ts: -------------------------------------------------------------------------------- 1 | export * from './link-client' 2 | export * from './message-port' 3 | export * from './rpc-link' 4 | -------------------------------------------------------------------------------- /packages/standard-server-node/src/method.ts: -------------------------------------------------------------------------------- 1 | export function toStandardMethod(method: string | undefined): string { 2 | return method ?? 'GET' 3 | } 4 | -------------------------------------------------------------------------------- /playgrounds/nest/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/ai-sdk/src/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports createTool', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('createTool') 3 | }) 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | auto-install-peers = true 2 | shamefully-hoist = true 3 | link-workspace-packages = true 4 | prefer-workspace-packages = true 5 | use-node-version=22.21.1 -------------------------------------------------------------------------------- /packages/publisher/src/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports Publisher', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('Publisher') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/server/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './base64url' 2 | export * from './cookie' 3 | export * from './encryption' 4 | export * from './signing' 5 | -------------------------------------------------------------------------------- /playgrounds/next/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/standard-server/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './event-iterator' 2 | export * from './hibernation' 3 | export * from './types' 4 | export * from './utils' 5 | -------------------------------------------------------------------------------- /packages/contract/src/plugins/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports something', async () => { 2 | expect(await import('./index')).toHaveProperty('ResponseValidationPlugin') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/interop/src/compression/index.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-restricted-imports 2 | import compression from 'compression' 3 | 4 | export default compression 5 | -------------------------------------------------------------------------------- /packages/openapi-client/src/helpers/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports something', async () => { 2 | expect(await import('./index')).toHaveProperty('getIssueMessage') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/react-swr/src/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports createSWRUtils', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('createSWRUtils') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/tanstack-query/src/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports something', async () => { 2 | expect(await import('./index')).toHaveProperty('createTanstackQueryUtils') 3 | }) 4 | -------------------------------------------------------------------------------- /apps/content/public/images/opentelemetry-integration-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unnoq/orpc/HEAD/apps/content/public/images/opentelemetry-integration-preview.png -------------------------------------------------------------------------------- /packages/pino/src/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports LoggingHandlerPlugin', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('LoggingHandlerPlugin') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/server/src/adapters/fastify/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports RPCHandler', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('RPCHandler') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/standard-server-fastify/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './request' 2 | export * from './response' 3 | 4 | export type { FastifyReply, FastifyRequest } from 'fastify' 5 | -------------------------------------------------------------------------------- /packages/interop/src/compression/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports something', async () => { 2 | expect(Object.keys(await import('./index')).length).toBeGreaterThanOrEqual(1) 3 | }) 4 | -------------------------------------------------------------------------------- /packages/durable-iterator/src/client/index.test.ts: -------------------------------------------------------------------------------- 1 | it('export something', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('DurableIteratorLinkPlugin') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/durable-iterator/src/index.test.ts: -------------------------------------------------------------------------------- 1 | it('export something', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('DurableIteratorHandlerPlugin') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/openapi/src/adapters/fastify/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports OpenAPIHandler', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('OpenAPIHandler') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/openapi/src/adapters/standard/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openapi-codec' 2 | export * from './openapi-handler' 3 | export * from './openapi-matcher' 4 | export * from './utils' 5 | -------------------------------------------------------------------------------- /packages/publisher-durable-object/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './durable-object' 2 | export * from './durable-publisher' 3 | export * from './resume-storage' 4 | export * from './types' 5 | -------------------------------------------------------------------------------- /packages/react/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './action-form' 2 | export * from './deferred-interceptors' 3 | export { getIssueMessage, parseFormData } from '@orpc/openapi-client/standard' 4 | -------------------------------------------------------------------------------- /packages/contract/src/meta.ts: -------------------------------------------------------------------------------- 1 | export type Meta = Record 2 | 3 | export function mergeMeta(meta1: T, meta2: T): T { 4 | return { ...meta1, ...meta2 } 5 | } 6 | -------------------------------------------------------------------------------- /packages/interop/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | rollup: { 5 | inlineDependencies: true, 6 | }, 7 | }) 8 | -------------------------------------------------------------------------------- /packages/ratelimit/src/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports createRatelimitMiddleware', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('createRatelimitMiddleware') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/standard-server-peer/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client' 2 | export * from './codec' 3 | export * from './event-iterator' 4 | export * from './server' 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/durable-iterator/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | externals: [ 5 | 'cloudflare:workers', 6 | ], 7 | }) 8 | -------------------------------------------------------------------------------- /packages/standard-server-fastify/src/index.test.ts: -------------------------------------------------------------------------------- 1 | it('exports toStandardLazyRequest', async () => { 2 | expect(Object.keys(await import('./index'))).toContain('toStandardLazyRequest') 3 | }) 4 | -------------------------------------------------------------------------------- /packages/standard-server-fetch/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './body' 2 | export * from './event-iterator' 3 | export * from './headers' 4 | export * from './request' 5 | export * from './response' 6 | -------------------------------------------------------------------------------- /packages/standard-server/src/event-iterator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './decoder' 2 | export * from './encoder' 3 | export * from './errors' 4 | export * from './meta' 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/otel/src/consts.ts: -------------------------------------------------------------------------------- 1 | export const ORPC_OTEL_PACKAGE_NAME = '__ORPC_OTEL_PACKAGE_NAME_PLACEHOLDER__' 2 | export const ORPC_OTEL_PACKAGE_VERSION = '__ORPC_OTEL_PACKAGE_VERSION_PLACEHOLDER__' 3 | -------------------------------------------------------------------------------- /packages/publisher-durable-object/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { EventMeta } from '@orpc/standard-server' 2 | 3 | export interface SerializedMessage { 4 | data: unknown 5 | meta?: EventMeta 6 | } 7 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/content.ts: -------------------------------------------------------------------------------- 1 | export default defineContentScript({ 2 | matches: ['*://*.google.com/*'], 3 | main() { 4 | console.log('Hello content.') 5 | }, 6 | }) 7 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.wxt/tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "allowImportingTsExtensions": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/entry-client.tsx: -------------------------------------------------------------------------------- 1 | // @refresh reload 2 | import { mount, StartClient } from '@solidjs/start/client' 3 | 4 | mount(() => , document.getElementById('app')!) 5 | -------------------------------------------------------------------------------- /packages/publisher-durable-object/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | externals: [ 5 | 'cloudflare:workers', 6 | ], 7 | }) 8 | -------------------------------------------------------------------------------- /packages/client/src/consts.ts: -------------------------------------------------------------------------------- 1 | export const ORPC_CLIENT_PACKAGE_NAME = '__ORPC_CLIENT_PACKAGE_NAME_PLACEHOLDER__' 2 | export const ORPC_CLIENT_PACKAGE_VERSION = '__ORPC_CLIENT_PACKAGE_VERSION_PLACEHOLDER__' 3 | -------------------------------------------------------------------------------- /packages/client/src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | export * from './batch' 2 | export * from './dedupe-requests' 3 | export * from './retry' 4 | export * from './retry-after' 5 | export * from './simple-csrf-protection' 6 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/wxt.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'wxt' 2 | 3 | // See https://wxt.dev/api/config.html 4 | export default defineConfig({ 5 | modules: ['@wxt-dev/module-react'], 6 | }) 7 | -------------------------------------------------------------------------------- /playgrounds/nuxt/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | compatibilityDate: '2024-11-01', 4 | devtools: { enabled: true }, 5 | }) 6 | -------------------------------------------------------------------------------- /apps/content/public/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/server/src/adapters/fetch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './body-limit-plugin' 2 | export * from './compression-plugin' 3 | export * from './handler' 4 | export * from './plugin' 5 | export * from './rpc-handler' 6 | -------------------------------------------------------------------------------- /packages/server/src/adapters/node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './body-limit-plugin' 2 | export * from './compression-plugin' 3 | export * from './handler' 4 | export * from './plugin' 5 | export * from './rpc-handler' 6 | -------------------------------------------------------------------------------- /packages/server/src/hibernation/index.ts: -------------------------------------------------------------------------------- 1 | export * from './event-iterator' 2 | export * from './plugin' 3 | export { HibernationEventIterator, type HibernationEventIteratorCallback } from '@orpc/standard-server' 4 | -------------------------------------------------------------------------------- /apps/content/public/_redirects: -------------------------------------------------------------------------------- 1 | /docs /docs/getting-started 301 2 | /docs/openapi /docs/openapi/getting-started 301 3 | /sponsor https://github.com/sponsors/unnoq 301 4 | /docs/integrations/nextjs /docs/integrations/next 301 -------------------------------------------------------------------------------- /playgrounds/electron/src/preload/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ElectronAPI } from '@electron-toolkit/preload' 2 | 3 | declare global { 4 | interface Window { 5 | electron: ElectronAPI 6 | api: unknown 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/contract/src/meta.test.ts: -------------------------------------------------------------------------------- 1 | import { mergeMeta } from './meta' 2 | 3 | it('mergeMeta', () => { 4 | expect(mergeMeta({}, { a: 2 })).toEqual({ a: 2 }) 5 | expect(mergeMeta({ a: 1, b: 1 }, { a: 2 })).toEqual({ a: 2, b: 1 }) 6 | }) 7 | -------------------------------------------------------------------------------- /packages/durable-iterator/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './consts' 2 | export * from './contract' 3 | export * from './error' 4 | export * from './iterator' 5 | export * from './object' 6 | export * from './plugin' 7 | export * from './schemas' 8 | -------------------------------------------------------------------------------- /packages/shared/src/consts.ts: -------------------------------------------------------------------------------- 1 | export const ORPC_NAME = 'orpc' 2 | export const ORPC_SHARED_PACKAGE_NAME = '__ORPC_SHARED_PACKAGE_NAME_PLACEHOLDER__' 3 | export const ORPC_SHARED_PACKAGE_VERSION = '__ORPC_SHARED_PACKAGE_VERSION_PLACEHOLDER__' 4 | -------------------------------------------------------------------------------- /packages/shared/src/uri.ts: -------------------------------------------------------------------------------- 1 | export function tryDecodeURIComponent(value: string): string { 2 | try { 3 | // eslint-disable-next-line ban/ban 4 | return decodeURIComponent(value) 5 | } 6 | catch { 7 | return value 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/server/src/adapters/standard/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './plugin' 3 | export * from './rpc-codec' 4 | export * from './rpc-handler' 5 | export * from './rpc-matcher' 6 | export * from './types' 7 | export * from './utils' 8 | -------------------------------------------------------------------------------- /playgrounds/astro/astro.config.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { defineConfig } from 'astro/config' 3 | 4 | import react from '@astrojs/react' 5 | 6 | // https://astro.build/config 7 | export default defineConfig({ 8 | integrations: [react()], 9 | }) 10 | -------------------------------------------------------------------------------- /playgrounds/astro/src/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/nest/src/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/next/src/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /packages/react-swr/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './general-utils' 2 | export * from './procedure-utils' 3 | export * from './router-utils' 4 | export { createRouterUtils as createSWRUtils } from './router-utils' 5 | export * from './types' 6 | export * from './utils' 7 | -------------------------------------------------------------------------------- /packages/standard-server-fetch/playground/event-source.http: -------------------------------------------------------------------------------- 1 | POST http://localhost:3000 2 | Content-Type: text/event-stream 3 | 4 | event: message 5 | data: {"foo":"bar"} 6 | 7 | event: message 8 | data: {"foo":"bar"} 9 | 10 | event: done 11 | data: 123 12 | -------------------------------------------------------------------------------- /playgrounds/nest/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "deleteOutDir": true, 7 | "builder": "webpack" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /playgrounds/nuxt/server/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /packages/server/src/config.test.ts: -------------------------------------------------------------------------------- 1 | import { fallbackConfig } from './config' 2 | 3 | it('fallbackConfig', () => { 4 | expect(fallbackConfig('initialInputValidationIndex', 1)).toBe(1) 5 | expect(fallbackConfig('initialInputValidationIndex', undefined)).toBe(0) 6 | }) 7 | -------------------------------------------------------------------------------- /packages/standard-server-peer/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Promisable } from '@orpc/shared' 2 | 3 | export type EncodedMessage = string | ArrayBufferLike | Uint8Array 4 | 5 | export interface EncodedMessageSendFn { 6 | (message: EncodedMessage): Promisable 7 | } 8 | -------------------------------------------------------------------------------- /playgrounds/contract-first/src/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/electron/src/main/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/next/src/app/error.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | export default function ErrorPage({ error }: { error: Error }) { 4 | return ( 5 |
6 |

7 | Error: 8 | {error.message} 9 |

10 |
11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/src/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /packages/server/src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | export * from './batch' 2 | export * from './cors' 3 | export * from './request-headers' 4 | export * from './response-headers' 5 | export * from './rethrow' 6 | export * from './simple-csrf-protection' 7 | export * from './strict-get-method' 8 | -------------------------------------------------------------------------------- /packages/shared/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "include": ["src"], 4 | "exclude": [ 5 | "**/*.test.*", 6 | "**/*.test-d.ts", 7 | "**/__tests__/**", 8 | "**/__mocks__/**", 9 | "**/__snapshots__/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/src/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/worker/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /packages/contract/src/config.test.ts: -------------------------------------------------------------------------------- 1 | import { fallbackContractConfig } from './config' 2 | 3 | it('fallbackConfig', () => { 4 | expect(fallbackContractConfig('defaultMethod', undefined)).toBe('POST') 5 | expect(fallbackContractConfig('defaultMethod', 'GET')).toBe('GET') 6 | }) 7 | -------------------------------------------------------------------------------- /packages/interop/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "include": ["src"], 4 | "exclude": [ 5 | "**/*.test.*", 6 | "**/*.test-d.ts", 7 | "**/__tests__/**", 8 | "**/__mocks__/**", 9 | "**/__snapshots__/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/server/src/context.test.ts: -------------------------------------------------------------------------------- 1 | import { mergeCurrentContext } from './context' 2 | 3 | it('mergeCurrentContext', () => { 4 | expect(mergeCurrentContext({ a: 1 }, { b: 2 })).toEqual({ a: 1, b: 2 }) 5 | expect(mergeCurrentContext({ a: 1 }, { a: 2 })).toEqual({ a: 2 }) 6 | }) 7 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/routes/api/index.ts: -------------------------------------------------------------------------------- 1 | import { POST as handle } from './[...rest]' 2 | 3 | export const HEAD = handle 4 | export const GET = handle 5 | export const POST = handle 6 | export const PUT = handle 7 | export const PATCH = handle 8 | export const DELETE = handle 9 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/routes/rpc/index.ts: -------------------------------------------------------------------------------- 1 | import { POST as handle } from './[...rest]' 2 | 3 | export const HEAD = handle 4 | export const GET = handle 5 | export const POST = handle 6 | export const PUT = handle 7 | export const PATCH = handle 8 | export const DELETE = handle 9 | -------------------------------------------------------------------------------- /packages/react-swr/tests/shared.tsx: -------------------------------------------------------------------------------- 1 | import { orpc as client, streamedOrpc as streamedClient } from '../../client/tests/shared' 2 | import { createSWRUtils } from '../src' 3 | 4 | export const orpc = createSWRUtils(client) 5 | export const streamedOrpc = createSWRUtils(streamedClient) 6 | -------------------------------------------------------------------------------- /playgrounds/next/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from 'next' 2 | 3 | const nextConfig: NextConfig = { 4 | typescript: { 5 | ignoreBuildErrors: true, 6 | }, 7 | experimental: { 8 | authInterrupts: true, 9 | }, 10 | } 11 | 12 | export default nextConfig 13 | -------------------------------------------------------------------------------- /packages/standard-server-aws-lambda/src/url.ts: -------------------------------------------------------------------------------- 1 | import type { APIGatewayProxyEventV2 } from './types' 2 | 3 | export function toStandardUrl(event: APIGatewayProxyEventV2): URL { 4 | return new URL(`https://${event.requestContext.domainName}${event.rawPath}?${event.rawQueryString}`) 5 | } 6 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/background/schemas/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from 'zod' 2 | 3 | export const CredentialSchema = z.object({ 4 | email: z.email(), 5 | password: z.string(), 6 | }) 7 | 8 | export const TokenSchema = z.object({ 9 | token: z.string(), 10 | }) 11 | -------------------------------------------------------------------------------- /packages/durable-iterator/src/durable-object/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler' 2 | export * from './object' 3 | export * from './object-state' 4 | export * from './resume-storage' 5 | export * from './upgrade' 6 | export * from './websocket' 7 | 8 | export { withEventMeta } from '@orpc/server' 9 | -------------------------------------------------------------------------------- /packages/standard-server-aws-lambda/src/types.test-d.ts: -------------------------------------------------------------------------------- 1 | import type * as awslambda from 'aws-lambda' 2 | import type { APIGatewayProxyEventV2 } from './types' 3 | 4 | it('APIGatewayProxyEvent', () => { 5 | expectTypeOf().toExtend() 6 | }) 7 | -------------------------------------------------------------------------------- /packages/client/src/adapters/standard/index.ts: -------------------------------------------------------------------------------- 1 | export * from './link' 2 | export * from './plugin' 3 | export * from './rpc-json-serializer' 4 | export * from './rpc-link' 5 | export * from './rpc-link-codec' 6 | export * from './rpc-serializer' 7 | export * from './types' 8 | export * from './utils' 9 | -------------------------------------------------------------------------------- /packages/standard-server-node/src/method.test.ts: -------------------------------------------------------------------------------- 1 | import { toStandardMethod } from './method' 2 | 3 | it('toStandardMethod', () => { 4 | expect(toStandardMethod('GET')).toEqual('GET') 5 | expect(toStandardMethod('POST')).toEqual('POST') 6 | expect(toStandardMethod(undefined)).toEqual('GET') 7 | }) 8 | -------------------------------------------------------------------------------- /packages/ai-sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tool' 2 | 3 | export { 4 | AsyncIteratorClass, 5 | asyncIteratorToStream as eventIteratorToStream, 6 | asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, 7 | streamToAsyncIteratorClass as streamToEventIterator, 8 | } from '@orpc/shared' 9 | -------------------------------------------------------------------------------- /playgrounds/astro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "jsxImportSource": "react" 6 | }, 7 | "include": [ 8 | ".astro/types.d.ts", 9 | "**/*" 10 | ], 11 | "exclude": [ 12 | "dist" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /apps/content/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "types": ["node"] 5 | }, 6 | "exclude": [ 7 | "**/*.test.*", 8 | "**/*.test-d.ts", 9 | "**/__tests__/**", 10 | "**/__mocks__/**", 11 | "**/__snapshots__/**" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/durable-iterator/src/consts.ts: -------------------------------------------------------------------------------- 1 | export const DURABLE_ITERATOR_TOKEN_PARAM = 'token' as const 2 | export const DURABLE_ITERATOR_ID_PARAM = 'id' as const 3 | export const DURABLE_ITERATOR_PLUGIN_HEADER_KEY = 'x-orpc-durable-iterator' as const 4 | export const DURABLE_ITERATOR_PLUGIN_HEADER_VALUE = '1' as const 5 | -------------------------------------------------------------------------------- /packages/otel/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | import pkg from './package.json' 3 | 4 | export default defineBuildConfig({ 5 | replace: { 6 | __ORPC_OTEL_PACKAGE_NAME_PLACEHOLDER__: pkg.name, 7 | __ORPC_OTEL_PACKAGE_VERSION_PLACEHOLDER__: pkg.version, 8 | }, 9 | }) 10 | -------------------------------------------------------------------------------- /packages/shared/src/chain.ts: -------------------------------------------------------------------------------- 1 | import type { AnyFunction } from './function' 2 | 3 | export type OmitChainMethodDeep = { 4 | [P in keyof Omit]: T[P] extends AnyFunction 5 | ? ((...args: Parameters) => OmitChainMethodDeep, K>) 6 | : T[P] 7 | } 8 | -------------------------------------------------------------------------------- /packages/standard-server-node/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './body' 2 | export * from './event-iterator' 3 | export * from './headers' 4 | export * from './method' 5 | export * from './request' 6 | export * from './response' 7 | export * from './signal' 8 | export * from './types' 9 | export * from './url' 10 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | import { cloudflare } from '@cloudflare/vite-plugin' 5 | 6 | // https://vite.dev/config/ 7 | export default defineConfig({ 8 | plugins: [react(), cloudflare()], 9 | }) 10 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # copy this file and rename it to .env 2 | # then fill in the appropriate values 3 | 4 | # Some tests in the project depend on Redis or Upstash Redis 5 | # You can create a free redis instance at upstash and copy the connection details here 6 | REDIS_URL= 7 | UPSTASH_REDIS_REST_URL= 8 | UPSTASH_REDIS_REST_TOKEN= -------------------------------------------------------------------------------- /packages/nest/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | rollup: { 5 | esbuild: { 6 | tsconfigRaw: { 7 | compilerOptions: { 8 | experimentalDecorators: true, 9 | }, 10 | }, 11 | }, 12 | }, 13 | }) 14 | -------------------------------------------------------------------------------- /packages/client/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | import pkg from './package.json' 3 | 4 | export default defineBuildConfig({ 5 | replace: { 6 | __ORPC_CLIENT_PACKAGE_NAME_PLACEHOLDER__: pkg.name, 7 | __ORPC_CLIENT_PACKAGE_VERSION_PLACEHOLDER__: pkg.version, 8 | }, 9 | }) 10 | -------------------------------------------------------------------------------- /packages/openapi-client/src/adapters/standard/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bracket-notation' 2 | export * from './bracket-notation-utils' 3 | export * from './openapi-json-serializer' 4 | export * from './openapi-link' 5 | export * from './openapi-link-codec' 6 | export * from './openapi-serializer' 7 | export * from './utils' 8 | -------------------------------------------------------------------------------- /packages/shared/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | import pkg from './package.json' 3 | 4 | export default defineBuildConfig({ 5 | replace: { 6 | __ORPC_SHARED_PACKAGE_NAME_PLACEHOLDER__: pkg.name, 7 | __ORPC_SHARED_PACKAGE_VERSION_PLACEHOLDER__: pkg.version, 8 | }, 9 | }) 10 | -------------------------------------------------------------------------------- /playgrounds/astro/src/orpc.ts: -------------------------------------------------------------------------------- 1 | import { os } from '@orpc/server' 2 | import { dbProviderMiddleware } from './middlewares/db' 3 | import { requiredAuthMiddleware } from './middlewares/auth' 4 | 5 | export const pub = os 6 | .use(dbProviderMiddleware) 7 | 8 | export const authed = pub 9 | .use(requiredAuthMiddleware) 10 | -------------------------------------------------------------------------------- /playgrounds/nest/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core' 2 | import { AppModule } from './app.module' 3 | 4 | async function bootstrap() { 5 | const app = await NestFactory.create(AppModule, { 6 | bodyParser: false, 7 | }) 8 | 9 | await app.listen(process.env.PORT ?? 3000) 10 | } 11 | bootstrap() 12 | -------------------------------------------------------------------------------- /playgrounds/next/src/orpc.ts: -------------------------------------------------------------------------------- 1 | import { os } from '@orpc/server' 2 | import { dbProviderMiddleware } from './middlewares/db' 3 | import { requiredAuthMiddleware } from './middlewares/auth' 4 | 5 | export const pub = os 6 | .use(dbProviderMiddleware) 7 | 8 | export const authed = pub 9 | .use(requiredAuthMiddleware) 10 | -------------------------------------------------------------------------------- /playgrounds/solid-start/app.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@solidjs/start/config' 2 | import topLevelAwait from 'vite-plugin-top-level-await' 3 | 4 | export default defineConfig({ 5 | vite: { 6 | plugins: [ 7 | // TODO: remove `as any` 8 | topLevelAwait() as any, 9 | ], 10 | }, 11 | }) 12 | -------------------------------------------------------------------------------- /playgrounds/electron/src/main/orpc.ts: -------------------------------------------------------------------------------- 1 | import { os } from '@orpc/server' 2 | import { dbProviderMiddleware } from './middlewares/db' 3 | import { requiredAuthMiddleware } from './middlewares/auth' 4 | 5 | export const pub = os 6 | .use(dbProviderMiddleware) 7 | 8 | export const authed = pub 9 | .use(requiredAuthMiddleware) 10 | -------------------------------------------------------------------------------- /packages/otel/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../shared" } 5 | ], 6 | "include": ["src"], 7 | "exclude": [ 8 | "**/*.test.*", 9 | "**/*.test-d.ts", 10 | "**/__tests__/**", 11 | "**/__mocks__/**", 12 | "**/__snapshots__/**" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/shared/src/args.test.ts: -------------------------------------------------------------------------------- 1 | import { resolveMaybeOptionalOptions } from './args' 2 | 3 | it('resolveMaybeOptionalOptions', () => { 4 | expect(resolveMaybeOptionalOptions([{ a: 1 }])).toEqual({ a: 1 }) 5 | expect(resolveMaybeOptionalOptions([undefined])).toEqual({}) 6 | expect(resolveMaybeOptionalOptions([])).toEqual({}) 7 | }) 8 | -------------------------------------------------------------------------------- /packages/vue-colada/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouterUtils } from './router-utils' 2 | 3 | export * from './general-utils' 4 | export * from './key' 5 | export * from './procedure-utils' 6 | export * from './router-utils' 7 | export * from './types' 8 | 9 | export { 10 | createRouterUtils as createORPCVueColadaUtils, 11 | } 12 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/src/orpc.ts: -------------------------------------------------------------------------------- 1 | import { os } from '@orpc/server' 2 | import { dbProviderMiddleware } from './middlewares/db' 3 | import { requiredAuthMiddleware } from './middlewares/auth' 4 | 5 | export const pub = os 6 | .use(dbProviderMiddleware) 7 | 8 | export const authed = pub 9 | .use(requiredAuthMiddleware) 10 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/src/orpc.ts: -------------------------------------------------------------------------------- 1 | import { os } from '@orpc/server' 2 | import { dbProviderMiddleware } from './middlewares/db' 3 | import { requiredAuthMiddleware } from './middlewares/auth' 4 | 5 | export const pub = os 6 | .use(dbProviderMiddleware) 7 | 8 | export const authed = pub 9 | .use(requiredAuthMiddleware) 10 | -------------------------------------------------------------------------------- /packages/shared/src/args.ts: -------------------------------------------------------------------------------- 1 | export type MaybeOptionalOptions = Record extends TOptions 2 | ? [options?: TOptions] 3 | : [options: TOptions] 4 | 5 | export function resolveMaybeOptionalOptions(rest: MaybeOptionalOptions): T { 6 | return rest[0] ?? {} as T // 0 only undefined when all fields are optional 7 | } 8 | -------------------------------------------------------------------------------- /playgrounds/nest/src/contract/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, oc } from '@orpc/contract' 2 | import * as z from 'zod' 3 | 4 | export const sse = oc 5 | .route({ 6 | method: 'GET', 7 | path: '/sse', 8 | tags: ['SSE'], 9 | summary: 'Server-Sent Events', 10 | }) 11 | .output(eventIterator(z.object({ time: z.date() }))) 12 | -------------------------------------------------------------------------------- /packages/shared/src/error.test.ts: -------------------------------------------------------------------------------- 1 | import { AbortError } from './error' 2 | 3 | it('abortError', () => { 4 | const error = new AbortError('Operation aborted', { 5 | cause: '__cause__', 6 | }) 7 | expect(error.name).toBe('AbortError') 8 | expect(error.message).toBe('Operation aborted') 9 | expect(error.cause).toBe('__cause__') 10 | }) 11 | -------------------------------------------------------------------------------- /packages/shared/src/json.test-d.ts: -------------------------------------------------------------------------------- 1 | import { stringifyJSON } from './json' 2 | 3 | it('stringifyJSON', () => { 4 | expectTypeOf(stringifyJSON(undefined)).toEqualTypeOf() 5 | expectTypeOf(stringifyJSON({})).toEqualTypeOf() 6 | expectTypeOf(stringifyJSON({ toJSON: () => undefined })).toEqualTypeOf() 7 | }) 8 | -------------------------------------------------------------------------------- /playgrounds/contract-first/src/contract/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, oc } from '@orpc/contract' 2 | import * as z from 'zod' 3 | 4 | export const sse = oc 5 | .route({ 6 | method: 'GET', 7 | path: '/sse', 8 | tags: ['SSE'], 9 | summary: 'Server-Sent Events', 10 | }) 11 | .output(eventIterator(z.object({ time: z.date() }))) 12 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # Output 4 | .output 5 | .vercel 6 | .netlify 7 | .wrangler 8 | /.svelte-kit 9 | /build 10 | 11 | # OS 12 | .DS_Store 13 | Thumbs.db 14 | 15 | # Env 16 | .env 17 | .env.* 18 | !.env.example 19 | !.env.test 20 | 21 | # Vite 22 | vite.config.js.timestamp-* 23 | vite.config.ts.timestamp-* 24 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite' 2 | import { defineConfig } from 'vite' 3 | 4 | export default defineConfig({ 5 | plugins: [sveltekit()], 6 | ssr: { 7 | // Tell Vite not to externalize this package, so it will be processed by Vite. 8 | noExternal: [/^@orpc\/.+/], 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/background/orpc.ts: -------------------------------------------------------------------------------- 1 | import { os } from '@orpc/server' 2 | import { dbProviderMiddleware } from './middlewares/db' 3 | import { requiredAuthMiddleware } from './middlewares/auth' 4 | 5 | export const pub = os 6 | .use(dbProviderMiddleware) 7 | 8 | export const authed = pub 9 | .use(requiredAuthMiddleware) 10 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/src/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | export const sse = os 5 | .input(eventIterator(z.object({ time: z.date() }))) 6 | .output(eventIterator(z.object({ time: z.date() }))) 7 | .handler(async function* ({ input }) { 8 | yield* input 9 | }) 10 | -------------------------------------------------------------------------------- /packages/shared/src/error.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Error thrown when an operation is aborted. 3 | * Uses the standardized 'AbortError' name for consistency with JavaScript APIs. 4 | */ 5 | export class AbortError extends Error { 6 | constructor(...rest: ConstructorParameters) { 7 | super(...rest) 8 | this.name = 'AbortError' 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/background/index.ts: -------------------------------------------------------------------------------- 1 | import { RPCHandler } from '@orpc/server/message-port' 2 | import { router } from './routers' 3 | 4 | const handler = new RPCHandler(router) 5 | 6 | export default defineBackground(() => { 7 | browser.runtime.onConnect.addListener((port) => { 8 | handler.upgrade(port) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | catalogMode: prefer 2 | cleanupUnusedCatalogs: true 3 | shellEmulator: true 4 | trustPolicy: no-downgrade 5 | packages: 6 | - 'apps/*' 7 | - 'packages/*' 8 | - 'playgrounds/*' 9 | overrides: 10 | '@wxt-dev/storage': 1.2.0 11 | typescript: ~5.8.3 12 | onlyBuiltDependencies: 13 | - better-sqlite3 14 | - electron 15 | - esbuild 16 | -------------------------------------------------------------------------------- /tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.base.json", 4 | "compilerOptions": { 5 | "composite": true, 6 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 7 | "declaration": true, 8 | "declarationMap": true, 9 | "emitDeclarationOnly": true, 10 | "noEmit": false 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/standard-server/src/event-iterator/types.ts: -------------------------------------------------------------------------------- 1 | export interface EventMessage { 2 | event: string | undefined 3 | id: string | undefined 4 | data: string | undefined 5 | 6 | /** 7 | * The number of milliseconds to wait before retrying the event iterator if error occurs. 8 | */ 9 | retry: number | undefined 10 | 11 | comments: string[] 12 | } 13 | -------------------------------------------------------------------------------- /packages/standard-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../shared" } 5 | ], 6 | "include": ["src"], 7 | "exclude": [ 8 | "**/*.test.*", 9 | "**/*.test-d.ts", 10 | "**/*.bench.*", 11 | "**/__tests__/**", 12 | "**/__mocks__/**", 13 | "**/__snapshots__/**" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/contract/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.test-d.ts", 11 | "**/__tests__/**", 12 | "**/__mocks__/**", 13 | "**/__snapshots__/**" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://svelte.dev/docs/kit/types#app.d.ts 2 | // for information about these interfaces 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface PageState {} 9 | // interface Platform {} 10 | } 11 | } 12 | 13 | export {} 14 | -------------------------------------------------------------------------------- /packages/publisher-durable-object/src/index.test.ts: -------------------------------------------------------------------------------- 1 | vi.mock('cloudflare:workers', () => ({ 2 | DurableObject: class { 3 | constructor(protected readonly ctx: any, protected readonly env: unknown) {} 4 | }, 5 | })) 6 | 7 | it('exports PublisherDurableObject', async () => { 8 | expect(Object.keys(await import('./index'))).toContain('PublisherDurableObject') 9 | }) 10 | -------------------------------------------------------------------------------- /packages/svelte-query/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.test-d.ts", 11 | "**/__tests__/**", 12 | "**/__mocks__/**", 13 | "**/__snapshots__/**" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /playgrounds/nuxt/app/app.vue: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /packages/pino/src/context.test.ts: -------------------------------------------------------------------------------- 1 | import pino from 'pino' 2 | import { CONTEXT_LOGGER_SYMBOL, getLogger } from './context' 3 | 4 | it('getLogger', async () => { 5 | expect(getLogger({})).toBeUndefined() 6 | expect(getLogger({ something: true } as any)).toBeUndefined() 7 | 8 | const logger = pino() 9 | expect(getLogger({ [CONTEXT_LOGGER_SYMBOL]: logger })).toBe(logger) 10 | }) 11 | -------------------------------------------------------------------------------- /packages/pino/src/context.ts: -------------------------------------------------------------------------------- 1 | import type { Logger } from 'pino' 2 | 3 | export const CONTEXT_LOGGER_SYMBOL: unique symbol = Symbol('ORPC_PINO_CONTEXT_LOGGER_SYMBOL') 4 | 5 | export interface LoggerContext { 6 | [CONTEXT_LOGGER_SYMBOL]?: Logger 7 | } 8 | 9 | export function getLogger(context: LoggerContext): Logger | undefined { 10 | return context[CONTEXT_LOGGER_SYMBOL] 11 | } 12 | -------------------------------------------------------------------------------- /packages/server/src/link-utils.test-d.ts: -------------------------------------------------------------------------------- 1 | import { RPCLink } from '@orpc/client/fetch' 2 | import { router } from '../tests/shared' 3 | import { inferRPCMethodFromRouter } from './link-utils' 4 | 5 | it('inferRPCMethodFromContractRouter', () => { 6 | const link = new RPCLink({ 7 | url: 'http://localhost:3000/rpc', 8 | method: inferRPCMethodFromRouter(router), 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/contract-first/src/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { pub } from '../orpc' 2 | 3 | const MAX_EVENTS = 5 4 | 5 | export const sse = pub.sse 6 | .handler(async function* () { 7 | let count = 0 8 | 9 | while (count < MAX_EVENTS) { 10 | count++ 11 | yield { time: new Date() } 12 | await new Promise(resolve => setTimeout(resolve, 1000)) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /playgrounds/nuxt/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | 26 | pnpm-lock.yaml 27 | package-lock.json 28 | yarn.lock -------------------------------------------------------------------------------- /playgrounds/tanstack-start/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | yarn.lock 4 | 5 | .DS_Store 6 | .cache 7 | .env 8 | .vercel 9 | .output 10 | .vinxi 11 | 12 | /build/ 13 | /api/ 14 | /server/build 15 | /public/build 16 | .vinxi 17 | # Sentry Config File 18 | .env.sentry-build-plugin 19 | /test-results/ 20 | /playwright-report/ 21 | /blob-report/ 22 | /playwright/.cache/ 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Discord 4 | url: https://discord.com/invite/TXEbwRBvQn 5 | about: Join our Discord server to chat with the community and get help. 6 | - name: GitHub Discussions 7 | url: https://github.com/unnoq/orpc/discussions 8 | about: Use discussions if you have questions, ideas, or need general help. 9 | -------------------------------------------------------------------------------- /packages/hey-api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.test-d.ts", 11 | "**/*.bench.*", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/react-swr/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.test-d.ts", 11 | "**/*.bench.*", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/vue-colada/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.bench.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/vue-query/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.bench.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /playgrounds/astro/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | 23 | # jetbrains setting folder 24 | .idea/ 25 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .output 12 | stats.html 13 | stats-*.json 14 | .wxt 15 | web-ext.config.ts 16 | 17 | # Editor directories and files 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /apps/content/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? -------------------------------------------------------------------------------- /packages/durable-iterator/src/durable-object/index.test.ts: -------------------------------------------------------------------------------- 1 | vi.mock('cloudflare:workers', () => ({ 2 | DurableObject: class { 3 | constructor( 4 | protected readonly ctx: any, 5 | protected readonly env: unknown, 6 | ) { } 7 | }, 8 | })) 9 | 10 | it('export something', async () => { 11 | expect(Object.keys(await import('./index'))).toContain('DurableIteratorObject') 12 | }) 13 | -------------------------------------------------------------------------------- /packages/standard-server-node/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "lib": ["ES2022"], 5 | "types": ["node"] 6 | }, 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.test-d.ts", 11 | "**/*.bench.*", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/tanstack-query/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.test-d.ts", 11 | "**/*.bench.*", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/trpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../server" }, 5 | { "path": "../client" }, 6 | { "path": "../shared" } 7 | ], 8 | "include": ["src"], 9 | "exclude": [ 10 | "**/*.test.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Cloudflare Worker Playground 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/ai-sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../openapi" }, 5 | { "path": "../contract" }, 6 | { "path": "../server" } 7 | ], 8 | "include": ["src"], 9 | "exclude": [ 10 | "**/*.test.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/arktype/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../openapi" }, 5 | { "path": "../contract" }, 6 | { "path": "../server" } 7 | ], 8 | "include": ["src"], 9 | "exclude": [ 10 | "**/*.test.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/publisher/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../shared" }, 5 | { "path": "../standard-server" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.bench.*", 10 | "**/*.test.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/shared/src/array.ts: -------------------------------------------------------------------------------- 1 | export function toArray(value: T): T extends readonly any[] ? T : Exclude[] { 2 | return (Array.isArray(value) ? value : value === undefined || value === null ? [] : [value]) as any 3 | } 4 | 5 | export function splitInHalf(arr: readonly T[]): [T[], T[]] { 6 | const half = Math.ceil(arr.length / 2) 7 | return [arr.slice(0, half), arr.slice(half)] 8 | } 9 | -------------------------------------------------------------------------------- /packages/shared/src/json.ts: -------------------------------------------------------------------------------- 1 | export function parseEmptyableJSON(text: string | null | undefined): unknown { 2 | if (!text) { 3 | return undefined 4 | } 5 | 6 | return JSON.parse(text) 7 | } 8 | 9 | export function stringifyJSON(value: T | { toJSON(): T }): undefined extends T ? undefined | string : string { 10 | // eslint-disable-next-line ban/ban 11 | return JSON.stringify(value) 12 | } 13 | -------------------------------------------------------------------------------- /packages/valibot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../openapi" }, 5 | { "path": "../contract" }, 6 | { "path": "../server" } 7 | ], 8 | "include": ["src"], 9 | "exclude": [ 10 | "**/*.test.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/zod/src/zod4/coercer.rest.test.ts: -------------------------------------------------------------------------------- 1 | import z from 'zod/v4' 2 | import { testSchemaSmartCoercion } from '../../tests/shared' 3 | 4 | testSchemaSmartCoercion([ 5 | { 6 | name: 'number - 123', 7 | schema: z.number().or(z.string()), 8 | input: '123', 9 | }, 10 | { 11 | name: 'boolean - true', 12 | schema: z.boolean().or(z.string()), 13 | input: 'true', 14 | }, 15 | ]) 16 | -------------------------------------------------------------------------------- /playgrounds/next/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /playgrounds/next/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /playgrounds/solid-start/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | .solid 3 | .output 4 | .vercel 5 | .netlify 6 | .vinxi 7 | app.config.timestamp_*.js 8 | 9 | # Environment 10 | .env 11 | .env*.local 12 | 13 | # dependencies 14 | /node_modules 15 | 16 | # IDEs and editors 17 | /.idea 18 | .project 19 | .classpath 20 | *.launch 21 | .settings/ 22 | 23 | # Temp 24 | gitignore 25 | 26 | # System Files 27 | .DS_Store 28 | Thumbs.db 29 | -------------------------------------------------------------------------------- /packages/react-query/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../tanstack-query" }, 6 | { "path": "../shared" } 7 | ], 8 | "include": ["src"], 9 | "exclude": [ 10 | "**/*.test.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/solid-query/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../tanstack-query" }, 6 | { "path": "../shared" } 7 | ], 8 | "include": ["src"], 9 | "exclude": [ 10 | "**/*.test.*", 11 | "**/*.test-d.ts", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/standard-server-aws-lambda/src/url.test.ts: -------------------------------------------------------------------------------- 1 | import { toStandardUrl } from './url' 2 | 3 | it('toStandardUrl', () => { 4 | expect(toStandardUrl({ 5 | requestContext: { 6 | domainName: 'example.com', 7 | }, 8 | rawPath: '/api/planets', 9 | rawQueryString: 'key1=value1&key2=value2', 10 | } as any)).toEqual(new URL('https://example.com/api/planets?key1=value1&key2=value2')) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/standard-server-fetch/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../standard-server" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.test-d.ts", 11 | "**/*.bench.*", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/standard-server-peer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../standard-server" }, 5 | { "path": "../shared" } 6 | ], 7 | "include": ["src"], 8 | "exclude": [ 9 | "**/*.test.*", 10 | "**/*.test-d.ts", 11 | "**/*.bench.*", 12 | "**/__tests__/**", 13 | "**/__mocks__/**", 14 | "**/__snapshots__/**" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | oRPC + Bun WebSocket + OpenTelemetry 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/contract/src/link-utils.test-d.ts: -------------------------------------------------------------------------------- 1 | import { RPCLink } from '@orpc/client/fetch' 2 | import { router as contract } from '../tests/shared' 3 | import { inferRPCMethodFromContractRouter } from './link-utils' 4 | 5 | it('inferRPCMethodFromContractRouter', () => { 6 | const link = new RPCLink({ 7 | url: 'http://localhost:3000/rpc', 8 | method: inferRPCMethodFromContractRouter(contract), 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /packages/client/src/error.test-d.ts: -------------------------------------------------------------------------------- 1 | import type { ORPCError } from './error' 2 | import { isDefinedError } from './error' 3 | 4 | it('isDefinedError', () => { 5 | const orpcError = {} as ORPCError<'CODE', { value: string }> | ORPCError<'BASE', { value: number }> 6 | const error = {} as Error | typeof orpcError 7 | 8 | if (isDefinedError(error)) { 9 | expectTypeOf(error).toEqualTypeOf(orpcError) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /packages/pino/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../server" }, 5 | { "path": "../client" }, 6 | { "path": "../shared" } 7 | ], 8 | "include": ["src"], 9 | "exclude": [ 10 | "**/*.test.*", 11 | "**/*.test-d.ts", 12 | "**/*.bench.*", 13 | "**/__tests__/**", 14 | "**/__mocks__/**", 15 | "**/__snapshots__/**" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/server/src/router-hidden.test.ts: -------------------------------------------------------------------------------- 1 | import { contract, router } from '../tests/shared' 2 | import { getHiddenRouterContract, setHiddenRouterContract } from './router-hidden' 3 | 4 | it('setHiddenRouterContract & getHiddenRouterContract', () => { 5 | const applied = setHiddenRouterContract(router, contract) 6 | 7 | expect(applied).toEqual(router) 8 | expect(getHiddenRouterContract(applied)).toEqual(contract) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/standard-server-fetch/playground/event-source-client.ts: -------------------------------------------------------------------------------- 1 | const eventSource = new EventSource('http://localhost:3000') 2 | 3 | eventSource.addEventListener('message', (event) => { 4 | console.log('message', event) 5 | }) 6 | 7 | eventSource.addEventListener('error', (event) => { 8 | console.log('error', event) 9 | }) 10 | 11 | eventSource.addEventListener('done', (event) => { 12 | console.log('done', event) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/zod/src/schemas/url.test.ts: -------------------------------------------------------------------------------- 1 | import { getCustomZodDef } from './base' 2 | import { url } from './url' 3 | 4 | it('url', () => { 5 | expect(url().parse(new URL('https://example.com'))).toBeInstanceOf(URL) 6 | expect(() => url().parse({})).toThrow('Input is not a URL') 7 | expect(() => url('__INVALID__').parse({})).toThrow('__INVALID__') 8 | 9 | expect(getCustomZodDef(url()._def)).toEqual({ type: 'url' }) 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/worker/dos/publisher.ts: -------------------------------------------------------------------------------- 1 | import { PublisherDurableObject } from '@orpc/experimental-publisher-durable-object' 2 | 3 | export class PublisherDO extends PublisherDurableObject { 4 | constructor(ctx: DurableObjectState, env: Env) { 5 | super(ctx, env, { 6 | resume: { 7 | retentionSeconds: 60 * 2, // Retain events for 2 minutes to support resume 8 | }, 9 | }) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/nest/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "experimentalDecorators": true, 6 | "types": ["node", "vitest/globals"] 7 | }, 8 | "references": [ 9 | { "path": "./tsconfig.json" } 10 | ], 11 | "include": [ 12 | "tests", 13 | "src/**/*.test.*", 14 | "src/**/*.test-d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | !.vscode/extensions.json 17 | .idea 18 | .DS_Store 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | 25 | # wrangler files 26 | .wrangler 27 | .dev.vars* 28 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/bun-env.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by `bun init` 2 | 3 | declare module '*.svg' { 4 | /** 5 | * A path to the SVG file 6 | */ 7 | const path: `${string}.svg` 8 | export = path 9 | } 10 | 11 | declare module '*.module.css' { 12 | /** 13 | * A record of class names to their corresponding CSS module classes 14 | */ 15 | const classes: { readonly [key: string]: string } 16 | export = classes 17 | } 18 | -------------------------------------------------------------------------------- /packages/nest/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/otel/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/trpc/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/zod/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/ai-sdk/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/arktype/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/client/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/contract/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/interop/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/openapi/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/publisher/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/ratelimit/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/react-swr/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/react/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/server/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/shared/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/valibot/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/vue-query/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/zod/src/schemas/regexp.test.ts: -------------------------------------------------------------------------------- 1 | import { getCustomZodDef } from './base' 2 | import { regexp } from './regexp' 3 | 4 | it('regexp', () => { 5 | expect(regexp().parse(/d/)).toBeInstanceOf(RegExp) 6 | expect(() => regexp().parse({})).toThrow('Input is not a regexp') 7 | expect(() => regexp(() => ({ message: '__INVALID__' })).parse({})).toThrow('__INVALID__') 8 | 9 | expect(getCustomZodDef(regexp()._def)).toEqual({ type: 'regexp' }) 10 | }) 11 | -------------------------------------------------------------------------------- /playgrounds/next/src/app/providers.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query' 4 | import { useState } from 'react' 5 | 6 | export function Providers(props: { children: React.ReactNode }) { 7 | const [queryClient] = useState(() => new QueryClient()) 8 | 9 | return ( 10 | 11 | {props.children} 12 | 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /packages/client/src/adapters/fetch/plugin.test-d.ts: -------------------------------------------------------------------------------- 1 | import type { StandardLinkPlugin } from '../standard' 2 | import type { LinkFetchPlugin } from './plugin' 3 | 4 | describe('LinkFetchPlugin', () => { 5 | it('backward compatibility', () => { 6 | expectTypeOf>().toExtend>() 7 | expectTypeOf>().toExtend>() 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/json-schema/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/openapi-client/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/react-query/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/solid-query/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/svelte-query/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/tanstack-query/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/vue-colada/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /playgrounds/nest/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | entries: [ 5 | { input: 'dist/main.js', outDir: 'dist/unbuild', name: 'main' }, 6 | ], 7 | failOnWarn: false, 8 | clean: false, 9 | rollup: { 10 | esbuild: { 11 | tsconfigRaw: { 12 | compilerOptions: { 13 | experimentalDecorators: true, 14 | }, 15 | }, 16 | }, 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /packages/durable-iterator/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/standard-server-aws-lambda/src/index.ts: -------------------------------------------------------------------------------- 1 | import type Stream from 'node:stream' 2 | 3 | export * from './body' 4 | export * from './event-iterator' 5 | export * from './headers' 6 | export * from './request' 7 | export * from './response' 8 | export * from './types' 9 | export * from './url' 10 | 11 | export { toAbortSignal, toEventStream, type ToEventStreamOptions } from '@orpc/standard-server-node' 12 | 13 | export type ResponseStream = Stream.Writable 14 | -------------------------------------------------------------------------------- /packages/standard-server/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/publisher-durable-object/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/ratelimit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../shared" }, 5 | { "path": "../client" }, 6 | { "path": "../server" }, 7 | { "path": "../standard-server" } 8 | ], 9 | "include": ["src"], 10 | "exclude": [ 11 | "**/*.bench.*", 12 | "**/*.test.*", 13 | "**/*.test-d.ts", 14 | "**/__tests__/**", 15 | "**/__mocks__/**", 16 | "**/__snapshots__/**" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/standard-server-fastify/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/standard-server-fetch/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/standard-server-node/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/standard-server-peer/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /playgrounds/astro/src/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/popup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Default Popup Title 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /playgrounds/next/src/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /packages/openapi/src/index.ts: -------------------------------------------------------------------------------- 1 | import { customOpenAPIOperation } from './openapi-custom' 2 | 3 | export * from './openapi-custom' 4 | export * from './openapi-generator' 5 | export * from './openapi-utils' 6 | export * from './router-client' 7 | export * from './schema' 8 | export * from './schema-converter' 9 | export * from './schema-utils' 10 | 11 | export type { OpenAPI } from '@orpc/contract' 12 | 13 | export const oo = { 14 | spec: customOpenAPIOperation, 15 | } 16 | -------------------------------------------------------------------------------- /packages/ratelimit/src/adapters/cloudflare-ratelimit.ts: -------------------------------------------------------------------------------- 1 | import type { Ratelimiter, RatelimiterLimitResult } from '../types' 2 | 3 | export class CloudflareRatelimiter implements Ratelimiter { 4 | constructor( 5 | private readonly ratelimit: { 6 | limit: (options: { key: string }) => Promise 7 | }, 8 | ) {} 9 | 10 | limit(key: string): Promise { 11 | return this.ratelimit.limit({ key }) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/shared/src/uri.test.ts: -------------------------------------------------------------------------------- 1 | import { tryDecodeURIComponent } from './uri' 2 | 3 | it('tryDecodeURIComponent', () => { 4 | expect(tryDecodeURIComponent('test')).toBe('test') 5 | expect(tryDecodeURIComponent('test%20value')).toBe('test value') 6 | expect(tryDecodeURIComponent('invalid%20value%')).toBe('invalid%20value%') 7 | expect(tryDecodeURIComponent('%E0%A4%A')).toBe('%E0%A4%A') // Invalid UTF-8 sequence 8 | expect(tryDecodeURIComponent('')).toBe('') 9 | }) 10 | -------------------------------------------------------------------------------- /packages/standard-server-aws-lambda/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem -------------------------------------------------------------------------------- /packages/zod/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../openapi" }, 5 | { "path": "../json-schema" }, 6 | { "path": "../contract" }, 7 | { "path": "../server" }, 8 | { "path": "../shared" } 9 | ], 10 | "include": ["src"], 11 | "exclude": [ 12 | "**/*.test.*", 13 | "**/*.test-d.ts", 14 | "**/__tests__/**", 15 | "**/__mocks__/**", 16 | "**/__snapshots__/**" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /playgrounds/nest/src/contract/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const contract = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/nuxt/server/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /packages/durable-iterator/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "experimentalDecorators": true, 6 | "types": ["node", "@cloudflare/workers-types", "vitest/globals"] 7 | }, 8 | "references": [ 9 | { "path": "./tsconfig.json" } 10 | ], 11 | "include": [ 12 | "tests", 13 | "src/**/*.test.*", 14 | "src/**/*.test-d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/json-schema/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../shared" }, 5 | { "path": "../server" }, 6 | { "path": "../openapi" }, 7 | { "path": "../contract" }, 8 | { "path": "../interop" } 9 | ], 10 | "include": ["src"], 11 | "exclude": [ 12 | "**/*.test.*", 13 | "**/*.test-d.ts", 14 | "**/__tests__/**", 15 | "**/__mocks__/**", 16 | "**/__snapshots__/**" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/openapi-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../contract" }, 6 | { "path": "../shared" }, 7 | { "path": "../standard-server" } 8 | ], 9 | "include": ["src"], 10 | "exclude": [ 11 | "**/*.test.*", 12 | "**/*.bench.*", 13 | "**/*.test-d.ts", 14 | "**/__tests__/**", 15 | "**/__mocks__/**", 16 | "**/__snapshots__/**" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/standard-server-fastify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "lib": ["ES2022"], 5 | "types": ["node"] 6 | }, 7 | "references": [ 8 | { "path": "../standard-server-node" } 9 | ], 10 | "include": ["src"], 11 | "exclude": [ 12 | "**/*.test.*", 13 | "**/*.test-d.ts", 14 | "**/*.bench.*", 15 | "**/__tests__/**", 16 | "**/__mocks__/**", 17 | "**/__snapshots__/**" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [WXT](https://wxt.dev/) 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | ## Sponsors 14 | 15 |

16 | 17 | 18 | 19 |

20 | -------------------------------------------------------------------------------- /playgrounds/electron/src/main/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/src/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /packages/publisher-durable-object/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "experimentalDecorators": true, 6 | "types": ["node", "@cloudflare/workers-types", "vitest/globals"] 7 | }, 8 | "references": [ 9 | { "path": "./tsconfig.json" } 10 | ], 11 | "include": [ 12 | "tests", 13 | "src/**/*.test.*", 14 | "src/**/*.test-d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/standard-server-aws-lambda/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "lib": ["ES2022"], 5 | "types": ["node"] 6 | }, 7 | "references": [ 8 | { "path": "../standard-server-node" } 9 | ], 10 | "include": ["src"], 11 | "exclude": [ 12 | "**/*.test.*", 13 | "**/*.test-d.ts", 14 | "**/*.bench.*", 15 | "**/__tests__/**", 16 | "**/__mocks__/**", 17 | "**/__snapshots__/**" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/tanstack-query/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './general-utils' 2 | export * from './key' 3 | export * from './procedure-utils' 4 | export * from './router-utils' 5 | export { createRouterUtils as createTanstackQueryUtils } from './router-utils' 6 | export * from './stream-query' 7 | export * from './types' 8 | export { 9 | OPERATION_CONTEXT_SYMBOL as TANSTACK_QUERY_OPERATION_CONTEXT_SYMBOL, 10 | type OperationContext as TanstackQueryOperationContext, 11 | } from './types' 12 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/src/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/contract-first/src/contract/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const contract = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/electron/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [Electron](https://www.electronjs.org). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | ## Sponsors 14 | 15 |

16 | 17 | 18 | 19 |

20 | -------------------------------------------------------------------------------- /packages/server/src/adapters/fetch/plugin.test-d.ts: -------------------------------------------------------------------------------- 1 | import type { StandardHandlerPlugin } from '../standard' 2 | import type { FetchHandlerPlugin } from './plugin' 3 | 4 | describe('FetchHandlerPlugin', () => { 5 | it('backward compatibility', () => { 6 | expectTypeOf>().toMatchTypeOf>() 7 | expectTypeOf>().toMatchTypeOf>() 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/zod/src/schemas/blob.test.ts: -------------------------------------------------------------------------------- 1 | import { getCustomZodDef } from './base' 2 | import { blob } from './blob' 3 | 4 | it('blob', () => { 5 | expect(blob().parse(new Blob([]))).toBeInstanceOf(Blob) 6 | expect(blob().parse(new File([], ''))).toBeInstanceOf(File) 7 | expect(() => blob().parse({})).toThrow('Input is not a blob') 8 | expect(() => blob('__INVALID__').parse({})).toThrow('__INVALID__') 9 | 10 | expect(getCustomZodDef(blob()._def)).toEqual({ type: 'blob' }) 11 | }) 12 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App' 4 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query' 5 | 6 | const queryClient = new QueryClient() 7 | 8 | createRoot(document.getElementById('root')!).render( 9 | 10 | 11 | 12 | 13 | , 14 | ) 15 | -------------------------------------------------------------------------------- /packages/server/src/adapters/standard/utils.test.ts: -------------------------------------------------------------------------------- 1 | import { resolveFriendlyStandardHandleOptions } from './utils' 2 | 3 | it('resolveFriendlyStandardHandleOptions', () => { 4 | expect(resolveFriendlyStandardHandleOptions({})).toEqual({ context: {} }) 5 | expect(resolveFriendlyStandardHandleOptions({ context: { a: 1 } })).toEqual({ context: { a: 1 } }) 6 | expect(resolveFriendlyStandardHandleOptions({ prefix: '/api/v1', context: { a: 1 } })).toEqual({ prefix: '/api/v1', context: { a: 1 } }) 7 | }) 8 | -------------------------------------------------------------------------------- /playgrounds/astro/src/middlewares/auth.ts: -------------------------------------------------------------------------------- 1 | import type { User } from '../schemas/user' 2 | import { ORPCError, os } from '@orpc/server' 3 | 4 | export const requiredAuthMiddleware = os 5 | .$context<{ session?: { user?: User } }>() 6 | .middleware(async ({ context, next }) => { 7 | if (!context.session || !context.session.user) { 8 | throw new ORPCError('UNAUTHORIZED') 9 | } 10 | 11 | return next({ 12 | context: { user: context.session.user }, 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /playgrounds/electron/src/renderer/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App' 4 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query' 5 | 6 | const queryClient = new QueryClient() 7 | 8 | createRoot(document.getElementById('root')!).render( 9 | 10 | 11 | 12 | 13 | , 14 | ) 15 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { tanstackStart } from '@tanstack/react-start/plugin/vite' 2 | import { defineConfig } from 'vite' 3 | import tsConfigPaths from 'vite-tsconfig-paths' 4 | import viteReact from '@vitejs/plugin-react' 5 | 6 | export default defineConfig({ 7 | server: { 8 | port: 3000, 9 | }, 10 | plugins: [ 11 | tsConfigPaths({ 12 | projects: ['./tsconfig.json'], 13 | }), 14 | tanstackStart(), 15 | viteReact(), 16 | ], 17 | }) 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.npmrc 5 | !.*.example 6 | !.vscode/ 7 | !.github/ 8 | !.vitepress/ 9 | 10 | # Common generated folders 11 | logs/ 12 | node_modules/ 13 | out/ 14 | dist/ 15 | dist-ssr/ 16 | build/ 17 | coverage/ 18 | temp/ 19 | 20 | # Common generated files 21 | *.log 22 | *.log.* 23 | *.tsbuildinfo 24 | *.vitest-temp.json 25 | vite.config.ts.timestamp-* 26 | vitest.config.ts.timestamp-* 27 | 28 | # Common manual ignore files 29 | *.local 30 | *.pem -------------------------------------------------------------------------------- /packages/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../shared" }, 5 | { "path": "../standard-server" }, 6 | { "path": "../standard-server-fetch" }, 7 | { "path": "../standard-server-peer" } 8 | ], 9 | "include": ["src"], 10 | "exclude": [ 11 | "**/*.test.*", 12 | "**/*.bench.*", 13 | "**/*.test-d.ts", 14 | "**/__tests__/**", 15 | "**/__mocks__/**", 16 | "**/__snapshots__/**" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/react-query/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouterUtils } from './router-utils' 2 | 3 | export * from './general-utils' 4 | export * from './procedure-utils' 5 | export * from './router-utils' 6 | export * from './types' 7 | 8 | export { 9 | createRouterUtils as createORPCReactQueryUtils, 10 | } 11 | 12 | export type { OperationKeyOptions as BuildKeyOptions, OperationType as KeyType } from '@orpc/tanstack-query' 13 | export { generateOperationKey as buildKey } from '@orpc/tanstack-query' 14 | -------------------------------------------------------------------------------- /packages/solid-query/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouterUtils } from './router-utils' 2 | 3 | export * from './general-utils' 4 | export * from './procedure-utils' 5 | export * from './router-utils' 6 | export * from './types' 7 | 8 | export { 9 | createRouterUtils as createORPCSolidQueryUtils, 10 | } 11 | 12 | export type { OperationKeyOptions as BuildKeyOptions, OperationType as KeyType } from '@orpc/tanstack-query' 13 | export { generateOperationKey as buildKey } from '@orpc/tanstack-query' 14 | -------------------------------------------------------------------------------- /packages/svelte-query/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouterUtils } from './router-utils' 2 | 3 | export * from './general-utils' 4 | export * from './procedure-utils' 5 | export * from './router-utils' 6 | export * from './types' 7 | 8 | export { 9 | createRouterUtils as createORPCSvelteQueryUtils, 10 | } 11 | 12 | export type { OperationKeyOptions as BuildKeyOptions, OperationType as KeyType } from '@orpc/tanstack-query' 13 | export { generateOperationKey as buildKey } from '@orpc/tanstack-query' 14 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/background/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { me, signin, signup } from './auth' 2 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 3 | import { sse } from './sse' 4 | 5 | export const router = { 6 | auth: { 7 | signup, 8 | signin, 9 | me, 10 | }, 11 | 12 | planet: { 13 | list: listPlanets, 14 | create: createPlanet, 15 | find: findPlanet, 16 | update: updatePlanet, 17 | }, 18 | 19 | sse, 20 | } 21 | -------------------------------------------------------------------------------- /packages/durable-iterator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "types": ["node", "@cloudflare/workers-types"] 5 | }, 6 | "references": [ 7 | { "path": "../client" }, 8 | { "path": "../server" }, 9 | { "path": "../shared" } 10 | ], 11 | "include": ["src"], 12 | "exclude": [ 13 | "**/*.test.*", 14 | "**/*.test-d.ts", 15 | "**/__tests__/**", 16 | "**/__mocks__/**", 17 | "**/__snapshots__/**" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/hey-api/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem 27 | 28 | ## Hey API Code gen 29 | /tests/client/ -------------------------------------------------------------------------------- /packages/pino/.gitignore: -------------------------------------------------------------------------------- 1 | # Hidden folders and files 2 | .* 3 | !.gitignore 4 | !.*.example 5 | 6 | # Common generated folders 7 | logs/ 8 | node_modules/ 9 | out/ 10 | dist/ 11 | dist-ssr/ 12 | build/ 13 | coverage/ 14 | temp/ 15 | 16 | # Common generated files 17 | *.log 18 | *.log.* 19 | *.tsbuildinfo 20 | *.vitest-temp.json 21 | vite.config.ts.timestamp-* 22 | vitest.config.ts.timestamp-* 23 | 24 | # Common manual ignore files 25 | *.local 26 | *.pem 27 | 28 | ## Hey API Code gen 29 | /tests/client/ -------------------------------------------------------------------------------- /packages/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../contract" }, 6 | { "path": "../openapi-client" }, 7 | { "path": "../server" }, 8 | { "path": "../shared" } 9 | ], 10 | "include": ["src"], 11 | "exclude": [ 12 | "**/*.test.*", 13 | "**/*.test-d.ts", 14 | "**/*.bench.*", 15 | "**/__tests__/**", 16 | "**/__mocks__/**", 17 | "**/__snapshots__/**" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/server/src/adapters/node/plugin.test-d.ts: -------------------------------------------------------------------------------- 1 | import type { StandardHandlerPlugin } from '../standard' 2 | import type { NodeHttpHandlerPlugin } from './plugin' 3 | 4 | describe('NodeHttpHandlerPlugin', () => { 5 | it('backward compatibility', () => { 6 | expectTypeOf>().toMatchTypeOf>() 7 | expectTypeOf>().toMatchTypeOf>() 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/worker/routers/message-v2.ts: -------------------------------------------------------------------------------- 1 | import { pub } from '../orpc' 2 | import * as z from 'zod' 3 | 4 | export const onMessageV2 = pub.handler(({ context, lastEventId, signal }) => { 5 | return context.messagePublisher.subscribe('some-room', { signal, lastEventId }) 6 | }) 7 | 8 | export const sendMessageV2 = pub 9 | .input(z.object({ message: z.string() })) 10 | .handler(async ({ context, input }) => { 11 | await context.messagePublisher.publish('some-room', input) 12 | }) 13 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/routes/orpc-stream.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 |

oRPC and Tanstack Query | Event Iterator example

15 |
16 | {JSON.stringify(streamed.data, null, 2)}
17 |   
18 |
-------------------------------------------------------------------------------- /packages/vue-query/tests/shared.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/vue-query' 2 | import { orpc as client, streamedOrpc as streamedClient } from '../../client/tests/shared' 3 | import { createORPCVueQueryUtils } from '../src' 4 | 5 | export const orpc = createORPCVueQueryUtils(client) 6 | export const streamedOrpc = createORPCVueQueryUtils(streamedClient) 7 | 8 | export const queryClient = new QueryClient({ 9 | defaultOptions: { 10 | queries: { 11 | retry: false, 12 | }, 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/popup/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query' 5 | 6 | const queryClient = new QueryClient() 7 | 8 | ReactDOM.createRoot(document.getElementById('root')!).render( 9 | 10 | 11 | 12 | 13 | , 14 | ) 15 | -------------------------------------------------------------------------------- /playgrounds/nuxt/app/components/orpc-stream.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | -------------------------------------------------------------------------------- /packages/react-query/tests/shared.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/react-query' 2 | import { orpc as client, streamedOrpc as streamedClient } from '../../client/tests/shared' 3 | import { createORPCReactQueryUtils } from '../src' 4 | 5 | export const orpc = createORPCReactQueryUtils(client) 6 | export const streamedOrpc = createORPCReactQueryUtils(streamedClient) 7 | 8 | export const queryClient = new QueryClient({ 9 | defaultOptions: { 10 | queries: { 11 | retry: false, 12 | }, 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /packages/solid-query/tests/shared.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/solid-query' 2 | import { orpc as client, streamedOrpc as streamedClient } from '../../client/tests/shared' 3 | import { createORPCSolidQueryUtils } from '../src' 4 | 5 | export const orpc = createORPCSolidQueryUtils(client) 6 | export const streamedOrpc = createORPCSolidQueryUtils(streamedClient) 7 | 8 | export const queryClient = new QueryClient({ 9 | defaultOptions: { 10 | queries: { 11 | retry: false, 12 | }, 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /packages/tanstack-query/tests/shared.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/react-query' 2 | import { orpc as client, streamedOrpc as streamedClient } from '../../client/tests/shared' 3 | import { createTanstackQueryUtils } from '../src' 4 | 5 | export const orpc = createTanstackQueryUtils(client) 6 | export const streamedOrpc = createTanstackQueryUtils(streamedClient) 7 | 8 | export const queryClient = new QueryClient({ 9 | defaultOptions: { 10 | queries: { 11 | retry: false, 12 | }, 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /packages/vue-query/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouterUtils } from './router-utils' 2 | 3 | export * from './general-utils' 4 | export * from './procedure-utils' 5 | export * from './router-utils' 6 | export * from './types' 7 | export * from './utils' 8 | 9 | export { 10 | createRouterUtils as createORPCVueQueryUtils, 11 | } 12 | 13 | export type { OperationKeyOptions as BuildKeyOptions, OperationType as KeyType } from '@orpc/tanstack-query' 14 | export { generateOperationKey as buildKey } from '@orpc/tanstack-query' 15 | -------------------------------------------------------------------------------- /playgrounds/contract-first/src/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { pub } from '../orpc' 2 | import { me, signin, signup } from './auth' 3 | import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet' 4 | import { sse } from './sse' 5 | 6 | export const router = pub.router({ 7 | auth: { 8 | signup, 9 | signin, 10 | me, 11 | }, 12 | 13 | planet: { 14 | list: listPlanets, 15 | create: createPlanet, 16 | find: findPlanet, 17 | update: updatePlanet, 18 | }, 19 | 20 | sse, 21 | }) 22 | -------------------------------------------------------------------------------- /playgrounds/electron/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@electron-toolkit/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "composite": true, 5 | "moduleResolution": "bundler", 6 | "types": ["electron-vite/node"], 7 | 8 | "noImplicitReturns": false, 9 | "noUnusedLocals": false, 10 | "noUnusedParameters": false, 11 | "emitDeclarationOnly": true, 12 | "outDir": "${configDir}/dist" 13 | }, 14 | "include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*"] 15 | } 16 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/src/components/orpc-stream.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import { orpc } from '~/lib/orpc' 3 | 4 | export function EventIteratorQueries() { 5 | const streamed = useQuery(orpc.sse.experimental_streamedOptions({ queryFnOptions: { maxChunks: 3 } })) 6 | 7 | return ( 8 |
9 |

oRPC and Tanstack Query | Event Iterator example

10 |
11 |         {JSON.stringify(streamed.data, null, 2)}
12 |       
13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /packages/svelte-query/tests/shared.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/svelte-query' 2 | import { orpc as client, streamedOrpc as streamedClient } from '../../client/tests/shared' 3 | import { createORPCSvelteQueryUtils } from '../src' 4 | 5 | export const orpc = createORPCSvelteQueryUtils(client) 6 | export const streamedOrpc = createORPCSvelteQueryUtils(streamedClient) 7 | 8 | export const queryClient = new QueryClient({ 9 | defaultOptions: { 10 | queries: { 11 | retry: false, 12 | }, 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/src/components/orpc-stream.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import { orpc } from '../lib/orpc' 3 | 4 | export function EventIteratorQueries() { 5 | const streamed = useQuery(orpc.sse.experimental_streamedOptions({ queryFnOptions: { maxChunks: 3 } })) 6 | 7 | return ( 8 |
9 |

oRPC and Tanstack Query | Event Iterator example

10 |
11 |         {JSON.stringify(streamed.data, null, 2)}
12 |       
13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /playgrounds/next/src/app/orpc-stream.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { orpc } from '@/lib/orpc' 4 | import { useQuery } from '@tanstack/react-query' 5 | 6 | export function EventIteratorQueries() { 7 | const streamed = useQuery(orpc.sse.experimental_streamedOptions({ queryFnOptions: { maxChunks: 3 } })) 8 | 9 | return ( 10 |
11 |

oRPC and Tanstack Query | Event Iterator example

12 |
13 |         {JSON.stringify(streamed.data, null, 2)}
14 |       
15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "jsx": "react-jsx", 5 | "lib": ["DOM", "DOM.Iterable", "ES2022"], 6 | "baseUrl": ".", 7 | "module": "ESNext", 8 | "moduleResolution": "Bundler", 9 | "paths": { 10 | "~/*": ["./src/*"] 11 | }, 12 | "resolveJsonModule": true, 13 | "strict": true, 14 | "noEmit": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "skipLibCheck": true 17 | }, 18 | "include": ["src"] 19 | } 20 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/popup/components/orpc-stream.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import { orpc } from '../lib/orpc' 3 | 4 | export function EventIteratorQueries() { 5 | const streamed = useQuery(orpc.sse.experimental_streamedOptions({ queryFnOptions: { maxChunks: 3 } })) 6 | 7 | return ( 8 |
9 |

oRPC and Tanstack Query | Event Iterator example

10 |
11 |         {JSON.stringify(streamed.data, null, 2)}
12 |       
13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /playgrounds/electron/src/renderer/src/components/orpc-stream.tsx: -------------------------------------------------------------------------------- 1 | import { orpc } from '@renderer/lib/orpc' 2 | import { useQuery } from '@tanstack/react-query' 3 | 4 | export function EventIteratorQueries() { 5 | const streamed = useQuery(orpc.sse.experimental_streamedOptions({ queryFnOptions: { maxChunks: 3 } })) 6 | 7 | return ( 8 |
9 |

oRPC and Tanstack Query | Event Iterator example

10 |
11 |         {JSON.stringify(streamed.data, null, 2)}
12 |       
13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/routes/orpc-stream.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/solid-query' 2 | import { orpc } from '~/lib/orpc' 3 | 4 | export function EventIteratorQueries() { 5 | const streamed = useQuery( 6 | () => orpc.sse.experimental_streamedOptions({ queryFnOptions: { maxChunks: 3 } }), 7 | ) 8 | 9 | return ( 10 |
11 |

oRPC and Tanstack Query | Event Iterator example

12 |
13 |         {JSON.stringify(streamed.data, null, 2)}
14 |       
15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /packages/standard-server/src/event-iterator/errors.ts: -------------------------------------------------------------------------------- 1 | export class EventEncoderError extends TypeError { } 2 | export class EventDecoderError extends TypeError { } 3 | 4 | export interface ErrorEventOptions extends ErrorOptions { 5 | message?: string 6 | data?: unknown 7 | } 8 | 9 | export class ErrorEvent extends Error { 10 | public data: unknown 11 | 12 | constructor(options?: ErrorEventOptions) { 13 | super(options?.message ?? 'An error event was received', options) 14 | 15 | this.data = options?.data 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/zod/src/zod4/converter.rest.test.ts: -------------------------------------------------------------------------------- 1 | import z from 'zod/v4' 2 | import { testSchemaConverter } from '../../tests/shared' 3 | 4 | testSchemaConverter([ 5 | { 6 | name: 'z.symbol()', 7 | schema: z.symbol(), 8 | input: [true, { not: {} }], 9 | }, 10 | { 11 | name: 'z.promise(z.string())', 12 | schema: z.promise(z.string()), 13 | input: [true, { not: {} }], 14 | }, 15 | { 16 | name: 'z.custom(() => false)', 17 | schema: z.custom(() => false), 18 | input: [true, { not: {} }], 19 | }, 20 | ]) 21 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/popup/App.tsx: -------------------------------------------------------------------------------- 1 | import { CreatePlanetMutationForm } from './components/orpc-mutation' 2 | import { ListPlanetsQuery } from './components/orpc-query' 3 | import { EventIteratorQueries } from './components/orpc-stream' 4 | 5 | export default function App() { 6 | return ( 7 |
8 |

ORPC Playground

9 |
10 | 11 |
12 | 13 |
14 | 15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /packages/standard-server-node/src/signal.ts: -------------------------------------------------------------------------------- 1 | import type Stream from 'node:stream' 2 | import { AbortError } from '@orpc/shared' 3 | 4 | export function toAbortSignal(stream: Stream.Writable): AbortSignal { 5 | const controller = new AbortController() 6 | 7 | stream.once('error', error => controller.abort(error)) 8 | 9 | stream.once('close', () => { 10 | if (!stream.writableFinished) { 11 | controller.abort(new AbortError('Writable stream closed before it finished writing')) 12 | } 13 | }) 14 | 15 | return controller.signal 16 | } 17 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/worker/orpc.ts: -------------------------------------------------------------------------------- 1 | import { os } from '@orpc/server' 2 | import { dbProviderMiddleware } from './middlewares/db' 3 | import { requiredAuthMiddleware } from './middlewares/auth' 4 | import type { Publisher } from '@orpc/experimental-publisher' 5 | 6 | type ORPCContext = { 7 | env: Env 8 | messagePublisher: Publisher> 9 | } 10 | 11 | export const pub = os 12 | .$context() 13 | .use(dbProviderMiddleware) 14 | 15 | export const authed = pub 16 | .use(requiredAuthMiddleware) 17 | -------------------------------------------------------------------------------- /playgrounds/electron/electron.vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineConfig, externalizeDepsPlugin } from 'electron-vite' 3 | import react from '@vitejs/plugin-react' 4 | 5 | export default defineConfig({ 6 | main: { 7 | plugins: [externalizeDepsPlugin()], 8 | }, 9 | preload: { 10 | plugins: [externalizeDepsPlugin()], 11 | }, 12 | renderer: { 13 | resolve: { 14 | alias: { 15 | '@renderer': resolve('src/renderer/src'), 16 | }, 17 | }, 18 | plugins: [react()], 19 | }, 20 | }) 21 | -------------------------------------------------------------------------------- /packages/server/src/config.ts: -------------------------------------------------------------------------------- 1 | export interface Config { 2 | initialInputValidationIndex: number 3 | initialOutputValidationIndex: number 4 | dedupeLeadingMiddlewares: boolean 5 | } 6 | 7 | const DEFAULT_CONFIG: Config = { 8 | initialInputValidationIndex: 0, 9 | initialOutputValidationIndex: 0, 10 | dedupeLeadingMiddlewares: true, 11 | } 12 | 13 | export function fallbackConfig(key: T, value?: Config[T]): Config[T] { 14 | if (value === undefined) { 15 | return DEFAULT_CONFIG[key] 16 | } 17 | 18 | return value 19 | } 20 | -------------------------------------------------------------------------------- /packages/shared/src/buffer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts Request/Response/Blob/File/.. to a buffer (ArrayBuffer or Uint8Array). 3 | * 4 | * Prefers the newer `.bytes` method when available as it more efficient but not widely supported yet. 5 | */ 6 | export function readAsBuffer(source: Pick): Promise { 7 | if (typeof source.bytes === 'function') { 8 | // eslint-disable-next-line ban/ban 9 | return source.bytes() 10 | } 11 | 12 | return (source as Pick).arrayBuffer() 13 | } 14 | -------------------------------------------------------------------------------- /packages/standard-server-node/src/headers.ts: -------------------------------------------------------------------------------- 1 | import type { StandardHeaders } from '@orpc/standard-server' 2 | import type { OutgoingHttpHeaders } from 'node:http' 3 | 4 | export function toNodeHttpHeaders(headers: StandardHeaders): OutgoingHttpHeaders { 5 | const nodeHttpHeaders: OutgoingHttpHeaders = {} 6 | 7 | for (const [key, value] of Object.entries(headers)) { 8 | // Node.js does not allow headers to be undefined 9 | if (value !== undefined) { 10 | nodeHttpHeaders[key] = value 11 | } 12 | } 13 | 14 | return nodeHttpHeaders 15 | } 16 | -------------------------------------------------------------------------------- /playgrounds/electron/src/renderer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Electron x oRPC 6 | 7 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /playgrounds/solid-start/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "jsx": "preserve", 5 | "jsxImportSource": "solid-js", 6 | "module": "ESNext", 7 | "moduleResolution": "bundler", 8 | "paths": { 9 | "~/*": ["./src/*"] 10 | }, 11 | "types": ["vinxi/types/client"], 12 | "allowJs": true, 13 | "strict": true, 14 | "noEmit": true, 15 | "allowSyntheticDefaultImports": true, 16 | "esModuleInterop": true, 17 | "isolatedModules": true, 18 | "skipLibCheck": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/contract/src/procedure-client.ts: -------------------------------------------------------------------------------- 1 | import type { Client, ClientContext } from '@orpc/client' 2 | import type { ErrorFromErrorMap, ErrorMap } from './error' 3 | import type { AnySchema, InferSchemaInput, InferSchemaOutput } from './schema' 4 | 5 | export type ContractProcedureClient< 6 | TClientContext extends ClientContext, 7 | TInputSchema extends AnySchema, 8 | TOutputSchema extends AnySchema, 9 | TErrorMap extends ErrorMap, 10 | > = Client, InferSchemaOutput, ErrorFromErrorMap> 11 | -------------------------------------------------------------------------------- /playgrounds/nest/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [NestJS](https://nestjs.com). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run start:dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) to see the Scalar API Client. 14 | 15 | ## Sponsors 16 | 17 |

18 | 19 | 20 | 21 |

22 | -------------------------------------------------------------------------------- /playgrounds/electron/src/renderer/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { CreatePlanetMutationForm } from './components/orpc-mutation' 2 | import { ListPlanetsQuery } from './components/orpc-query' 3 | import { EventIteratorQueries } from './components/orpc-stream' 4 | 5 | function App(): React.JSX.Element { 6 | return ( 7 |
8 |

ORPC Playground

9 |
10 | 11 |
12 | 13 |
14 | 15 |
16 | ) 17 | } 18 | 19 | export default App 20 | -------------------------------------------------------------------------------- /packages/server/src/context.ts: -------------------------------------------------------------------------------- 1 | export type Context = Record 2 | 3 | export type MergedInitialContext< 4 | TInitial extends Context, 5 | TAdditional extends Context, 6 | TCurrent extends Context, 7 | > = TInitial & Omit 8 | 9 | export type MergedCurrentContext = Omit & U 10 | 11 | export function mergeCurrentContext( 12 | context: T, 13 | other: U, 14 | ): MergedCurrentContext { 15 | return { ...context, ...other } 16 | } 17 | -------------------------------------------------------------------------------- /packages/server/src/procedure.test.ts: -------------------------------------------------------------------------------- 1 | import { isContractProcedure } from '@orpc/contract' 2 | import { ping } from '../tests/shared' 3 | import { isProcedure } from './procedure' 4 | 5 | describe('procedure', () => { 6 | it('also a contract procedure', () => { 7 | expect(ping).toSatisfy(isContractProcedure) 8 | }) 9 | }) 10 | 11 | it('isProcedure', () => { 12 | expect(ping).toSatisfy(isProcedure) 13 | expect(Object.assign({}, ping)).toSatisfy(isProcedure) 14 | 15 | expect({}).not.toSatisfy(isProcedure) 16 | expect(true).not.toSatisfy(isProcedure) 17 | }) 18 | -------------------------------------------------------------------------------- /packages/tanstack-query/src/key.ts: -------------------------------------------------------------------------------- 1 | import type { OperationKey, OperationKeyOptions, OperationType } from './types' 2 | 3 | export function generateOperationKey( 4 | path: readonly string[], 5 | state: OperationKeyOptions = {}, 6 | ): OperationKey { 7 | return [path, { 8 | ...state.input !== undefined ? { input: state.input } : {}, 9 | ...state.type !== undefined ? { type: state.type } : {}, 10 | ...state.fnOptions !== undefined ? { fnOptions: state.fnOptions } : {}, 11 | } as any] 12 | } 13 | -------------------------------------------------------------------------------- /playgrounds/astro/src/components/orpc-stream.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import { orpc } from '../lib/orpc' 3 | import { queryClient } from '../shared/query' 4 | 5 | export function EventIteratorQueries() { 6 | const streamed = useQuery(orpc.sse.experimental_streamedOptions({ queryFnOptions: { maxChunks: 3 } }), queryClient) 7 | 8 | return ( 9 |
10 |

oRPC and Tanstack Query | Event Iterator example

11 |
12 |         {JSON.stringify(streamed.data, null, 2)}
13 |       
14 |
15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /packages/openapi/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../openapi-client" }, 6 | { "path": "../contract" }, 7 | { "path": "../server" }, 8 | { "path": "../standard-server" }, 9 | { "path": "../interop" }, 10 | { "path": "../shared" } 11 | ], 12 | "include": ["src"], 13 | "exclude": [ 14 | "**/*.bench.*", 15 | "**/*.test.*", 16 | "**/*.test-d.ts", 17 | "**/__tests__/**", 18 | "**/__mocks__/**", 19 | "**/__snapshots__/**" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/publisher-durable-object/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "types": ["node", "@cloudflare/workers-types"] 5 | }, 6 | "references": [ 7 | { "path": "../client" }, 8 | { "path": "../shared" }, 9 | { "path": "../publisher" }, 10 | { "path": "../standard-server" } 11 | ], 12 | "include": ["src"], 13 | "exclude": [ 14 | "**/*.bench.*", 15 | "**/*.test.*", 16 | "**/*.test-d.ts", 17 | "**/__tests__/**", 18 | "**/__mocks__/**", 19 | "**/__snapshots__/**" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies (bun install) 2 | node_modules 3 | 4 | # output 5 | out 6 | dist 7 | *.tgz 8 | 9 | # code coverage 10 | coverage 11 | *.lcov 12 | 13 | # logs 14 | logs 15 | _.log 16 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 17 | 18 | # dotenv environment variable files 19 | .env 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | .env.local 24 | 25 | # caches 26 | .eslintcache 27 | .cache 28 | *.tsbuildinfo 29 | 30 | # IntelliJ based IDEs 31 | .idea 32 | 33 | # Finder (MacOS) folder config 34 | .DS_Store 35 | -------------------------------------------------------------------------------- /playgrounds/astro/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { CreatePlanetMutationForm } from "../components/orpc-mutation"; 3 | import { ListPlanetsQuery } from "../components/orpc-query"; 4 | import { EventIteratorQueries } from "../components/orpc-stream"; 5 | --- 6 | 7 |
8 |

ORPC Playground

9 | You can visit the 10 | Scalar API Reference 11 | page. 12 |
13 | 14 |
15 | 16 |
17 | 18 |
-------------------------------------------------------------------------------- /playgrounds/nest/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from './lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/next/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from '@/lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /packages/shared/src/id.ts: -------------------------------------------------------------------------------- 1 | export class SequentialIdGenerator { 2 | private index = BigInt(1) 3 | 4 | generate(): string { 5 | const id = this.index.toString(36) 6 | this.index++ 7 | return id 8 | } 9 | } 10 | 11 | /** 12 | * Compares two sequential IDs. 13 | * Returns: 14 | * - negative if `a` < `b` 15 | * - positive if `a` > `b` 16 | * - 0 if equal 17 | */ 18 | export function compareSequentialIds(a: string, b: string): number { 19 | if (a.length !== b.length) { 20 | return a.length - b.length 21 | } 22 | 23 | return a < b ? -1 : a > b ? 1 : 0 24 | } 25 | -------------------------------------------------------------------------------- /playgrounds/astro/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from './lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "jsx": "react-jsx", 5 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 6 | "moduleDetection": "force", 7 | "module": "ESNext", 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "types": ["node", "./worker-configuration.d.ts", "vite/client"], 12 | 13 | /* Linting */ 14 | "strict": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "skipLibCheck": true 17 | }, 18 | "include": ["src", "worker", "worker-configuration.d.ts"] 19 | } 20 | -------------------------------------------------------------------------------- /playgrounds/nuxt/server/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from '@/lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /packages/standard-server-node/src/headers.test.ts: -------------------------------------------------------------------------------- 1 | import { toNodeHttpHeaders } from './headers' 2 | 3 | describe('toNodeHttpHeaders', () => { 4 | it('filters out undefined values', () => { 5 | const headers = toNodeHttpHeaders({ 6 | 'x-custom': 'value', 7 | 'x-undefined': undefined, 8 | 'set-cookie': ['cookie1=value1', 'cookie2=value2'], 9 | }) 10 | 11 | expect(headers).toEqual({ 12 | 'x-custom': 'value', 13 | 'set-cookie': ['cookie1=value1', 'cookie2=value2'], 14 | }) 15 | expect(headers).not.toHaveProperty('x-undefined') 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/popup/lib/orpc.ts: -------------------------------------------------------------------------------- 1 | import type { router } from '../.../../../background/routers' 2 | import type { RouterClient } from '@orpc/server' 3 | import { createORPCClient } from '@orpc/client' 4 | import { RPCLink } from '@orpc/client/message-port' 5 | import { createTanstackQueryUtils } from '@orpc/tanstack-query' 6 | 7 | const port = browser.runtime.connect() 8 | 9 | const link = new RPCLink({ 10 | port, 11 | }) 12 | 13 | export const client: RouterClient = createORPCClient(link) 14 | 15 | export const orpc = createTanstackQueryUtils(client) 16 | -------------------------------------------------------------------------------- /playgrounds/contract-first/src/routers/auth.ts: -------------------------------------------------------------------------------- 1 | import { authed, pub } from '../orpc' 2 | 3 | export const signup = pub.auth.signup 4 | .handler(async ({ input, context }) => { 5 | return { 6 | id: '28aa6286-48e9-4f23-adea-3486c86acd55', 7 | email: input.email, 8 | name: input.name, 9 | } 10 | }) 11 | 12 | export const signin = pub.auth.signin 13 | .handler(async ({ input, context }) => { 14 | return { token: 'token' } 15 | }) 16 | 17 | export const me = authed.auth.me 18 | .handler(async ({ input, context }) => { 19 | return context.user 20 | }) 21 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from '~/lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from './lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from '~/lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /packages/shared/src/value.test.ts: -------------------------------------------------------------------------------- 1 | import { fallback, value } from './value' 2 | 3 | it('value', async () => { 4 | expect(value(42)).toBe(42) 5 | expect(value(() => 42)).toBe(42) 6 | expect(await value(async () => 42)).toBe(42) 7 | 8 | expect(await value(async () => ({ 9 | then: (resolve: (value: PromiseLike) => void) => resolve(Promise.resolve(42)), 10 | }))).toBe(42) 11 | 12 | expect(value(() => ({ value: '42' }))).toEqual({ value: '42' }) 13 | }) 14 | 15 | it('fallback', () => { 16 | expect(fallback(42, 0)).toBe(42) 17 | expect(fallback(undefined, 0)).toBe(0) 18 | }) 19 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from './lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/contract-first/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { orpcClient as orpc } from './lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/next/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import '../lib/orpc.server' 2 | 3 | import type { Metadata } from 'next' 4 | import { Providers } from './providers' 5 | 6 | export const metadata: Metadata = { 7 | title: 'ORPC Playground', 8 | description: 'End-to-end typesafe APIs builder, Developer-first simplicity', 9 | } 10 | 11 | export default function RootLayout({ 12 | children, 13 | }: Readonly<{ 14 | children: React.ReactNode 15 | }>) { 16 | return ( 17 | 18 | 19 | {children} 20 | 21 | 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | We take security very seriously. If you believe you have found a security vulnerability, please report it to us as described below. 6 | 7 | ### Before Reporting 8 | 9 | Please ensure you are running the latest version of the software. The vulnerability may have already been addressed in a recent update. 10 | 11 | ### How to Report 12 | 13 | To report a security vulnerability, please email us at contact@unnoq.com. 14 | 15 | We appreciate your efforts to disclose your findings responsibly. 16 | -------------------------------------------------------------------------------- /packages/contract/src/schema.test.ts: -------------------------------------------------------------------------------- 1 | import { type } from './schema' 2 | 3 | describe('type', async () => { 4 | it('without map', async () => { 5 | const schema = type() 6 | const val = {} 7 | expect((await schema['~standard'].validate(val) as any).value).toBe(val) 8 | }) 9 | 10 | it('with map', async () => { 11 | const val = {} 12 | const check = vi.fn().mockReturnValueOnce('__mapped__') 13 | const schema = type(check) 14 | expect((await schema['~standard'].validate(val) as any).value).toBe('__mapped__') 15 | expect(check).toHaveBeenCalledWith(val) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /packages/server/src/lazy.test.ts: -------------------------------------------------------------------------------- 1 | import { ping } from '../tests/shared' 2 | import { getLazyMeta, isLazy, lazy, unlazy } from './lazy' 3 | 4 | it('lazy & isLazy & getLazyMeta & unlazy ', () => { 5 | const lazied = lazy(() => Promise.resolve({ default: ping }), { prefix: '/adapt' }) 6 | expect(lazied).toSatisfy(isLazy) 7 | expect(unlazy(lazied)).resolves.toEqual({ default: ping }) 8 | expect(getLazyMeta(lazied)).toEqual({ prefix: '/adapt' }) 9 | 10 | expect({}).not.toSatisfy(isLazy) 11 | expect(true).not.toSatisfy(isLazy) 12 | expect(unlazy(123)).resolves.toEqual({ default: 123 }) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/standard-server-node/src/url.ts: -------------------------------------------------------------------------------- 1 | import type { NodeHttpRequest } from './types' 2 | import { guard } from '@orpc/shared' 3 | 4 | export function toStandardUrl(req: NodeHttpRequest): URL { 5 | const protocol = ('encrypted' in req.socket && req.socket.encrypted ? 'https:' : 'http:') 6 | 7 | // fallback for malformed host 8 | const origin = guard(() => new URL(`${protocol}//${req.headers.host ?? 'localhost'}`).origin) ?? `${protocol}//localhost` 9 | 10 | const path = req.originalUrl ?? req.url ?? '/' 11 | 12 | return new URL(`${origin}${path.startsWith('/') ? '' : '/'}${path}`) 13 | } 14 | -------------------------------------------------------------------------------- /playgrounds/electron/src/renderer/src/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from './lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/astro/src/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /playgrounds/next/src/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/popup/playground-client.ts: -------------------------------------------------------------------------------- 1 | import { client as orpc } from './lib/orpc' 2 | import { safe } from '@orpc/client' 3 | 4 | const token = await orpc.auth.signin({ 5 | email: 'john@doe.com', 6 | password: '123456', 7 | }) 8 | 9 | const [error, planet, isDefined] = await safe(orpc.planet.update({ id: 1, name: 'Earth', description: 'The planet Earth' })) 10 | 11 | if (error) { 12 | if (isDefined) { 13 | const id = error.data.id 14 | // ^ type-safe 15 | } 16 | 17 | console.log('ERROR', error) 18 | } 19 | else { 20 | console.log('PLANET', planet) 21 | } 22 | -------------------------------------------------------------------------------- /playgrounds/nuxt/server/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /packages/react-swr/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { isObject } from '@orpc/shared' 2 | 3 | export function isSubsetOf(subsetKey: unknown, fullKey: unknown): boolean { 4 | return subsetKey === fullKey 5 | ? true 6 | : typeof subsetKey !== typeof fullKey 7 | ? false 8 | : isObject(subsetKey) && isObject(fullKey) 9 | ? Object.keys(subsetKey).every(key => subsetKey[key] === undefined || isSubsetOf(subsetKey[key], fullKey[key])) 10 | : Array.isArray(subsetKey) && Array.isArray(fullKey) 11 | ? subsetKey.every((value, index) => isSubsetOf(value, fullKey[index])) 12 | : false 13 | } 14 | -------------------------------------------------------------------------------- /packages/vue-colada/tests/shared.tsx: -------------------------------------------------------------------------------- 1 | import { PiniaColada } from '@pinia/colada' 2 | import { mount as baseMount } from '@vue/test-utils' 3 | import { createPinia } from 'pinia' 4 | import { orpc as client } from '../../client/tests/shared' 5 | import { createORPCVueColadaUtils } from '../src' 6 | 7 | export const orpc = createORPCVueColadaUtils(client) 8 | 9 | export const mount: typeof baseMount = (component, options) => { 10 | return baseMount(component, { 11 | global: { 12 | plugins: [ 13 | createPinia(), 14 | PiniaColada, 15 | ], 16 | }, 17 | ...options, 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /playgrounds/electron/src/main/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/src/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /packages/shared/src/value.ts: -------------------------------------------------------------------------------- 1 | export type Value = T | ((...args: TArgs) => T) 2 | 3 | export function value( 4 | value: Value, 5 | ...args: NoInfer 6 | ): T extends Value ? U : never { 7 | if (typeof value === 'function') { 8 | return (value as any)(...args) 9 | } 10 | 11 | return value as any 12 | } 13 | 14 | /** 15 | * Returns the value if it is defined, otherwise returns the fallback 16 | */ 17 | export function fallback(value: T | undefined, fallback: T): T { 18 | return value === undefined ? fallback : value 19 | } 20 | -------------------------------------------------------------------------------- /packages/zod/src/schemas/url.ts: -------------------------------------------------------------------------------- 1 | import type { ZodType, ZodTypeDef } from 'zod/v3' 2 | import type { CustomParams } from './base' 3 | import { custom } from 'zod/v3' 4 | import { composeParams, setCustomZodDef } from './base' 5 | 6 | export function url( 7 | params?: string | CustomParams | ((input: unknown) => CustomParams), 8 | ): ZodType { 9 | const schema = custom( 10 | val => val instanceof URL, 11 | composeParams( 12 | () => 'Input is not a URL', 13 | params, 14 | ), 15 | ) 16 | 17 | setCustomZodDef(schema._def, { type: 'url' }) 18 | 19 | return schema 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/worker/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /packages/ratelimit/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface RatelimiterLimitResult { 2 | /** 3 | * Whether the request may pass(true) or exceeded the limit(false) 4 | */ 5 | success: boolean 6 | /** 7 | * Maximum number of requests allowed within a window. 8 | */ 9 | limit?: number 10 | /** 11 | * How many requests the user has left within the current window. 12 | */ 13 | remaining?: number 14 | /** 15 | * Unix timestamp in milliseconds when the limits are reset. 16 | */ 17 | reset?: number 18 | } 19 | 20 | export interface Ratelimiter { 21 | limit(key: string): Promise 22 | } 23 | -------------------------------------------------------------------------------- /packages/standard-server-node/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { IncomingMessage, ServerResponse } from 'node:http' 2 | import type { Http2ServerRequest, Http2ServerResponse } from 'node:http2' 3 | 4 | export type NodeHttpRequest = (IncomingMessage | Http2ServerRequest) & { 5 | /** 6 | * Replace `req.url` with `req.originalUrl` when `req.originalUrl` is available. 7 | * This is useful for `express.js` middleware. 8 | */ 9 | originalUrl?: string 10 | 11 | /** 12 | * Prefer parsed body if it is available. 13 | */ 14 | body?: unknown 15 | } 16 | 17 | export type NodeHttpResponse = ServerResponse | Http2ServerResponse 18 | -------------------------------------------------------------------------------- /packages/openapi-client/src/adapters/standard/utils.ts: -------------------------------------------------------------------------------- 1 | import type { HTTPPath } from '@orpc/client' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export function standardizeHTTPPath(path: HTTPPath): HTTPPath { 7 | return `/${path.replace(/\/{2,}/g, '/').replace(/^\/|\/$/g, '')}` 8 | } 9 | 10 | /** 11 | * @internal 12 | */ 13 | export function getDynamicParams(path: HTTPPath | undefined): { raw: string, name: string }[] | undefined { 14 | return path 15 | ? standardizeHTTPPath(path).match(/\/\{[^}]+\}/g)?.map(v => ({ 16 | raw: v, 17 | name: v.match(/\{\+?([^}]+)\}/)![1]!, 18 | })) 19 | : undefined 20 | } 21 | -------------------------------------------------------------------------------- /packages/openapi/src/adapters/standard/utils.test.ts: -------------------------------------------------------------------------------- 1 | import { decodeParams, toRou3Pattern } from './utils' 2 | 3 | it('toRou3Pattern', () => { 4 | expect(toRou3Pattern('/api/v1/users/{id}')).toBe('/api/v1/users/:id') 5 | expect(toRou3Pattern('/api/v1/users/{+id}')).toBe('/api/v1/users/**:id') 6 | expect(toRou3Pattern('/api/v1/users/name')).toBe('/api/v1/users/name') 7 | expect(toRou3Pattern('/api/v1/users/name{id}')).toBe('/api/v1/users/name{id}') 8 | }) 9 | 10 | it('decodeParams', () => { 11 | expect(decodeParams({ id: '1' })).toEqual({ id: '1' }) 12 | expect(decodeParams({ id: '1%2B1' })).toEqual({ id: '1+1' }) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/shared/src/buffer.test.ts: -------------------------------------------------------------------------------- 1 | import { readAsBuffer } from './buffer' 2 | 3 | it('readAsBuffer', async () => { 4 | const blob = new Blob(['test'], { type: 'text/plain' }) 5 | 6 | expect(new TextDecoder().decode(await readAsBuffer(blob))).toBe('test') 7 | expect(new TextDecoder().decode(await readAsBuffer(new Proxy(blob, { 8 | get: (target, prop) => { 9 | if (prop === 'bytes') { 10 | return undefined 11 | } 12 | return Reflect.get(target, prop) 13 | }, 14 | })))).toBe('test') 15 | 16 | expect(new TextDecoder().decode(await readAsBuffer((new Response(blob) as any)))).toBe('test') 17 | }) 18 | -------------------------------------------------------------------------------- /packages/zod/src/schemas/blob.ts: -------------------------------------------------------------------------------- 1 | import type { ZodType, ZodTypeDef } from 'zod/v3' 2 | import type { CustomParams } from './base' 3 | import { custom } from 'zod/v3' 4 | import { composeParams, setCustomZodDef } from './base' 5 | 6 | export function blob( 7 | params?: string | CustomParams | ((input: unknown) => CustomParams), 8 | ): ZodType { 9 | const schema = custom( 10 | val => val instanceof Blob, 11 | composeParams( 12 | () => 'Input is not a blob', 13 | params, 14 | ), 15 | ) 16 | 17 | setCustomZodDef(schema._def, { type: 'blob' }) 18 | 19 | return schema 20 | } 21 | -------------------------------------------------------------------------------- /packages/openapi/src/adapters/fetch/openapi-handler.test.ts: -------------------------------------------------------------------------------- 1 | import { os } from '@orpc/server' 2 | import { OpenAPIHandler } from './openapi-handler' 3 | 4 | describe('openAPIHandler', () => { 5 | it('works', async () => { 6 | const handler = new OpenAPIHandler(os.route({ method: 'GET', path: '/ping' }).handler(({ input }) => ({ output: input }))) 7 | 8 | const { response } = await handler.handle(new Request('https://example.com/api/v1/ping?input=hello'), { 9 | prefix: '/api/v1', 10 | }) 11 | 12 | await expect(response?.text()).resolves.toContain('hello') 13 | expect(response?.status).toBe(200) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /playgrounds/browser-extension/entrypoints/background/routers/sse.ts: -------------------------------------------------------------------------------- 1 | import { eventIterator, os } from '@orpc/server' 2 | import * as z from 'zod' 3 | 4 | const MAX_EVENTS = 5 5 | 6 | export const sse = os 7 | .route({ 8 | method: 'GET', 9 | path: '/sse', 10 | tags: ['SSE'], 11 | summary: 'Server-Sent Events', 12 | }) 13 | .output(eventIterator(z.object({ time: z.date() }))) 14 | .handler(async function* () { 15 | let count = 0 16 | 17 | while (count < MAX_EVENTS) { 18 | count++ 19 | yield { time: new Date() } 20 | await new Promise(resolve => setTimeout(resolve, 1000)) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /packages/server/src/adapters/standard/utils.ts: -------------------------------------------------------------------------------- 1 | import type { Context } from '../../context' 2 | import type { StandardHandleOptions } from './handler' 3 | 4 | export type FriendlyStandardHandleOptions 5 | = & Omit, 'context'> 6 | & (Record extends T ? { context?: T } : { context: T }) 7 | 8 | export function resolveFriendlyStandardHandleOptions(options: FriendlyStandardHandleOptions): StandardHandleOptions { 9 | return { 10 | ...options, 11 | context: options.context ?? {} as T, // Context only optional if all fields are optional 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/zod/src/schemas/regexp.ts: -------------------------------------------------------------------------------- 1 | import type { ZodType, ZodTypeDef } from 'zod/v3' 2 | import type { CustomParams } from './base' 3 | import { custom } from 'zod/v3' 4 | import { composeParams, setCustomZodDef } from './base' 5 | 6 | export function regexp( 7 | params?: string | CustomParams | ((input: unknown) => CustomParams), 8 | ): ZodType { 9 | const schema = custom( 10 | val => val instanceof RegExp, 11 | composeParams( 12 | () => 'Input is not a regexp', 13 | params, 14 | ), 15 | ) 16 | 17 | setCustomZodDef(schema._def, { type: 'regexp' }) 18 | 19 | return schema 20 | } 21 | -------------------------------------------------------------------------------- /playgrounds/contract-first/src/lib/orpc.ts: -------------------------------------------------------------------------------- 1 | import { createORPCClient } from '@orpc/client' 2 | import { RPCLink } from '@orpc/client/fetch' 3 | import { createTanstackQueryUtils } from '@orpc/tanstack-query' 4 | import type { ContractRouterClient } from '@orpc/contract' 5 | import type { contract } from '../contract' 6 | 7 | const rpcLink = new RPCLink({ 8 | url: 'http://localhost:3000/rpc', 9 | headers: () => ({ 10 | Authorization: 'Bearer default-token', 11 | }), 12 | }) 13 | 14 | export const orpcClient: ContractRouterClient = createORPCClient(rpcLink) 15 | 16 | export const orpc = createTanstackQueryUtils(orpcClient) 17 | -------------------------------------------------------------------------------- /playgrounds/nest/src/other/other.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller } from '@nestjs/common' 2 | import { Implement, implement } from '@orpc/nest' 3 | import { contract } from 'src/contract' 4 | 5 | const MAX_EVENTS = 5 6 | 7 | @Controller() 8 | export class OtherController { 9 | constructor() {} 10 | 11 | @Implement(contract.sse) 12 | list() { 13 | return implement(contract.sse).handler(async function* () { 14 | let count = 0 15 | 16 | while (count < MAX_EVENTS) { 17 | count++ 18 | yield { time: new Date() } 19 | await new Promise(resolve => setTimeout(resolve, 1000)) 20 | } 21 | }) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /playgrounds/nuxt/server/orpc.ts: -------------------------------------------------------------------------------- 1 | import type { z } from 'zod' 2 | import type { UserSchema } from './schemas/user' 3 | import { ORPCError, os } from '@orpc/server' 4 | import { dbProviderMiddleware } from './middlewares/db' 5 | 6 | export interface ORPCContext { 7 | user?: z.infer 8 | } 9 | 10 | export const pub = os 11 | .$context() 12 | .use(dbProviderMiddleware) 13 | 14 | export const authed = pub.use(({ context, next }) => { 15 | if (!context.user) { 16 | throw new ORPCError('UNAUTHORIZED') 17 | } 18 | 19 | return next({ 20 | context: { 21 | user: context.user, 22 | }, 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/durable-iterator/src/object.ts: -------------------------------------------------------------------------------- 1 | import type { NestedClient } from '@orpc/client' 2 | import type { AsyncIteratorClass } from '@orpc/shared' 3 | 4 | export interface DurableIteratorObjectDef { 5 | '~eventPayloadType'?: { type: T } 6 | } 7 | 8 | export interface DurableIteratorObject { 9 | '~orpc'?: DurableIteratorObjectDef 10 | } 11 | 12 | export type InferDurableIteratorObjectRPC< 13 | T extends DurableIteratorObject, 14 | > = Exclude<{ 15 | [K in keyof T]: T[K] extends ((...args: any[]) => NestedClient) 16 | ? K 17 | : never 18 | }[keyof T], keyof AsyncIteratorClass> & string 19 | -------------------------------------------------------------------------------- /packages/ratelimit/src/adapters/cloudflare-ratelimit.test.ts: -------------------------------------------------------------------------------- 1 | import { CloudflareRatelimiter } from './cloudflare-ratelimit' 2 | 3 | it('cloudflareRatelimiter', async () => { 4 | const ratelimit = { 5 | limit: vi.fn(() => Promise.resolve({ success: true })), 6 | } 7 | 8 | const ratelimiter = new CloudflareRatelimiter(ratelimit) 9 | 10 | const result = ratelimiter.limit('test-key') 11 | 12 | expect(ratelimit.limit).toHaveBeenCalledTimes(1) 13 | expect(ratelimit.limit).toHaveBeenCalledWith({ key: 'test-key' }) 14 | expect(result).toBe(ratelimit.limit.mock.results[0]!.value) 15 | 16 | expect(await result).toEqual({ success: true }) 17 | }) 18 | -------------------------------------------------------------------------------- /packages/server/src/adapters/standard/utils.test-d.ts: -------------------------------------------------------------------------------- 1 | import type { FriendlyStandardHandleOptions } from './utils' 2 | 3 | it('FriendlyStandardHandleOptions', () => { 4 | const _1: FriendlyStandardHandleOptions<{ a: string }> = { context: { a: '1' } } 5 | // @ts-expect-error - context is required 6 | const _2: FriendlyStandardHandleOptions<{ a: string }> = { } 7 | const _3: FriendlyStandardHandleOptions<{ a?: string }> = { context: { a: '1' } } 8 | const _4: FriendlyStandardHandleOptions<{ a?: string }> = { } 9 | // @ts-expect-error - context is invalid 10 | const _5: FriendlyStandardHandleOptions<{ a?: string }> = { context: { a: 1 } } 11 | }) 12 | -------------------------------------------------------------------------------- /packages/zod/src/index.ts: -------------------------------------------------------------------------------- 1 | import { customJsonSchema } from './custom-json-schema' 2 | import { blob } from './schemas/blob' 3 | import { file } from './schemas/file' 4 | import { regexp } from './schemas/regexp' 5 | import { url } from './schemas/url' 6 | 7 | export * from './coercer' 8 | export * from './converter' 9 | export * from './custom-json-schema' 10 | export * from './schemas/base' 11 | export * from './schemas/blob' 12 | export * from './schemas/file' 13 | export * from './schemas/regexp' 14 | export * from './schemas/url' 15 | 16 | export const oz = { 17 | file, 18 | blob, 19 | url, 20 | regexp, 21 | openapi: customJsonSchema, 22 | } 23 | -------------------------------------------------------------------------------- /playgrounds/astro/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [Astro](https://astro.build). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | Open [http://localhost:3000/api](http://localhost:3000/api) to see the Scalar API Client. 15 | 16 | ## Sponsors 17 | 18 |

19 | 20 | 21 | 22 |

23 | -------------------------------------------------------------------------------- /playgrounds/next/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [Next.js](https://nextjs.org). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | Open [http://localhost:3000/api](http://localhost:3000/api) to see the Scalar API Client. 15 | 16 | ## Sponsors 17 | 18 |

19 | 20 | 21 | 22 |

23 | -------------------------------------------------------------------------------- /playgrounds/nuxt/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [Nuxt.js](https://nuxt.com). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | Open [http://localhost:3000/api](http://localhost:3000/api) to see the Scalar API Client. 15 | 16 | ## Sponsors 17 | 18 |

19 | 20 | 21 | 22 |

23 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/orpc.ts: -------------------------------------------------------------------------------- 1 | import type { z } from 'zod' 2 | import type { UserSchema } from './schemas/user' 3 | import { ORPCError, os } from '@orpc/server' 4 | import { dbProviderMiddleware } from './middlewares/db' 5 | 6 | export interface ORPCContext { 7 | user?: z.infer 8 | } 9 | 10 | export const pub = os 11 | .$context() 12 | .use(dbProviderMiddleware) 13 | 14 | export const authed = pub.use(({ context, next }) => { 15 | if (!context.user) { 16 | throw new ORPCError('UNAUTHORIZED') 17 | } 18 | 19 | return next({ 20 | context: { 21 | user: context.user, 22 | }, 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/src/orpc.ts: -------------------------------------------------------------------------------- 1 | import type { z } from 'zod' 2 | import type { UserSchema } from './schemas/user' 3 | import { ORPCError, os } from '@orpc/server' 4 | import { dbProviderMiddleware } from './middlewares/db' 5 | 6 | export interface ORPCContext { 7 | user?: z.infer 8 | } 9 | 10 | export const pub = os 11 | .$context() 12 | .use(dbProviderMiddleware) 13 | 14 | export const authed = pub.use(({ context, next }) => { 15 | if (!context.user) { 16 | throw new ORPCError('UNAUTHORIZED') 17 | } 18 | 19 | return next({ 20 | context: { 21 | user: context.user, 22 | }, 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/shared/src/array.test.ts: -------------------------------------------------------------------------------- 1 | import { splitInHalf, toArray } from './array' 2 | 3 | it('toArray', () => { 4 | expect(toArray(undefined)).toEqual([]) 5 | expect(toArray(null)).toEqual([]) 6 | expect(toArray(1)).toEqual([1]) 7 | expect(toArray([1])).toEqual([1]) 8 | }) 9 | 10 | it('splitInHalf', () => { 11 | expect(splitInHalf([1, 2, 3, 4, 5])).toEqual([[1, 2, 3], [4, 5]]) 12 | expect(splitInHalf([1, 2, 3, 4])).toEqual([[1, 2], [3, 4]]) 13 | expect(splitInHalf([1, 2, 3])).toEqual([[1, 2], [3]]) 14 | expect(splitInHalf([1, 2])).toEqual([[1], [2]]) 15 | expect(splitInHalf([1])).toEqual([[1], []]) 16 | expect(splitInHalf([])).toEqual([[], []]) 17 | }) 18 | -------------------------------------------------------------------------------- /playgrounds/bun-websocket-otel/src/lib/orpc.ts: -------------------------------------------------------------------------------- 1 | import type { RouterClient } from '@orpc/server' 2 | import type { router } from '../routers' 3 | import { createORPCClient } from '@orpc/client' 4 | import { RPCLink } from '@orpc/client/websocket' 5 | import { createTanstackQueryUtils } from '@orpc/tanstack-query' 6 | 7 | declare global { 8 | var $client: RouterClient | undefined 9 | } 10 | 11 | const link = new RPCLink({ 12 | websocket: new WebSocket(`${location.origin}/ws/rpc`), 13 | }) 14 | 15 | export const client: RouterClient = globalThis.$client ?? createORPCClient(link) 16 | 17 | export const orpc = createTanstackQueryUtils(client) 18 | -------------------------------------------------------------------------------- /playgrounds/svelte-kit/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [SvelteKit](https://kit.svelte.dev/). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | Open [http://localhost:3000/api](http://localhost:3000/api) to see the Scalar API Client. 15 | 16 | ## Sponsors 17 | 18 |

19 | 20 | 21 | 22 |

23 | -------------------------------------------------------------------------------- /playgrounds/solid-start/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [Solid Start](https://start.solidjs.com/). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | Open [http://localhost:3000/api](http://localhost:3000/api) to see the Scalar API Client. 15 | 16 | ## Sponsors 17 | 18 |

19 | 20 | 21 | 22 |

23 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/entry-server.tsx: -------------------------------------------------------------------------------- 1 | // @refresh reload 2 | import { createHandler, StartServer } from '@solidjs/start/server' 3 | 4 | export default createHandler(() => ( 5 | ( 7 | 8 | 9 | 10 | 11 | 12 | {assets} 13 | 14 | 15 |
{children}
16 | {scripts} 17 | 18 | 19 | )} 20 | /> 21 | )) 22 | -------------------------------------------------------------------------------- /playgrounds/solid-start/src/routes/index.tsx: -------------------------------------------------------------------------------- 1 | import { CreatePlanetMutationForm } from './orpc-mutation' 2 | import { ListPlanetsQuery } from './orpc-query' 3 | import { EventIteratorQueries } from './orpc-stream' 4 | 5 | export default function Home() { 6 | return ( 7 |
8 |

ORPC Playground

9 |

10 | You can visit the 11 | {' '} 12 | Scalar API Reference 13 | {' '} 14 | page. 15 |

16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /packages/contract/src/schema-utils.ts: -------------------------------------------------------------------------------- 1 | import type { SchemaIssue } from './schema' 2 | import { isPropertyKey, isTypescriptObject } from '@orpc/shared' 3 | 4 | export function isSchemaIssue(issue: unknown): issue is SchemaIssue { 5 | if (!isTypescriptObject(issue) || typeof issue.message !== 'string') { 6 | return false 7 | } 8 | 9 | if (issue.path !== undefined) { 10 | if (!Array.isArray(issue.path)) { 11 | return false 12 | } 13 | 14 | if ( 15 | !issue.path.every(segment => isPropertyKey(segment) || (isTypescriptObject(segment) && isPropertyKey(segment.key))) 16 | ) { 17 | return false 18 | } 19 | } 20 | 21 | return true 22 | } 23 | -------------------------------------------------------------------------------- /packages/server/tests/advanced.test.ts: -------------------------------------------------------------------------------- 1 | import z from 'zod' 2 | import { os } from '../src' 3 | 4 | it('support disable output validation by setting initialOutputValidationIndex to NaN', async () => { 5 | // docs: apps/content/docs/openapi/advanced/disabling-output-validation.md 6 | 7 | const procedure = os.$config({ 8 | initialOutputValidationIndex: Number.NaN, 9 | }) 10 | .use(({ next }) => next()) 11 | .output(z.number()) 12 | .use(({ next }) => next()) 13 | // @ts-expect-error invalid output type 14 | .handler(() => { 15 | return 'invalid' 16 | }) 17 | .callable() 18 | 19 | await expect(procedure()).resolves.toBe('invalid') 20 | }) 21 | -------------------------------------------------------------------------------- /packages/standard-server/src/hibernation.test.ts: -------------------------------------------------------------------------------- 1 | import { HibernationEventIterator } from './hibernation' 2 | 3 | it('hibernationEventIterator', async () => { 4 | const callback = vi.fn() 5 | 6 | const iterator1 = new HibernationEventIterator(callback) 7 | await expect(iterator1.next()).rejects.toThrowError('Cannot iterate over hibernating iterator directly') 8 | const iterator2 = new HibernationEventIterator(callback) 9 | await expect(iterator2.return()).rejects.toThrowError('Cannot cleanup hibernating iterator directly') 10 | 11 | iterator1.hibernationCallback?.('12344') 12 | 13 | expect(callback).toBeCalledWith('12344') 14 | expect(callback).toBeCalledTimes(1) 15 | }) 16 | -------------------------------------------------------------------------------- /packages/contract/src/router-client.test-d.ts: -------------------------------------------------------------------------------- 1 | import type { ClientContext, NestedClient } from '@orpc/client' 2 | import type { ContractRouterClient } from './router-client' 3 | import { ping, pong } from '../tests/shared' 4 | 5 | const router = { 6 | ping, 7 | pong, 8 | nested: { 9 | ping, 10 | pong, 11 | }, 12 | } 13 | 14 | describe('ContractRouterClient', () => { 15 | it('is a NestedClient', () => { 16 | expectTypeOf>().toMatchTypeOf>() 17 | expectTypeOf>().not.toMatchTypeOf>() 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /packages/shared/src/args.test-d.ts: -------------------------------------------------------------------------------- 1 | import type { MaybeOptionalOptions } from './args' 2 | 3 | it('MaybeOptionalOptions', () => { 4 | const a = (...[options]: MaybeOptionalOptions<{ a: number }>) => { 5 | expectTypeOf(options).toEqualTypeOf<{ a: number }>() 6 | } 7 | 8 | // @ts-expect-error - options is required 9 | a() 10 | // @ts-expect-error - options is invalid 11 | a({ a: '1' }) 12 | a({ a: 1 }) 13 | 14 | const b = (...[options]: MaybeOptionalOptions<{ b?: number }>) => { 15 | expectTypeOf(options).toEqualTypeOf<{ b?: number } | undefined>() 16 | } 17 | 18 | b() 19 | // @ts-expect-error - options is invalid 20 | b({ b: '1' }) 21 | b({ b: 1 }) 22 | }) 23 | -------------------------------------------------------------------------------- /playgrounds/tanstack-start/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [Tanstack Start](https://tanstack.com/start/latest). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | Open [http://localhost:3000/api](http://localhost:3000/api) to see the Scalar API Client. 15 | 16 | ## Sponsors 17 | 18 |

19 | 20 | 21 | 22 |

23 | -------------------------------------------------------------------------------- /packages/json-schema/src/types.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-restricted-imports 2 | import type * as Draft07 from 'json-schema-typed/draft-07' 3 | // eslint-disable-next-line no-restricted-imports 4 | import type * as Draft2019 from 'json-schema-typed/draft-2019-09' 5 | // eslint-disable-next-line no-restricted-imports 6 | import type * as Draft2020 from 'json-schema-typed/draft-2020-12' 7 | 8 | export type JsonSchema 9 | = | Draft2020.JSONSchema 10 | | Draft2019.JSONSchema 11 | | Draft07.JSONSchema 12 | 13 | export enum JsonSchemaXNativeType { 14 | BigInt = 'bigint', 15 | RegExp = 'regexp', 16 | Date = 'date', 17 | Url = 'url', 18 | Set = 'set', 19 | Map = 'map', 20 | } 21 | -------------------------------------------------------------------------------- /packages/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "references": [ 4 | { "path": "../client" }, 5 | { "path": "../contract" }, 6 | { "path": "../standard-server" }, 7 | { "path": "../standard-server-fetch" }, 8 | { "path": "../standard-server-node" }, 9 | { "path": "../standard-server-aws-lambda" }, 10 | { "path": "../standard-server-peer" }, 11 | { "path": "../shared" }, 12 | { "path": "../interop" } 13 | ], 14 | "include": ["src"], 15 | "exclude": [ 16 | "**/*.test.*", 17 | "**/*.bench.*", 18 | "**/*.test-d.ts", 19 | "**/__tests__/**", 20 | "**/__mocks__/**", 21 | "**/__snapshots__/**" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /playgrounds/cloudflare-worker/README.md: -------------------------------------------------------------------------------- 1 | # ORPC Playground 2 | 3 | This is a playground for [oRPC](https://orpc.dev) and [Cloudflare Workers](https://workers.cloudflare.com). 4 | 5 | ## Getting Started 6 | 7 | First, run the development server: 8 | 9 | ```bash 10 | npm run dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | Open [http://localhost:3000/api](http://localhost:3000/api) to see the Scalar API Client. 15 | 16 | ## Sponsors 17 | 18 |

19 | 20 | 21 | 22 |

23 | --------------------------------------------------------------------------------