AdonisJS

repository·7.x·Indexed 12 days ago

https://github.com/adonisjs/core

A fullstack MVC framework for Node.js that prioritizes developer ergonomics and speed. Version 7.4.0 provides a stable API for building web applications and microservices, featuring the Ace CLI for package installation, production builds, environment variable management, and scaffolding generation via make commands.

Tokens
20.5K
Snippets
89
Records
100
Agent score
96%

What's inside AdonisJS

  1. Overview of AdonisJS

    7.x
    AdonisJS is a fullstack MVC (Model-View-Controller) framework for Node.js designed with a focus on ergonomics and speed. It provides a clean and stable API to handle common web development complexities, making it suitable for building both full-scale web applications and microservices.
  2. Extend EncryptorsList to register custom encryptors

    7.x

    To register multiple encryption configurations (e.g., a primary and a secondary encryptor), extend the EncryptorsList interface. This enables the EncryptionService to manage multiple encryption keys or configurations.

    // Extending EncryptorsList in user code
    declare module '@adonisjs/core' {
      interface EncryptorsList {
        default: EncryptionConfig
        secondary: EncryptionConfig
      }
    }
  3. How HttpServerProcess manages server lifecycle

    7.x

    The HttpServerProcess implements several lifecycle management patterns to ensure stability:

    1. Initialization: It triggers the application's init() and boot() phases before the server starts listening.
    2. Graceful Shutdown: It listens for the application's terminating event. When triggered, it calls the underlying Node.js server's .close() method to stop accepting new connections.
    3. Error Monitoring: It monitors the Node.js server for 'error' events. If the server crashes, it logs a fatal error, sets the process exit code to 1, and calls app.terminate() to shut down the application.
    4. Startup Notification: Once the server is listening, it notifies the system via:
      • The application's notify method (with isAdonisJS: true and environment: 'web').
      • The logger service.
      • The emitter service via the http:server_ready event.
  4. Extend LoggersList to register custom loggers

    7.x

    To register custom loggers that are available via the logger service, extend the LoggersList interface using module augmentation. This allows the LoggerService to provide type-safe access to your specific logger configurations.

    // Extending LoggersList in user code
    declare module '@adonisjs/core' {
      interface LoggersList {
        default: LoggerConfig
        file: LoggerConfig
      }
    }
  5. Extend HashersList to register custom hashers

    7.x

    To add custom hashing algorithms (drivers) to the hash service, extend the HashersList interface. This allows you to use different hashing strategies defined in your configuration.

    // Extending HashersList in user code
    declare module '@adonisjs/core' {
      interface HashersList {
        scrypt: ManagerDriverFactory
        argon: ManagerDriverFactory
      }
    }
  6. Behavioral notes for `make:controller` flags

    7.x

    When using make:controller, certain flags have precedence or conflicts:

    • Custom Actions vs Resource Flags: If you provide custom method names via actions, the --resource and --api flags are ignored. The command will log a warning and use the actions stub instead.
    • API vs Resource: The --api flag and --resource flag cannot be used together. If both are provided, --api takes precedence and --resource is ignored. The command will log a warning.
  7. How configuration providers work

    7.x

    Configuration providers are an abstraction used to defer the resolution of configuration until the application is fully booted. This pattern is essential when configuration depends on other application services (like environment variables or other providers) that are not available during the initial module loading phase.

    Instead of passing a static object, you pass a ConfigProvider which contains a resolver function. The lifecycle involves:

    1. Creation: Defining the provider using configProvider.create().
    2. Resolution: Calling configProvider.resolve(app, provider) during the application boot process to transform the provider into the final configuration object.
  8. Extend EventsList to register custom events

    7.x

    AdonisJS uses a type-safe event system. To add your own custom events and define their payload types, you must extend the EventsList interface using TypeScript module augmentation. This ensures that when you use the emitter service, your custom events are recognized and type-checked.

    // Extending EventsList in user code
    declare module '@adonisjs/core' {
      interface EventsList {
        'user:created': { user: User }
        'order:placed': { orderId: string, amount: number }
      }
    }
  9. Install and configure AdonisJS packages with `ace add`

    7.x

    The ace add command automates the process of installing one or more packages and immediately running their configuration hooks. This replaces the manual two-step process of running npm install followed by node ace configure.

    Key Features:

    • Shorthand Names: You can use shorthand names for common packages:
      • vinejs resolves to @vinejs/vine
      • edge resolves to edge.js
    • Batch Installation: You can pass multiple package names in a single command.
    • Automatic Configuration: After successful installation, the command automatically invokes the configure command for each package.
    # Install a single package
    ace add @adonisjs/lucid
    
    # Install multiple packages at once
    ace add @adonisjs/lucid @adonisjs/auth @adonisjs/session
    
    # Install a package as a dev dependency
    ace add @adonisjs/session --dev
    
    # Forcefully overwrite existing configuration files
    ace add vinejs --force
    
    # Specify a specific package manager (e.g., pnpm)
    ace add edge --package-manager=pnpm
  10. Create a new CLI command

    7.x

    When using the AdonisJS CLI to generate a new command, the resulting file follows a specific structure based on the BaseCommand class. A generated command includes a static commandName for the CLI entrypoint, a description, and an options object for defining flags and arguments.

    Note that the generator uses placeholders like {{ commandName }} and {{ commandTerminalName }} which are resolved during the scaffolding process to create the class name and the CLI command string respectively.

    import { BaseCommand } from '@adonisjs/core/ace'
    import type { CommandOptions } from '@adonisjs/core/types/ace'
    
    export default class MyCommand extends BaseCommand {
      static commandName = 'my:command'
      static description = 'A description of what this command does'
    
      static options: CommandOptions = {}
    
      async run() {
        this.logger.info('Hello world from "MyCommand"')
      }
    }
  11. Configure ESLint with @adonisjs/eslint-config

    7.x

    To use the recommended ESLint configuration for AdonisJS projects, import configPkg from @adonisjs/eslint-config and export it as the default configuration in your eslint.config.js file. You can pass an options object to configPkg to define global ignores for the linting process.

    import { configPkg } from '@adonisjs/eslint-config'
    
    export default configPkg({
      ignores: ['coverage'],
    })
  12. Configure IndexEntities via IndexEntitiesConfig

    7.x

    The IndexEntitiesConfig type is used to configure the automatic generation of barrel files for various application entities like controllers, listeners, events, and transformers. This helps in maintaining clean imports.

    Configuration Options

    • controllers: Configures indexing for controllers.
    • listeners: Configures indexing for event listeners.
    • events: Configures indexing for event files.
    • transformers: Configures indexing for transformers (e.g., for Inertia).
    • manifest: Configures manifest generation settings.

    Each entity group (controllers, listeners, etc.) supports the following sub-options:

    • enabled: Boolean to toggle indexing.
    • source: The directory where files are located.
    • importAlias: The alias used for imports (e.g., #controllers).
    • glob: Array of glob patterns to match files.
    • skipSegments: Array of path segments to exclude from generated keys.
    // Basic configuration
    const config: IndexEntitiesConfig = {
      controllers: { enabled: true },
      events: { source: 'app/custom-events' }
    }
    
    // Detailed configuration with custom paths
    const config: IndexEntitiesConfig = {
      controllers: {
        enabled: true,
        source: 'app/http/controllers',
        importAlias: '#controllers',
        glob: ['**/*_controller.ts']
      },
      listeners: {
        enabled: false
      }
    }