Skip to content
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

Add registerAsync #16

Merged
merged 6 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# [1.1.0-beta.1](https://github.com/ronati/narango/compare/v1.0.0...v1.1.0-beta.1) (2023-10-26)


### Features

* **module:** add registerAsync function to Narango module ([5bd1f51](https://github.com/ronati/narango/commit/5bd1f513034bfd6feee322ab73dd1bdc4ba35c3a))

# 1.0.0 (2023-10-26)


Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,36 @@ For sake of simplicity the database credentials are passed directly to the regis

```

### Async registration

If you need to use providers to provide the options to Narango module, you can use `NarangoModule.registerAsync`:

```ts
import { Module } from "@nestjs/common";
import { NarangoModule } from "@ronatilabs/narango";
import { ConfigModule, ConfigService } from "@nestjs/config";

@Module({
imports: [
ConfigModule.forRoot(),
NarangoModule.registerAsync({
useFactory: (config: ConfigService) => ({
database: {
url: config.get<string>("url"),
databaseName: config.get<string>("databaseName"),
auth: {
username: config.get<string>("username"),
password: config.get<string>("password"),
},
},
}),
inject: [ConfigService],
}),
],
})
export class MyAppModule {}
```

## Inject NarangoService

Now you can access the `NarangoService` everywhere you need it in your application:
Expand Down Expand Up @@ -108,3 +138,7 @@ This project is setup with automatic semver versioning based on your commit sema
3. Follow along the wizard to create your commit.
4. Push your commit on the branch.
5. Create your PR.

## Notes for project's maintainers

When you merge a PR from `beta` into `main` and it successfully published a new version on the `latest` channel, **don't forget to create a PR from `main` to `beta`**. **This is mandatory** for `semantic-release` to take it into account for next `beta` version.
2 changes: 1 addition & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from "./narango.config";
export { NarangoModuleOptions } from "./narango.module-definition";
export * from "./narango.service";
export * from "./narango.module";
7 changes: 0 additions & 7 deletions lib/narango.config.ts

This file was deleted.

15 changes: 15 additions & 0 deletions lib/narango.module-definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Config as ArangoDBConfig } from "arangojs/connection";
import { ConfigurableModuleBuilder } from "@nestjs/common";

export interface NarangoModuleOptions {
global?: boolean;
database: ArangoDBConfig;
}

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
new ConfigurableModuleBuilder<NarangoModuleOptions>()
.setExtras({ global: false }, (definition, extras) => ({
...definition,
global: extras.global,
}))
.build();
23 changes: 6 additions & 17 deletions lib/narango.module.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
import { Module } from "@nestjs/common";
import type { DynamicModule } from "@nestjs/common";

import { NarangoService } from "./narango.service";
import { MODULE_OPTIONS } from "./narango.config";
import type { NarangoModuleOptions } from "./narango.config";
import { ConfigurableModuleClass } from "./narango.module-definition";

@Module({})
export class NarangoModule {
static register(options: NarangoModuleOptions): DynamicModule {
return {
module: NarangoModule,
global: options.global,
providers: [
{ provide: MODULE_OPTIONS, useValue: options },
NarangoService,
],
exports: [NarangoService],
};
}
}
@Module({
providers: [NarangoService],
exports: [NarangoService],
})
export class NarangoModule extends ConfigurableModuleClass {}
10 changes: 7 additions & 3 deletions lib/narango.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ import { Inject, Injectable } from "@nestjs/common";
import type { OnApplicationShutdown } from "@nestjs/common";
import { Database } from "arangojs";

import { MODULE_OPTIONS } from "./narango.config";
import type { NarangoModuleOptions } from "./narango.config";
import {
MODULE_OPTIONS_TOKEN,
NarangoModuleOptions,
} from "./narango.module-definition";

@Injectable()
export class NarangoService implements OnApplicationShutdown {
public db: Database;

constructor(@Inject(MODULE_OPTIONS) private options: NarangoModuleOptions) {
constructor(
@Inject(MODULE_OPTIONS_TOKEN) private options: NarangoModuleOptions,
) {
this.db = new Database(options.database);
}

Expand Down
38 changes: 37 additions & 1 deletion lib/narango.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Test } from "@nestjs/testing";

import { NarangoModule } from "./narango.module";
import { NarangoService } from "./narango.service";
import { Injectable, Module } from "@nestjs/common";
import { Global, Injectable, Module } from "@nestjs/common";

const closeSpy = jest.fn();
jest.mock("arangojs", () => ({
Expand Down Expand Up @@ -86,6 +86,42 @@ describe("Narango module", () => {
expect(serviceFromRoot).toBeDefined();
expect((serviceFromRoot.db as any).options).toEqual(options);
});

it("can be registered async", async () => {
@Injectable()
class TestService {
public options = { url: "http://overridden.url" };
constructor() {}
}

@Global()
@Module({ providers: [TestService], exports: [TestService] })
class ChildModule {}

const rootModule = await Test.createTestingModule({
imports: [
ChildModule,
NarangoModule.registerAsync({
useFactory: (testService: TestService) => {
return {
database: {
...options,
url: testService.options.url,
},
};
},
inject: [TestService],
}),
],
}).compile();

const serviceFromRoot = rootModule.get<NarangoService>(NarangoService);
expect(serviceFromRoot).toBeDefined();
expect((serviceFromRoot.db as any).options).toEqual({
...options,
url: "http://overridden.url",
});
});
});

/* eslint-enable @typescript-eslint/no-explicit-any */
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ronatilabs/narango",
"version": "1.0.0",
"version": "1.1.0-beta.1",
"description": "A NestJS wrapper service for ArangoDB NodeJS driver",
"exports": "./dist/index.js",
"typings": "./dist/index.d.ts",
Expand Down