### Install @golevelup/nestjs-modules Source: https://github.com/golevelup/nestjs/blob/master/docs/modules.md Install the package using npm, yarn, or pnpm. ```bash npm install ---save @golevelup/nestjs-modules ``` ```bash yarn add @golevelup/nestjs-modules ``` ```bash pnpm add @golevelup/nestjs-modules ``` -------------------------------- ### Install Dependencies with PNPM Source: https://github.com/golevelup/nestjs/blob/master/docs/contributing.md Run this command at the root of the repository to install all project dependencies and register githooks. This ensures that commit hooks are active and all necessary packages are installed before making changes. ```bash pnpm i ``` -------------------------------- ### Install @golevelup/nestjs-webhooks Source: https://github.com/golevelup/nestjs/blob/master/docs/webhooks.md Install the webhook package using npm, yarn, or pnpm. ```bash npm install ---save @golevelup/nestjs-webhooks ``` ```bash yarn add @golevelup/nestjs-webhooks ``` ```bash pnpm add @golevelup/nestjs-webhooks ``` -------------------------------- ### Install ts-sinon with pnpm Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-sinon.md Install the @golevelup/ts-sinon package as a development dependency using pnpm. ```bash pnpm add @golevelup/ts-sinon -D ``` -------------------------------- ### Install @golevelup/ts-vitest with npm Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-vitest.md Install the @golevelup/ts-vitest package as a development dependency using npm. ```bash npm install @golevelup/ts-vitest -D ``` -------------------------------- ### Install RabbitMQ Module Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Install the @golevelup/nestjs-rabbitmq package using npm, yarn, or pnpm. ```bash npm install ---save @golevelup/nestjs-rabbitmq ``` ```bash yarn add @golevelup/nestjs-rabbitmq ``` ```bash pnpm add @golevelup/nestjs-rabbitmq ``` -------------------------------- ### Install @golevelup/ts-vitest with pnpm Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-vitest.md Install the @golevelup/ts-vitest package as a development dependency using pnpm. ```bash pnpm add @golevelup/ts-vitest -D ``` -------------------------------- ### Install GraphQL Request Module Source: https://github.com/golevelup/nestjs/blob/master/docs/graphql-request.md Install the library using npm, yarn, or pnpm. ```bash npm install ---save @golevelup/nestjs-graphql-request ``` ```bash yarn add @golevelup/nestjs-graphql-request ``` ```bash pnpm add @golevelup/nestjs-graphql-request ``` -------------------------------- ### Install ts-sinon with npm Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-sinon.md Install the @golevelup/ts-sinon package as a development dependency using npm. ```bash npm install @golevelup/ts-sinon -D ``` -------------------------------- ### Install @golevelup/ts-vitest with yarn Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-vitest.md Install the @golevelup/ts-vitest package as a development dependency using yarn. ```bash yarn add @golevelup/ts-vitest -D ``` -------------------------------- ### Install @golevelup/nestjs-hasura Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/hasura.md Install the Hasura module using npm, yarn, or pnpm. ```bash npm install ---save @golevelup/nestjs-hasura ``` ```bash yarn add @golevelup/nestjs-hasura ``` ```bash pnpm add @golevelup/nestjs-hasura ``` -------------------------------- ### Install ts-sinon with yarn Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-sinon.md Install the @golevelup/ts-sinon package as a development dependency using yarn. ```bash yarn add @golevelup/ts-sinon -D ``` -------------------------------- ### Install @golevelup/ts-jest with pnpm Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-jest.md Install the @golevelup/ts-jest package as a development dependency using pnpm. ```bash pnpm add @golevelup/ts-jest -D ``` -------------------------------- ### Install @golevelup/ts-jest with npm Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-jest.md Install the @golevelup/ts-jest package as a development dependency using npm. ```bash npm install @golevelup/ts-jest -D ``` -------------------------------- ### Install NestJS Discovery Module Source: https://github.com/golevelup/nestjs/blob/master/docs/discovery.md Install the discovery module using npm, yarn, or pnpm. ```bash npm install ---save @golevelup/nestjs-discovery ``` ```bash yarn add @golevelup/nestjs-discovery ``` ```bash pnpm add @golevelup/nestjs-discovery ``` -------------------------------- ### Install @golevelup/ts-jest with yarn Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-jest.md Install the @golevelup/ts-jest package as a development dependency using yarn. ```bash yarn add @golevelup/ts-jest -D ``` -------------------------------- ### Install @golevelup/nestjs-common with npm Source: https://github.com/golevelup/nestjs/blob/master/docs/common.md Use this command to install the common NestJS utilities package using npm. ```bash npm install ---save @golevelup/nestjs-common ``` -------------------------------- ### Install Dependencies Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/stripe.md Install the necessary packages for Stripe integration using npm, yarn, or pnpm. ```bash npm install ---save @golevelup/nestjs-stripe stripe ``` ```bash yarn add @golevelup/nestjs-stripe stripe ``` ```bash pnpm add @golevelup/nestjs-stripe stripe ``` -------------------------------- ### Install @golevelup/nestjs-common with pnpm Source: https://github.com/golevelup/nestjs/blob/master/docs/common.md Use this command to install the common NestJS utilities package using pnpm. ```bash pnpm add @golevelup/nestjs-common ``` -------------------------------- ### Install @golevelup/nestjs-common with yarn Source: https://github.com/golevelup/nestjs/blob/master/docs/common.md Use this command to install the common NestJS utilities package using yarn. ```bash yarn add @golevelup/nestjs-common ``` -------------------------------- ### Install Google Cloud Pub/Sub Dependencies Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/google-pubsub.md Install the necessary packages for Google Cloud Pub/Sub integration with NestJS, including the Pub/Sub client library, Avro schema encoder, and Protobuf runtime. ```bash npm install @golevelup/nestjs-google-cloud-pubsub npm install @google-cloud/pubsub avsc @protobuf-ts/runtime ``` -------------------------------- ### Install Graphile Worker (pnpm) Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/graphile-worker.md Install the Graphile Worker NestJS integration package using pnpm. ```bash pnpm add @golevelup/nestjs-graphile-worker ``` -------------------------------- ### Install Graphile Worker (yarn) Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/graphile-worker.md Install the Graphile Worker NestJS integration package using yarn. ```bash yarn add @golevelup/nestjs-graphile-worker ``` -------------------------------- ### Install Graphile Worker (npm) Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/graphile-worker.md Install the Graphile Worker NestJS integration package using npm. ```bash npm install --save @golevelup/nestjs-graphile-worker ``` -------------------------------- ### Handle Pub/Sub Message Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/google-pubsub.md This is an example of a message handler for a 'order.created' event. It logs the received payload. ```typescript import { GoogleCloudPubsubMessage, GoogleCloudPubsubPayloadsMap, } from '@google-cloud/pubsub'; // ... inside a class decorated with @MessagePattern('order.created.subscription.analytic-service') public async onOrderCreated( payload: GoogleCloudPubsubMessage< GoogleCloudPubsubPayloadsMap['order.created'] >, ) { console.log({ data: payload.data }); } } ``` -------------------------------- ### Find Controller Methods with Specific Metadata Source: https://github.com/golevelup/nestjs/blob/master/docs/discovery.md Query for controller methods decorated with a specific metadata key and retrieve the associated metadata value. This example assumes a custom decorator `ExampleDecorator` that sets metadata at 'exampleKey'. ```typescript const exampleMethodsMeta = await this.discover.controllerMethodsWithMetaAtKey('exampleKey'); ``` -------------------------------- ### Configure Connection Resiliency Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Enable connection resiliency by configuring `connectionInitOptions` to not wait for a connection during app bootstrap. This allows the application to start even if RabbitMQ is unavailable. ```typescript import { RabbitMQModule, } from '@golevelup/nestjs-rabbitmq'; @Module({ imports: [ RabbitMQModule.forRoot({ exchanges: [ { name: 'exchange1', type: 'topic', }, ], uri: 'amqp://rabbitmq:rabbitmq@localhost:5672', connectionInitOptions: { wait: false }, }), ], }) export class RabbitExampleModule {} ``` -------------------------------- ### Mock RabbitMQ Connection for Testing Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md In your test setup, override the `RabbitMQModule` with a `MockRabbitExampleModule` that provides a mocked `AmqpConnection`. This ensures that publishers injecting `AmqpConnection` receive a mock instance during tests. ```typescript // In your test setup... import { Module } from '@nestjs/common'; import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; import { createMock } from '@golevelup/ts-jest'; import { Test } from '@nestjs/testing'; import { AppModule } from 'where your root module is located'; import { RabbitExampleModule } from 'where your rabbitmq module is located'; // Create a valid mock module @Module({ providers: [ { provide: AmqpConnection, useValue: createMock(), }, ], exports: [AmqpConnection], }) class MockRabbitExampleModule {} // Then override the real `RabbitMqModule` with the mocked one beforeAll(async () => { const moduleFixture = await Test.createTestingModule({ imports: [AppModule], }) .overrideModule(RabbitExampleModule) .useModule(MockRabbitExampleModule) .compile(); const app = moduleFixture.createNestApplication(); await app.init(); }); ``` -------------------------------- ### Generate Commit Message with Commitizen Source: https://github.com/golevelup/nestjs/blob/master/docs/contributing.md Execute this command to initiate the Commitizen prompt, which guides you through creating a well-formatted commit message according to project conventions. Remember to reference issue numbers using the `#{number}` syntax. ```bash pnpm commit ``` -------------------------------- ### Mocking Nested Calls and Providing Custom Mocks Source: https://github.com/golevelup/nestjs/blob/master/packages/testing/ts-sinon/README.md Demonstrates how to mock nested calls within `createMock` and how to provide custom mock implementations for specific methods. When providing custom mocks, the parent mock call count includes these custom setups. ```typescript it('should correctly resolve mocked providers', async () => { const request = { key: 'val', }; mockExecutionContext.switchToHttp.returns( createMock({ getRequest: () => request, }), ); const mockResult = mockExecutionContext.switchToHttp().getRequest(); expect(mockResult).toBe(request); }); ``` ```typescript const mockExecutionContext = createMock({ switchToHttp: () => ({ getRequest: () => ({ headers: { authorization: 'auth', }, }), getResponse: sinon.stub().returns({ data: 'res return data' }), }), }); ``` -------------------------------- ### Module Initialization with Exchanges and Channels Source: https://github.com/golevelup/nestjs/blob/master/packages/rabbitmq/README.md Import `RabbitMQModule` and configure exchanges and channels for message handling. Custom channels can be defined with specific `prefetchCount` values. ```typescript import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'; import { Module } from '@nestjs/common'; import { MessagingController } from './messaging/messaging.controller'; import { MessagingService } from './messaging/messaging.service'; @Module({ imports: [ RabbitMQModule.forRoot({ exchanges: [ { name: 'exchange1', type: 'topic', }, ], uri: 'amqp://rabbitmq:rabbitmq@localhost:5672', channels: { 'channel-1': { prefetchCount: 15, default: true, }, 'channel-2': { prefetchCount: 2, }, }, }), RabbitExampleModule, ], providers: [MessagingService], controllers: [MessagingController], }) export class RabbitExampleModule {} ``` -------------------------------- ### Configure Pub/Sub Topics and Subscriptions Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/google-pubsub.md Define Avro and Protocol Buffer schemas for topics and configure subscription options, including batching and flow control. This configuration is used to initialize the Pub/Sub kit. ```typescript import { GoogleCloudPubsubModule, PubsubTopicConfiguration, } from '@golevelup/nestjs-google-cloud-pubsub'; import { SchemaTypes, Encodings } from '@google-cloud/pubsub'; import { MessageType } from '@protobuf-ts/runtime'; import { PaymentProcessedProtocolBufferSchema } from './generated-proto/payment-processed-schema'; export const topics = [ { name: 'order.created', schema: { definition: { fields: [ { name: 'field1', type: 'string' }, { name: 'field2', type: 'int' }, { name: 'field3', type: 'boolean' }, { name: 'field4', type: 'double' }, { name: 'field5', type: { fields: [{ name: 'nestedField1', type: 'string' }], name: 'Nested1', type: 'record', }, }, { name: 'field6', type: ['double', 'null'] }, ], name: 'order.created.schema', type: 'record', }, encoding: Encodings.Binary, name: 'order.created.schema', type: SchemaTypes.Avro, }, subscriptions: [ /** * High Density Configuration (Designed for up to 100 subscriptions per instance): * * 1. Flow Control: * - Limits each subscription to 10MB or 500 messages. * - Math: 100 subs * 10MB = 1GB Raw Buffer (~2GB Real RAM Usage). * * 2. Batch Manager: * - Aggregates up to 125 messages. * - Flushes every 200ms even if 125 messages weren't aggregated. */ { name: 'order.created.subscription.order-processor-service', batchManagerOptions: { maxMessages: 125, maxWaitTimeMilliseconds: 200 }, options: { flowControl: { allowExcessMessages: false, maxBytes: 10 * 1024 * 1024, maxMessages: 500, }, }, }, { name: 'order.created.subscription.analytic-service' }, ], }, { name: 'payment.processed', schema: { definition: PaymentProcessedProtocolBufferSchema as MessageType, encoding: Encodings.Binary, name: 'payment.processed.schema', protoPath: '/Users/Desktop/google-cloud-pubsub/proto/payment-processed.proto', type: SchemaTypes.ProtocolBuffer, }, subscriptions: [ { name: 'payment.processed.payment-processor-service' }, { name: 'payment.processed.analytic-service' }, ], }, ] as const satisfies readonly PubsubTopicConfiguration[]; const googleCloudPubsubKit = GoogleCloudPubsubModule.initializeKit(); const { GoogleCloudPubsubAbstractPublisher, GoogleCloudPubsubBatchSubscribe, GoogleCloudPubsubSubscribe, } = googleCloudPubsubKit; export type GoogleCloudPubsubPayloadsMap = typeof googleCloudPubsubKit._GoogleCloudPubsubPayloadsMap; export class GoogleCloudPubsubPublisher extends GoogleCloudPubsubAbstractPublisher {} export { GoogleCloudPubsubSubscribe, GoogleCloudPubsubBatchSubscribe }; ``` -------------------------------- ### Module Initialization with Exchanges and Channels Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Initialize the RabbitMQModule by importing it and providing exchange and channel configurations. Exchanges are automatically asserted, and channels can be configured with prefetch counts and default settings. ```typescript import { RabbitMQModule, } from '@golevelup/nestjs-rabbitmq'; import { Module } from '@nestjs/common'; import { MessagingController } from './messaging/messaging.controller'; import { MessagingService } from './messaging/messaging.service'; @Module({ imports: [ RabbitMQModule.forRoot({ exchanges: [ { name: 'exchange1', type: 'topic', }, ], uri: 'amqp://rabbitmq:rabbitmq@localhost:5672', channels: { 'channel-1': { prefetchCount: 15, default: true, }, 'channel-2': { prefetchCount: 2, }, }, }), RabbitExampleModule, ], providers: [MessagingService], controllers: [MessagingController], }) export class RabbitExampleModule {} ``` -------------------------------- ### Provide Custom Mock Implementations Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-vitest.md Shows how to provide custom implementations for mock methods and how to assert their behavior, including call counts and return values. Note the explanation regarding call counts when setting mocks. ```typescript import { createMock } from '@golevelup/ts-vitest'; import { ExecutionContext } from '@nestjs/common'; describe('Mocked Execution Context', () => { it('should have a fully mocked Execution Context', () => { const mockExecutionContext = createMock({ switchToHttp: () => ({ getRequest: () => ({ headers: { authorization: 'auth', }, }), }), }); mockExecutionContext .switchToHttp() .getResponse.mockReturnValue({ data: 'res return data' }); expect(mockExecutionContext.switchToHttp().getRequest()).toEqual({ headers: { authorization: 'auth', }, }); expect(mockExecutionContext.switchToHttp().getResponse()).toEqual({ data: 'res return data', }); expect(mockExecutionContext.switchToHttp).toBeCalledTimes(3); expect(mockExecutionContext.switchToRPC().getContext()).toBeDefined(); expect(mockExecutionContext.switchToWs().getClient()).toBeDefined(); }); }); ``` -------------------------------- ### Configure GraphileWorkerModule with forRootAsync Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/graphile-worker.md Dynamically configure the Graphile Worker module using `forRootAsync`, suitable for loading configuration asynchronously, for example, from a ConfigService. ```typescript GraphileWorkerModule.forRootAsync({ useFactory: (configService: ConfigService) => ({ connectionString: configService.get('DATABASE_URL'), // ...other options }), inject: [ConfigService], }) ``` -------------------------------- ### Configure HasuraModule with Metadata Synchronization Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/hasura.md Configure the HasuraModule for event handling and automatic metadata synchronization. This setup is recommended for development environments to manage Hasura metadata files. ```typescript import { HasuraModule } from '@golevelup/nestjs-hasura'; @Module({ imports: [ HasuraModule.forRoot({ webhookConfig: { secretFactory: secret, secretHeader: secretHeader, }, managedMetaDataConfig: { dirPath: join(process.cwd(), 'hasura/metadata'), secretHeaderEnvName: 'HASURA_NESTJS_WEBHOOK_SECRET_HEADER_VALUE', nestEndpointEnvName: 'NESTJS_EVENT_WEBHOOK_ENDPOINT', defaultEventRetryConfig: { intervalInSeconds: 15, numRetries: 3, timeoutInSeconds: 100, toleranceSeconds: 21600, }, }, }), ], }) export class AppModule { // ... } ``` -------------------------------- ### Provide Custom Mocks Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-sinon.md Shows how to provide custom mock implementations when using `createMock`. This allows for specific control over mock behavior. ```typescript const mockExecutionContext = createMock({ switchToHttp: () => ({ getRequest: () => ({ headers: { authorization: 'auth', }, }), getResponse: sinon.stub().returns({ data: 'res return data' }), }), }); ``` -------------------------------- ### Register Hasura Scheduled Event Handlers Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/hasura.md Use the TrackedHasuraScheduledEventHandler decorator to register methods that will be triggered by Hasura's scheduled events. This example shows a task that runs every minute. ```typescript import { TrackedHasuraScheduledEventHandler } from '@golevelup/nestjs-hasura'; @Injectable() class RecurringJobService { @TrackedHasuraScheduledEventHandler({ cronSchedule: CommonCronSchedules.EveryMinute, name: 'every-minute', payload: {}, comment: 'this is my comment', }) public async cronTask(evt: any) { this.logger.log(evt); } } ``` -------------------------------- ### Selecting Channel for RabbitMQ Handler Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Specify a dedicated channel for a handler by setting `queueOptions.channel` to the desired channel name. The channel must be pre-configured in the module setup. Defaults to the default channel if not specified. ```typescript import { RabbitSubscribe, RabbitRPC, } from '@golevelup/nestjs-rabbitmq'; import { Injectable } from '@nestjs/common'; @Injectable() export class MessagingService { @RabbitRPC({ exchange: 'exchange1', routingKey: 'subscribe-route', queue: 'subscribe-queue', queueOptions: { channel: 'channel-2', }, }) public async rpcHandler(msg: {}) { console.log(`Received rpc message: ${JSON.stringify(msg)}`); return { message: 'hi' }; } @RabbitSubscribe({ exchange: 'exchange1', routingKey: 'subscribe-route-2', queue: 'subscribe-queue-2', }) public async pubSubHandler(msg: {}) { console.log(`Received pub/sub message: ${JSON.stringify(msg)}`); } } ``` -------------------------------- ### Configure Dynamic Module Synchronously Source: https://github.com/golevelup/nestjs/blob/master/docs/modules.md In your root module, import the configured dynamic module using `ConfigModule.forRoot()`, passing the module class and synchronous configuration options. ```typescript @Module({ imports: [ConfigModule.forRoot(ConfigModule, synchronousConfigModuleOptions)], }) export class AppModule {} ``` -------------------------------- ### Create a Basic Mock with createMock Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-vitest.md Import and use `createMock` with a generic type to generate a fully mocked object. This is useful for quickly creating mock dependencies in your tests. ```typescript import { createMock } from '@golevelup/ts-vitest'; import { ExecutionContext } from '@nestjs/common'; describe('Mocked Execution Context', () => { it('should have a fully mocked Execution Context', () => { const mockExecutionContext = createMock(); expect(mockExecutionContext.switchToHttp()).toBeDefined(); }); }); ``` -------------------------------- ### Mock with Chained Method Calls Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-jest.md Demonstrates creating a mock that allows for chaining multiple method calls, such as `switchToHttp().getRequest()`. This is useful when your code relies on nested method calls. ```typescript import { createMock } from '@golevelup/ts-jest'; import { ExecutionContext } from '@nestjs/common'; describe('Mocked Execution Context', () => { it('should have a fully mocked Execution Context', () => { const mockExecutionContext = createMock(); expect(mockExecutionContext.switchToHttp().getRequest()).toBeDefined(); expect(mockExecutionContext.switchToRPC().getContext()).toBeDefined(); expect(mockExecutionContext.switchToWs().getClient()).toBeDefined(); }); }); ``` -------------------------------- ### Configure Dynamic Module Asynchronously Source: https://github.com/golevelup/nestjs/blob/master/docs/modules.md In your root module, import the configured dynamic module using `ConfigModule.forRootAsync()`, passing the module class and asynchronous configuration options. ```typescript @Module({ imports: [ConfigModule.forRootAsync(ConfigModule, asyncConfigModuleOptions)], }) export class AppModule {} ``` -------------------------------- ### Using Deferred Dynamic Module Source: https://github.com/golevelup/nestjs/blob/master/docs/modules.md Import a dynamically configured module using its deferred method. This is useful when you want to defer the configuration or instantiation of a module until it's actually needed. ```typescript @Module({ imports: [ConfigModule.deferred()], }) export class ConfigModuleDependentModule {} ``` -------------------------------- ### Import GraphQLRequestModule Source: https://github.com/golevelup/nestjs/blob/master/docs/graphql-request.md Import and configure the GraphQLRequestModule in your application's root module. This sets up the GraphQLClient with specified endpoint and headers. ```typescript import { GraphQLRequestModule, } from '@golevelup/nestjs-graphql-request'; @Module({ imports: [ GraphQLRequestModule.forRoot({ // Exposes configuration options based on the graphql-request package endpoint: config.get('endpoint'), options: { headers: { 'content-type': 'application/json', 'x-hasura-admin-secret': config.get('secret'), }, }, }), ], }) export class AppModule { // ... } ``` -------------------------------- ### Create a Configurable Dynamic Root Module Source: https://github.com/golevelup/nestjs/blob/master/docs/modules.md Use `createConfigurableDynamicRootModule` to define a dynamic module that can be configured with options. Ensure the `CONFIG_MODULE_OPTIONS` constant and `ConfigModuleOptions` interface are correctly defined and imported. ```typescript import { createConfigurableDynamicRootModule } from '@golevelup/nestjs-modules'; import { Module } from '@nestjs/common'; import { CONFIG_MODULE_OPTIONS } from './config.constants'; // the constant string/symbol/token import { ConfigModuleOptions } from './config.options'; // the options to provide to the service import { ConfigService } from './config.service'; // the service to be provided to the rest of the server @Module({ providers: [ConfigService], exports: [ConfigService], }) export class ConfigModule extends createConfigurableDynamicRootModule< ConfigModule, ConfigModuleOptions >(CONFIG_MODULE_OPTIONS) {} ``` -------------------------------- ### Apply Hasura Metadata Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/hasura.md After generating changes to metadata files, apply them to your Hasura instance using the Hasura CLI. ```bash hasura metadata apply ``` -------------------------------- ### Configure GraphileWorkerModule with forRoot Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/graphile-worker.md Set up the Graphile Worker integration in your AppModule using `forRoot` with connection details. ```typescript import { Module } from '@nestjs/common'; import { GraphileWorkerModule } from '@golevelup/nestjs-graphile-worker'; @Module({ imports: [ GraphileWorkerModule.forRoot({ connectionString: process.env.DATABASE_URL, // ...other options }), ], }) export class AppModule {} ``` -------------------------------- ### Import GraphQLRequestModule Source: https://github.com/golevelup/nestjs/blob/master/packages/graphql-request/README.md Import and configure the GraphQLRequestModule in your application's root module. Provide the GraphQL endpoint and any necessary options. ```typescript import { GraphQLRequestModule } from '@golevelup/nestjs-graphql-request'; @Module({ imports: [ GraphQLRequestModule.forRoot({ // Exposes configuration options based on the graphql-request package endpoint: config.get('endpoint'), options: { headers: { 'content-type': 'application/json', 'x-hasura-admin-secret': config.get('secret'), }, }, }), ], }) export class AppModule { // ... } ``` -------------------------------- ### Import StripeModule Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/stripe.md Import and configure StripeModule in your AppModule. Provide your Stripe API key and optionally webhook secrets for event processing. ```typescript import { StripeModule } from '@golevelup/nestjs-stripe'; @Module({ imports: [ StripeModule.forRoot({ apiKey: 'sk_***', webhookConfig: { // Snapshot event secrets stripeSecrets: { account: 'whsec_***', accountTest: 'whsec_***', connect: 'whsec_***', connectTest: 'whsec_***', }, // Thin event secrets (optional) stripeThinSecrets: { account: 'whsec_***', accountTest: 'whsec_***', connect: 'whsec_***', connectTest: 'whsec_***', }, }, }), ], }) export class AppModule { // ... } ``` -------------------------------- ### Configure Consumer-Side Message Batching Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Configure message batching options for a RabbitMQ subscriber. Ensure prefetchCount is sufficient for batching to work correctly. An optional error handler can be provided to manage batch-level errors. ```typescript import { RabbitSubscribe } from '@golevelup/nestjs-rabbitmq'; const batchErrorHandler = (channel, messages, error) => { console.log(`Received message batch of length: ${messages.length}`); }; @Injectable() export class MessagingService { @RabbitSubscribe({ exchange: 'exchange1', routingKey: 'batch-route', queue: 'batch-queue', batchOptions: { size: 10, timeout: 200, errorHandler: batchErrorHandler, }, }) public async batchHandler(messages) { console.log(`Received message batch of length: ${messages.length}`); } } ``` -------------------------------- ### Typesafe GraphQL Access with SDK Source: https://github.com/golevelup/nestjs/blob/master/docs/graphql-request.md Combine GraphQLRequestModule with GraphQL code generation tools to create a type-safe SDK. This factory provides the SDK instance, enabling intellisense and type safety for all requests. ```typescript import { GraphQLRequestModule, GraphQLClientInject, } from '@golevelup/nestjs-graphql-request'; import { getSdk } from './your-codegen-location'; @Module({ imports: [ GraphQLRequestModule.forRoot({ // Exposes configuration options based on the graphql-request package endpoint: config.get('endpoint'), options: { headers: { 'content-type': 'application/json', 'x-hasura-admin-secret': config.get('secret'), }, }, }), ], providers: [ { // you can provide whatever key you want. use it in conjunction with @Inject("TypeSafeGqlSdk") to get the SDK instance in your controllers/services provide: 'TypeSafeGqlSdk', inject: [GraphQLClientInject], useFactory: (client: GraphQLClient) => getSdk(client), }, ], }) export class AppModule { // ... } ``` -------------------------------- ### Selecting Channel for Handler Source: https://github.com/golevelup/nestjs/blob/master/packages/rabbitmq/README.md Specify a channel for a handler by setting `queueOptions.channel` to the desired channel name. If the channel doesn't exist or is not specified, the default channel is used. The channel must be created in the module configuration. ```typescript import { RabbitSubscribe, RabbitRPC } from '@golevelup/nestjs-rabbitmq'; import { Injectable } from '@nestjs/common'; @Injectable() export class MessagingService { @RabbitRPC({ exchange: 'exchange1', routingKey: 'subscribe-route', queue: 'subscribe-queue', queueOptions: { channel: 'channel-2', }, }) public async rpcHandler(msg: {}) { console.log(`Received rpc message: ${JSON.stringify(msg)}`); return { message: 'hi' }; } @RabbitSubscribe({ exchange: 'exchange1', routingKey: 'subscribe-route-2', queue: 'subscribe-queue-2', }) public async pubSubHandler(msg: {}) { console.log(`Received pub/sub message: ${JSON.stringify(msg)}`); } } ``` -------------------------------- ### Create a Mocked ExecutionContext Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-sinon.md Import and use the `createMock` function to generate a fully mocked `ExecutionContext` for testing NestJS applications. All sub-properties are automatically stubbed. ```typescript import { createMock } from '@golevelup/ts-sinon'; import { ExecutionContext } from '@nestjs/common'; describe('Mocked Execution Context', () => { it('should have a fully mocked Execution Context', () => { const mockExecutionContext = createMock(); expect(mockExecutionContext.switchToHttp()).toBeDefined(); }); }); ``` -------------------------------- ### Create Basic Mock with ts-jest Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-jest.md Import `createMock` and use it with a generic type to create a fully mocked instance of a class like `ExecutionContext`. This is useful for simple mocking scenarios. ```typescript import { createMock } from '@golevelup/ts-jest'; import { ExecutionContext } from '@nestjs/common'; describe('Mocked Execution Context', () => { it('should have a fully mocked Execution Context', () => { const mockExecutionContext = createMock(); expect(mockExecutionContext.switchToHttp()).toBeDefined(); }); }); ``` -------------------------------- ### Requesting Data via RPC Source: https://github.com/golevelup/nestjs/blob/master/packages/rabbitmq/README.md Details how to send RPC requests to other services and receive responses using the `request` method of `AmqpConnection`. Includes information on type inference and interoperability. ```APIDOC ## Requesting Data from an RPC ### Description Send a request to an RPC server and wait for a response. This method utilizes RabbitMQ's Direct Reply-To Queue functionality. ### Method Signature ```typescript public async request( data: { exchange: string; routingKey: string; payload: any; timeout?: number; } ): Promise ``` ### Parameters - **data.exchange** (string): The exchange to send the request to. - **data.routingKey** (string): The routing key for the request. - **data.payload** (any): The message payload for the request. - **data.timeout** (number, optional): The maximum time in milliseconds to wait for a response before timing out. ### Example Usage ```typescript interface ExpectedReturnType { /* ... */ } const response = await amqpConnection.request({ exchange: 'exchange1', routingKey: 'rpc', payload: { request: 'val' }, timeout: 10000, }); ``` ### Type Inference The generic parameter `` allows for type safety and editor intellisense for the expected response type. Note that this does not perform runtime validation of the received object. ``` -------------------------------- ### Configurable Dynamic Module Definition Source: https://github.com/golevelup/nestjs/blob/master/docs/modules.md Define a dynamic module that can be configured externally. Use `createConfigurableDynamicRootModule` to set up options and provide services. The `static deferred` property allows for lazy initialization. ```typescript import { createConfigurableDynamicRootModule } from '@golevelup/nestjs-modules'; import { Module } from '@nestjs/common'; import { CONFIG_MODULE_OPTIONS } from './config.constants'; // the constant string/symbol/token import { ConfigModuleOptions } from './config.options'; // the options to provide to the service import { ConfigService } from './config.service'; // the service to be provided to the rest of the server @Module({ providers: [ConfigService], exports: [ConfigService], }) export class ConfigModule extends createConfigurableDynamicRootModule< ConfigModule, ConfigModuleOptions >(CONFIG_MODULE_OPTIONS) { static deferred = () => ConfigModule.externallyConfigured(ConfigModule, 0); } ``` -------------------------------- ### Injecting AmqpConnection Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Shows how to inject the `AmqpConnection` service into a NestJS controller or service to interact with RabbitMQ. ```APIDOC ## Injecting AmqpConnection ### Description To perform RabbitMQ operations like publishing or requesting data, you need to inject the `AmqpConnection` service into your NestJS components. ### Usage Add `AmqpConnection` as a constructor parameter in your controller or service. ### Example ```typescript import { Controller } from '@nestjs/common'; import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; @Controller() export class AppController { constructor(private readonly amqpConnection: AmqpConnection) {} // ... other methods } ``` ``` -------------------------------- ### Configure Default Publish Options for Persistence Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Set `defaultPublishOptions` in the `RabbitMQModule.forRoot` configuration to automatically mark all published messages as persistent. ```typescript RabbitMQModule.forRoot(RabbitMQModule, { exchanges: [{ name: 'some-exchange', type: 'topic' }], uri: 'amqp://rabbitmq:rabbitmq@localhost:5672', defaultPublishOptions: { persistent: true, }, }); ``` -------------------------------- ### Mix Bindings with Top-Level Exchange/Routing Key Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Combine top-level `exchange` and `routingKey` options with the `bindings` array in `@RabbitSubscribe` for flexible message routing to a single queue. ```typescript @RabbitSubscribe({ exchange: 'exchange1', routingKey: 'route.c', queue: 'my-queue', bindings: [ { exchange: 'exchange2', routingKey: 'route.d' }, ], }) public async mixedHandler(msg: {}) { console.log(`Received message: ${JSON.stringify(msg)}`); } ``` -------------------------------- ### Requesting Data from an RPC Source: https://github.com/golevelup/nestjs/blob/master/docs/modules/rabbitmq.md Explains how to send a request to an RPC handler and receive a response using the `request` method of the `AmqpConnection` service. Includes details on type inference and potential interoperability. ```APIDOC ## Requesting Data from an RPC ### Description Send a request to a remote procedure call (RPC) handler and wait for a response. This method is suitable for scenarios where you need to query data or trigger an action that requires a reply. ### Method `AmqpConnection.request(options: { exchange: string, routingKey: string, payload: any, timeout?: number }): Promise` ### Parameters - `exchange` (string): The exchange to send the request to. - `routingKey` (string): The routing key for the RPC handler. - `payload` (any): The data payload for the request. - `timeout` (number, optional): The maximum time in milliseconds to wait for a response before timing out. ### Type Inference The generic parameter `` allows you to specify the expected return type for type safety and editor intellisense. Note that this does not perform runtime validation of the received object. ### Example ```typescript const response = await amqpConnection.request({ exchange: 'exchange1', routingKey: 'rpc', payload: { request: 'val', }, timeout: 10000, // optional timeout }); ``` ### Interoperability This RPC functionality uses RabbitMQ's Direct Reply-To Queue. While it might be possible to interact with RPC servers implemented in other languages, this has not been verified. ``` -------------------------------- ### Publish a Message to RabbitMQ Source: https://github.com/golevelup/nestjs/blob/master/packages/rabbitmq/README.md Use the `publish` method on the `AmqpConnection` object to send a message to a specified exchange with a routing key. Options can be provided to configure message persistence. ```typescript amqpConnection.publish('some-exchange', 'routing-key', { msg: 'hello world' }); ``` ```typescript amqpConnection.publish( 'some-exchange', 'routing-key', { msg: 'hello world' }, { persistent: true }, ); ``` -------------------------------- ### Mock with Custom Values and Assertions Source: https://github.com/golevelup/nestjs/blob/master/docs/testing/ts-jest.md Shows how to provide custom mock implementations and assert specific return values and call counts. This allows for more detailed control and testing of mock interactions. Be aware of how parent mock function calls are counted. ```typescript import { createMock } from '@golevelup/ts-jest'; import { ExecutionContext } from '@nestjs/common'; describe('Mocked Execution Context', () => { it('should have a fully mocked Execution Context', () => { const mockExecutionContext = createMock({ switchToHttp: () => ({ getRequest: () => ({ headers: { authorization: 'auth', }, }), }), }); mockExecutionContext .switchToHttp() .getResponse.mockReturnValue({ data: 'res return data' }); expect(mockExecutionContext.switchToHttp().getRequest()).toEqual({ headers: { authorization: 'auth', }, }); expect(mockExecutionContext.switchToHttp().getResponse()).toEqual({ data: 'res return data', }); expect(mockExecutionContext.switchToHttp).toBeCalledTimes(3); expect(mockExecutionContext.switchToRPC().getContext()).toBeDefined(); expect(mockExecutionContext.switchToWs().getClient()).toBeDefined(); }); }); ```