{"_id":"@dev5c32373043/nestjs-pulsar","name":"@dev5c32373043/nestjs-pulsar","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@dev5c32373043/nestjs-pulsar","version":"1.0.0","description":"Apache Pulsar module for Nest.js framework","license":"MIT","scripts":{"build":"rimraf dist && tsc -p tsconfig.build.json","format":"prettier --write \"**/*.ts\"","lint":"eslint 'lib/**/*.ts' --fix","prepublish:npm":"npm run build","publish:npm":"npm publish --access public","prepublish:next":"npm run build","publish:next":"npm publish --access public --tag next","test:e2e":"jest --config ./test/jest-e2e.json --runInBand","test:e2e:dev":"jest --config ./test/jest-e2e.json --runInBand --watch","prerelease":"npm run build","release":"release-it","prepare":"husky install"},"devDependencies":{"@commitlint/cli":"17.4.4","@commitlint/config-angular":"17.4.4","@nestjs/common":"^10.0.2","@nestjs/core":"^10.0.2","@nestjs/testing":"^10.0.5","@types/jest":"^29.5.2","@types/node":"^20.3.1","@types/supertest":"2.0.12","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","eslint":"^8.44.0","eslint-config-prettier":"^8.8.0","eslint-plugin-prettier":"^5.0.0","jest":"^29.6.1","husky":"8.0.3","lint-staged":"^13.2.2","prettier":"^3.0.0","reflect-metadata":"^0.1.13","rxjs":"^7.8.1","ts-jest":"^29.1.1","ts-loader":"^9.4.4","ts-node":"^10.9.1","tsconfig-paths":"^4.2.0","tslint":"^6.1.3","typescript":"^5.1.3","release-it":"15.6.1","rimraf":"^4.2.0","supertest":"^6.3.3"},"dependencies":{"pulsar-client":"^1.8.0"},"peerDependencies":{"@nestjs/common":"^8.0.0 || ^9.0.0 || ^10.0.0","@nestjs/core":"^8.0.0 || ^9.0.0 || ^10.0.0","reflect-metadata":"^0.1.13","rxjs":"^6.0.0 || ^7.0.0"},"lint-staged":{"**/*.{ts,json}":[]},"homepage":"https://github.com/dev5c32373043/nestjs-pulsar#readme","repository":{"type":"git","url":"git+https://github.com/dev5c32373043/nestjs-pulsar.git"},"bugs":{"url":"https://github.com/dev5c32373043/nestjs-pulsar/issues"},"keywords":["nest","nestjs","pulsar","apache pulsar","pulsar-client"],"directories":{"lib":"lib","test":"test"},"types":"./index.d.ts","main":"index.js","author":"","gitHead":"bf645ace92a6d4569a3b229c2c2e30f0b282d5ec","_id":"@dev5c32373043/nestjs-pulsar@1.0.0","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-jePg2fMP+AXUDFY70ROZD0yeIXYJe8qm8qqAd3UeaH67bKzWWHn0T0hKXEzjR/m9QMzC/Xq6YkDSEdXyDUBJig==","shasum":"41fbfdde49c6dd3d7c15ab853acd3da29a378e4c","tarball":"https://registry.npmjs.org/@dev5c32373043/nestjs-pulsar/-/nestjs-pulsar-1.0.0.tgz","fileCount":34,"unpackedSize":41172,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD0hRyjHJAy/RfPqW1dKtpqKp2TxMT+nG05D+CR2tXJ/AIgUN2ab6nkZDzVPQDxCvnOx+Zsxmm35HtjUG0GRGncA6E="}]},"_npmUser":{"name":"pickydude","email":"nofound12345@gmail.com"},"maintainers":[{"name":"pickydude","email":"nofound12345@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestjs-pulsar_1.0.0_1690122963020_0.6103746566280996"},"_hasShrinkwrap":false}},"time":{"created":"2023-07-23T14:36:02.939Z","1.0.0":"2023-07-23T14:36:03.196Z","modified":"2023-07-23T14:36:03.474Z"},"maintainers":[{"name":"pickydude","email":"nofound12345@gmail.com"}],"description":"Apache Pulsar module for Nest.js framework","homepage":"https://github.com/dev5c32373043/nestjs-pulsar#readme","keywords":["nest","nestjs","pulsar","apache pulsar","pulsar-client"],"repository":{"type":"git","url":"git+https://github.com/dev5c32373043/nestjs-pulsar.git"},"bugs":{"url":"https://github.com/dev5c32373043/nestjs-pulsar/issues"},"license":"MIT","readme":"<p align=\"center\">\n  <a href=\"http://nestjs.com/\" target=\"blank\"><img src=\"https://nestjs.com/img/logo-small.svg\" width=\"120\" alt=\"Nest Logo\" /></a>\n</p>\n\n<p align=\"center\">A progressive <a href=\"http://nodejs.org\" target=\"blank\">Node.js</a> framework for building efficient and scalable server-side applications.</p>\n\n## Description\n\n[Apache Pulsar](https://pulsar.apache.org) module for [Nest](https://nestjs.com).\n\nBased on https://www.npmjs.com/package/nest-pulsar with dependency updates and small improvements.\n\n## Installation\n\n```bash\n$ npm i @dev5c32373043/nestjs-pulsar\n```\n\n> **Note**\n>\n> Pulsar Node.js client library is based on the C++ client library. You must install the Pulsar C++ client library before installing a Node.js client. For more details, see [pulsar-client-node on GitHub](https://github.com/apache/pulsar-client-node) or [The Pulsar Node.js client dedicated page](https://pulsar.apache.org/docs/3.0.x/client-libraries-node/) on [Apache Pulsar documentation](https://pulsar.apache.org/docs/3.0.x/).\n\n## Getting started\n\nOnce the installation process (npm install) is complete, we can import the `PulsarModule` into the root `AppModule`.\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { PulsarModule } from '@dev5c32373043/nestjs-pulsar';\n\n@Module({\n  imports: [\n    PulsarModule.forRoot({\n      serviceUrl: 'pulsar://localhost:6650',\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nThe `forRoot()` method supports all the configuration properties exposed by the Client class constructor from the [`pulsar-client`](https://www.npmjs.com/package/pulsar-client) package.\n\n> **Note**\n>\n> `forRoot()` inject the Pulsar Client provider globally.\n\nNext, let's look at another module, let's say the `UsersModule`.\n\nOnce the pulsar Client configured. You can inject the needed `Producer`, `Consumer`, `Reader` using the `forFeature()` method:\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { PulsarModule, MessageId } from '@dev5c32373043/nestjs-pulsar';\n\n@Module({\n  imports: [\n    PulsarModule.forFeature('producer', 'my-producer', {\n      topic: 'my-topic',\n    }),\n    PulsarModule.forFeature('consumer', 'my-consumer', {\n      topic: 'my-topic',\n      subscription: 'my-sub',\n    }),\n    PulsarModule.forFeature('reader', 'my-reader', {\n      topic: 'my-topic',\n      startMessageId: MessageId.earliest(),\n    }),\n  ],\n})\nexport class UsersModule {}\n```\n\n> **Warning**\n>\n> Producer, consumer, reader name (2nd param) is mandatory. Please note that you shouldn't have multiple producers, consumers or readers with the same name, otherwise they will get overridden.\n\nThe `forFeature()` method third param supports all the configuration properties exposed by the following Pulsar `Client` factory methods:\n\n- `producer` feature configuration object corresponds to `client.createProducer()` configuration object.\n- `consumer` feature configuration object corresponds to `client.subscribe()` configuration object.\n- `reader` feature configuration object corresponds to `client.createReader()` configuration object.\n\nThis module uses the `forFeature()` method to define which features (producer, consumer or reader) are registered in the current scope. With that in place, we can inject the `Producer`, `Consumer` and `Reader` Pulsar objects into the UsersService using the @PulsarInject() decorator:\n\n```ts\nimport { Injectable } from '@nestjs/common';\nimport { InjectPulsar, Producer, Consumer, Reader } from '@dev5c32373043/nestjs-pulsar';\n\n@Injectable()\nexport class UsersService {\n  constructor(\n    @InjectPulsar('producer', 'my-producer')\n    private readonly producer: Producer,\n    @InjectPulsar('consumer', 'my-consumer')\n    private readonly consumer: Consumer,\n    @InjectPulsar('reader', 'my-reader')\n    private readonly reader: Reader,\n  ) {}\n\n  async publish(data: any) {\n    await this.producer.send({ data: Buffer.from(JSON.stringify(data)) });\n  }\n\n  async consume(timeout: number = 1000) {\n    const rawMessage = await this.consumer.receive(timeout); // timeout is optional\n    const data = JSON.parse(rawMessage.getData().toString());\n    await this.consumer.acknowledge(rawMessage);\n\n    return data;\n  }\n\n  async read() {\n    if (!this.reader.hasNext()) return;\n\n    const rawMessage = await this.reader.readNext();\n    const data = JSON.parse(rawMessage.getData().toString());\n\n    return data;\n  }\n}\n```\n\nIf you want to use the producer, consumer or reader outside of the module which imports `PulsarModule.forFeature()`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { PulsarModule } from '@dev5c32373043/nestjs-pulsar';\n\n@Module({\n  imports: [\n    PulsarModule.forFeature('producer', 'my-producer', {\n      topic: 'my-topic',\n    }),\n    PulsarModule.forFeature('consumer', 'my-consumer', {\n      topic: 'my-topic',\n      subscription: 'my-sub',\n    }),\n    PulsarModule.forFeature('reader', 'my-reader', {\n      topic: 'my-topic',\n    }),\n  ],\n  exports: [PulsarModule],\n})\nexport class UsersModule {}\n```\n\n## Async configuration\n\nYou may want to pass your module options asynchronously instead of statically. In this case, use the `forRootAsync()` method:\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { PulsarModule } from '@dev5c32373043/nestjs-pulsar';\n\n@Module({\n  imports: [\n    PulsarModule.forRootAsync({\n      useFactory: () => ({\n        serviceUrl: 'pulsar://localhost:6650',\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nOur factory behaves like any other asynchronous provider (e.g., it can be async and it's able to inject dependencies through inject):\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { PulsarModule } from '@dev5c32373043/nestjs-pulsar';\n\n@Module({\n  imports: [\n    PulsarModule.forRootAsync({\n      imports: [ConfigModule],\n      inject: [ConfigService],\n      useFactory: (config: ConfigService) => ({\n        serviceUrl: config.get('SERVICE_URL'),\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n## Multiple clients\n\nSome projects require multiple pulsar clients. This can also be achieved with this module. To work with multiple clients, first create the clients. In this case, client naming becomes mandatory.\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { PulsarModule } from '@dev5c32373043/nestjs-pulsar';\n\n@Module({\n  imports: [\n    PulsarModule.forRoot({\n      serviceUrl: 'pulsar://localhost:6650',\n    }),\n    PulsarModule.forRoot(\n      {\n        serviceUrl: 'pulsar://other.client:6650',\n      },\n      'other-client', // client name\n    ),\n  ],\n})\nexport class AppModule {}\n```\n\n> **Warning**\n>\n> If you don't set the name for a client, its name is set to default. Please note that you shouldn't have multiple clients without a name, or with the same name, otherwise they will get overridden.\n\nIf you are using `PulsarModule.forRootAsync()`, you have to also set the client name the same way:\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { PulsarModule } from '@dev5c32373043/nestjs-pulsar';\n\n@Module({\n  imports: [\n    PulsarModule.forRootAsync({\n      useFactory: () => ({\n        serviceUrl: 'pulsar://localhost:6650',\n      }),\n    }),\n    PulsarModule.forRootAsync(\n      {\n        useFactory: () => ({\n          serviceUrl: 'pulsar://other.client:6650',\n        }),\n      },\n      'other-client',\n    ),\n  ],\n})\nexport class AppModule {}\n```\n\n## Testing\n\nWhen it comes to unit testing an application, we usually want to avoid making a real Pulsar connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on producers, consumers or readears that are pulled that are created from the client instance. How do we handle that? The solution is to create mocks. In order to achieve that, we set up custom providers. Each registered producer, consumer or reader is automatically represented by an auto-generated token.\n\nThe @dev5c32373043/nestjs-pulsar package exposes the `getFeatureToken()` function which returns a prepared token based on a given feature type and name.\n\n```ts\n@Module({\n  providers: [\n    UsersService,\n    {\n      provide: getFeatureToken('consumer', 'my-consumer'),\n      useValue: mockConsumer,\n    },\n  ],\n})\nexport class UsersModule {}\n```\n\nNow a substitute mockConsumer will be used as the `Consumer` named `myConsumer`. Whenever any class asks for `myConsumer` using an `@PulsarInject()` decorator, Nest will use the registered mockConsumer object.\n\n## License\n\nNest Pulsar is [MIT licensed](LICENSE).\n","readmeFilename":"README.md"}