# tRPC Decorator

A library to simplify building [tRPC](https://github.com/trpc/trpc) routes using decorator syntax, enhancing ease of use and compatibility with Dependency Injection paradigms like [TSyringe](https://github.com/microsoft/tsyringe).

## Benefits

- Class-style declaration of [tRPC](https://github.com/trpc/trpc) routes
- Better integration with Dependency-Injection paradigms (e.g. [TSyringe](https://github.com/microsoft/tsyringe))
- Improved code organization and readability

## Installation

```bash
npm install trpc-decorator
```

## Requirements

Ensure the following configurations are set in your project:

1. Install the `reflect-metadata` package and import it in your project's root.

2. If using TypeScript 5.0 or above, update your `tsconfig.json`:
   ```json
   {
     "compilerOptions": {
       "experimentalDecorators": true,
       "emitDecoratorMetadata": true
     }
   }
   ```

## Usage

`Note: Only tRPC v10 is currently support`

### Setting up tRPC v10

```typescript
// server/trpc.ts
import { initTRPC } from '@trpc/server';
import { useDecorators } from "trpc-decorator";
import type { ContextOf } from "trpc-decorator";

const t = initTRPC.create();

export const router = t.router;
export const publicProcedure = t.procedure;
export const authProcedure = t.procedure.use(() => {
  // Implement your authentication logic here
});

export const decorators = useDecorators({
  "public": publicProcedure,
  "auth": authProcedure,
  // Add more custom procedures as needed
});

export type contextOf = ContextOf<typeof decorators>
```

### Define tRPC routes using decorators

```typescript
// server/TestRoute.ts
import { decorators } from "./trpc";
import type { contextOf } from "./trpc";
import { z } from "zod";

@decorators.route()
export class TestRoute {
    @decorators.query("public")
    sayHello(@decorators.input(z.string()) name: string) {
        return `Hello ${name}! How are you?`;
    }

    @decorators.query("auth")
    whoAmI(@decorators.context() ctx: contextOf<"auth">) {
        return `You are ${ctx.user.name}`;
    }
}
```

### Integrating routes

```typescript
// server/_app.ts
import { router } from './trpc';
import { createTrpcDecoratorRoutes } from "trpc-decorator";
import { GeneratedRouteTypes } from "./types-generated"; // generated by `npx trpc-decorator-gen`
import { TestRoute } from './TestRoute';

const routes = createTrpcDecoratorRoutes([
    new UserRoute(),
    // In case of using IoC libraries such as TSyringe:
    // container.resolve(UserRoute)
], router) as GeneratedRouteTypes;

export const appRouter = router({
  ...routes,
  // your regular routes here
  // ...
})

// Export only the type of the router to prevent importing server code on the client
export type AppRouter = typeof appRouter;
```

## Generating Types for Routes

To generate type definitions for your class-based routes, run:

```bash
npx trpc-decorator-gen
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
