/**
* @module @adminjs/nestjs
* @subcategory Plugins
* @section modules
*
* @classdesc
* This is an official plugin which allows you to render AdminJS in [NestJS
* framework](https://nestjs.com/)
*
* ## Installation
*
* 1. First of all, install the AdminJS along with the module:
*
* ```
* yarn add adminjs @adminjs/nestjs
* ```
*
* ### Express:
* You have to additionally add adminjs express plugin along with packages it's using, express and express formidable:
*
* ```
* yarn add express @adminjs/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.
*
* ```
* import { Module } from '@nestjs/common';
* import { AdminModule } from '@adminjs/nestjs';
*
* \@Module({
* imports: [
* AdminModule.createAdmin({
* adminJsOptions: {
* rootPath: '/admin',
* resources: [],
* }),
* },
* ],
* })
* export class AppModule {}
* ```
*
* Then enter `/admin` path in your browser and you should see the AdminJS.
*
* 3. Passing resources
*
* Let say you use @nestjs/typeorm module, and you have users module.
*
* - you have to install @adminjs/typeorm adapter
* - you have to register it in AdminJS (as stated in the docs)
* - and you have to pass it to your options
*
* ```
* import AdminJS from 'adminjs';
* import { Module } from '@nestjs/common';
* import { AdminModule } from '@adminjs/nestjs';
* import { Database, Resource } from '@adminjs/typeorm'
* import { TypeOrmModule } from '@nestjs/typeorm';
* import { UsersModule } from './users/users.module';
*
* AdminJS.registerAdapter({ Database, Resource })
*
* \@Module({
* imports: [
* // you will have to change connection data of course :)
* TypeOrmModule.forRoot({
* type: 'postgres',
* host: 'localhost',
* port: 5432,
* username: 'postgres',
* password: '',
* database: 'database_test',
* entities: [User],
* synchronize: true,
* }),
* AdminModule.createAdmin({
* adminJsOptions: {
* rootPath: '/admin',
* resources: [User],
* }
* }),
* ],
* })
* export class AppModule {}
* ```
*
* ## Authentication
*
* Apart from the `adminJsOptions` 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.createAdmin({
* adminJsOptions: {
* rootPath: '/admin',
* resources: [User],
* },
* auth: {
* authenticate: async (email, password) => Promise.resolve({ email: 'test' }),
* 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 adminjs 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
* adminJsOptions: {
* rootPath: '/admin',
* resources: [
* { resource: adminModel },
* ],
* },
* }),
* }),
* MongooseSchemasModule,
* ],
* })
* export class AppModule { }
* ```
*
* ## Custom loader
* In most cases default plugins for adminjs are enough for functionality we need, but in rare ocasions
* we want to customize routing, or achieve different logic after login and this cases can be achieved only
* by providing own plugin implementation. Because @adminjs/nestjs under the hood uses plugin for express (@adminjs/express)
* it would require basically copying whole nestjs plugin and express plugin to own project to put any changes.
* Instead there is optional parameter to put your custom loader if you don't want to use official one for any reason.
* Your custom loader must extend AbstractLoader.
*
* ```
* \@Injectable()
* export class CustomLoader extends AbstractLoader {
* public register(
* admin: AdminJS,
* httpAdapter: AbstractHttpAdapter,
* options: AdminModuleOptions,
* ) {}
* }
* ```
*
* And then in module:
*
* ```
* AdminModule.createAdmin({
* adminJsOptions: {
* //...
* },
* auth: {
* //...
* },
* customLoader: CustomLoader,
* }),
* ```
*
* or if you using more advanced techniques:
*
* ```
* AdminModule.createAdmin({
* useFactory: () => {}
* customLoader: CustomLoader,
* }),
* ```
*
* ## Example
* There is a working example [here](https://github.com/SoftwareBrothers/adminjs-nestjs/tree/master/example-app)
*/
import * as NestJSPlugin from './admin.module'
export * from './admin.module';
export default NestJSPlugin;
export * from './interfaces/admin-module-factory.interface';
export * from './interfaces/admin-module-options.interface';
export * from './interfaces/custom-loader.interface';
export * from './loaders/abstract.loader';
Source