8000 feat(nest): implement contract in NestJS by unnoq · Pull Request #480 · unnoq/orpc · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(nest): implement contract in NestJS #480

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
May 10, 2025
Merged

feat(nest): implement contract in NestJS #480

merged 27 commits into from
May 10, 2025

Conversation

unnoq
Copy link
Owner
@unnoq unnoq commented May 8, 2025

This PR is heavily inspired by the NestJS integration from ts-rest.

Closes: #85

Summary by CodeRabbit

  • New Features

    • Introduced @orpc/nest for deep integration of oRPC with NestJS.
    • Added decorators and utilities to implement and bind oRPC contracts in NestJS controllers.
    • Provided a full NestJS playground with example controllers, services, contracts, and schemas for authentication, planets, and server-sent events.
    • Enabled OpenAPI specification generation and an interactive API reference UI within the NestJS playground.
  • Documentation

    • Added a comprehensive guide on implementing oRPC contracts in NestJS.
    • Updated multiple package READMEs and docs to include the new NestJS integration and playground.
    • Included NestJS in the framework integrations listing.
  • Tests

    • Added extensive unit and type-level tests covering NestJS integration, contract utilities, and error handling.
  • Chores

    • Added TypeScript, ESLint, and NestJS CLI configuration files for the new package and playground.
    • Enhanced type-checking scripts and updated ignore patterns to support new directories.

Copy link
vercel bot commented May 8, 2025
edited
Loading

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
orpc ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 10, 2025 7:20am

Copy link
coderabbitai bot commented May 8, 2025
## Walkthrough

This update introduces a comprehensive oRPC integration for the NestJS framework, centered around a new `@orpc/nest` package. It includes implementation, utility functions, and decorators for contract-based RPC in NestJS, extensive documentation, type and runtime tests, and a full-featured NestJS playground app demonstrating contract definition, controller implementation, service logic, OpenAPI generation, and client integration.

## Changes

| Files/Groups                                                                                       | Change Summary |
|--------------------------------------------------------------------------------------------------|----------------|
| `packages/nest/src/implement.ts`, `packages/nest/src/utils.ts`, `packages/nest/src/index.ts`     | Added core implementation: `@Implement` decorator, interceptor, contract path utilities, and re-exports for oRPC/NestJS integration. |
| `packages/nest/src/implement.test.ts`, `packages/nest/src/implement.test-d.ts`, `packages/nest/src/utils.test.ts`, `packages/nest/src/utils.test-d.ts` | Added runtime and type-level tests for decorator, interceptor, and utility functions. |
| `packages/nest/package.json`, `packages/nest/README.md`, `packages/nest/.gitignore`, `packages/nest/tsconfig.json`, `packages/nest/tsconfig.test.json` | Added package metadata, documentation, gitignore, and TypeScript configs for the new package. |
| `apps/content/docs/openapi/nest/implement-contract.md`, `apps/content/.vitepress/config.ts`, `apps/content/docs/playgrounds.md`, `apps/content/index.md` | Added/updated documentation and sidebar entries for NestJS integration and playground. |
| `playgrounds/nest/**`                                                                            | Introduced a full NestJS playground: controllers, services, contract definitions, schemas, OpenAPI reference, client integration, configs, and documentation. |
| `eslint.config.js`, `tsconfig.json`, `package.json`, `vitest.jsdom.ts`                           | Updated project-level configs for type-checking, linting, and testing to accommodate new package and playground. |
| `packages/*/README.md`                                                                           | Added `@orpc/nest` to the list of packages in all relevant oRPC package READMEs. |
| `playgrounds/*/README.md` (other playgrounds)                                                   | Corrected Scalar API Client URL paths in documentation. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Client
    participant NestController
    participant @Implement Decorator
    participant ORPC Procedure/Router
    participant NestInterceptor
    participant Service

    Client->>NestController: HTTP request (matches contract route)
    NestController->>@Implement Decorator: Method decorated
    @Implement Decorator->>NestInterceptor: Attach interceptor, route metadata
    NestInterceptor->>ORPC Procedure/Router: Decode, invoke handler
    ORPC Procedure/Router->>Service: (Business logic)
    Service-->>ORPC Procedure/Router: Result/Error
    ORPC Procedure/Router-->>NestInterceptor: Encoded response/error
    NestInterceptor-->>NestController: Send HTTP response
    NestController-->>Client: HTTP response

Assessment against linked issues

Objective Addressed Explanation
Add deep, type-safe oRPC integration for NestJS (#85)

Poem

In burrows deep, with code so neat,
The NestJS rabbit hops on fleet—
Contracts bound with types so tight,
Decorators gleam, tests run right.
From docs to playground, all in sync,
oRPC and Nest now link!
🐇✨


<!-- walkthrough_end -->

<!-- announcements_start -->

> [!TIP]
> <details>
> <summary>⚡️ Faster reviews with caching</summary>
> 
> - CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure `Review - Disable Cache` at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the `Data Retention` setting under your Organization Settings.
> 
> Enjoy the performance boost—your workflow just got faster.
> 
> </details>

<!-- announcements_end -->
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=unnoq/orpc&utm_con
8000
tent=480):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link
codecov bot commented May 8, 2025

Codecov Report

Attention: Patch coverage is 97.36842% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/nest/src/index.ts 0.00% 3 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copy link
pkg-pr-new bot commented May 8, 2025
More templates

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@480

@orpc/client

npm i https://pkg.pr.new/@orpc/client@480

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@480

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@480

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@480

@orpc/openapi-client

npm i https://pkg.pr.new/@orpc/openapi-client@480

@orpc/react

npm i https://pkg.pr.new/@orpc/react@480

@orpc/react-query

npm i https://pkg.pr.new/@orpc/react-query@480

@orpc/server

npm i https://pkg.pr.new/@orpc/server@480

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@480

@orpc/solid-query

npm i https://pkg.pr.new/@orpc/solid-query@480

@orpc/standard-server

npm i https://pkg.pr.new/@orpc/standard-server@480

@orpc/standard-server-fetch

npm i https://pkg.pr.new/@orpc/standard-server-fetch@480

@orpc/standard-server-node

npm i https://pkg.pr.new/@orpc/standard-server-node@480

@orpc/standard-server-peer

npm i https://pkg.pr.new/@orpc/standard-server-peer@480

@orpc/svelte-query

npm i https://pkg.pr.new/@orpc/svelte-query@480

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@480

@orpc/vue-colada

npm i https://pkg.pr.new/@orpc/vue-colada@480

@orpc/vue-query

npm i https://pkg.pr.new/@orpc/vue-query@480

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@480

commit: 17fe6a7

@unnoq unnoq marked this pull request as ready for review May 9, 2025 14:12
Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 20

🧹 Nitpick comments (34)
playgrounds/nest/.gitignore (4)

1-4: Consider adding TypeScript incremental build artifacts
It's common for projects using tsc --incremental to generate .tsbuildinfo files. Ignoring them prevents accidental commits of build metadata.

Apply this diff to include the pattern:

 /dist
 /node_modules
 /build
+*.tsbuildinfo

15-17: Add common Windows OS artifacts
You already ignore macOS .DS_Store. You may also want to ignore Windows shell files like Thumbs.db and desktop.ini to cover cross-OS development.

 # OS
 .DS_Store
+Thumbs.db
+desktop.ini

22-30: Editor swap and backup files
You ignore IDE project files, but vim/emacs swap or backup files can slip in. Consider adding patterns like *~ and *.swp.

 # IDEs and editors
 /idea
 ...
 *.sublime-workspace
+*~        # Emacs/Vim backup files
+*.swp     # Vim swap files

55-57: Ensure file ends with a single newline
A trailing newline at EOF is a small but helpful convention to prevent issues with some tools and diffs.

playgrounds/nest/src/main.ts (1)

4-8: Consider enhancing the bootstrap function with additional configurations.

The bootstrap function works correctly, but could benefit from:

  1. Error handling
  2. CORS configuration if the API will be accessed from different origins
  3. Logging to indicate when the server starts and on which port
  4. Swagger/OpenAPI documentation setup for this playground environment
async function bootstrap() {
  const app = await NestFactory.create(AppModule)
+  // Enable CORS for all origins in playground
+  app.enableCors()
+  
+  // Log when server starts
+  const port = process.env.PORT ?? 3000
-  await app.listen(process.env.PORT ?? 3000)
+  await app.listen(port)
+  console.log(`🚀 Server running on port ${port}`)
}
bootstrap().catch(err => {
  console.error('Failed to start server:', err)
  process.exit(1)
})
playgrounds/nest/src/app.module.ts (1)

9-14: Module structure looks good with proper organization of components.

The AppModule correctly registers all controllers and providers, following NestJS best practices with proper separation of concerns (auth, planet, reference, and other controllers).

For a more comprehensive playground, you might consider adding commonly used NestJS modules:

