Skip to content

Releases: unnoq/orpc

v0.38.0

10 Feb 13:54
Compare
Choose a tag to compare

🚨 Breaking Changes 🚨

  • The .key utility in @orpc/vue-query and @orpc/vue-colada no longer accepts refs as values, ensuring that it does not return a reactive value.
  • ClientContext in @orpc/client now behaves like the context on the server:
    • It is optional when all fields are optional.
    • It must match the Record<string, any> condition.

🌟 .call Utility 🌟

The .call utility is now available in @orpc/react-query, @orpc/vue-query, and @orpc/vue-colada. It serves as an alias for the client, allowing you to call the client directly.

const client = createORPCClient<typeof router>()
const orpc = createORPCReactQueryUtils(client)

client.ping() === orpc.ping.call()

   🚨 Breaking Changes

   🚀 Features

  • query, colada: Add .call utility for direct client call  -  by @unnoq in #138 (b42ba)
    View changes on GitHub

v0.37.0

08 Feb 14:01
Compare
Choose a tag to compare

🚨 Breaking Changes 🚨

.infiniteOptions input now accepts a function

.infiniteOptions input now requires a function, giving you more control over where the cursor is placed and improves compatibility by removing the requirement for your input to match { cursor?: any }.

const listQuery = useInfiniteQuery(
  orpc.planet.list.infiniteOptions({
    input: cursor => ({ cursor }),
    getNextPageParam: lastPage => (lastPage.at(-1)?.id ?? -1) + 1,
    initialPageParam: 0,
  }),
)

🌟 .spec Helper 🌟

The .spec helper allows you to customize OpenAPI specs based on middlewares and error handling.

Example: Adding security via middleware

import { oo } from '@orpc/openapi'

const authMid = oo.spec(
  os.middleware(({ context, path, next }, input) => {
    // Authentication logic
    return next()
  }),
  {
    security: [{ bearerAuth: [] }],
  },
)

Example: Attaching OpenAPI metadata to errors

const base = os.errors({
  UNAUTHORIZED: oo.spec({}, {
    security: [{ bearerAuth: [] }],
  }),
})

Any procedure using authMid or derived from base will automatically include the security field in the OpenAPI spec.

   🚨 Breaking Changes

  • query: Redesign pageParam input to use a function and refine internal types  -  by @unnoq in #126 (172fe)

   🚀 Features

   🏎 Performance

  • server: Use empty body for undefined RPC input/output  -  by @unnoq in #128 (854b6)
    View changes on GitHub

v0.36.1

07 Feb 06:59
Compare
Choose a tag to compare

   🐞 Bug Fixes

  • server, client: Replace Node.js-dependent modules for better compatibility  -  by @unnoq in #125 (56469)
    View changes on GitHub

v0.36.0

06 Feb 13:10
Compare
Choose a tag to compare

🚨 Breaking Changes 🚨

  • The onError, onSuccess, and similar hooks have been completely removed from all APIs. Please use the new interceptors instead.
  • The ZodCoercer has been removed. Use the new ZodAutoCoercePlugin instead.

🌟 ZodAutoCoercePlugin 🌟

The ZodAutoCoercePlugin fully replaces ZodCoercer for automatically coercing types based on your schema.

const openAPIHandler = new OpenAPIHandler(router, {
  interceptors: [
    onError((error) => {
      console.error(error)
    }),
  ],
  plugins: [
    new CORSPlugin({
      origin: 'http://localhost:3000',
    }),
    new ResponseHeadersPlugin(),
    new ZodAutoCoercePlugin(),
  ],
})

Note: Do not use ZodAutoCoercePlugin in RPCHandler as it is unnecessary and impacts performance.

   🚨 Breaking Changes

   🚀 Features

  • server: Support Timing-Allow-Origin in CORSPlugin  -  by @unnoq and Alexander Niebuhr in #124 (b825e)
    View changes on GitHub

v0.35.1

05 Feb 14:17
Compare
Choose a tag to compare

   🐞 Bug Fixes

    View changes on GitHub

v0.35.0

05 Feb 14:01
Compare
Choose a tag to compare

