Skip to content

Commit

Permalink
feat: added async and sync, docs
Browse files Browse the repository at this point in the history
- Changed name from createAdminModule to createAdminAsync
- Fixed type for authentication in AdminModuleOptions
- Improvements for jsdoc
- Adjusted example for the change
- Removed packages for express, as developer should add them on his own
  • Loading branch information
SimonB407 committed Sep 2, 2020
1 parent 5044e98 commit e99d978
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 111 deletions.
5 changes: 3 additions & 2 deletions example-app/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Module } from '@nestjs/common';
import { MongooseModule, getModelToken } from '@nestjs/mongoose';
import { AdminModule } from '@admin-bro/nestjs';
import { Model } from 'mongoose';

import { AdminModule } from '../../src'; // lib

import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Admin } from './mongoose/admin-model';
Expand All @@ -11,7 +12,7 @@ import { MongooseSchemasModule } from './mongoose/mongoose.module';
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27017/nest'),
AdminModule.createAdminModule({
AdminModule.createAdminAsync({
imports: [
MongooseSchemasModule,
],
Expand Down
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
},
"peerDependencies": {
"admin-bro": ">=3.0.0-beta.7"
"admin-bro": ">=3.0.0"
},
"devDependencies": {
"@commitlint/cli": "^8.3.5",
Expand All @@ -41,12 +41,9 @@
"typescript": "^3.9.7"
},
"dependencies": {
"@admin-bro/express": "^3.0.0-beta.3",
"@nestjs/common": "^7.4.2",
"@nestjs/core": "^7.4.2",
"@types/express-session": "^1.17.0",
"express-formidable": "^1.2.0",
"express-session": "^1.17.1",
"reflect-metadata": "^0.1.13",
"rxjs": "^6.5.3"
}
Expand Down
15 changes: 13 additions & 2 deletions src/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,20 @@ export class AdminModule implements OnModuleInit {
@Inject(CONFIG_TOKEN)
private readonly adminModuleOptions: AdminModuleOptions,
) {}

public static createAdmin(options: AdminModuleOptions): DynamicModule {
return {
module: AdminModule,
providers: [
{
provide: CONFIG_TOKEN,
useValue: options,
},
],
}
}

public static createAdminModule(options: AdminModuleFactory): DynamicModule {
public static createAdminAsync(options: AdminModuleFactory): DynamicModule {
return {
imports: options.imports,
module: AdminModule,
Expand All @@ -41,6 +53,5 @@ export class AdminModule implements OnModuleInit {
...this.adminModuleOptions,
adminBroOptions: admin.options,
});
admin.watch()
}
}
97 changes: 76 additions & 21 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,26 @@
* 1. First of all, install the AdminBro along with the module:
*
* ```
* yarn add admin-bro @admin-bro/nestjs @admin-bro/express
* yarn add admin-bro @admin-bro/nestjs
* ```
*
* 2. Once the installation process is complete, we can import the AdminBroModule
* ### Express:
* You have to additionally add admin-bro express plugin along with packages it's using, express and express formidable:
*
* ```
* yarn add express @admin-bro/express express-formidable
* ```
*
* If you are passing `authenticate` object you have to also add express-session:
*
* ```
* yarn add express-session
* ```
*
* ### Fastify:
* Work in progress - currently not available
*
* 2. Once the installation process is complete, we can import the AdminModule
* into the root AppModule.
*
* ```
Expand All @@ -22,14 +38,10 @@
*
* @Module({
* imports: [
* AdminModule.createAdminModule({
* useFactory: () => ({
* adminBroOptions: {
* rootPath: '/admin',
* resources: [],
* },
* }),
* }),
* AdminModule.createAdmin({
* rootPath: '/admin',
* resources: [],
* }),
* ],
* })
* export class AppModule {}
Expand Down Expand Up @@ -68,31 +80,28 @@
* entities: [User],
* synchronize: true,
* }),
* AdminModule.createAdminModule({
* useFactory: () => ({
* adminBroOptions: {
* AdminModule.createAdmin({
* adminBroOptions: {
* rootPath: '/admin',
* resources: [User],
* },
* }),
* }),
* }
* }),
* ],
* })
* export class AppModule {}
* ```
*
* ## Authentication
*
* Apart from the `adminBroOptions` useFactory can return `auth` settings.
* Apart from the `adminBroOptions` you can define `auth` settings.
*
* This is an example which always logs users in, since authenticate method
* always returns a Promise resolving to {@link CurrentAdmin}. You may
* want to compare the password against what what you have encrypted
* in the database.
*
* ```
* AdminModule.createAdminModule({
* useFactory: () => ({
* AdminModule.createAdmin({
* adminBroOptions: {
* rootPath: '/admin',
* resources: [User],
Expand All @@ -102,11 +111,57 @@
* cookieName: 'test',
* cookiePassword: 'testPass',
* },
* }),
* }),
* ```
* ## Advanced techniques
* Sometimes some thing couldn't be provided synchronously, that's why there is also asynchronous way of providing options.
*
* Let's say you use @nestjs/mongoose module, which could define models in modules that fit the best contextually.
* This creates a problem that we don't have model instance available yet when we are creating AdminModule synchronously.
*
* We can take advantage of nestjs dependency injection using `AdminModule.createAdminAsync()`.
* This method alows us to import modules that have necessary dependencies and then inject them to admin bro config.
*
* For example:
* - we have MongooseSchemasModule which defines Admin model and exports it:
* ```
* @Module({
* imports: [
* MongooseModule.forFeature([{ name: 'Admin', schema: AdminSchema }]),
* ],
* exports: [MongooseModule],
* })
* export class MongooseSchemasModule {}
* ```
* - we want to use Admin model in admin-bro panel, to be displayed as the resource
* ```
* @Module({
* imports: [
* MongooseModule.forRoot('mongodb://localhost:27017/test'),
* AdminModule.createAdminAsync({
* imports: [
* MongooseSchemasModule, // importing module that exported model we want to inject
* ],
* inject: [
* getModelToken('Admin'), // using mongoose function to inject dependency
* ],
* useFactory: (adminModel: Model<Admin>) => ({ // injected dependecy will appear as an argument
* adminBroOptions: {
* rootPath: '/admin',
* resources: [
* { resource: adminModel },
* ],
* },
* }),
* }),
* MongooseSchemasModule,
* ],
* })
* export class AppModule { }
* ```
*
* There is a working example [here](https://github.com/SoftwareBrothers/admin-bro-nestjs/tree/master/example-app)
*/

import * as NestJSPlugin from './admin.module'

export * from './admin.module';
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/admin-module-options.interface.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { AdminBroOptions } from 'admin-bro';
import { AdminBroOptions, CurrentAdmin } from 'admin-bro';
import { SessionOptions } from 'express-session';

import { ExpressFormidableOptions } from './express-formidable-options.interface';

export interface AdminModuleOptions {
adminBroOptions: AdminBroOptions,
auth?: {
authenticate: Function,
authenticate: (email: string, password: string) => Promise<CurrentAdmin>,
cookiePassword: string,
cookieName: string,
}
Expand Down
Loading

0 comments on commit e99d978

Please sign in to comment.