@Module({
-  imports: [],
+  imports: [
+    // ConfigModule.forRoot({ isGlobal: true }), // For environment variables
+    // TypeOrmModule.forRoot({...}), // For database integration example
+  ],
  controllers: [AuthController, PlanetController, ReferenceController, OtherController],
  providers: [PlanetService, ReferenceService],
})
export class AppModule {}
packages/nest/tsconfig.test.json (1)

1-16: Test configuration setup looks appropriate for NestJS testing.

The tsconfig.test.json file is properly configured for testing a NestJS package:

  • Extends the base configuration
  • Enables experimentalDecorators (required for NestJS)
  • Includes necessary type definitions
  • Correctly specifies test files to include

If you're using custom type definitions or assertion libraries in your tests, consider adding them to the "types" array:

"compilerOptions": {
  "experimentalDecorators": true,
-  "types": ["node", "vitest/globals"]
+  "types": ["node", "vitest/globals"/* , other types if needed */]
},
playgrounds/nest/src/schemas/auth.ts (1)

8-10: Token schema provides simple token validation.

The TokenSchema correctly validates that the token is a string. Consider adding more specific validation if your tokens follow a particular format (e.g., JWT pattern validation).

playgrounds/nest/src/other/other.controller.ts (2)

7-10: Remove unnecessary empty constructor.

The empty constructor serves no purpose and should be removed.

@Controller()
export class OtherController {
-  constructor() {}

  @Implement(contract.sse)
🧰 Tools
🪛 Biome (1.9.4)

[error] 9-9: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)


16-20: Consider making the event interval configurable.

The interval between events is hardcoded to 1000ms. For better flexibility, consider making this configurable.

const MAX_EVENTS = 5
+const EVENT_INTERVAL_MS = 1000

@Controller()
export class OtherController {
  @Implement(contract.sse)
  list() {
    return implement(contract.sse).handler(async function* () {
      let count = 0

      while (count < MAX_EVENTS) {
        count++
        yield { time: new Date() }
-        await new Promise(resolve => setTimeout(resolve, 1000))
+        await new Promise(resolve => setTimeout(resolve, EVENT_INTERVAL_MS))
      }
    })
  }
}
playgrounds/nest/src/auth/auth.controller.ts (1)

7-7: Remove unnecessary constructor

The constructor doesn't have any injected dependencies or initialization logic, making it unnecessary.

-  constructor() {}
🧰 Tools
🪛 Biome (1.9.4)

[error] 7-7: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

playgrounds/nest/src/contract/index.ts (2)

12-17: Add JSDoc comments to clarify renamed method aliases

The planet methods have been renamed from their original form (e.g., listPlanets to list). While this creates a cleaner API, it could cause confusion. Consider adding JSDoc comments to clarify the mapping.

  planet: {
+    /**
+     * Alias for listPlanets - Lists all planets with pagination
+     */
    list: listPlanets,
+    /**
+     * Alias for createPlanet - Creates a new planet
+     */
    create: createPlanet,
+    /**
+     * Alias for findPlanet - Finds a planet by ID
+     */
    find: findPlanet,
+    /**
+     * Alias for updatePlanet - Updates a planet by ID
+     */
    update: updatePlanet,
  },

1-20: Add module JSDoc documentation

Consider adding JSDoc documentation at the top of the file to explain the contract's purpose and structure. This improves code readability and helps developers understand how to use the contract.

+/**
+ * Central contract definition that consolidates all API contracts.
+ * This object serves as the single entry point for both server-side implementations
+ * and client-side consumption of the API.
+ *
+ * Contracts are organized by domain:
+ * - auth: Authentication related endpoints
+ * - planet: Planet management endpoints
+ * - sse: Server-sent events endpoints
+ */
 import { me, signin, signup } from './auth'
 import { createPlanet, findPlanet, listPlanets, updatePlanet } from './planet'
 import { sse } from './sse'
playgrounds/nest/package.json (2)

16-22: Consider using fixed versions instead of 'next' tag for oRPC dependencies.

Using the next tag for dependencies (@orpc/*) can lead to unexpected behavior as the packages may update with breaking changes. For a playground that's meant to be stable and demonstrative, consider using fixed versions.

-    "@orpc/client": "next",
-    "@orpc/contract": "next",
-    "@orpc/nest": "next",
-    "@orpc/openapi": "next",
-    "@orpc/openapi-client": "next",
-    "@orpc/react-query": "next",
-    "@orpc/zod": "next",
+    "@orpc/client": "^1.0.0", // Replace with actual version
+    "@orpc/contract": "^1.0.0", // Replace with actual version
+    "@orpc/nest": "^1.0.0", // Replace with actual version
+    "@orpc/openapi": "^1.0.0", // Replace with actual version
+    "@orpc/openapi-client": "^1.0.0", // Replace with actual version
+    "@orpc/react-query": "^1.0.0", // Replace with actual version
+    "@orpc/zod": "^1.0.0", // Replace with actual version

5-9: Consider adding a test script to the package.json.

The package.json includes scripts for preview, development, and type checking, but no script for running tests. Adding a test script would make it easier for developers to run tests for this playground.

  "scripts": {
    "preview": "nest build && tsx dist/main.js",
    "start:dev": "nest start --watch",
-   "type:check": "tsc --noEmit"
+   "type:check": "tsc --noEmit",
+   "test": "jest"
  },
playgrounds/nest/src/contract/auth.ts (1)

25-32: Consider adding authentication requirement metadata to the 'me' endpoint.

The 'me' endpoint typically requires authentication but there's no metadata indicating this requirement. Consider adding authentication metadata to make this explicit for consumers and documentation systems.

export const me = oc
  .route({
    method: 'GET',
    path: '/auth/me',
    summary: 'Get the current user',
    tags: ['Authentication'],
+   security: [{ BearerAuth: [] }], // Explicitly indicate auth requirement
  })
  .output(UserSchema)
packages/nest/src/utils.test.ts (2)

11-11: Consider adding a descriptive comment for the mixed pattern test case.

The test case for '/{id}/name{name}' is testing an edge case mixing path parameters with parameter-like segments in the path. A comment would help clarify what this test is verifying.

- expect(toNestPattern('/{id}/name{name}')).toBe('/:id/name{name}')
+ // Test that path parameters within segments are not transformed
+ expect(toNestPattern('/{id}/name{name}')).toBe('/:id/name{name}')

14-38: Consider adding tests for edge cases in path generation.

While the tests are comprehensive, consider adding tests for additional edge cases:

  1. Empty path segments
  2. Multiple levels of nesting
  3. Routes with both input and output schemas
  4. Custom path overrides at different nesting levels
it('populateContractRouterPaths', () => {
  // Existing test cases...
  
+  // Test deeper nesting levels
+  const deeplyNested = {
+    level1: {
+      level2: {
+        level3: oc.input(inputSchema),
+      }
+    }
+  }
+  
+  const populatedDeep = populateContractRouterPaths(deeplyNested)
+  expect(populatedDeep.level1.level2.level3['~orpc'].route.path).toBe('/level1/level2/level3')
+  
+  // Test with both input and output schemas
+  const bothSchemas = {
+    complete: oc.input(inputSchema).output(outputSchema)
+  }
+  
+  const populatedBoth = populateContractRouterPaths(bothSchemas)
+  expect(populatedBoth.complete['~orpc'].route.path).toBe('/complete')
+  expect(populatedBoth.complete['~orpc'].inputSchema).toBe(inputSchema)
+  expect(populatedBoth.complete['~orpc'].outputSchema).toBe(outputSchema)
})
packages/nest/src/index.ts (3)

1-2: Ensure local module exports are tested.
Static analysis indicates that exports from ./implement and ./utils are not covered by tests. Please add unit or integration tests that import these modules via the public API (@orpc/nest) and verify their exported members behave as expected.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 2-2: packages/nest/src/index.ts#L2
Added line #L2 was not covered by tests


4-4: Add test coverage for external re-exports.
The implement and ORPCError exports from @orpc/server aren’t covered by the existing test suite. Validate through tests that these symbols are accessible and function correctly when imported from @orpc/nest.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 4-4: packages/nest/src/index.ts#L4
Added line #L4 was not covered by tests


5-13: Consider adding type-level tests for re-exported types.
You’ve re-exported several types (ImplementedProcedure, Implementer, etc.). It’s worth adding a *.test-d.ts to assert that these types correctly resolve and match expectations, ensuring consumers get the intended type definitions.

playgrounds/nest/src/schemas/user.ts (2)

7-22: Well-formed NewUserSchema with OpenAPI examples.
This schema correctly defines required fields and attaches example metadata. Consider adding a description or a minLength constraint for password if you want more realistic playground validation.


24-39: UserSchema is accurate and leverages examples.
The output schema is concise and correctly decorated for OpenAPI. Optionally, you could include field descriptions or deprecation notices if necessary in the future.

packages/nest/src/implement.test-d.ts (1)

13-13: Consider creating type-safe mocks rather than using as any casts.

While using ({}) as any is acceptable in test files to focus on specific type checks, consider creating proper type-safe mock implementations to improve readability and maintainability of tests.

- return implement(contract).handler(() => ({}) as any)
+ return implement(contract).handler(() => ({ /* mock response matching outputSchema */ }))