🚨 Breaking Changes 🚨

  • Handlers have been rewritten to use native APIs in both fetch and Node.js' HTTP server.
  • The options onStart, onSuccess, onError, and onFinish have been removed—use the new interceptors (onStart, onError, etc.) instead.
  • OpenAPIServerHandler and OpenAPIServerlessHandler has been removed now OpenAPIHandler optimized for both.

🌟 Plugins 🌟

We're introducing two plugins: CORSPlugin and ResponseHeadersPlugin.

const openAPIHandler = new OpenAPIHandler(router, {
  schemaCoercers: [new ZodCoercer()],
  interceptors: [
    onError((error) => {
      console.error(error);
    }),
  ],
  plugins: [
    new CORSPlugin({ origin: 'http://localhost:3000' }),
    new ResponseHeadersPlugin(),
  ],
});

export interface ORPCContext extends ResponseHeadersPluginContext {
  // ResponseHeadersPluginContext is injected
  user?: z.infer<typeof UserSchema>;
  db?: any;
}

const pub = os
  .$context<ORPCContext>()
  .use(({ context, next }) => {
    context.resHeaders?.set('x-custom-header', 'custom-value');
    return next();
  });

   🚨 Breaking Changes

   🚀 Features

   🐞 Bug Fixes

    View changes on GitHub

v0.34.0

03 Feb 05:11
Compare
Choose a tag to compare

   🐞 Bug Fixes

    View changes on GitHub

v0.33.0

31 Jan 13:35
Compare
Choose a tag to compare

🚨 Breaking Changes in Builder 🚨

The builder has been rewritten with breaking changes. Please review the following updates:

  • .config has been removed. Use .$route, .$meta, and .$config instead.
  • .context has been renamed to .$context.
  • .contract has been removed. Use the new implement function instead.
  • New .$route: Help you config initial route
  • New .$config: Help you config validation behavior (docs later)
  • New .meta and .$meta: Similar to .route, but for customizable metadata.
  • Builders now have a smaller bundle size.

🌟 Introducing the New Implementer 🌟

The new implement function fully replaces the old .contract. It is designed exclusively for Contract-First development, preventing accidental access to APIs that are not contract-compliant.

Example Usage

const os = implement(contract); // Fully replaces `os` export from @orpc/server

os.router({
  ping: os.ping.handler(() => 'pong'),
});

This update ensures stricter contract adherence while improving maintainability and performance.

   🚨 Breaking Changes

   🚀 Features

  • server: Reexport ValidationError from @orpc/contract  -  by @unnoq (f56d2)
    View changes on GitHub

v0.32.0

17 Jan 14:05
Compare
Choose a tag to compare

🚨 configGlobal function replaced with .config method in builders

The configGlobal function has been deprecated and replaced with the .config method for configuring default settings in builders. You can now customize the configuration more easily.

const pub = os
    .context<{user?: {id: string}}>()
    .config({ // Optional configuration to override defaults
        initialRoute: {
            method: 'DELETE', // Set the default HTTP method to DELETE
            inputStructure: 'detailed', // Set the default input structure to 'detailed'
            outputStructure: 'detailed' // Set the default output structure to 'detailed'
        }
    })

   🚀 Features

  • contract, server: Replace configGlobal fn with .config in builders  -  by @unnoq in #95 (4e274)
    View changes on GitHub

v0.31.0

16 Jan 13:29
Compare
Choose a tag to compare

🌟 1. Improved Chaining Flow

The chaining flow has been enhanced to reduce confusion and enable more flexible middleware usage.

  • You can now insert middleware between .input and .output for more granular control.
  • TypeScript will now catch invalid chaining patterns, such as calling .middleware after .use, or chaining .input after another .input. This ensures developers are guided toward the correct sequence at compile time.

🚀 2. Custom Schemas with type

The type utility allows you to create custom schemas:

export const getting = oc.input(type<{ id: string }>());

This simplifies validation and reduces bundle size, especially in scenarios where heavy validation logic is unnecessary.

   🚀 Features

  • contract:
  • server:
    • Strict .callable/.actionable cannot chainable after call  -  by @unnoq in #88 (f22c7)
    • Strict builders & allow use middleware between .input/output  -  by @unnoq in #93 (43c0c)
    View changes on GitHub