Also applies to: 50-50, 64-64, 94-94, 102-102

playgrounds/nest/src/reference/reference.controller.ts (1)

39-42: Consider adding error handling for spec generation.

The spec() method call lacks error handling. If the reference service throws an exception, it will propagate to the client without a graceful response.

@Get('spec.json')
spec() {
-  return this.referenceService.spec()
+  try {
+    return this.referenceService.spec()
+  } catch (error) {
+    // Log the error
+    throw new InternalServerErrorException('Could not generate API specification')
+  }
}
playgrounds/nest/src/planet/planet.service.ts (1)

49-64: Create method has potential issue with image URL generation.

The create method has a potential issue with image URL generation when the image is undefined. The current implementation will set imageUrl to undefined, but it might be better to set a default image URL.

create(newPlanet: NewPlanet, creator: User = { id: '1', name: 'John Doe', email: 'john@doe.com' }): Planet {
  const id = planets.length + 1
-  const imageUrl = newPlanet.image ? `https://example.com/cdn/${newPlanet.image.name}` : undefined
+  const imageUrl = newPlanet.image 
+    ? `https://example.com/cdn/${newPlanet.image.name}` 
+    : 'https://example.com/default-planet.jpg'

  const planet: Planet = {
    creator,
    id,
    name: newPlanet.name,
    description: newPlanet.description,
    imageUrl,
  }

  planets.push(planet)

  return planet
}
playgrounds/nest/src/planet/planet.controller.ts (2)

17-28: Inconsistent error–handling approach

find() throws a raw ORPCError, while update() uses the contract-generated, type-safe errors.NOT_FOUND(...). Pick one style (preferably the type-safe helper) for consistency and stronger static guarantees.

-        throw new ORPCError('NOT_FOUND', { message: 'Planet not found' })
+        throw errors.NOT_FOUND({ data: { id: input.id } })

This also lets you remove the unused ORPCError import if it’s no longer needed.


10-35: Micro-allocation of handlers

Every request instantiates a new handler closure (implement(...).handler(...)).
Although lightweight, doing this per call is unnecessary—implement(...).handler(...) is stateless and can be evaluated once at class construction time:

private readonly listHandler = implement(contract.planet.list)
  .handler(({ input }) => this.planetService.list(input.limit, input.cursor));

@Implement(contract.planet.list)
list() { return this.listHandler; }

This avoids needless allocations inside Hot paths.

playgrounds/nest/src/schemas/planet.ts (1)

1-8: Forward type aliases rely on later declarations

Placing the type ... = z.infer<typeof Schema> aliases before the schema constants compiles, but it relies on forward value references and can confuse readers. Moving the aliases below the schema declarations improves readability without functional impact.

packages/nest/src/implement.test.ts (1)

226-246: Expecting specific error shape couples test to implementation

The test asserts an exact error message:

message: 'Malformed request. Ensure the request body is properly formatted …'

A minor copy edit in the error text will break the test. Consider asserting only the error code or using toMatchObject with partial fields to make the test less brittle.

packages/nest/src/implement.ts (1)

67-78: Metadata & descriptor cloning should preserve property attributes

Assigning a function directly (target[methodName] = async …) makes the new property enumerable and configurable by default and drops other descriptor flags (e.g., writable: false).
Better clone the original descriptor:

-      target[methodName] = async function (...args: any[]) {
+      Object.defineProperty(target, methodName, {
+        ...descriptor,
+        async value(...args: any[]) {
           const router = await descriptor.value!.apply(this, args)
           return getRouter(router, [key])
-      }
+        },
+      })
apps/content/docs/openapi/nest/implement-contract.md (3)

61-64: Grammar nit – drop the comma before “because”

“…, because …” should be “… because …” when the clause is essential.

-…not compile `node_modules`, because Fastify does not…
+…not compile `node_modules` because Fastify does not…

138-140: Same comma-before-because issue

-…Fastify platform, because Fastify does not allow…
+…Fastify platform because Fastify does not allow…
🧰 Tools
🪛 LanguageTool

[formatting] ~138-~138: If the ‘because’ clause is essential to the meaning, do not use a comma before the clause.
Context: ... not work on the NestJS Fastify platform, because Fastify does not allow wildcard (*) a...

(COMMA_BEFORE_BECAUSE)


218-219: Missing comma after introductory phrase

-Please refer to the [OpenAPILink](/docs/openapi/client/openapi-link) documentation…
+Please refer to the [OpenAPILink](/docs/openapi/client/openapi-link) documentation,…
🧰 Tools
🪛 LanguageTool

[typographical] ~218-~218: Consider adding a comma here.
Context: ...> = createORPCClient(link) ``` ::: info Please refer to the [OpenAPILink](/docs/openap...

(PLEASE_COMMA)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d7bc23 and b652589.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (69)
  • README.md (1 hunks)
  • apps/content/.vitepress/config.ts (1 hunks)
  • apps/content/docs/openapi/nest/implement-contract.md (1 hunks)
  • apps/content/docs/playgrounds.md (2 hunks)
  • apps/content/index.md (1 hunks)
  • eslint.config.js (1 hunks)
  • package.json (1 hunks)
  • packages/arktype/README.md (1 hunks)
  • packages/client/README.md (1 hunks)
  • packages/contract/README.md (1 hunks)
  • packages/nest/.gitignore (1 hunks)
  • packages/nest/README.md (1 hunks)
  • packages/nest/package.json (1 hunks)
  • packages/nest/src/implement.test-d.ts (1 hunks)
  • packages/nest/src/implement.test.ts (1 hunks)
  • packages/nest/src/implement.ts (1 hunks)
  • packages/nest/src/index.ts (1 hunks)
  • packages/nest/src/utils.test-d.ts (1 hunks)
  • packages/nest/src/utils.test.ts (1 hunks)
  • packages/nest/src/utils.ts (1 hunks)
  • packages/nest/tsconfig.json (1 hunks)
  • packages/nest/tsconfig.test.json (1 hunks)
  • packages/openapi-client/README.md (1 hunks)
  • packages/openapi/README.md (1 hunks)
  • packages/react-query/README.md (1 hunks)
  • packages/react/README.md (1 hunks)
  • packages/server/README.md (1 hunks)
  • packages/shared/README.md (1 hunks)
  • packages/solid-query/README.md (1 hunks)
  • packages/standard-server-fetch/README.md (1 hunks)
  • packages/standard-server-node/README.md (1 hunks)
  • packages/standard-server-peer/README.md (1 hunks)
  • packages/standard-server/README.md (1 hunks)
  • packages/svelte-query/README.md (1 hunks)
  • packages/valibot/README.md (1 hunks)
  • packages/vue-colada/README.md (1 hunks)
  • packages/vue-query/README.md (1 hunks)
  • packages/zod/README.md (1 hunks)
  • playgrounds/contract-first/README.md (1 hunks)
  • playgrounds/nest/.gitignore (1 hunks)
  • playgrounds/nest/README.md (1 hunks)
  • playgrounds/nest/nest-cli.json (1 hunks)
  • playgrounds/nest/package.json (1 hunks)
  • playgrounds/nest/src/app.module.ts (1 hunks)
  • playgrounds/nest/src/auth/auth.controller.ts (1 hunks)
  • playgrounds/nest/src/contract/auth.ts (1 hunks)
  • playgrounds/nest/src/contract/index.ts (1 hunks)
  • playgrounds/nest/src/contract/planet.ts (1 hunks)
  • playgrounds/nest/src/contract/sse.ts (1 hunks)
  • playgrounds/nest/src/lib/orpc.ts (1 hunks)
  • playgrounds/nest/src/main.ts (1 hunks)
  • playgrounds/nest/src/other/other.controller.ts (1 hunks)
  • playgrounds/nest/src/planet/planet.controller.ts (1 hunks)
  • playgrounds/nest/src/planet/planet.service.ts (1 hunks)
  • playgrounds/nest/src/playground-client.ts (1 hunks)
  • playgrounds/nest/src/playground-query.ts (1 hunks)
  • playgrounds/nest/src/reference/reference.controller.ts (1 hunks)
  • playgrounds/nest/src/reference/reference.service.ts (1 hunks)
  • playgrounds/nest/src/schemas/auth.ts (1 hunks)
  • playgrounds/nest/src/schemas/planet.ts (1 hunks)
  • playgrounds/nest/src/schemas/user.ts (1 hunks)
  • playgrounds/nest/tsconfig.build.json (1 hunks)
  • playgrounds/nest/tsconfig.json (1 hunks)
  • playgrounds/nextjs/README.md (1 hunks)
  • playgrounds/nuxt/README.md (1 hunks)
  • playgrounds/solid-start/README.md (1 hunks)
  • playgrounds/svelte-kit/README.md (1 hunks)
  • tsconfig.json (1 hunks)
  • vitest.jsdom.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (14)
playgrounds/nest/src/planet/planet.service.ts (1)
playgrounds/nest/src/schemas/planet.ts (3)
  • Planet (7-7)
  • NewPlanet (5-5)
  • UpdatePlanet (6-6)
packages/nest/src/utils.test.ts (3)
packages/nest/src/utils.ts (2)
  • toNestPattern (7-11)
  • populateContractRouterPaths (32-56)
packages/contract/src/builder.ts (1)
  • oc (189-198)
packages/contract/tests/shared.ts (2)
  • inputSchema (6-6)
  • outputSchema (8-8)
playgrounds/nest/src/auth/auth.controller.ts (3)
playgrounds/nest/src/other/other.controller.ts (1)
  • Controller (7-23)
playgrounds/nest/src/planet/planet.controller.ts (1)
  • Controller (6-61)
packages/nest/src/implement.ts (1)
  • Implement (31-83)
playgrounds/nest/src/playground-client.ts (1)
playgrounds/nest/src/lib/orpc.ts (1)
  • orpc (17-17)
playgrounds/nest/src/contract/sse.ts (1)
packages/contract/src/builder.ts (1)
  • oc (189-198)
packages/nest/src/utils.ts (5)
packages/openapi-client/src/adapters/standard/utils.ts (1)
  • standardizeHTTPPath (6-8)
packages/contract/src/router.ts (1)
  • AnyContractRouter (17-17)
packages/shared/src/array.ts (1)
  • toArray (1-3)
packages/contract/src/procedure.ts (1)
  • isContractProcedure (51-66)
packages/client/src/adapters/standard/utils.ts (1)
  • toHttpPath (4-6)
playgrounds/nest/src/contract/planet.ts (2)
packages/contract/src/builder.ts (1)
  • oc (189-198)
playgrounds/nest/src/schemas/planet.ts (3)
  • PlanetSchema (22-28)
  • NewPlanetSchema (9-13)
  • UpdatePlanetSchema (15-20)
playgrounds/nest/src/schemas/user.ts (1)
packages/zod/src/index.ts (1)
  • oz (16-22)
playgrounds/nest/src/contract/index.ts (1)
playgrounds/nest/src/contract/planet.ts (4)
  • listPlanets (5-18)
  • createPlanet (20-28)
  • findPlanet (30-40)
  • updatePlanet (42-56)
packages/nest/src/utils.test-d.ts (3)
packages/nest/src/utils.ts (1)
  • PopulatedContractRouterPaths (13-18)
packages/contract/src/builder.ts (1)
  • oc (189-198)
packages/contract/tests/shared.ts (3)
  • inputSchema (6-6)
  • baseErrorMap (12-17)
  • outputSchema (8-8)
playgrounds/nest/src/contract/auth.ts (3)
packages/contract/src/builder.ts (1)
  • oc (189-198)
playgrounds/nest/src/schemas/user.ts (2)
  • NewUserSchema (7-22)
  • UserSchema (24-39)
playgrounds/nest/src/schemas/auth.ts (2)
  • CredentialSchema (3-6)
  • TokenSchema (8-10)
playgrounds/nest/src/playground-query.ts (1)
playgrounds/nest/src/lib/orpc.ts (1)
  • orpc (17-17)
packages/nest/src/implement.ts (12)
packages/shared/src/index.ts (1)
  • Promisable (15-15)
packages/server/src/router.ts (1)
  • Router (12-17)
packages/contract/src/procedure.ts (1)
  • isContractProcedure (51-66)
packages/contract/src/config.ts (1)
  • fallbackContractConfig (20-26)
packages/nest/src/utils.ts (1)
  • toNestPattern (7-11)
packages/server/src/router-utils.ts (1)
  • getRouter (13-49)
packages/server/src/lazy.ts (1)
  • unlazy (42-44)
packages/server/src/procedure.ts (1)
  • isProcedure (75-87)
packages/standard-server-node/src/types.ts (2)
  • NodeHttpRequest (4-10)
  • NodeHttpResponse (12-12)
packages/standard-server/src/types.ts (1)
  • StandardResponse (34-41)
packages/client/src/error.ts (1)
  • toORPCError (139-146)
packages/standard-server-node/src/response.ts (1)
  • sendStandardResponse (8-39)
playgrounds/nest/src/schemas/planet.ts (2)
packages/zod/src/index.ts (1)
  • oz (16-22)
playgrounds/nest/src/schemas/user.ts (1)
  • UserSchema (24-39)
🪛 LanguageTool
packages/standard-server-peer/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/openapi-client/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/valibot/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/shared/README.md

[style] ~57-~57: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/arktype/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/react/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/standard-server-fetch/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/vue-query/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/contract/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/svelte-query/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/server/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/standard-server/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/standard-server-node/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/client/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/zod/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/solid-query/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/react-query/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/vue-colada/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/openapi/README.md

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/nest/README.md

[misspelling] ~33-~33: Possible spelling mistakes found.
Context: ...tack Query (React, Vue, Solid, Svelte), Pinia Colada, and more. - 🚀 Server Actions: Ful...

(EN_MULTITOKEN_SPELLING_TWO)


[style] ~51-~51: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... your API or implement API contract. - [@orpc/client](https://www.npmjs.com/package/@...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~53-~53: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...: Deeply integrate oRPC with NestJS. - [@orpc/react](https://www.npmjs.com/package/@o...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~54-~54: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...with React and React Server Actions. - [@orpc/react-query](https://www.npmjs.com/pack...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~55-~55: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...test/docs/framework/react/overview). - [@orpc/vue-query](https://www.npmjs.com/packag...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~56-~56: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...latest/docs/framework/vue/overview). - [@orpc/solid-query](https://www.npmjs.com/pack...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~57-~57: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...test/docs/framework/solid/overview). - [@orpc/svelte-query](https://www.npmjs.com/pac...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~58-~58: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...est/docs/framework/svelte/overview). - [@orpc/vue-colada](https://www.npmjs.com/packa...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[misspelling] ~58-~58: Possible spelling mistakes found.
Context: ...ge/@orpc/vue-colada): Integration with Pinia Colada. - [@or...

(EN_MULTITOKEN_SPELLING_TWO)


[style] ~59-~59: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ada](https://pinia-colada.esm.dev/). - [@orpc/openapi](https://www.npmjs.com/package/...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~60-~60: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...I specs and handle OpenAPI requests. - [@orpc/zod](https://www.npmjs.com/package/@orp...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~61-~61: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...tps://zod.dev/) doesn't support yet. - [@orpc/valibot](https://www.npmjs.com/package/...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~62-~62: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...rom Valibot. - [@orpc/arktype](https://www.npmjs.com/package/...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/content/docs/openapi/nest/implement-contract.md

[formatting] ~138-~138: If the ‘because’ clause is essential to the meaning, do not use a comma before the clause.
Context: ... not work on the NestJS Fastify platform, because Fastify does not allow wildcard (*) a...

(COMMA_BEFORE_BECAUSE)


[typographical] ~218-~218: Consider adding a comma here.
Context: ...> = createORPCClient(link) ``` ::: info Please refer to the [OpenAPILink](/docs/openap...

(PLEASE_COMMA)

🪛 Biome (1.9.4)
playgrounds/nest/src/other/other.controller.ts

[error] 9-9: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

playgrounds/nest/src/auth/auth.controller.ts

[error] 7-7: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🪛 GitHub Check: codecov/patch
packages/nest/src/index.ts

[warning] 2-2: packages/nest/src/index.ts#L2
Added line #L2 was not covered by tests


[warning] 4-4: packages/nest/src/index.ts#L4
Added line #L4 was not covered by tests

🔇 Additional comments (81)
playgrounds/nest/.gitignore (7)

6-13: Log file patterns look comprehensive
The logs, *.log, and various package manager debug patterns cover the usual cases. Good to go.


18-21: Test output directories are properly excluded
Ignoring /coverage and /.nyc_output aligns with standard coverage tooling.


31-37: VSCode folder exclusions are appropriate
The pattern excludes everything under .vscode/ except the committed workspace configs. This matches the intended behavior.


38-43: dotenv files are correctly ignored
All environment variants (.env*) are covered to avoid leaking secrets.


45-48: Temporary directories are covered
Ignoring .temp and .tmp will catch most transient build artifacts or cache directories.


49-54: Runtime data files are excluded
Patterns for PID and seed files look good and prevent leftover runtime data from polluting commits.


55-56: Diagnostic reports pattern is correct
The Node.js diagnostic report glob matches the official naming scheme.

eslint.config.js (1)

61-66: LGTM! Configuration correctly scoped for NestJS integration

The ESLint override for NestJS playground files appropriately disables rules that would conflict with typical NestJS coding patterns, particularly around process access and type imports. The changes are well-scoped and only target the new playground files.

packages/nest/.gitignore (1)

1-26: LGTM! Comprehensive and well-structured .gitignore

The .gitignore file is well-organized with appropriate patterns for a TypeScript/Node.js package. It properly excludes build artifacts, temporary files, and sensitive configuration files that shouldn't be version-controlled.

playgrounds/svelte-kit/README.md (1)

14-14: LGTM! Documentation path correction

This update correctly fixes the path for accessing the Scalar API Client, ensuring consistency with other playground environments that also use the /api endpoint.

packages/shared/README.md (1)

57-57: LGTM! Documentation properly updated

The README is correctly updated to include the new @orpc/nest package in the packages list, maintaining consistency with the documentation of other packages.

🧰 Tools
🪛 LanguageTool

[style] ~57-~57: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

playgrounds/solid-start/README.md (1)

14-14: Update Scalar API Client endpoint
The URL has been correctly updated from /scalar to /api, aligning with other playgrounds. This ensures users access the right endpoint for the Scalar API Client.

packages/server/README.md (1)

52-52: Document NestJS integration
The @orpc/nest package entry has been added to the list, reflecting the new NestJS integration. The change is clear and consistent with the monorepo’s other package READMEs.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/arktype/README.md (1)

52-52: Add @orpc/nest to package list
Including @orpc/nest here correctly updates the documentation to reflect the newly introduced NestJS integration package.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/contract/README.md (1)

52-52: Add @orpc/nest to package list
The new @orpc/nest entry aligns the @orpc/contract README with the other packages, ensuring consistent documentation of NestJS support.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/client/README.md (1)

52-52: Add @orpc/nest to package list
Adding @orpc/nest here keeps the client package’s documentation in sync with the rest of the ecosystem for NestJS integration.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

README.md (1)

52-52: Add @orpc/nest to Packages section.
The new package entry for deep integration with NestJS is correctly added under "Packages", fulfilling the PR objective.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

tsconfig.json (1)

39-41: Properly scope NestJS package compilation.
Adding "packages/nest/**" to the root exclude isolates the new @orpc/nest package into its own TypeScript project, preventing it from being compiled twice by the main config.

playgrounds/nuxt/README.md (1)

14-14: Correct Scalar API Client endpoint.
The URL path has been updated to /api to align with the actual route, matching other playgrounds.

packages/standard-server/README.md (1)

52-52: List @orpc/nest in supported packages.
Including the NestJS integration in the package listing ensures consistency across all standard-server documentation.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

playgrounds/nextjs/README.md (1)

14-14: Update Scalar API Client URL to /api.
Aligns the Next.js playground instructions with the corrected endpoint, consistent with other guides.

packages/standard-server-node/README.md (1)

52-52: ✅ Consistent addition of @orpc/nest in Packages list
The new - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest) entry is formatted correctly and aligns with the existing package entries.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/react/README.md (1)

52-52: ✅ Added @orpc/nest to the Packages section
The inserted @orpc/nest entry follows the existing list pattern and is consistent with other package READMEs.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/solid-query/README.md (1)

52-52: ✅ Inserted @orpc/nest entry in the list
The new bullet for @orpc/nest is correctly placed and matches the style of the surrounding items.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/zod/README.md (1)

52-52: ✅ Documentation update: @orpc/nest added
The new package link for @orpc/nest is properly integrated into the Packages section with consistent formatting.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/svelte-query/README.md (1)

52-52: ✅ Added @orpc/nest to the Packages list
The entry for @orpc/nest is correctly formatted and in line with the other framework integrations.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

playgrounds/contract-first/README.md (1)

14-14: Correct URL for Scalar API Client
The update aligns the playground documentation with the actual API route (/api instead of /scalar), improving accuracy and consistency.

packages/vue-query/README.md (1)

52-52: Add @orpc/nest package entry
The new bullet accurately introduces the NestJS integration for oRPC in the Vue Query package documentation, aligning with other package READMEs.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/openapi-client/README.md (1)

52-52: Include @orpc/nest in related packages
This entry keeps the package list consistent by adding the NestJS integration to the OpenAPI Client docs.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/valibot/README.md (1)

52-52: Announce NestJS integration
The @orpc/nest package is now included in the Valibot README, maintaining uniform documentation across all integrations.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/content/index.md (1)

33-33: Update Framework Integrations section
Adding "NestJS" to the integrations list ensures the homepage reflects the new NestJS support. Please verify that the VitePress sidebar config (apps/content/.vitepress/config.ts) also includes the NestJS section.

packages/standard-server-peer/README.md (1)

52-52: Approve: Add @orpc/nest package entry
The new bullet for @orpc/nest correctly extends the related packages list with the NestJS integration, preserving alphabetical order.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/standard-server-fetch/README.md (1)

52-52: Approve: Add @orpc/nest package entry
The newly added @orpc/nest bullet integrates the NestJS support into the package list, matching the formatting and ordering of existing entries.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/vue-colada/README.md (1)

52-52: Approve: Add @orpc/nest package entry
This update introduces the NestJS integration reference alongside other oRPC packages, maintaining consistency in the list.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/openapi/README.md (1)

52-52: Approve: Add @orpc/nest package entry
The new entry for @orpc/nest aligns with the pattern of framework integrations and follows the existing list’s style and order.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

packages/react-query/README.md (1)

52-52: Approve: Add @orpc/nest package entry
Adding the @orpc/nest bullet enriches the list of supported integrations and keeps the alphabetical structure intact.

🧰 Tools
🪛 LanguageTool

[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence 10000 or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

vitest.jsdom.ts (1)

1-1: Appropriate dependency update for NestJS integration testing

The change from @testing-library/jest-dom to @testing-library/dom aligns with the NestJS integration requirements and provides more general DOM testing utilities instead of Jest-specific matchers.

apps/content/docs/playgrounds.md (2)

20-20: Well-integrated NestJS playground documentation

The NestJS playground entry follows the established format and provides consistent links to both StackBlitz and GitHub source repositories.


36-36: Complete local development instructions

The degit command for cloning the NestJS playground locally is correctly added, maintaining consistency with the other playground examples.

playgrounds/nest/tsconfig.build.json (1)

1-4: Standard NestJS build configuration

This TypeScript build configuration properly extends the base configuration and excludes appropriate directories and test files, following NestJS project conventions.

playgrounds/nest/README.md (3)

1-4: Clear playground introduction

The README provides a concise introduction to the playground, clearly identifying it as an integration between oRPC and NestJS with appropriate links to both projects.


5-14: Complete getting started instructions

The instructions for running the development server and accessing the Scalar API Client are clear and sufficient for users to begin using the playground.


15-21: Consistent sponsors section

The sponsors section maintains the same format found in other oRPC documentation, using a centered image from the JSDelivr CDN.

apps/content/.vitepress/config.ts (1)

203-209: Looks good! Documentation properly organized.

The addition of the NestJS section to the sidebar follows the existing documentation structure and is properly placed under the OpenAPI section, making it easy for users to discover the new NestJS integration.

playgrounds/nest/nest-cli.json (1)

1-9: Standard NestJS configuration properly implemented.

The NestJS CLI configuration follows best practices with appropriate settings for schema validation, source root, and build options. Using webpack as the builder is a good choice for the playground environment.

playgrounds/nest/src/contract/sse.ts (1)

1-11: Well-designed SSE contract with proper typing.

The SSE contract is well-implemented with appropriate method (GET), tagging, and proper type definitions using the event iterator pattern. The zod schema ensures type safety for the event payload.

package.json (1)

12-12: Enhanced type checking to include test files is a good practice.

Adding pnpm run -r type:check:test to the type checking process ensures that test files are also type-checked, which helps maintain type safety across both implementation and test code. This is especially valuable for the new NestJS integration.

playgrounds/nest/src/playground-client.ts (1)

9-9:

❓ Verification inconclusive

Use the authentication token for subsequent API calls.

The token from authentication isn't being used in the planet update request. Typically, you would include this token in the headers for authenticated requests.


🏁 Script executed:

#!/bin/bash
# Check if the orpc client automatically uses tokens or if manual configuration is needed

# First, search for the client setup
rg -A 10 "export const client" --glob "*.ts" ./playgrounds/nest/src/

Length of output: 331


Could you share how the link passed into createORPCClient(link) is configured? I’d like to confirm whether it automatically attaches the auth token or if we need to inject it manually (e.g. via headers in a custom fetch/link).

playgrounds/nest/src/schemas/auth.ts (1)

3-6: Credential schema implements standard authentication validation.

The CredentialSchema correctly validates email format and ensures the password is a string. This follows good security practices by validating inputs at the schema level.

playgrounds/nest/src/other/other.controller.ts (1)

11-22: Server-Sent Events implementation looks good.

The SSE implementation correctly uses the @Implement decorator with implement().handler() pattern to create a server-sent events endpoint. The async generator function properly yields events with timestamps at regular intervals.

playgrounds/nest/src/lib/orpc.ts (2)

8-13: Hard-coded URL and authorization token in OpenAPILink.

The URL is hard-coded to http://localhost:3000 and the authorization token is set to a static value. For a playground this is fine, but for production code these values should be configurable.

In a production environment, consider replacing these with environment variables or configuration parameters:

const link = new OpenAPILink(contract, {
-  url: new URL('/', 'http://localhost:3000'),
+  url: new URL('/', process.env.API_BASE_URL || 'http://localhost:3000'),
  headers: () => ({
-    Authorization: 'Bearer default-token',
+    Authorization: `Bearer ${getAuthToken()}`,
  }),
})

+function getAuthToken() {
+  // Get token from secure storage or context
+  return process.env.AUTH_TOKEN || 'default-token';
+}

15-17: Client and React Query utility exports look good.

The client is properly typed using JsonifiedClient<ContractRouterClient<typeof contract>> and the React Query utilities are correctly created from the client.

packages/nest/src/utils.test-d.ts (2)

7-25: Type-level tests for PopulatedContractRouterPaths look correct.

The test verifies that PopulatedContractRouterPaths properly preserves the type structure of contract routers. The test is well-structured, using expectTypeOf from Vitest to assert type equality.


17-24: Complex type assertion with nested generics.

The type assertion correctly verifies that PopulatedContractRouterPaths preserves the structure of a ContractProcedure with its input schema, output schema, error map, and metadata. This is a good practice to ensure type safety.

packages/nest/tsconfig.json (1)

1-20: Configuration looks appropriate for a NestJS integration package

The TypeScript configuration correctly enables experimental decorators (required for NestJS) and sets up project references to dependencies. The include/exclude patterns are appropriate for a library package.

playgrounds/nest/src/contract/auth.ts (2)

5-14: Well-structured authentication route with comprehensive metadata.

The signup route is properly defined with clear HTTP method, path, summary, and appropriate tags. The input and output schemas provide strong typing and validation.


15-24: The signin endpoint uses appropriate schemas for authentication flow.

The signin route appropriately accepts credentials and returns a token using well-defined schemas. This follows security best practices by clearly defining the input validation requirements.

packages/nest/src/utils.test.ts (2)

5-12: Well-structured tests for the toNestPattern utility function.

The tests thoroughly verify that the toNestPattern function correctly converts oRPC path patterns to NestJS-compatible patterns, including path parameters and wildcards.


14-38: Comprehensive tests for the populateContractRouterPaths utility.

These tests effectively verify that the populateContractRouterPaths function correctly handles:

  1. Preserving explicitly defined paths
  2. Auto-generating paths for routes without explicit paths
  3. Preserving input and output schemas
  4. Processing nested routes correctly

This ensures the utility functions will work correctly in the NestJS integration.

playgrounds/nest/src/schemas/user.ts (1)

1-5: Schemas imports and type exports are correctly defined.
The oz and z imports along with NewUser/User type inferences are properly set up for OpenAPI metadata and Zod validation.

playgrounds/nest/tsconfig.json (5)

3-6: Compiler target and libs are appropriate.
Using ES2022 with the corresponding library is consistent with the NestJS playground requirements.


6-8: Decorator metadata settings look good.
emitDecoratorMetadata and experimentalDecorators are correctly enabled for NestJS.


9-11: Module resolution configuration is valid.
module: "ES2022" and moduleResolution: "bundler" align with the playground’s ESM setup, and including node types is correct.


12-16: Review relaxed strictness settings.
You have disabled strictBindCallApply, noFallthroughCasesInSwitch, and noImplicitAny. Please confirm that these relaxations are intentional for the playground (e.g., for rapid prototyping) and won’t mask type errors in example code.


17-24: Output and declaration settings are solid.
Generating declarations, source maps, and cleaning comments for the dist directory supports a clear playground build.

packages/nest/package.json (5)

4-4: Verify the initial version placeholder.
The version is currently set to "0.0.0". Ensure you bump this to an actual release version (e.g., 0.1.0) before publishing.


31-36: Build and type-check scripts are configured.
The build, build:watch, and type:check scripts look good for development and CI.


37-44: Peer dependencies appropriately defined.
Requiring NestJS v11+, Express/Fastify optional, and RxJS is correct for this integration.


53-61: Runtime dependencies are accurate.
Listing the necessary @orpc/* packages ensures your package can operate at runtime.


62-75: Development dependencies cover testing and schema validation.
Including @nestjs/testing, supertest, and zod is appropriate for your test suites.

packages/nest/src/implement.test-d.ts (3)

1-4: Imports look complete and appropriate.

The imports correctly bring in necessary dependencies from @orpc/contract, @orpc/server, and the local testing schemas. The Implement decorator is correctly imported for testing.


6-39: Well-structured type tests for single procedure implementations.

This test suite thoroughly validates the @Implement decorator's type behavior for single procedures, covering both valid usage patterns and correctly catching invalid implementations. The test cases check:

  • Basic implementation
  • Middleware context usage
  • Invalid return types
  • Prohibited initial context
  • Contract mismatch

Using @ts-expect-error annotations appropriately ensures type errors are caught during compilation.


41-106: Comprehensive type tests for router object implementations.

This test suite effectively validates the @Implement decorator's behavior with router objects, covering essential scenarios including:

  • Basic router implementation
  • Middleware context in routers
  • Lazy loading with the lazy() function
  • Error cases for invalid returns
  • Prohibited initial context (both direct and lazy-loaded)
  • Contract mismatches (both direct and lazy-loaded)

The test cases ensure type safety at the compile time, which is crucial for the correctness of the integration.

playgrounds/nest/src/reference/reference.controller.ts (2)

1-7: Controller setup looks correct.

The controller is properly configured with the necessary imports and decorators. The dependency injection of ReferenceService follows NestJS best practices.


8-37: Security concern with hardcoded authentication token.

The API reference viewer is configured with a hardcoded bearer token (default-token). While this may be acceptable for a playground, it would be a security risk in production.

For a playground environment, consider:

  1. Making the token configurable through environment variables
  2. Adding a comment clarifying this is for demonstration purposes only
  3. Implementing a more secure authentication method
data-configuration="${JSON.stringify({
  authentication: {
    preferredSecurityScheme: 'bearerAuth',
    http: {
-     bearer: { token: 'default-token' },
+     bearer: { token: process.env.API_REFERENCE_TOKEN || 'default-token' },
    },
  },
-}).replaceAll('"', '&quot;')}">
+// Note: This token is for demonstration purposes only
+}).replaceAll('"', '&quot;')}">
playgrounds/nest/src/planet/planet.service.ts (2)

1-38: In-memory storage implementation is appropriate for a playground.

The planet data array provides a good example structure with realistic sample data. Each planet includes all required properties according to the schema, which is helpful for demonstration purposes.


40-48: List and find methods implemented correctly.

The list method properly implements pagination with cursor and limit parameters. The find method correctly looks up planets by ID, returning undefined when not found.

playgrounds/nest/src/contract/planet.ts (4)

1-4: Imports are appropriate and well-organized.

The imports bring in necessary dependencies for schema validation and contract definition. Using the oc object from @orpc/contract follows the library's recommended pattern.


5-18: List planets endpoint is well-defined with pagination.

The contract for listing planets correctly:

  • Uses the GET method with an appropriate path
  • Provides meaningful summary and tags for documentation
  • Defines input schema with sensible pagination defaults
  • Specifies the output as an array of planets

This follows RESTful API design practices.


20-28: Create planet endpoint is properly defined.

The contract for creating a planet correctly:

  • Uses the POST method with an appropriate path
  • Provides meaningful summary and tags for documentation
  • Uses the predefined NewPlanetSchema for input validation
  • Returns the created planet with the full PlanetSchema

This follows RESTful API design practices.


42-56: Update planet endpoint correctly includes error handling.

The contract for updating a planet:

  • Uses the PUT method with an appropriate path
  • Provides meaningful summary and tags for documentation
  • Properly defines a NOT_FOUND error with structured error data
  • Uses the predefined schema for input validation
  • Returns the updated planet with the full schema

This follows best practices for robust API contract definition.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
playgrounds/nest/README.md (2)

18-20: Add alt text to the sponsors image for accessibility

The sponsors image is missing alt text, which is important for screen readers and accessibility compliance.

  <a href="https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg">
-    <img src='https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg'/>
+    <img src='https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg' alt="ORPC Sponsors"/>
  </a>
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

19-19: Images should have alternate text (alt text)
null

(MD045, no-alt-text)


5-13: Consider adding more detailed playground instructions

The getting started section is minimal. Consider adding more information about what features the playground demonstrates and how to interact with it beyond just opening the Scalar API Client.

You could include:

  1. Brief explanation of what APIs are demonstrated
  2. How to use the Scalar client to interact with them
  3. Where to find the relevant code files for learning
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b652589 and 4477631.

📒 Files selected for processing (2)
  • packages/nest/src/implement.ts (1 hunks)
  • playgrounds/nest/README.md (1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
playgrounds/nest/README.md

19-19: Images should have alternate text (alt text)
null

(MD045, no-alt-text)

🔇 Additional comments (3)
packages/nest/src/implement.ts (3)

31-88: Great implementation of the Implement decorator

The decorator intelligently handles both individual procedures and nested routers, correctly applying NestJS method decorators and interceptors. The error message for missing paths is clear and actionable, suggesting the populateContractRouterPaths utility as a solution.


97-151: Well-structured error handling in the interceptor

The ImplementInterceptor provides robust error handling by differentiating between decoding errors (resulting in BAD_REQUEST status) and other ORPC errors. It also gracefully handles both Express and Fastify HTTP adapters.


153-166: Good utility for flattening parameters

The flattenParams function correctly handles both regular string parameters and array parameters, joining array values with forward slashes as expected for path parameters.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
apps/content/docs/openapi/nest/implement-contract.md (2)

132-140: Informative path parameters section with platform-specific limitation warning.

The explanation about path parameter limitations on NestJS Fastify platform is valuable for developers using that combination.

There's a minor grammar issue with the comma before "because". While not incorrect, you could consider removing it for cleaner style:

- Path Parameter matching with slashes (/) does not work on the NestJS Fastify platform, because Fastify does not allow wildcard (`*`) aliasing in path parameters.
+ Path Parameter matching with slashes (/) does not work on the NestJS Fastify platform because Fastify does not allow wildcard (`*`) aliasing in path parameters.
🧰 Tools
🪛 LanguageTool

[formatting] ~138-~138: If the ‘because’ clause is essential to the meaning, do not use a comma before the clause.
Context: ... not work on the NestJS Fastify platform, because Fastify does not allow wildcard (*) a...

(COMMA_BEFORE_BECAUSE)


223-247: Clear client setup instructions with proper type definitions.

The section on creating a type-safe client provides all necessary information, including imports, configuration options, and type definitions.

Consider adding a comma before "Please" in line 245 for improved readability:

- Please refer to the [OpenAPILink](/docs/openapi/client/openapi-link) documentation for more information on client setup and options.
+ Please, refer to the [OpenAPILink](/docs/openapi/client/openapi-link) documentation for more information on client setup and options.
🧰 Tools
🪛 LanguageTool

[typographical] ~244-~244: Consider adding a comma here.
Context: ...> = createORPCClient(link) ``` ::: info Please refer to the [OpenAPILink](/docs/openap...

(PLEASE_COMMA)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4477631 and a3d1d25.

📒 Files selected for processing (4)
  • apps/content/docs/openapi/nest/implement-contract.md (1 hunks)
  • packages/nest/package.json (1 hunks)
  • packages/nest/src/index.ts (1 hunks)
  • playgrounds/nest/src/main.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/nest/package.json
🧰 Additional context used
🪛 LanguageTool
apps/content/docs/openapi/nest/implement-contract.md

[formatting] ~138-~138: If the ‘because’ clause is essential to the meaning, do not use a comma before the clause.
Context: ... not work on the NestJS Fastify platform, because Fastify does not allow wildcard (*) a...

(COMMA_BEFORE_BECAUSE)


[uncategorized] ~202-~202: A comma might be missing here.
Context: ... a file with application/json content type the NestJS parser not treat it as a fil...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)


[typographical] ~244-~244: Consider adding a comma here.
Context: ...> = createORPCClient(link) ``` ::: info Please refer to the [OpenAPILink](/docs/openap...

(PLEASE_COMMA)

🪛 GitHub Check: codecov/patch
packages/nest/src/index.ts

[warning] 2-3: packages/nest/src/index.ts#L2-L3
Added lines #L2 - L3 were not covered by tests


[warning] 5-5: packages/nest/src/index.ts#L5
Added line #L5 was not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: publish-commit
  • GitHub Check: lint
🔇 Additional comments (7)
playgrounds/nest/src/main.ts (1)

1-11: Well-structured NestJS bootstrap with proper oRPC configuration.

The bootstrap function correctly initializes the NestJS application with bodyParser: false, which is recommended for oRPC integration to avoid conflicts with bracket notation parsing and file uploads, as documented in the implementation guide.

The port configuration using environment variables with a fallback is a good practice for deployment flexibility.

apps/content/docs/openapi/nest/implement-contract.md (6)

1-7: Clear and informative documentation header with appropriate metadata.

The title and description effectively communicate the purpose of this guide to users.


8-13: Good introduction with appropriate experimental status warning.

The introduction clearly establishes the purpose of the guide and properly warns users about the experimental nature of the feature, setting appropriate expectations.


14-39: Comprehensive installation instructions for multiple package managers.

The code-group with instructions for npm, yarn, pnpm, bun, and deno provides excellent developer experience.


40-64: Clear ESM configuration requirements with helpful warnings.

The section clearly explains the ESM requirements and potential bundler configuration needs, which is crucial for successful integration.


65-131: Well-structured contract definition example with helpful utility explanation.

The example contract provides a clear demonstration of defining an oRPC contract with the required paths for NestJS implementation. The explanation of populateContractRouterPaths utility is especially valuable.


141-196: Excellent implementation examples covering both standalone and full contract approaches.

The code examples clearly demonstrate how to implement both individual procedures and entire contract routers, which gives developers flexibility in their implementation approach.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/content/docs/openapi/nest/implement-contract.md (2)

133-140: Refine Grammar in Warning Clause
Remove the comma before “because” as the clause is essential to the meaning:

- does not work on the NestJS Fastify platform, because Fastify does not allow wildcard (`*`) aliasing in path parameters.
+ does not work on the NestJS Fastify platform because Fastify does not allow wildcard (`*`) aliasing in path parameters.
🧰 Tools
🪛 LanguageTool

[formatting] ~138-~138: If the ‘because’ clause is essential to the meaning, do not use a comma before the clause.
Context: ... not work on the NestJS Fastify platform, because Fastify does not allow wildcard (*) a...

(COMMA_BEFORE_BECAUSE)


206-214: Clarify Code Highlight Directive
The inline comment // [!code highlight] may not be recognized by all markdown renderers. Consider using VitePress’s line highlight syntax, for example:

- bodyParser: false, // [!code highlight]
+ bodyParser: false, // highlight-next-line
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3d1d25 and 3944e8d.

📒 Files selected for processing (1)
  • apps/content/docs/openapi/nest/implement-contract.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
apps/content/docs/openapi/nest/implement-contract.md

[formatting] ~138-~138: If the ‘because’ clause is essential to the meaning, do not use a comma before the clause.
Context: ... not work on the NestJS Fastify platform, because Fastify does not allow wildcard (*) a...

(COMMA_BEFORE_BECAUSE)


[uncategorized] ~202-~202: A comma might be missing here.
Context: ...n standard oRPC parsers. - In some edge cases like uploading a file with `application...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)


[typographical] ~244-~244: Consider adding a comma here.
Context: ...> = createORPCClient(link) ``` ::: info Please refer to the [OpenAPILink](/docs/openap...

(PLEASE_COMMA)

🔇 Additional comments (7)
apps/content/docs/openapi/nest/implement-contract.md (7)

1-4: Frontmatter and Metadata Look Good
The document title, description, and YAML frontmatter are correctly specified and conform to VitePress standards.


10-12: Experimental Warning Section Is Clear
The warning block clearly communicates the experimental nature of this feature. No changes needed.


16-38: Installation Code-Group Correct
The multi-package installation example using ::: code-group covers npm, yarn, pnpm, bun, and deno. The grouping and code fences are properly structured.


40-64: Requirements Section Is Accurate
The ESM setup instructions and bundler notes are precise and informative.


65-127: Define Contract Guide Is Comprehensive
The example contract code correctly demonstrates oc.route, Zod schemas, and populateContractRouterPaths.


197-222: Body Parser Recommendation Is Clear
The recommendation to disable the default NestJS body parser aligns with the oRPC interceptor behavior. This section is well explained.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~202-~202: A comma might be missing here.
Context: ...n standard oRPC parsers. - In some edge cases like uploading a file with `application...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)


223-246: Type-Safe Client Section Is Correct
The client example using OpenAPILink and createORPCClient is accurate and follows the documented API.

🧰 Tools
🪛 LanguageTool

[typographical] ~244-~244: Consider adding a comma here.
Context: ...> = createORPCClient(link) ``` ::: info Please refer to the [OpenAPILink](/docs/openap...

(PLEASE_COMMA)

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
packages/nest/README.md (1)

5-6: Empty main header – please fill in the package name
The <h1></h1> element renders nothing and hurts accessibility / SEO.
Same issue was pointed out previously.

-<h1></h1>
+<h1>@orpc/nest</h1>
packages/nest/src/implement.test.ts (1)

123-135: Nest application is never closed – potential resource leak
Each suite spins up an INestApplication, but nothing calls app.close(). This leaves open handles that slow the suite and may fail CI with “open handles” warnings. The same issue was flagged earlier.

 const moduleRef = await Test.createTestingModule({ controllers: [Controller] }).compile()
 const app = moduleRef.createNestApplication()
 await app.init()

+afterAll(async () => {
+  await app.close()
+})

Apply the same pattern to every place a new Nest application is created (lines 226-233, 257-264, 306-309, 363-365).

🧹 Nitpick comments (4)
packages/nest/tsconfig.json (1)

3-5: Consider adding emitDecoratorMetadata for full NestJS reflection support
Most NestJS samples enable both experimentalDecorators and emitDecoratorMetadata. Without the latter, runtime reflection data (e.g. for automatic provider injection or class-validator pipes) is unavailable and may surface as “undefined metadata” errors when consumers rely on reflection.

   "compilerOptions": {
     "experimentalDecorators": true,
+    "emitDecoratorMetadata": true
   },
packages/nest/README.md (1)

125-128: Add alt text to the sponsor image
Markdown-lint (MD045) flags images without alternative text. Provide a short description for screen-reader users.

-<img src='https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg'/>
+<img src='https://cdn.jsdelivr.net/gh/unnoq/unnoq/sponsors.svg' alt="oRPC sponsors"/>
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

126-126: Images should have alternate text (alt text)
null

(MD045, no-alt-text)

packages/nest/src/implement.ts (2)

78-85: Metadata copy loop can duplicate keys

Calling Reflect.defineMetadata inside the same iteration that enumerates Reflect.getOwnMetadataKeys(target, propertyKey) risks duplicating metadata when the decorator is evaluated multiple times (e.g. hot-reload). Consider checking for existing metadata before redefining or use Reflect.hasMetadata to avoid duplication.


118-122: Minor: double-promise is harmless but avoidable

Promise.resolve(req.body ?? fallbackStandardBody()) may wrap the original Promise returned by fallbackStandardBody() in another Promise, relying on promise-flattening. For clarity you could eliminate the extra layer:

-standardRequest.body = () => Promise.resolve(req.body ?? fallbackStandardBody())
+standardRequest.body = () =>
+  req.body !== undefined ? Promise.resolve(req.body) : fallbackStandardBody()
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3944e8d and 17fe6a7.

📒 Files selected for processing (5)
  • packages/nest/README.md (1 hunks)
  • packages/nest/package.json (1 hunks)
  • packages/nest/src/implement.test.ts (1 hunks)
  • packages/nest/src/implement.ts (1 hunks)
  • packages/nest/tsconfig.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/nest/package.json
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/nest/src/implement.ts (12)
packages/contract/src/procedure.ts (1)
  • isContractProcedure (51-66)
packages/contract/src/config.ts (1)
  • fallbackContractConfig (20-26)
packages/nest/src/utils.ts (1)
  • toNestPattern (7-11)
packages/server/src/router-utils.ts (1)
  • getRouter (13-49)
packages/server/src/lazy.ts (1)
  • unlazy (42-44)
packages/server/src/procedure.ts (1)
  • isProcedure (75-87)
packages/standard-server-node/src/types.ts (2)
  • NodeHttpRequest (4-10)
  • NodeHttpResponse (12-12)
packages/standard-server/src/types.ts (1)
  • StandardResponse (34-41)
packages/server/src/procedure-client.ts (1)
  • createProcedureClient (72-124)
packages/standard-server/src/utils.ts (1)
  • flattenHeader (51-61)
packages/client/src/error.ts (1)
  • toORPCError (139-146)
packages/standard-server-node/src/response.ts (1)
  • sendStandardResponse (8-39)
🪛 LanguageTool
packages/nest/README.md

[misspelling] ~33-~33: Possible spelling mistakes found.
Context: ...tack Query (React, Vue, Solid, Svelte), Pinia Colada, and more. - 🚀 Server Actions: Ful...

(EN_MULTITOKEN_SPELLING_TWO)


[style] ~51-~51: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... your API or implement API contract. - [@orpc/client](https://www.npmjs.com/package/@...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~52-~52: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... API on the client with type-safety. - [@orpc/nest](https://www.npmjs.com/package/@or...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~53-~53: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...: Deeply integrate oRPC with NestJS. - [@orpc/react](https://www.npmjs.com/package/@o...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~54-~54: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...with React and React Server Actions. - [@orpc/react-query](https://www.npmjs.com/pack...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~55-~55: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...test/docs/framework/react/overview). - [@orpc/vue-query](https://www.npmjs.com/packag...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~56-~56: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...latest/docs/framework/vue/overview). - [@orpc/solid-query](https://www.npmjs.com/pack...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~57-~57: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...test/docs/framework/solid/overview). - [@orpc/svelte-query](https://www.npmjs.com/pac...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~58-~58: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...est/docs/framework/svelte/overview). - [@orpc/vue-colada](https://www.npmjs.com/packa...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[misspelling] ~58-~58: Possible spelling mistakes found.
Context: ...ge/@orpc/vue-colada): Integration with Pinia Colada. - [@or...

(EN_MULTITOKEN_SPELLING_TWO)


[style] ~59-~59: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ada](https://pinia-colada.esm.dev/). - [@orpc/openapi](https://www.npmjs.com/package/...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~60-~60: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...I specs and handle OpenAPI requests. - [@orpc/zod](https://www.npmjs.com/package/@orp...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~61-~61: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...tps://zod.dev/) doesn't support yet. - [@orpc/valibot](https://www.npmjs.com/package/...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~62-~62: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...rom Valibot. - [@orpc/arktype](https://www.npmjs.com/package/...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.17.2)
packages/nest/README.md

126-126: Images should have alternate text (alt text)
null

(MD045, no-alt-text)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: publish-commit
  • GitHub Check: lint
🔇 Additional comments (2)
packages/nest/src/implement.ts (2)

12-12: 👍 Switched to public package entry – thank you!

toORPCError is now imported from @orpc/client, eliminating the prior cross-package relative import and making the new package consumable when published.


158-168: Edge-case: path wildcards may produce empty segments

flattenParams joins string[] params with '/', but Fastify splits * (catch-all) params on /, meaning "foo//bar" could emerge for consecutive slashes. If your codec treats empty segments as meaningful, normalise the array before joining:

-      flatten[key] = value.join('/')
+      flatten[key] = value.filter(Boolean).join('/')

Comment on lines +16 to +17
describe('@Implement', async () => {
const ping_handler = vi.fn(() => ({ body: 'pong', headers: { 'x-ping': 'pong' } }))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid async callbacks in describe blocks – they are ignored
Vitest/Jest do not await promises returned from describe, so side-effects inside the async callback may run after the tests start or be silently swallowed.
Move asynchronous setup into beforeAll/afterAll hooks instead.

-describe('@Implement', async () => {
+describe('@Implement', () => {
    // put async preparation inside hooks
})

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +23 to +30
const MethodDecoratorMap = {
HEAD: Head,
GET: Get,
POST: Post,
PUT: Put,
PATCH: Patch,
DELETE: Delete,
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Guard against unsupported / future HTTP methods

MethodDecoratorMap hard-codes six verbs. If a contract’s route.method is anything else (e.g. OPTIONS, TRACE or a future verb), MethodDecoratorMap[method] will be undefined, producing a runtime TypeError when applyDecorators is called.

 const MethodDecoratorMap = {
   HEAD: Head,
   GET: Get,
   POST: Post,
   PUT: Put,
   PATCH: Patch,
   DELETE: Delete,
+  // Consider: OPTIONS: Options,
 }

Below (see lines 56-61) add an explicit check and helpful error:

 const nestMethodDecorator = MethodDecoratorMap[method]
-if (!nestMethodDecorator) {
-  throw new Error(`Unsupported HTTP method "${method}" – extend MethodDecoratorMap.`)
-}
-
-applyDecorators(
-  nestMethodDecorator(toNestPattern(path)),
-  UseInterceptors(ImplementInterceptor),
-)(target, propertyKey, descriptor)
+if (!nestMethodDecorator) {
+  throw new Error(
+    `@Implement: HTTP method "${method}" is not supported. ` +
+    `Add it to MethodDecoratorMap or adjust your contract.`,
+  )
+}
+
+applyDecorators(
+  nestMethodDecorator(toNestPattern(path)),
+  UseInterceptors(ImplementInterceptor),
+)(target, propertyKey, descriptor)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const MethodDecoratorMap = {
HEAD: Head,
GET: Get,
POST: Post,
PUT: Put,
PATCH: Patch,
DELETE: Delete,
}
// … earlier in the file …
const MethodDecoratorMap = {
HEAD: Head,
GET: Get,
POST: Post,
PUT: Put,
PATCH: Patch,
DELETE: Delete,
// Consider: OPTIONS: Options,
}
// … later around line 56 …
const nestMethodDecorator = MethodDecoratorMap[method]
if (!nestMethodDecorator) {
throw new Error(
`@Implement: HTTP method "${method}" is not supported. ` +
`Add it to MethodDecoratorMap or adjust your contract.`,
)
}
applyDecorators(
nestMethodDecorator(toNestPattern(path)),
UseInterceptors(ImplementInterceptor),
)(target, propertyKey, descriptor)

@unnoq unnoq changed the title feat(nest): NestJS Integration feat(nest): implement contract in NestJS May 10, 2025
@unnoq unnoq merged commit b47b94e into main May 10, 2025
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nestjs support?
1 participant
0