import { RuntimeException, createError } from "@poppinss/utils/exception";
import Hooks from "@poppinss/hooks";
import { fileURLToPath } from "node:url";
import { extname, join, relative } from "node:path";
import { Container } from "@adonisjs/fold";
import Macroable from "@poppinss/macroable";
import { detectAIAgent, importDefault, isRunningInAIAgent } from "@poppinss/utils";
import { debuglog, inspect } from "node:util";
import string from "@poppinss/utils/string";
import StringBuilder from "@poppinss/utils/string_builder";
import { Config, ConfigLoader } from "@adonisjs/config";
import globParent from "glob-parent";
import diagnostics_channel from "node:diagnostics_channel";
//#region \0rolldown/runtime.js
var __defProp = Object.defineProperty;
var __exportAll = (all, no_symbols) => {
	let target = {};
	for (var name in all) __defProp(target, name, {
		get: all[name],
		enumerable: true
	});
	if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
	return target;
};
//#endregion
//#region src/errors.ts
var errors_exports = /* @__PURE__ */ __exportAll({
	E_INVALID_HOOKS_VALUE: () => E_INVALID_HOOKS_VALUE,
	E_INVALID_PRELOAD_FILE: () => E_INVALID_PRELOAD_FILE,
	E_INVALID_PRESETS_VALUE: () => E_INVALID_PRESETS_VALUE,
	E_INVALID_PRESET_FUNCTION: () => E_INVALID_PRESET_FUNCTION,
	E_INVALID_PROVIDER: () => E_INVALID_PROVIDER,
	E_MISSING_METAFILE_PATTERN: () => E_MISSING_METAFILE_PATTERN,
	E_MISSING_PRELOAD_FILE: () => E_MISSING_PRELOAD_FILE,
	E_MISSING_PROVIDER_FILE: () => E_MISSING_PROVIDER_FILE,
	E_MISSING_SUITE_FILES: () => E_MISSING_SUITE_FILES,
	E_MISSING_SUITE_NAME: () => E_MISSING_SUITE_NAME,
	E_PRESET_EXECUTION_ERROR: () => E_PRESET_EXECUTION_ERROR,
	E_UNKNOWN_ASSEMBLER_HOOK: () => E_UNKNOWN_ASSEMBLER_HOOK
});
/**
* Exception raised when the "pattern" property is missing in a metafile entry.
* Metafiles define file patterns for copying or watching operations.
*/
const E_MISSING_METAFILE_PATTERN = createError("Invalid metafile entry \"%s\". Missing pattern property", "E_MISSING_METAFILE_PATTERN");
/**
* Exception raised when the "file" property is missing in a preload entry.
* Preload entries must specify a file property containing an import function.
*/
const E_MISSING_PRELOAD_FILE = createError("Invalid preload entry \"%s\". Missing file property", "E_MISSING_PRELOAD_FILE");
/**
* Exception raised when the "file" property in a preload entry is not a function.
* The file property must be a dynamic import function that returns a module.
*/
const E_INVALID_PRELOAD_FILE = createError("Invalid preload entry \"%s\". The file property must be a function", "E_INVALID_PRELOAD_FILE");
/**
* Exception raised when the "file" property is missing in a provider entry.
* Provider entries must specify a file property containing an import function.
*/
const E_MISSING_PROVIDER_FILE = createError("Invalid provider entry \"%s\". Missing file property", "E_MISSING_PROVIDER_FILE");
/**
* Exception raised when the "file" property in a provider entry is not a function.
* The file property must be a dynamic import function that returns a provider class.
*/
const E_INVALID_PROVIDER = createError("Invalid provider entry \"%s\". The file property must be a function", "E_INVALID_PROVIDER");
/**
* Exception raised when the "name" property is missing in a test suite entry.
* Test suites must have a unique name identifier.
*/
const E_MISSING_SUITE_NAME = createError("Invalid suite entry \"%s\". Missing name property", "E_MISSING_SUITE_NAME");
/**
* Exception raised when the "files" property is missing in a test suite entry.
* Test suites must specify which files or patterns to include.
*/
const E_MISSING_SUITE_FILES = createError("Invalid suite entry \"%s\". Missing files property", "E_MISSING_SUITE_FILES");
/**
* Exception raised when a hook is defined for an unknown assembler event.
* Only predefined assembler events support hooks.
*/
const E_UNKNOWN_ASSEMBLER_HOOK = createError("Assembler hook defined for unknown event \"%s\"", "E_UNKNOWN_ASSEMBLER_HOOK");
/**
* Exception raised when hooks for an event are not specified as an array.
* Hooks must be provided as an array of dynamic import functions.
*/
const E_INVALID_HOOKS_VALUE = createError("Expected hooks for event \"%s\" to be an array of dynamic imports. Instead received \"%s\"", "E_INVALID_HOOKS_VALUE");
/**
* Exception raised when the presets property is not an array.
* Presets must be provided as an array of configuration functions.
*/
const E_INVALID_PRESETS_VALUE = createError("Expected presets to be an array of functions. Instead received \"%s\"", "E_INVALID_PRESETS_VALUE");
/**
* Exception raised when a preset at a specific index is not a function.
* Each preset must be a function that modifies the RC file configuration.
*/
const E_INVALID_PRESET_FUNCTION = createError("Expected preset at index %s to be a function. Instead received \"%s\"", "E_INVALID_PRESET_FUNCTION");
/**
* Exception raised when a preset function throws an error during execution.
* This indicates an issue with the preset implementation or configuration.
*/
const E_PRESET_EXECUTION_ERROR = createError("Preset at index %s failed to execute: %s", "E_PRESET_EXECUTION_ERROR");
//#endregion
//#region src/debug.ts
/**
* Debug logger instance configured for AdonisJS application debugging.
* Uses Node.js built-in debuglog with the 'adonisjs:app' namespace.
*
* Enable debug output by setting NODE_DEBUG=adonisjs:app environment variable.
*
* @example
* debug('Application state changed to: %s', newState)
*/
var debug_default = debuglog("adonisjs:app");
//#endregion
//#region src/generators.ts
/**
* Generators used for scaffolding various AdonisJS entities.
* Provides utilities for creating standardized names, file names,
* and paths for models, controllers, middleware, and other framework components.
*/
const generators = {
	/**
	* List of controller names that should always be generated in singular form.
	* These are typically system/admin controllers or special-purpose controllers
	* that don't represent plural resources.
	*
	* @example
	* // These will remain singular:
	* // 'home' -> 'HomeController'
	* // 'admin' -> 'AdminController'
	* // 'auth' -> 'AuthController'
	*/
	singularControllerNames: [
		"home",
		"admin",
		"session",
		"application",
		"money",
		"signup",
		"login",
		"auth",
		"authentication",
		"adonis",
		"adonisjs",
		"dashboard",
		"api",
		"about",
		"contact",
		"blog",
		"library",
		"password",
		"password_link",
		"new_password",
		"profile",
		"account",
		"new_account",
		"avatar",
		"forum"
	],
	/**
	* Converts an entity path segment to snake_case. Override this
	* method to customize how path segments are formatted.
	*
	* @param segmentName - The path segment to convert
	* @returns Formatted path segment
	*
	* @example
	* entityPathSegment('UserProfile') // 'user_profile'
	* entityPathSegment('blog-posts') // 'blog_posts'
	*/
	entityPathSegment(segmentName) {
		return new StringBuilder(segmentName).snakeCase().toString();
	},
	/**
	* Creates the entity path and name from user input.
	* Parses the entity name to separate directory path from the actual name,
	* handling file extensions and nested paths. Each path segment is formatted
	* using the {@link entityPathSegment} method.
	*
	* @param entityName - The entity name which may include path and extension
	* @returns Object containing the parsed path and name
	*
	* @example
	* createEntity('admin/users') // { path: 'admin', name: 'users' }
	* createEntity('user.ts') // { path: './', name: 'user' }
	* createEntity('profile') // { path: './', name: 'profile' }
	*/
	createEntity(entityName) {
		/**
		* Get rid of extensions
		*/
		entityName = entityName.replace(new RegExp(`${extname(entityName)}$`), "");
		/**
		* Split to see if we are dealing with a path
		*/
		const parts = entityName.split("/");
		/**
		* Last part is always the entity name
		*/
		const [name] = parts.splice(-1);
		/**
		* Still have parts? Join them back
		*/
		if (parts.length) return {
			path: parts.map((part) => this.entityPathSegment(part)).join("/"),
			name
		};
		/**
		* Use relative current dir
		*/
		return {
			path: "./",
			name
		};
	},
	/**
	* Constructs a Unix-style import path from given path segments.
	* Ensures consistent path separators regardless of the operating system.
	*
	* @param paths - Path segments to join
	* @returns Unix-style path string
	*
	* @example
	* importPath('app', 'models', 'user') // 'app/models/user'
	*/
	importPath(...paths) {
		return string.toUnixSlash(join(...paths));
	},
	/**
	* Converts an entity name to a database table name.
	* Removes 'table' suffix, converts to model name format,
	* then pluralizes and converts to snake_case.
	*
	* @param entityName - The entity name to convert
	* @returns Database table name in snake_case plural form
	*
	* @example
	* tableName('User') // 'users'
	* tableName('BlogPost') // 'blog_posts'
	* tableName('UserTable') // 'users'
	*/
	tableName(entityName) {
		return new StringBuilder(this.modelName(new StringBuilder(entityName).removeSuffix("table").toString())).plural().snakeCase().toString();
	},
	/**
	* Converts an entity name to a model class name.
	* Removes file extension and 'model' suffix, singularizes,
	* and converts to PascalCase.
	*
	* @param entityName - The entity name to convert
	* @returns Model class name in PascalCase singular form
	*
	* @example
	* modelName('users') // 'User'
	* modelName('blog-posts') // 'BlogPost'
	* modelName('user.model.ts') // 'User'
	*/
	modelName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("model").singular().pascalCase().toString();
	},
	/**
	* Converts an entity name to a model file name.
	* Uses the model name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Model file name in snake_case with .ts extension
	*
	* @example
	* modelFileName('User') // 'user.ts'
	* modelFileName('BlogPost') // 'blog_post.ts'
	*/
	modelFileName(entityName) {
		return new StringBuilder(this.modelName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a controller class name.
	* Removes file extension and 'controller' suffix, then applies
	* singularization rules based on special names list or parameter.
	*
	* @param entityName - The entity name to convert
	* @param singular - Force singular form regardless of special names
	* @returns Controller class name in PascalCase with 'Controller' suffix
	*
	* @example
	* controllerName('users') // 'UsersController'
	* controllerName('admin') // 'AdminController' (from singular list)
	* controllerName('posts', true) // 'PostController' (forced singular)
	*/
	controllerName(entityName, singular = false) {
		const controller = new StringBuilder(entityName).removeExtension().removeSuffix("controller");
		if (this.singularControllerNames.includes(controller.toString().toLowerCase())) controller.singular();
		else if (singular) controller.singular();
		else controller.plural();
		return controller.pascalCase().suffix("Controller").toString();
	},
	/**
	* Converts an entity name to a controller file name.
	* Uses the controller name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @param singular - Force singular form for the controller name
	* @returns Controller file name in snake_case with .ts extension
	*
	* @example
	* controllerFileName('users') // 'users_controller.ts'
	* controllerFileName('admin') // 'admin_controller.ts'
	*/
	controllerFileName(entityName, singular = false) {
		return new StringBuilder(this.controllerName(entityName, singular)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to an event class name.
	* Removes file extension and 'event' suffix, then converts to PascalCase.
	*
	* @param entityName - The entity name to convert
	* @returns Event class name in PascalCase
	*
	* @example
	* eventName('user-registered') // 'UserRegistered'
	* eventName('order.event.ts') // 'Order'
	*/
	eventName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("event").pascalCase().toString();
	},
	/**
	* Converts an entity name to an event file name.
	* Uses the event name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Event file name in snake_case with .ts extension
	*
	* @example
	* eventFileName('UserRegistered') // 'user_registered.ts'
	*/
	eventFileName(entityName) {
		return new StringBuilder(this.eventName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a listener class name.
	* Removes file extension and 'listener' suffix, then converts to PascalCase.
	*
	* @param entityName - The entity name to convert
	* @returns Listener class name in PascalCase
	*
	* @example
	* listenerName('send-email') // 'SendEmail'
	* listenerName('notification.listener.ts') // 'Notification'
	*/
	listenerName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("listener").pascalCase().toString();
	},
	/**
	* Converts an entity name to a listener file name.
	* Uses the listener name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Listener file name in snake_case with .ts extension
	*
	* @example
	* listenerFileName('SendEmail') // 'send_email.ts'
	*/
	listenerFileName(entityName) {
		return new StringBuilder(this.listenerName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a middleware class name.
	* Removes file extension and 'middleware' suffix, then converts to PascalCase
	* with 'Middleware' suffix.
	*
	* @param entityName - The entity name to convert
	* @returns Middleware class name in PascalCase with 'Middleware' suffix
	*
	* @example
	* middlewareName('auth') // 'AuthMiddleware'
	* middlewareName('cors.middleware.ts') // 'CorsMiddleware'
	*/
	middlewareName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("middleware").pascalCase().suffix("Middleware").toString();
	},
	/**
	* Converts an entity name to a middleware file name.
	* Uses the middleware name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Middleware file name in snake_case with .ts extension
	*
	* @example
	* middlewareFileName('Auth') // 'auth_middleware.ts'
	*/
	middlewareFileName(entityName) {
		return new StringBuilder(this.middlewareName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a provider class name.
	* Removes file extension and 'provider' suffix, singularizes,
	* then converts to PascalCase with 'Provider' suffix.
	*
	* @param entityName - The entity name to convert
	* @returns Provider class name in PascalCase with 'Provider' suffix
	*
	* @example
	* providerName('database') // 'DatabaseProvider'
	* providerName('redis.provider.ts') // 'RedisProvider'
	*/
	providerName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("provider").singular().pascalCase().suffix("Provider").toString();
	},
	/**
	* Converts an entity name to a provider file name.
	* Uses the provider name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Provider file name in snake_case with .ts extension
	*
	* @example
	* providerFileName('Database') // 'database_provider.ts'
	*/
	providerFileName(entityName) {
		return new StringBuilder(this.providerName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a policy class name.
	* Removes file extension, 'policy' and 'model' suffixes, singularizes,
	* then converts to PascalCase with 'Policy' suffix.
	*
	* @param entityName - The entity name to convert
	* @returns Policy class name in PascalCase with 'Policy' suffix
	*
	* @example
	* policyName('users') // 'UserPolicy'
	* policyName('post.policy.ts') // 'PostPolicy'
	*/
	policyName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("policy").removeSuffix("model").singular().pascalCase().suffix("Policy").toString();
	},
	/**
	* Converts an entity name to a policy file name.
	* Uses the policy name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Policy file name in snake_case with .ts extension
	*
	* @example
	* policyFileName('User') // 'user_policy.ts'
	*/
	policyFileName(entityName) {
		return new StringBuilder(this.policyName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a factory class name.
	* Removes file extension, 'factory' and 'model' suffixes, singularizes,
	* then converts to PascalCase with 'Factory' suffix.
	*
	* @param entityName - The entity name to convert
	* @returns Factory class name in PascalCase with 'Factory' suffix
	*
	* @example
	* factoryName('users') // 'UserFactory'
	* factoryName('post.factory.ts') // 'PostFactory'
	*/
	factoryName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("factory").removeSuffix("model").singular().pascalCase().suffix("Factory").toString();
	},
	/**
	* Converts an entity name to a factory file name.
	* Uses the factory name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Factory file name in snake_case with .ts extension
	*
	* @example
	* factoryFileName('User') // 'user_factory.ts'
	*/
	factoryFileName(entityName) {
		return new StringBuilder(this.factoryName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a service class name.
	* Removes file extension, 'service' and 'model' suffixes, singularizes,
	* then converts to PascalCase with 'Service' suffix.
	*
	* @param entityName - The entity name to convert
	* @returns Service class name in PascalCase with 'Service' suffix
	*
	* @example
	* serviceName('users') // 'UserService'
	* serviceName('email.service.ts') // 'EmailService'
	*/
	serviceName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("service").removeSuffix("model").singular().pascalCase().suffix("Service").toString();
	},
	/**
	* Converts an entity name to a service file name.
	* Uses the service name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Service file name in snake_case with .ts extension
	*
	* @example
	* serviceFileName('User') // 'user_service.ts'
	*/
	serviceFileName(entityName) {
		return new StringBuilder(this.serviceName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a seeder class name.
	* Removes file extension, 'seeder' and 'model' suffixes, singularizes,
	* then converts to PascalCase with 'Seeder' suffix.
	*
	* @param entityName - The entity name to convert
	* @returns Seeder class name in PascalCase with 'Seeder' suffix
	*
	* @example
	* seederName('users') // 'UserSeeder'
	* seederName('post.seeder.ts') // 'PostSeeder'
	*/
	seederName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("seeder").removeSuffix("model").singular().pascalCase().suffix("Seeder").toString();
	},
	/**
	* Converts an entity name to a seeder file name.
	* Uses the seeder name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Seeder file name in snake_case with .ts extension
	*
	* @example
	* seederFileName('User') // 'user_seeder.ts'
	*/
	seederFileName(entityName) {
		return new StringBuilder(this.seederName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a command terminal name.
	* Creates a namespaced command name using dash-case format,
	* where the first part becomes the namespace and remaining parts
	* are joined with colons.
	*
	* @param entityName - The entity name to convert
	* @returns Command terminal name in namespace:command format
	*
	* @example
	* commandTerminalName('MakeUser') // 'make:user'
	* commandTerminalName('DbSeed') // 'db:seed'
	* commandTerminalName('Clear') // 'clear'
	*/
	commandTerminalName(entityName) {
		const [namespace, ...rest] = new StringBuilder(this.commandName(entityName)).dashCase().toString().split("-");
		if (!rest.length) return namespace;
		return `${namespace}:${rest.join("-")}`;
	},
	/**
	* Converts an entity name to a command class name.
	* Removes file extension and 'command' suffix, then converts to PascalCase.
	*
	* @param entityName - The entity name to convert
	* @returns Command class name in PascalCase
	*
	* @example
	* commandName('make-user') // 'MakeUser'
	* commandName('db.seed.command.ts') // 'DbSeed'
	*/
	commandName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("command").pascalCase().toString();
	},
	/**
	* Converts an entity name to a command file name.
	* Uses the command name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Command file name in snake_case with .ts extension
	*
	* @example
	* commandFileName('MakeUser') // 'make_user.ts'
	*/
	commandFileName(entityName) {
		return new StringBuilder(this.commandName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a validator class name.
	* Removes file extension and 'validator' suffix, singularizes,
	* then converts to PascalCase.
	*
	* @param entityName - The entity name to convert
	* @returns Validator class name in PascalCase
	*
	* @example
	* validatorName('users') // 'User'
	* validatorName('create-post.validator.ts') // 'CreatePost'
	*/
	validatorName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("validator").singular().pascalCase().toString();
	},
	/**
	* Converts an entity name and action to a validator action name.
	* Creates a camelCase name by prefixing with action and suffixing with 'validator'.
	*
	* @param entityName - The entity name to convert
	* @param action - The action name (e.g., 'create', 'update')
	* @returns Validator action name in camelCase
	*
	* @example
	* validatorActionName('User', 'create') // 'createUserValidator'
	* validatorActionName('BlogPost', 'update') // 'updateBlogPostValidator'
	*/
	validatorActionName(entityName, action) {
		return new StringBuilder(this.validatorName(entityName)).prefix(`${action}_`).suffix("_validator").camelCase().toString();
	},
	/**
	* Converts an entity name to a validator file name.
	* Uses the validator name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Validator file name in snake_case with .ts extension
	*
	* @example
	* validatorFileName('User') // 'user.ts'
	*/
	validatorFileName(entityName) {
		return new StringBuilder(this.validatorName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to an exception class name.
	* Removes file extension and 'exception' suffix, then converts to PascalCase
	* with 'Exception' suffix.
	*
	* @param entityName - The entity name to convert
	* @returns Exception class name in PascalCase with 'Exception' suffix
	*
	* @example
	* exceptionName('validation-error') // 'ValidationErrorException'
	* exceptionName('not-found.exception.ts') // 'NotFoundException'
	*/
	exceptionName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("exception").pascalCase().suffix("Exception").toString();
	},
	/**
	* Converts an entity name to an exception file name.
	* Uses the exception name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Exception file name in snake_case with .ts extension
	*
	* @example
	* exceptionFileName('ValidationError') // 'validation_error_exception.ts'
	*/
	exceptionFileName(entityName) {
		return new StringBuilder(this.exceptionName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a mailer class name.
	* Removes file extension and various suffixes, then converts to PascalCase
	* with the specified type suffix.
	*
	* @param entityName - The entity name to convert
	* @param type - The mailer type ('notification' or 'provision')
	* @returns Mailer class name in PascalCase with type suffix
	*
	* @example
	* mailerName('welcome-email') // 'WelcomeEmailNotification'
	* mailerName('user-signup', 'provision') // 'UserSignupProvision'
	*/
	mailerName(entityName, type = "notification") {
		return new StringBuilder(entityName).removeExtension().removeSuffix("notification").removeSuffix("provision").removeSuffix("mailer").pascalCase().suffix(string.pascalCase(type)).toString();
	},
	/**
	* Converts an entity name to a mailer file name.
	* Uses the mailer name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @param type - The mailer type ('notification' or 'provision')
	* @returns Mailer file name in snake_case with .ts extension
	*
	* @example
	* mailerFileName('WelcomeEmail') // 'welcome_email_notification.ts'
	*/
	mailerFileName(entityName, type = "notification") {
		return new StringBuilder(this.mailerName(entityName, type)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to a class-based mail name.
	* Removes file extension and various suffixes, then converts to PascalCase
	* with the specified type suffix. Similar to mailerName but with more flexible type.
	*
	* @param entityName - The entity name to convert
	* @param type - The mail type (default: 'notification')
	* @returns Mail class name in PascalCase with type suffix
	*
	* @example
	* mailName('welcome') // 'WelcomeNotification'
	* mailName('password-reset', 'email') // 'PasswordResetEmail'
	*/
	mailName(entityName, type = "notification") {
		return new StringBuilder(entityName).removeExtension().removeSuffix(type).removeSuffix("mailer", { similarWords: ["emailer"] }).removeSuffix("mail", { similarWords: ["email"] }).pascalCase().suffix(string.pascalCase(type)).toString();
	},
	/**
	* Converts an entity name to a class-based mail file name.
	* Uses the mail name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @param type - The mail type (default: 'notification')
	* @returns Mail file name in snake_case with .ts extension
	*
	* @example
	* mailFileName('Welcome') // 'welcome_notification.ts'
	* mailFileName('PasswordReset', 'email') // 'password_reset_email.ts'
	*/
	mailFileName(entityName, type = "notification") {
		return new StringBuilder(this.mailName(entityName, type)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity to a test group name.
	* Creates a human-readable test group name by combining path and name,
	* removing extensions and converting to sentence case.
	*
	* @param entity - Object containing path and name properties
	* @returns Test group name in sentence case
	*
	* @example
	* testGroupName({ path: 'controllers', name: 'users' }) // 'Controllers users'
	* testGroupName({ path: 'models', name: 'user.spec' }) // 'Models user'
	*/
	testGroupName(entity) {
		return new StringBuilder(`${entity.path}/${entity.name}`).removeExtension().removeSuffix(".spec").sentenceCase().toString();
	},
	/**
	* Converts an entity name to a test file name.
	* Removes file extension and '.spec' suffix, converts to snake_case,
	* then adds '.spec.ts' extension.
	*
	* @param entityName - The entity name to convert
	* @returns Test file name in snake_case with .spec.ts extension
	*
	* @example
	* testFileName('UserController') // 'user_controller.spec.ts'
	* testFileName('auth-service.spec') // 'auth_service.spec.ts'
	*/
	testFileName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix(".spec").snakeCase().ext(".spec.ts").toString();
	},
	/**
	* Converts an entity name to a view template file name.
	* Removes file extension, converts to snake_case, and adds '.edge' extension
	* for Edge template files.
	*
	* @param entityName - The entity name to convert
	* @returns View file name in snake_case with .edge extension
	*
	* @example
	* viewFileName('UserProfile') // 'user_profile.edge'
	* viewFileName('admin-dashboard') // 'admin_dashboard.edge'
	*/
	viewFileName(entityName) {
		return new StringBuilder(entityName).removeExtension().snakeCase().ext(".edge").toString();
	},
	/**
	* Converts an entity name to a transformer class name.
	* Removes file extension, 'transformer' and 'model' suffixes, singularizes,
	* then converts to PascalCase with 'Transformer' suffix.
	*
	* @param entityName - The entity name to convert
	* @returns Transformer class name in PascalCase with 'Transformer' suffix
	*
	* @example
	* transformerName('users') // 'UserTransformer'
	* transformerName('blog-post.transformer.ts') // 'BlogPostTransformer'
	*/
	transformerName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("transformer").removeSuffix("model").singular().pascalCase().suffix("Transformer").toString();
	},
	/**
	* Converts an entity name to a transformer file name.
	* Uses the transformer name and converts to snake_case with .ts extension.
	*
	* @param entityName - The entity name to convert
	* @returns Transformer file name in snake_case with .ts extension
	*
	* @example
	* transformerFileName('User') // 'user_transformer.ts'
	*/
	transformerFileName(entityName) {
		return new StringBuilder(this.transformerName(entityName)).snakeCase().ext(".ts").toString();
	},
	/**
	* Converts an entity name to an Inertia page name.
	* Removes file extension and 'page' suffix, then converts to PascalCase.
	*
	* @param entityName - The entity name to convert
	* @returns Inertia page name in PascalCase
	*
	* @example
	* inertiaPageName('user-profile') // 'UserProfile'
	* inertiaPageName('admin_dashboard_page') // 'AdminDashboard'
	*/
	inertiaPageName(entityName) {
		return new StringBuilder(entityName).removeExtension().removeSuffix("page").pascalCase().toString();
	},
	/**
	* Converts an entity name to an Inertia page file name.
	* Uses the inertia page name and converts to snake_case with the given extension.
	*
	* @param entityName - The entity name to convert
	* @param extension - The file extension to use (e.g., '.tsx', '.vue')
	* @returns Inertia page file name in snake_case with the specified extension
	*
	* @example
	* inertiaPageFileName('UserProfile', '.tsx') // 'user_profile.tsx'
	* inertiaPageFileName('admin_dashboard_page', '.vue') // 'admin_dashboard.vue'
	*/
	inertiaPageFileName(entityName, extension) {
		return new StringBuilder(this.inertiaPageName(entityName)).snakeCase().ext(extension).toString();
	}
};
//#endregion
//#region src/managers/config.ts
/**
* ConfigManager handles loading, parsing, and managing application configuration.
* It can load configuration from file system directories or use explicitly
* provided configuration objects (useful for testing).
*
* The manager creates a Config instance that provides type-safe access to
* configuration values throughout the application.
*
* @example
* const manager = new ConfigManager(new URL('file:///app/'))
* await manager.process('config')
* const dbConfig = manager.config.get('database')
*
* @example
* // Using explicit config for testing
* const manager = new ConfigManager(appRoot)
* manager.useConfig({ database: { connection: 'sqlite' } })
* await manager.process('config')
*/
var ConfigManager = class {
	/**
	* The application root directory URL used to resolve the config directory path.
	*
	* @private
	* @type {URL}
	*/
	#appRoot;
	/**
	* Configuration values set explicitly via useConfig() method.
	* When provided, prevents loading config files from the file system.
	*
	* @private
	* @type {Record<any, any> | undefined}
	*/
	#configValues;
	/**
	* Reference to the Config instance that provides access to
	* all configuration values. Available after process() method has been called.
	*
	* @type {Config}
	*/
	config;
	/**
	* Creates a new ConfigManager instance.
	*
	* @param {URL} appRoot - The application root directory URL
	*/
	constructor(appRoot) {
		this.#appRoot = appRoot;
	}
	/**
	* Provides configuration values programmatically instead of loading from files.
	* Useful for testing or when configuration needs to be generated dynamically.
	* Calling this method disables reading config files from the file system.
	*
	* @param {Record<any, any>} values - The configuration values to use
	* @returns {this} Returns the ConfigManager instance for method chaining
	*/
	useConfig(values) {
		this.#configValues = values;
		return this;
	}
	/**
	* Loads and processes configuration values. If useConfig() was called,
	* uses those values; otherwise loads config files from the specified directory.
	* Creates a Config instance accessible via the config property.
	*
	* @param {string} configDirectory - The directory path containing config files (relative to appRoot)
	* @returns {Promise<void>} Promise that resolves when config processing is complete
	*/
	async process(configDirectory) {
		if (this.#configValues) this.config = new Config(this.#configValues);
		else {
			const loader = new ConfigLoader(new URL(configDirectory, this.#appRoot));
			debug_default("loading config from directory \"%s\"", configDirectory);
			this.config = new Config(await loader.load());
		}
		this.#configValues = void 0;
	}
};
//#endregion
//#region src/directories.ts
/**
* Default directory structure for AdonisJS applications.
* These paths are relative to the application root and define
* the conventional locations for different types of files.
*
* Applications can override these defaults in their adonisrc.js file.
*
* @example
* // In adonisrc.js
* export default defineConfig({
*   directories: {
*     ...directories,
*     controllers: 'app/http/controllers' // Custom path
*   }
* })
*/
const directories = {
	config: "config",
	commands: "commands",
	contracts: "contracts",
	public: "public",
	providers: "providers",
	languageFiles: "resources/lang",
	migrations: "database/migrations",
	seeders: "database/seeders",
	factories: "database/factories",
	views: "resources/views",
	start: "start",
	tmp: "tmp",
	tests: "tests",
	httpControllers: "app/controllers",
	models: "app/models",
	services: "app/services",
	exceptions: "app/exceptions",
	mailers: "app/mailers",
	mails: "app/mails",
	middleware: "app/middleware",
	policies: "app/policies",
	validators: "app/validators",
	events: "app/events",
	listeners: "app/listeners",
	transformers: "app/transformers",
	stubs: "stubs",
	generatedClient: ".adonisjs/client",
	generatedServer: ".adonisjs/server"
};
//#endregion
//#region src/rc_file/parser.ts
const KNOWN_ASSEMBLER_HOOKS = [
	"init",
	"routesCommitted",
	"routesScanning",
	"routesScanned",
	"routesCommitted",
	"buildStarting",
	"buildFinished",
	"devServerStarting",
	"devServerStarted",
	"testsStarting",
	"testsFinished",
	"fileAdded",
	"fileChanged",
	"fileRemoved"
];
/**
* RcFileParser processes and validates the adonisrc.js configuration file.
* It merges user configuration with defaults, applies presets, validates structure,
* and transforms the configuration into a normalized format.
*
* The parser handles:
* - Merging user config with framework defaults
* - Applying configuration presets
* - Validating providers, preloads, and hooks
* - Normalizing directory paths
* - Processing environment-specific configurations
*
* @example
* const parser = new RcFileParser({
*   typescript: true,
*   providers: [() => import('./providers/app_provider')]
* })
* const rcFile = parser.parse()
*/
var RcFileParser = class {
	/**
	* Default configuration values for an RcFile. This object initializes all known
	* properties with sensible defaults that will be merged with user configuration.
	*
	* @private
	*/
	#defaults = {
		typescript: true,
		preloads: [],
		metaFiles: [],
		presets: [],
		commandsAliases: {},
		commands: [],
		providers: [],
		directories,
		tests: {
			suites: [],
			timeout: 2e3,
			forceExit: true
		},
		hooks: {},
		experimental: {}
	};
	/**
	* The parsed RcFile configuration merged with default values.
	* This represents the final configuration after applying user overrides.
	*
	* @private
	*/
	#rcFile;
	/**
	* Reference to the original raw configuration object before processing.
	* Preserved for debugging and error reporting purposes.
	*
	* @private
	* @type {Record<string, any>}
	*/
	#raw;
	/**
	* Creates a new RcFileParser instance.
	*
	* @param {Record<string, any>} rcFile - The raw RC file configuration object to parse and validate
	*/
	constructor(rcFile) {
		this.#rcFile = Object.assign(this.#defaults, rcFile);
		this.#raw = rcFile;
	}
	/**
	* Returns all valid application environments excluding 'unknown'.
	* These environments can be used for conditional provider and preload loading.
	*
	* @private
	* @returns {Exclude<AppEnvironments, 'unknown'>[]} Array of valid environment names
	*/
	#knownEnvironments() {
		return [
			"web",
			"console",
			"test",
			"repl"
		];
	}
	/**
	* Validates and extracts assembler hooks from the configuration.
	* Hooks allow extending the build process at specific lifecycle events.
	*
	* @private
	* @returns {RcFile['hooks']} Validated hooks object or undefined
	* @throws {E_UNKNOWN_ASSEMBLER_HOOK} When an unknown hook event is encountered
	* @throws {E_INVALID_HOOKS_VALUE} When a hook value is not an array
	*/
	#getHooks() {
		const hooks = this.#rcFile.hooks;
		if (!hooks) return;
		return Object.keys(hooks).reduce((result, eventName) => {
			if (!KNOWN_ASSEMBLER_HOOKS.includes(eventName)) throw new E_UNKNOWN_ASSEMBLER_HOOK([eventName]);
			const eventHooks = hooks[eventName];
			if (!Array.isArray(eventHooks)) throw new E_INVALID_HOOKS_VALUE([eventName, inspect(eventHooks)]);
			result[eventName] = eventHooks;
			return result;
		}, {});
	}
	/**
	* Normalizes and validates the preload files configuration.
	* Converts simple function references to full PreloadNode objects with environment targeting.
	*
	* @throws {E_MISSING_PRELOAD_FILE} When a preload entry is missing the file property
	* @throws {E_INVALID_PRELOAD_FILE} When a preload file is not a function
	* @private
	*/
	#getPreloads() {
		return this.#rcFile.preloads.map((preload) => {
			const normalizedPreload = typeof preload === "function" ? {
				file: preload,
				environment: this.#knownEnvironments()
			} : preload;
			if (!normalizedPreload.file) throw new E_MISSING_PRELOAD_FILE([inspect(preload)]);
			if (typeof normalizedPreload.file !== "function") throw new E_INVALID_PRELOAD_FILE([inspect(preload)]);
			return {
				file: normalizedPreload.file,
				environment: normalizedPreload.environment ?? this.#knownEnvironments()
			};
		});
	}
	/**
	* Normalizes and validates the service providers configuration.
	* Converts simple function references to full ProviderNode objects with environment targeting.
	*
	* @throws {E_MISSING_PROVIDER_FILE} When a provider entry is missing the file property
	* @throws {E_INVALID_PROVIDER} When a provider file is not a function
	* @private
	*/
	#getProviders() {
		return this.#rcFile.providers.map((provider) => {
			const normalizedProvider = typeof provider === "function" ? {
				file: provider,
				environment: this.#knownEnvironments()
			} : provider;
			if (!normalizedProvider.file) throw new E_MISSING_PROVIDER_FILE([inspect(provider)]);
			if (typeof normalizedProvider.file !== "function") throw new E_INVALID_PROVIDER([inspect(provider)]);
			return {
				file: normalizedProvider.file,
				environment: normalizedProvider.environment ?? this.#knownEnvironments()
			};
		});
	}
	/**
	* Normalizes and validates the meta files configuration.
	* Meta files are patterns that define files to watch for changes during development.
	*
	* @throws {E_MISSING_METAFILE_PATTERN} When a meta file entry is missing the pattern property
	* @private
	*/
	#getMetaFiles() {
		return this.#rcFile.metaFiles.map((pattern) => {
			const normalizeMetaFile = typeof pattern === "string" ? {
				pattern,
				reloadServer: true
			} : pattern;
			if (!normalizeMetaFile.pattern) throw new E_MISSING_METAFILE_PATTERN([inspect(pattern)]);
			return {
				pattern: normalizeMetaFile.pattern,
				reloadServer: normalizeMetaFile.reloadServer ?? true
			};
		});
	}
	/**
	* Normalizes and validates the test suites configuration.
	* Each suite must have a name and file patterns, and automatically determines
	* the base directories for file watching.
	*
	* @throws {E_MISSING_SUITE_NAME} When a test suite is missing the name property
	* @throws {E_MISSING_SUITE_FILES} When a test suite is missing the files property
	* @private
	*/
	#getSuites() {
		return (this.#rcFile.tests.suites || []).map((suite) => {
			if (!suite.name) throw new E_MISSING_SUITE_NAME([inspect(suite)]);
			if (!suite.files) throw new E_MISSING_SUITE_FILES([inspect(suite)]);
			const files = Array.isArray(suite.files) ? [...suite.files] : [suite.files];
			return {
				name: suite.name,
				files,
				directories: files.map((file) => globParent(file)),
				timeout: suite.timeout
			};
		});
	}
	/**
	* Applies preset functions to modify the RC file configuration before parsing.
	* Presets are functions that can programmatically modify the configuration,
	* allowing for dynamic setup and shared configurations.
	*
	* @throws {E_INVALID_PRESETS_VALUE} When presets is not an array
	* @throws {E_INVALID_PRESET_FUNCTION} When a preset is not a function
	* @throws {E_PRESET_EXECUTION_ERROR} When a preset function throws an error
	* @private
	*/
	#applyPresets() {
		if (this.#rcFile.presets.length === 0) return;
		if (!Array.isArray(this.#rcFile.presets)) throw new E_INVALID_PRESETS_VALUE([inspect(this.#rcFile.presets)]);
		this.#rcFile.presets.forEach((preset, index) => {
			if (typeof preset !== "function") throw new E_INVALID_PRESET_FUNCTION([index, inspect(preset)]);
			try {
				preset({ rcFile: this.#rcFile });
			} catch (error) {
				throw new E_PRESET_EXECUTION_ERROR([index, error.message]);
			}
		});
	}
	/**
	* Parses and validates the RC file configuration, applying all normalization
	* and validation rules. This is the main entry point for processing RC file data.
	*
	* The parsing process:
	* 1. Applies any preset functions to modify the configuration
	* 2. Normalizes all configuration sections (preloads, providers, etc.)
	* 3. Validates the structure and values
	* 4. Merges with defaults to create the final configuration
	*/
	parse() {
		this.#applyPresets();
		return {
			typescript: this.#rcFile.typescript,
			preloads: this.#getPreloads(),
			metaFiles: this.#getMetaFiles(),
			commands: [...this.#rcFile.commands],
			directories: {
				...directories,
				...this.#rcFile.directories
			},
			commandsAliases: { ...this.#rcFile.commandsAliases },
			providers: this.#getProviders(),
			tests: {
				suites: this.#getSuites(),
				timeout: this.#rcFile.tests.timeout ?? 2e3,
				forceExit: this.#rcFile.tests.forceExit ?? true
			},
			hooks: this.#getHooks(),
			experimental: this.#rcFile.experimental,
			raw: this.#raw
		};
	}
};
//#endregion
//#region src/managers/rc_file.ts
/**
* RcFileManager handles loading, parsing, and processing of the AdonisJS
* configuration file (adonisrc.js). This file contains application metadata,
* directory mappings, providers, preloads, and other configuration.
*
* The manager can work with:
* - adonisrc.js file from disk
* - Explicitly provided RC contents (useful for testing)
*
* @example
* const manager = new RcFileManager(new URL('file:///app/'))
* await manager.process()
* console.log(manager.rcFile.providers)
*/
var RcFileManager = class {
	/**
	* The application root directory URL used to resolve the adonisrc.js file path.
	*
	* @private
	* @type {URL}
	*/
	#appRoot;
	/**
	* RC file contents set explicitly via rcContents() method.
	* When set, prevents loading adonisrc.js from disk.
	*
	* @private
	* @type {Record<string, any> | undefined}
	*/
	#rcContents;
	/**
	* Reference to the parsed and validated RC file configuration.
	* Available after the process() method has been called successfully.
	*
	* @type {RcFile}
	*/
	rcFile;
	/**
	* Creates a new RcFileManager instance.
	*
	* @param {URL} appRoot - The application root directory URL
	*/
	constructor(appRoot) {
		this.#appRoot = appRoot;
	}
	/**
	* Provides RC file contents programmatically instead of loading from disk.
	* Useful for testing or when the configuration needs to be generated dynamically.
	* Calling this method disables loading adonisrc.js from the file system.
	*
	* @param {Record<string, any>} value - The RC file contents as an object
	* @returns {this} Returns the RcFileManager instance for method chaining
	*/
	rcContents(value) {
		this.#rcContents = value;
		return this;
	}
	/**
	* Loads and processes the RC file configuration. If rcContents was provided,
	* uses that; otherwise attempts to load adonisrc.js from the application root.
	* Parses and validates the configuration, making it available via the rcFile property.
	*
	* @returns {Promise<void>} Promise that resolves when RC file processing is complete
	* @throws {Error} When adonisrc.js has syntax errors or invalid configuration
	*/
	async process() {
		if (!this.#rcContents) {
			const rcTSFile = new URL("adonisrc.js", this.#appRoot);
			try {
				const rcExports = await import(rcTSFile.href);
				this.#rcContents = rcExports.default;
				debug_default("adonisrc.ts file contents: %O", this.#rcContents);
			} catch (error) {
				if (!/Cannot find module/.test(error.message)) throw error;
			}
		}
		this.rcFile = new RcFileParser(this.#rcContents).parse();
		this.#rcContents = void 0;
	}
};
//#endregion
//#region src/managers/node_env.ts
/**
* Aliases for test environments that get normalized to 'test'
*/
const TEST_ENVS = ["test", "testing"];
/**
* Aliases for production environments that get normalized to 'production'
*/
const PROD_ENVS = ["prod", "production"];
/**
* Aliases for development environments that get normalized to 'development'
*/
const DEV_ENVS = [
	"dev",
	"develop",
	"development"
];
/**
* NodeEnvManager is used to extract a normalized node environment by
* inspecting the "process.env.NODE_ENV".
*
* - The "test" and "testing" envs are normalized to "test"
* - The "prod" and "production" envs are normalized to "production"
* - The "dev", "develop", and "development" envs are normalized to "development"
* - Unknown or invalid environments remain as-is
*
* @example
* const manager = new NodeEnvManager()
* manager.process()
* console.log(manager.nodeEnvironment) // 'development', 'production', 'test', or custom
*/
var NodeEnvManager = class {
	/**
	* The normalized node environment value. Defaults to 'unknown' until process() is called.
	*
	* @type {'unknown' | 'development' | 'production' | 'test' | string}
	* @default 'unknown'
	*/
	nodeEnvironment = "unknown";
	/**
	* Normalizes the NODE_ENV value to standard environment names.
	*
	* @private
	* @param {string} [env] - The environment string to normalize
	* @returns {string} The normalized environment string
	*/
	#normalizeNodeEnv(env) {
		if (!env || typeof env !== "string") return "unknown";
		env = env.toLowerCase();
		if (DEV_ENVS.includes(env)) return "development";
		if (PROD_ENVS.includes(env)) return "production";
		if (TEST_ENVS.includes(env)) return "test";
		return env;
	}
	/**
	* Captures and normalizes the current NODE_ENV value from process.env.
	* Sets the nodeEnvironment property with the normalized value.
	*/
	process() {
		this.nodeEnvironment = this.#normalizeNodeEnv(process.env.NODE_ENV);
	}
};
//#endregion
//#region src/tracing_channels.ts
var tracing_channels_exports = /* @__PURE__ */ __exportAll({
	preloadImport: () => preloadImport,
	providerBoot: () => providerBoot,
	providerReady: () => providerReady,
	providerRegister: () => providerRegister,
	providerShutdown: () => providerShutdown,
	providerStart: () => providerStart
});
/**
* Tracing channel for service provider register lifecycle hook.
* This channel traces when a provider's register() method is called during
* the application initialization phase.
*
* @example
* // Subscribe to register events
* providerRegister.subscribe({
*   start(provider) {
*     console.log('Provider registering:', provider.constructor.name)
*   },
*   end(provider) {
*     console.log('Provider registered:', provider.constructor.name)
*   }
* })
*/
const providerRegister = diagnostics_channel.tracingChannel("adonisjs.provider.register");
/**
* Tracing channel for service provider boot lifecycle hook.
* This channel traces when a provider's boot() method is called during
* the application boot phase, after all providers have been registered.
*
* @example
* // Monitor boot performance
* providerBoot.subscribe({
*   asyncStart(provider) {
*     console.time(`boot-${provider.constructor.name}`)
*   },
*   asyncEnd(provider) {
*     console.timeEnd(`boot-${provider.constructor.name}`)
*   }
* })
*/
const providerBoot = diagnostics_channel.tracingChannel("adonisjs.provider.boot");
/**
* Tracing channel for service provider start lifecycle hook.
* This channel traces when a provider's start() method is called during
* the application start phase, after all providers have been booted.
*
* @example
* // Track provider startup order
* const startupOrder: string[] = []
* providerStart.subscribe({
*   asyncStart(provider) {
*     startupOrder.push(provider.constructor.name)
*   }
* })
*/
const providerStart = diagnostics_channel.tracingChannel("adonisjs.provider.start");
/**
* Tracing channel for service provider ready lifecycle hook.
* This channel traces when a provider's ready() method is called after
* the application is fully ready and serving requests.
*
* @example
* // Log when providers are ready
* providerReady.subscribe({
*   asyncStart(provider) {
*     console.log('Provider ready:', provider.constructor.name)
*   },
*   error(provider, error) {
*     console.error('Provider ready failed:', provider.constructor.name, error)
*   }
* })
*/
const providerReady = diagnostics_channel.tracingChannel("adonisjs.provider.ready");
/**
* Tracing channel for service provider shutdown lifecycle hook.
* This channel traces when a provider's shutdown() method is called during
* graceful application termination.
*
* @example
* // Monitor shutdown process
* providerShutdown.subscribe({
*   asyncStart(provider) {
*     console.log('Provider shutting down:', provider.constructor.name)
*   },
*   asyncEnd(provider) {
*     console.log('Provider shutdown complete:', provider.constructor.name)
*   },
*   error(provider, error) {
*     console.error('Provider shutdown error:', provider.constructor.name, error)
*   }
* })
*/
const providerShutdown = diagnostics_channel.tracingChannel("adonisjs.provider.shutdown");
/**
* Tracing channel for preload file import.
* This channel traces when a preload module is imported during
* the application start phase.
*
* @example
* // Monitor preload imports
* preloadImport.subscribe({
*   asyncStart(data) {
*     console.log('Importing preload:', data.file.toString())
*   },
*   asyncEnd(data) {
*     console.log('Preload imported:', data.file.toString())
*   }
* })
*/
const preloadImport = diagnostics_channel.tracingChannel("adonisjs.preload.import");
//#endregion
//#region src/managers/preloads.ts
/**
* The PreloadsManager class is used to resolve and import preload modules.
* Preload modules are files that should be loaded before the application starts,
* typically for initialization code or setup tasks.
*
* The class relies on "import.meta.resolve" to resolve the provider modules from
* the root of the application.
*
* @example
* const manager = new PreloadsManager({ environment: 'web' })
* manager.use([{ file: () => import('./preloads/routes'), environment: ['web'] }])
* await manager.import()
*/
var PreloadsManager = class {
	/**
	* List of registered preload modules to be imported.
	* Each preload node contains the import function and environment restrictions.
	*
	* @private
	* @type {PreloadNode[]}
	* @default []
	*/
	#list = [];
	/**
	* Configuration options for the preloads manager.
	* Contains the current application environment used for filtering preloads.
	*
	* @private
	* @type {Object}
	* @property {AppEnvironments} environment - The current application environment
	*/
	#options;
	/**
	* Creates a new PreloadsManager instance
	*
	* @param options - Configuration options including environment
	*/
	constructor(options) {
		this.#options = options;
	}
	/**
	* Filters preload modules by the current environment.
	* Returns false for 'unknown' environments for security.
	*
	* @private
	* @param {PreloadNode} provider - The preload node to filter
	* @returns {boolean} Whether the preload should be included in the current environment
	*/
	#filterByEnvironment(provider) {
		if (this.#options.environment === "unknown") return false;
		return provider.environment.includes(this.#options.environment);
	}
	/**
	* Registers an array of preload modules to be imported later.
	* Replaces any previously registered preloads.
	*
	* @param {PreloadNode[]} list - Array of preload modules to register
	* @returns {this} Returns the PreloadsManager instance for method chaining
	*/
	use(list) {
		this.#list = list;
		return this;
	}
	/**
	* Changes the environment context for filtering preloads.
	* Used when the application environment changes after manager creation.
	*
	* @param {AppEnvironments} environment - The new environment to set
	* @returns {this} Returns the PreloadsManager instance for method chaining
	*/
	setEnvironment(environment) {
		debug_default("switching environment for preloads { from:\"%s\", to: \"%s\" }", this.#options.environment, environment);
		this.#options.environment = environment;
		return this;
	}
	/**
	* Imports all registered preload modules that match the current environment.
	* Clears the preloads list after importing to prevent duplicate imports.
	*
	* @returns {Promise<void>} Promise that resolves when all preload modules have been imported
	*/
	async import() {
		const preloads = this.#list.filter((preload) => this.#filterByEnvironment(preload));
		debug_default("preloading modules %O", preloads);
		await Promise.all(preloads.map((preload) => preloadImport.tracePromise(preload.file, preloadImport.hasSubscribers ? { file: preload.file } : void 0, preload)));
		this.#list = [];
	}
};
//#endregion
//#region src/managers/providers.ts
/**
* ProvidersManager handles the complete lifecycle of service providers in an AdonisJS application.
* It manages provider registration, booting, starting, readying, and shutdown phases.
*
* Service providers are classes that register services, bind dependencies, and set up
* application components during different phases of the application lifecycle.
*
* Lifecycle phases:
* 1. **Register**: Bind services to the IoC container
* 2. **Boot**: Initialize services after all providers are registered
* 3. **Start**: Start services (e.g., HTTP server, background jobs)
* 4. **Ready**: Notify services that application is ready to serve requests
* 5. **Shutdown**: Gracefully shutdown services during app termination
*
* @example
* const manager = new ProvidersManager({ environment: 'web', providersState: [app] })
* manager.use([
*   { file: () => import('./providers/app_provider'), environment: ['web', 'console'] }
* ])
* await manager.register()
* await manager.boot()
* await manager.start()
* await manager.ready()
*/
var ProvidersManager = class {
	/**
	* Array of instantiated provider instances used throughout the application lifecycle.
	* These instances are created during the register phase and reused for all subsequent phases.
	*
	* @private
	* @type {ContainerProviderContract[]}
	* @default []
	*/
	#providers = [];
	/**
	* Array of provider instances that implement the shutdown lifecycle method.
	* Kept separately to enable efficient shutdown processing without scanning all providers.
	* These providers are called during application termination for cleanup.
	*
	* @private
	* @type {ContainerProviderContract[]}
	* @default []
	*/
	#providersWithShutdownListeners = [];
	/**
	* Array of provider nodes from the adonisrc.js configuration.
	* Each node contains the import function and environment restrictions.
	* Cleared after providers are resolved and instantiated.
	*
	* @private
	* @type {ProviderNode[]}
	* @default []
	*/
	#list = [];
	/**
	* Configuration options for the providers manager.
	*
	* @private
	* @type {Object}
	* @property {AppEnvironments} environment - Current application environment for filtering providers
	* @property {any[]} providersState - Arguments passed to provider constructors (typically [app])
	*/
	#options;
	/**
	* Creates a new ProvidersManager instance.
	*
	* @param {Object} options - Configuration options
	* @param {AppEnvironments} options.environment - Current application environment
	* @param {any[]} options.providersState - Arguments to pass to provider constructors
	*/
	constructor(options) {
		this.#options = options;
	}
	/**
	* Filters providers based on the current application environment.
	* Returns false for 'unknown' environments for security.
	*
	* @private
	* @param {ProviderNode} provider - The provider node to filter
	* @returns {boolean} Whether the provider should be included in the current environment
	*/
	#filterByEnvironment(provider) {
		if (this.#options.environment === "unknown") return false;
		return provider.environment.includes(this.#options.environment);
	}
	/**
	* Checks if a value is a class constructor by examining its string representation.
	* Used to validate that provider exports are proper class constructors.
	*
	* @private
	* @param {any} providerClass - The value to check
	* @returns {boolean} Whether the value is a class constructor
	*/
	#isAClass(providerClass) {
		return typeof providerClass === "function" && providerClass.toString().startsWith("class ");
	}
	/**
	* Imports and validates a provider module from its import function.
	* Ensures the provider exports a default class constructor.
	*
	* @private
	* @param {ProviderNode} provider - The provider node to resolve
	* @returns {Promise<new (...args: any[]) => ContainerProviderContract | null>} The provider class constructor or null
	* @throws {RuntimeException} When provider has invalid exports or non-class default export
	*/
	async #resolveProvider(provider) {
		const providerExports = await provider.file();
		/**
		* Return null when there are no exports
		*/
		if (Object.keys(providerExports).length === 0) return null;
		/**
		* If there are exports and not a default export, then we consider
		* it to be an invalid provider
		*/
		if (!providerExports.default) throw new RuntimeException(`Invalid exports from "${provider.file.toString()}" provider. It must have a default export`);
		/**
		* If the default export is not a class, then also we consider it
		* to be an invalid provider
		*/
		if (!this.#isAClass(providerExports.default)) throw new RuntimeException(`Default export from module "${provider.file.toString()}" is not a class`);
		return providerExports.default;
	}
	/**
	* Resolves all providers that match the current environment.
	* Filters by environment and imports provider modules in parallel.
	*
	* @private
	* @returns {Promise<Array<new (...args: any[]) => ContainerProviderContract | null>>} Promise that resolves to array of provider classes
	*/
	#resolve() {
		const providers = this.#list.filter((provider) => this.#filterByEnvironment(provider));
		debug_default("loading providers %O", providers);
		return Promise.all(providers.map((provider) => this.#resolveProvider(provider)));
	}
	/**
	* Registers an array of provider nodes to be processed later.
	* Replaces any previously registered providers.
	*
	* @param {ProviderNode[]} list - Array of provider nodes to register
	* @returns {this} Returns the ProvidersManager instance for method chaining
	*/
	use(list) {
		this.#list = list;
		return this;
	}
	/**
	* Changes the environment context for filtering providers.
	* Used when the application environment changes after manager creation.
	*
	* @param {AppEnvironments} environment - The new environment to set
	* @returns {this} Returns the ProvidersManager instance for method chaining
	*/
	setEnvironment(environment) {
		debug_default("switching environment for providers { from:\"%s\", to: \"%s\" }", this.#options.environment, environment);
		this.#options.environment = environment;
		return this;
	}
	/**
	* Phase 1: Resolves, instantiates, and calls register() on all providers.
	* Creates provider instances and invokes their register methods to bind services to the IoC container.
	* Sets up tracking for providers with shutdown methods.
	*
	* @returns {Promise<void>} Promise that resolves when all providers are registered
	*/
	async register() {
		const providers = await this.#resolve();
		this.#list = [];
		providers.forEach((provider) => {
			if (provider) {
				debug_default("registering \"%s\"", provider.name);
				const providerInstance = new provider(...this.#options.providersState);
				this.#providers.push(providerInstance);
				if (providerInstance.shutdown) this.#providersWithShutdownListeners.push(providerInstance);
				if (providerInstance.register) providerRegister.traceSync(providerInstance.register, providerRegister.hasSubscribers ? { provider: providerInstance } : void 0, providerInstance);
			}
		});
	}
	/**
	* Phase 2: Calls boot() method on all registered providers.
	* Boot phase occurs after all providers have registered their services,
	* allowing providers to use services from other providers.
	*
	* @returns {Promise<void>} Promise that resolves when all providers are booted
	*/
	async boot() {
		for (let provider of this.#providers) if (provider.boot) {
			debug_default("booting \"%s\"", provider.constructor.name);
			await providerBoot.tracePromise(provider.boot, providerBoot.hasSubscribers ? { provider } : void 0, provider);
		}
	}
	/**
	* Phase 3: Calls start() method on all providers.
	* Start phase is for launching services like HTTP servers, background workers, etc.
	*
	* @returns {Promise<void>} Promise that resolves when all providers are started
	*/
	async start() {
		for (let provider of this.#providers) if (provider.start) {
			debug_default("invoking \"%s\" start method", provider.constructor.name);
			await providerStart.tracePromise(provider.start, providerStart.hasSubscribers ? { provider } : void 0, provider);
		}
	}
	/**
	* Phase 4: Calls ready() method on all providers.
	* Ready phase indicates the application is fully started and ready to serve requests.
	* Clears the providers array after completion as they're no longer needed.
	*
	* @returns {Promise<void>} Promise that resolves when all providers are ready
	*/
	async ready() {
		for (let provider of this.#providers) if (provider.ready) {
			debug_default("invoking \"%s\" ready method", provider.constructor.name);
			await providerReady.tracePromise(provider.ready, providerReady.hasSubscribers ? { provider } : void 0, provider);
		}
		this.#providers = [];
	}
	/**
	* Phase 5: Calls shutdown() method on providers that implement it.
	* Shutdown phase allows providers to perform cleanup during graceful app termination.
	* Only providers with shutdown methods are called.
	*
	* @param {boolean} inReverseOrder - Whether to shutdown providers in reverse order (recommended for cleanup)
	* @returns {Promise<void>} Promise that resolves when all providers are shutdown
	*/
	async shutdown(inReverseOrder) {
		const providersWithShutdownListeners = inReverseOrder ? Array.from(this.#providersWithShutdownListeners).reverse() : Array.from(this.#providersWithShutdownListeners);
		this.#providersWithShutdownListeners = [];
		for (let provider of providersWithShutdownListeners) if (provider.shutdown) {
			debug_default("shutting down \"%s\"", provider.constructor.name);
			await providerShutdown.tracePromise(provider.shutdown, providerShutdown.hasSubscribers ? { provider } : void 0, provider);
		}
	}
};
//#endregion
//#region src/feature_flags.ts
/**
* A light weight implementation of feature flags to conditionally enable
* experimental and legacy features.
*
* @template FlagsList - Type definition for the feature flags object
*
* @example
* const flags = new FeatureFlags({ newUI: true, betaFeature: false })
* if (flags.enabled('newUI')) {
*   // Enable new UI
* }
*
* @example
* const dynamicFlags = new FeatureFlags(() => getConfigFlags())
* flags.when('betaFeature',
*   () => console.log('Beta enabled'),
*   () => console.log('Beta disabled')
* )
*/
var FeatureFlags = class {
	/**
	* Static flags object containing feature flag values.
	* Used when flags are provided as a static object during construction.
	*
	* @private
	* @type {FlagsList | undefined}
	*/
	#flags;
	/**
	* Factory function to generate flags dynamically.
	* Used when flags need to be computed at runtime.
	*
	* @private
	* @type {(() => FlagsList) | undefined}
	*/
	#flagsFactory;
	/**
	* Creates a new FeatureFlags instance
	*
	* @param flags - Either a static flags object or a factory function
	*/
	constructor(flags) {
		if (typeof flags === "function") this.#flagsFactory = flags;
		else this.#flags = flags;
	}
	/**
	* Checks if a feature is enabled
	*
	* @param feature - The feature name to check
	* @returns boolean - True if the feature is enabled
	*/
	enabled(feature) {
		return (this.#flags ?? this.#flagsFactory())[feature] === true;
	}
	/**
	* Checks if a feature is disabled
	*
	* @param feature - The feature name to check
	* @returns boolean - True if the feature is disabled
	*/
	disabled(feature) {
		return (this.#flags ?? this.#flagsFactory())[feature] === false;
	}
	/**
	* Checks if a feature exists in the flags
	*
	* @param feature - The feature name to check
	* @returns boolean - True if the feature exists
	*/
	has(feature) {
		return feature in (this.#flags ?? this.#flagsFactory());
	}
	/**
	* Conditionally executes callbacks based on feature flag state
	*
	* @param feature - The feature name to check
	* @param enabledCallback - Callback to execute when feature is enabled
	* @param disabledCallback - Optional callback to execute when feature is disabled
	* @returns The result of the executed callback
	*/
	when(feature, enabledCallback, disabledCallback) {
		if (this.enabled(feature)) return enabledCallback();
		return disabledCallback ? disabledCallback() : void 0;
	}
};
//#endregion
//#region src/application.ts
/**
* Application class manages the state of an AdonisJS application. It includes:
*
* - Setting up the base features like importing config and setting up logger.
* - Parsing the "adonisrc.js" file
* - Setting up the IoC container
* - Registering and booting providers
* - Invoking lifecycle methods on the providers and hooks
*
* The Application class extends Macroable to allow runtime extension of functionality.
* It manages the entire lifecycle from creation to termination, providing hooks at
* each stage for customization.
*
* @template ContainerBindings - Type definition for IoC container bindings
* @extends {Macroable}
* @class Application
*/
var Application = class extends Macroable {
	/**
	* Importer function to import modules from the application context.
	* This function is used to dynamically import modules with proper
	* application context and error handling.
	*
	* @private
	* @type {Importer | undefined}
	*/
	#importer;
	/**
	* Flag to know if we have started the termination process.
	* Used to prevent multiple termination attempts and manage
	* graceful shutdown state.
	*
	* @private
	* @type {boolean}
	* @default false
	*/
	#terminating = false;
	/**
	* The environment in which the app is running. Currently tracks
	* process managers like PM2 to adjust behavior accordingly.
	*
	* @private
	* @type {Object}
	* @property {boolean} pm2 - Whether the app is running under PM2
	*/
	#surroundedEnvironment = { pm2: false };
	/**
	* Application root directory as a URL. This represents the base
	* path from which all other application paths are resolved.
	*
	* @private
	* @type {URL}
	*/
	#appRoot;
	/**
	* Current application environment (e.g., 'web', 'console', 'test').
	* Determines which providers and preloads are active.
	*
	* @private
	* @type {AppEnvironments}
	*/
	#environment;
	/**
	* Current state of the application lifecycle. Tracks the progression
	* through states: created → initiated → booted → ready → terminated.
	*
	* @private
	* @type {ApplicationStates}
	* @default 'created'
	*/
	#state = "created";
	/**
	* Configuration manager that handles loading and parsing of config files.
	*
	* @private
	* @type {ConfigManager}
	*/
	#configManager;
	/**
	* RC file manager that handles parsing of adonisrc.js file.
	*
	* @private
	* @type {RcFileManager}
	*/
	#rcFileManager;
	/**
	* Node environment manager that normalizes NODE_ENV values.
	*
	* @private
	* @type {NodeEnvManager}
	*/
	#nodeEnvManager;
	/**
	* Preloads manager that handles loading of preload files.
	*
	* @private
	* @type {PreloadsManager}
	*/
	#preloadsManager;
	/**
	* Providers manager that handles registration and lifecycle of service providers.
	*
	* @private
	* @type {ProvidersManager}
	*/
	#providersManager;
	/**
	* Lifecycle hooks manager that allows registering callbacks for different
	* application lifecycle events. Provides hooks for initiating, booting,
	* booted, starting, ready, and terminating phases.
	*
	* @private
	* @type {Hooks}
	*/
	#hooks = new Hooks();
	/**
	* Stores metadata information about the application including
	* app name, version, and AdonisJS version.
	*
	* @type {Map<string, any>}
	*/
	info = /* @__PURE__ */ new Map();
	/**
	* Returns the application name from the info map.
	* Defaults to 'adonisjs_app' if not set.
	*
	* @readonly
	* @type {string}
	*/
	get appName() {
		return this.info.get("appName") || "adonisjs_app";
	}
	/**
	* Returns the application version from the info map.
	* Returns null if no version is set.
	*
	* @readonly
	* @type {SemverNode | null}
	*/
	get version() {
		return this.info.get("version") || null;
	}
	/**
	* The parsed version for the "@adonisjs/core" package.
	* Returns null if no version is available.
	*
	* @readonly
	* @type {SemverNode | null}
	*/
	get adonisVersion() {
		return this.info.get("adonisVersion") || null;
	}
	/**
	* The URL for the root of the application directory.
	*
	* @readonly
	* @type {URL}
	*/
	get appRoot() {
		return this.#appRoot;
	}
	/**
	* A boolean to know if the application has been booted.
	* Returns true when the application state is beyond 'initiated'.
	*
	* @readonly
	* @type {boolean}
	*/
	get isBooted() {
		return this.#state !== "created" && this.#state !== "initiated";
	}
	/**
	* A boolean to know if the application is ready and fully started.
	* Returns true only when the application state is 'ready'.
	*
	* @readonly
	* @type {boolean}
	*/
	get isReady() {
		return this.#state === "ready";
	}
	/**
	* A boolean to know if the application has been terminated.
	* Returns true only when the application state is 'terminated'.
	*
	* @readonly
	* @type {boolean}
	*/
	get isTerminated() {
		return this.#state === "terminated";
	}
	/**
	* A boolean to know if the application is in the middle of
	* the termination process but not yet fully terminated.
	*
	* @readonly
	* @type {boolean}
	*/
	get isTerminating() {
		return this.#terminating && this.#state !== "terminated";
	}
	/**
	* Reference to the config instance. The value is available
	* after the "init" method has been called.
	*
	* @readonly
	* @type {any}
	*/
	get config() {
		return this.#configManager.config;
	}
	/**
	* Reference to the parsed adonisrc.js file. The value is available
	* after the "init" method has been called.
	*
	* @readonly
	* @type {any}
	*/
	get rcFile() {
		return this.#rcFileManager.rcFile;
	}
	/**
	* Normalized current NODE_ENV value. Converts common variations
	* to standard values (development, production, test).
	*
	* @readonly
	* @type {string}
	*/
	get nodeEnvironment() {
		return this.#nodeEnvManager.nodeEnvironment;
	}
	/**
	* Returns true when the NODE_ENV is set to 'production'.
	* Useful for conditional logic based on production environment.
	*
	* @readonly
	* @type {boolean}
	*/
	get inProduction() {
		return this.nodeEnvironment === "production";
	}
	/**
	* Returns true when the NODE_ENV is set to 'development'.
	* Useful for enabling development-specific features.
	*
	* @readonly
	* @type {boolean}
	*/
	get inDev() {
		return this.nodeEnvironment === "development";
	}
	/**
	* Returns true when the NODE_ENV is set to 'test'.
	* Useful for enabling test-specific behavior.
	*
	* @readonly
	* @type {boolean}
	*/
	get inTest() {
		return this.nodeEnvironment === "test";
	}
	/**
	* Returns true if the process is managed and running under PM2.
	* Detected by checking for the pm_id environment variable.
	*
	* @readonly
	* @type {boolean}
	*/
	get managedByPm2() {
		return this.#surroundedEnvironment.pm2;
	}
	/**
	* Reference to scaffolding generators for creating application files.
	* Provides utilities for generating controllers, models, migrations, etc.
	*
	* @readonly
	* @type {any}
	*/
	get generators() {
		return generators;
	}
	/**
	* Reference to the stubs module for scaffolding resources or ejecting stubs.
	* Provides functionality to create and manage code generation templates.
	*
	* @type {Object}
	* @property {Function} create - Factory function to create a StubsManager instance
	*/
	stubs = { create: async () => {
		const { StubsManager } = await import("./manager-CpbGmDZf.js");
		return new StubsManager(this, this.makePath(this.rcFile.directories.stubs));
	} };
	/**
	* Feature flags manager for checking the status of experimental features.
	* Reads configuration from adonisrc.js experimental section.
	*
	* @type {FeatureFlags<ExperimentalFlagsList>}
	*/
	experimentalFlags = new FeatureFlags(() => this.#rcFileManager.rcFile.experimental);
	/**
	* Flag indicating if VineJS provider is configured and available.
	* When true, the @vinejs/vine package can be safely imported.
	*
	* @type {boolean}
	* @default false
	*/
	usingVineJS = false;
	/**
	* Flag indicating if Edge template engine provider is configured.
	* When true, the edge.js package can be safely imported.
	*
	* @type {boolean}
	* @default false
	*/
	usingEdgeJS = false;
	/**
	* Detects which AI coding agent the application is running under.
	* Checks for environment variables set by different AI coding assistants:
	* - CLAUDECODE='1' for Claude Code
	* - GEMINI_CLI='1' for Gemini
	* - GITHUB_COPILOT_CLI_MODE='1' for GitHub Copilot
	* - WINDSURF_SESSION='1' or TERM_PROGRAM='windsurf' for Windsurf
	* - CODEX_CLI='1' or CODEX_SANDBOX='1' for Codex
	* - OPENCODE='1' for OpenCode
	* - CURSOR_AGENT='1' for Cursor
	*
	* @readonly
	* @type {'claude' | 'gemini' | 'copilot' | 'windsurf' | 'codex' | 'opencode' | 'cursor' | null}
	* @returns The name of the detected AI agent, or null if none detected
	*/
	get detectedAIAgent() {
		return detectAIAgent();
	}
	/**
	* Returns true if the application is running within any AI coding agent.
	* This is a convenience getter that checks if detectedAIAgent is not null.
	*
	* @readonly
	* @type {boolean}
	* @returns True when running under an AI coding agent, false otherwise
	*/
	get runningInAIAgent() {
		return isRunningInAIAgent();
	}
	/**
	* Creates an instance of Application.
	*
	* @param {URL} appRoot - The root URL of the application
	* @param {Object} options - Configuration options
	* @param {AppEnvironments} options.environment - The application environment
	* @param {Importer} [options.importer] - Optional module importer function
	*/
	constructor(appRoot, options) {
		super();
		this.#appRoot = appRoot;
		this.#importer = options.importer;
		this.#environment = options.environment;
		this.#nodeEnvManager = new NodeEnvManager();
		this.#configManager = new ConfigManager(this.appRoot);
		this.#rcFileManager = new RcFileManager(this.appRoot);
		this.#providersManager = new ProvidersManager({
			environment: this.#environment,
			providersState: [this]
		});
		this.#preloadsManager = new PreloadsManager({ environment: this.#environment });
		this.#surroundedEnvironment.pm2 = !!process.env.pm_id;
		if (debug_default.enabled) debug_default("app environment :%O", {
			pm2: this.#surroundedEnvironment.pm2,
			environment: this.#environment,
			nodeEnv: this.#nodeEnvManager.nodeEnvironment
		});
	}
	/**
	* Instantiate the application container
	*
	* @private
	*/
	#instantiateContainer() {
		this.container = new Container();
	}
	/**
	* The current environment in which the application is running
	*
	* @returns {AppEnvironments} The current application environment
	*/
	getEnvironment() {
		return this.#environment;
	}
	/**
	* Switch the environment in which the app is running. The
	* environment can only be changed before the app is booted.
	*
	* @param {AppEnvironments} environment - The new environment to set
	* @returns {this} Returns the application instance for method chaining
	* @throws {RuntimeException} When called after the app has been booted
	*/
	setEnvironment(environment) {
		if (this.#state !== "created" && this.#state !== "initiated") throw new RuntimeException("Cannot switch environment once the app has been booted");
		debug_default("switching environment { from:\"%s\", to: \"%s\" }", this.#environment, environment);
		this.#environment = environment;
		this.#preloadsManager.setEnvironment(environment);
		this.#providersManager.setEnvironment(environment);
		return this;
	}
	/**
	* The current state of the application
	*
	* @returns {ApplicationStates} The current application state
	*/
	getState() {
		return this.#state;
	}
	/**
	* Specify the contents of the "adonisrc.js" file as
	* an object. Calling this method will disable loading
	* the "adonisrc.js" file from the disk.
	*
	* @param {Record<string, any>} value - The RC file contents as an object
	* @returns {this} Returns the application instance for method chaining
	*/
	rcContents(value) {
		this.#rcFileManager.rcContents(value);
		return this;
	}
	/**
	* Define the config values to use when booting the
	* config provider. Calling this method disables
	* reading files from the config directory.
	*
	* @param {Record<any, any>} values - The config values to use
	* @returns {this} Returns the application instance for method chaining
	*/
	useConfig(values) {
		this.#configManager.useConfig(values);
		return this;
	}
	/**
	* Notify the parent process when the Node.js process is spawned with an IPC channel.
	* The arguments accepted are same as "process.send"
	*
	* @param {any} message - The message to send to the parent process
	* @param {any} [sendHandle] - Optional handle to send with the message
	* @param {Object} [options] - Options for sending the message
	* @param {boolean} [options.swallowErrors] - Whether to swallow errors
	* @param {boolean} [options.keepOpen] - Whether to keep the connection open
	* @param {function} [callback] - Callback function to handle send result
	*/
	notify(message, sendHandle, options, callback) {
		if (process.send) process.send(message, sendHandle, options, callback);
	}
	/**
	* Listen for a process signal. This method is same as calling
	* "process.on(signal)"
	*
	* @param {NodeJS.Signals} signal - The signal to listen for
	* @param {NodeJS.SignalsListener} callback - The callback to execute when signal is received
	* @returns {this} Returns the application instance for method chaining
	*/
	listen(signal, callback) {
		process.on(signal, callback);
		return this;
	}
	/**
	* Listen for a process signal once. This method is same as calling
	* "process.once(signal)"
	*
	* @param {NodeJS.Signals} signal - The signal to listen for
	* @param {NodeJS.SignalsListener} callback - The callback to execute when signal is received
	* @returns {this} Returns the application instance for method chaining
	*/
	listenOnce(signal, callback) {
		process.once(signal, callback);
		return this;
	}
	/**
	* Listen for a process signal conditionally.
	*
	* @param {boolean} conditional - Whether to register the listener
	* @param {NodeJS.Signals} signal - The signal to listen for
	* @param {NodeJS.SignalsListener} callback - The callback to execute when signal is received
	* @returns {this} Returns the application instance for method chaining
	*/
	listenIf(conditional, signal, callback) {
		if (conditional) process.on(signal, callback);
		return this;
	}
	/**
	* Listen for a process signal once conditionally.
	*
	* @param {boolean} conditional - Whether to register the listener
	* @param {NodeJS.Signals} signal - The signal to listen for
	* @param {NodeJS.SignalsListener} callback - The callback to execute when signal is received
	* @returns {this} Returns the application instance for method chaining
	*/
	listenOnceIf(conditional, signal, callback) {
		if (conditional) process.once(signal, callback);
		return this;
	}
	/**
	* Register hooks that are called before the app starts
	* the initiating process
	*
	* @param {HookHandler} handler - The hook handler function to register
	* @returns {this} Returns the application instance for method chaining
	*/
	initiating(handler) {
		this.#hooks.add("initiating", handler);
		return this;
	}
	/**
	* Initiate the application. Calling this method performs following
	* operations:
	*
	* - Parses the "adonisrc.js" file
	* - Validate and set environment variables
	* - Loads the application config from the configured config dir.
	* - Configures the logger
	* - Instantiates the IoC container
	*
	* @returns {Promise<void>} Promise that resolves when initiation is complete
	*/
	async init() {
		if (this.#state !== "created") {
			debug_default("cannot initiate app from state \"%s\"", this.#state);
			return;
		}
		debug_default("initiating app");
		/**
		* Metadata management is not considering part
		* of initiating the app
		*/
		this.#instantiateContainer();
		/**
		* Notify we are about to initiate the app
		*/
		await this.#hooks.runner("initiating").run(this);
		/**
		* Initiate essentials
		*/
		await this.#rcFileManager.process();
		/**
		* Cleanup registered hooks
		*/
		this.#hooks.clear("initiating");
		this.#state = "initiated";
	}
	/**
	* Register hooks that are called before the app boot
	* process starts
	*
	* @param {HookHandler} handler - The hook handler function to register
	* @returns {this} Returns the application instance for method chaining
	*/
	booting(handler) {
		this.#hooks.add("booting", handler);
		return this;
	}
	/**
	* Boot the application. Calling this method performs the following
	* operations:
	*
	* - Resolve providers and call the "register" method on them.
	* - Call the "boot" method on providers
	* - Run the "booted" hooks
	*
	* @returns {Promise<void>} Promise that resolves when boot is complete
	*/
	async boot() {
		if (this.#state !== "initiated") {
			debug_default("cannot boot app from state \"%s\"", this.#state);
			return;
		}
		debug_default("booting app");
		/**
		* Execute booting hooks
		*/
		await this.#hooks.runner("booting").run(this);
		this.#hooks.clear("booting");
		/**
		* Process node env and config files
		*/
		this.#nodeEnvManager.process();
		await this.#configManager.process(this.rcFile.directories.config);
		/**
		* Boot providers
		*/
		this.#providersManager.use(this.rcFile.providers);
		await this.#providersManager.register();
		await this.#providersManager.boot();
		/**
		* Notify the app is booted
		*/
		await this.#hooks.runner("booted").run(this);
		this.#hooks.clear("booted");
		this.#state = "booted";
	}
	/**
	* Register a hook to get notified when the application has
	* been booted.
	*
	* The hook will be called immediately if the app has already
	* been booted.
	*
	* @param {HookHandler} handler - The hook handler function to register
	* @returns {Promise<void>} Promise that resolves after the handler is executed
	*/
	async booted(handler) {
		if (this.isBooted) await handler(this);
		else this.#hooks.add("booted", handler);
	}
	/**
	* Register hooks that are called when the app is starting
	*
	* @param {HookHandler} handler - The hook handler function to register
	* @returns {this} Returns the application instance for method chaining
	*/
	starting(handler) {
		this.#hooks.add("starting", handler);
		return this;
	}
	/**
	* Start the application. Calling this method performs the following
	* operations:
	*
	* - Run the "start" lifecycle hooks on all the providers
	* - Start the application by invoking the supplied callback
	* - Run the "ready" lifecycle hooks on all the providers
	* - Run the "ready" application hooks
	*
	* @param {function} callback - The callback function to invoke when starting the app
	* @returns {Promise<void>} Promise that resolves when start is complete
	*/
	async start(callback) {
		if (this.#state !== "booted") {
			debug_default("cannot start app from state \"%s\"", this.#state);
			return;
		}
		debug_default("starting app");
		/**
		* Pre start phase
		*/
		await this.#providersManager.start();
		await this.#hooks.runner("starting").run(this);
		this.#hooks.clear("starting");
		await this.#preloadsManager.use(this.rcFile.preloads).import();
		/**
		* Callback to perform start of the application
		*/
		await callback(this);
		/**
		* Post start phase
		*/
		await this.#providersManager.ready();
		await this.#hooks.runner("ready").run(this);
		this.#hooks.clear("ready");
		/**
		* App ready
		*/
		this.#state = "ready";
		/**
		* Notify process is ready
		*/
		debug_default("application ready");
		this.notify("ready");
	}
	/**
	* Register hooks that are called when the app is ready.
	*
	* The hook will be called immediately if the app is already ready.
	*
	* @param {HookHandler} handler - The hook handler function to register
	* @returns {Promise<void>} Promise that resolves after the handler is executed
	*/
	async ready(handler) {
		if (this.isReady) await handler(this);
		else this.#hooks.add("ready", handler);
	}
	/**
	* Register hooks that are called before the app is terminated.
	*
	* @param {HookHandler} handler - The hook handler function to register
	* @returns {this} Returns the application instance for method chaining
	*/
	terminating(handler) {
		this.#hooks.add("terminating", handler);
		return this;
	}
	/**
	* Terminate application gracefully. Calling this method performs
	* the following operations:
	*
	* - Run "shutdown" hooks on all the providers
	* - Run "terminating" app lifecycle hooks
	*
	* @returns {Promise<void>} Promise that resolves when termination is complete
	*/
	async terminate() {
		if (this.#state === "created" || this.#state === "terminated") {
			debug_default("cannot terminate app from state \"%s\"", this.#state);
			return;
		}
		if (this.#terminating) {
			debug_default("app is already being terminated");
			return;
		}
		debug_default("terminating app");
		this.#terminating = true;
		await this.#hooks.runner("terminating").runReverse(this);
		await this.#providersManager.shutdown(true);
		this.#hooks.clear("terminating");
		this.#state = "terminated";
	}
	/**
	* Returns relative path to a file from the app root
	*
	* @param {string} absolutePath - The absolute path to convert
	* @returns {string} The relative path from app root
	*/
	relativePath(absolutePath) {
		return relative(fileURLToPath(this.appRoot), absolutePath);
	}
	/**
	* Returns URL to a path from the application root.
	*
	* @param {...string} paths - Path segments to join
	* @returns {URL} The constructed URL
	*/
	makeURL(...paths) {
		return new URL(join(...paths), this.#appRoot);
	}
	/**
	* Returns file system path from the application root.
	*
	* @param {...string} paths - Path segments to join
	* @returns {string} The constructed file system path
	*/
	makePath(...paths) {
		return fileURLToPath(this.makeURL(...paths));
	}
	/**
	* Makes path to the config directory
	*
	* @param {...string} paths - Path segments to append to config directory
	* @returns {string} The constructed config directory path
	*/
	configPath(...paths) {
		return this.makePath(this.rcFile.directories.config, ...paths);
	}
	/**
	* Makes path to the public directory
	*
	* @param {...string} paths - Path segments to append to public directory
	* @returns {string} The constructed public directory path
	*/
	publicPath(...paths) {
		return this.makePath(this.rcFile.directories.public, ...paths);
	}
	/**
	* Makes path to the providers directory
	*
	* @param {...string} paths - Path segments to append to providers directory
	* @returns {string} The constructed providers directory path
	*/
	providersPath(...paths) {
		return this.makePath(this.rcFile.directories.providers, ...paths);
	}
	/**
	* Makes path to the factories directory
	*
	* @param {...string} paths - Path segments to append to factories directory
	* @returns {string} The constructed factories directory path
	*/
	factoriesPath(...paths) {
		return this.makePath(this.rcFile.directories.factories, ...paths);
	}
	/**
	* Makes path to the migrations directory
	*
	* @param {...string} paths - Path segments to append to migrations directory
	* @returns {string} The constructed migrations directory path
	*/
	migrationsPath(...paths) {
		return this.makePath(this.rcFile.directories.migrations, ...paths);
	}
	/**
	* Makes path to the seeders directory
	*
	* @param {...string} paths - Path segments to append to seeders directory
	* @returns {string} The constructed seeders directory path
	*/
	seedersPath(...paths) {
		return this.makePath(this.rcFile.directories.seeders, ...paths);
	}
	/**
	* Makes path to the language files directory
	*
	* @param {...string} paths - Path segments to append to language files directory
	* @returns {string} The constructed language files directory path
	*/
	languageFilesPath(...paths) {
		return this.makePath(this.rcFile.directories.languageFiles, ...paths);
	}
	/**
	* Makes path to the views directory
	*
	* @param {...string} paths - Path segments to append to views directory
	* @returns {string} The constructed views directory path
	*/
	viewsPath(...paths) {
		return this.makePath(this.rcFile.directories.views, ...paths);
	}
	/**
	* Makes path to the start directory
	*
	* @param {...string} paths - Path segments to append to start directory
	* @returns {string} The constructed start directory path
	*/
	startPath(...paths) {
		return this.makePath(this.rcFile.directories.start, ...paths);
	}
	/**
	* Makes path to the tmp directory
	*
	* @param {...string} paths - Path segments to append to tmp directory
	* @returns {string} The constructed tmp directory path
	*/
	tmpPath(...paths) {
		return this.makePath(this.rcFile.directories.tmp, ...paths);
	}
	/**
	* Makes path to the contracts directory
	*
	* @param {...string} paths - Path segments to append to contracts directory
	* @returns {string} The constructed contracts directory path
	* @deprecated Use "types" directory instead
	*/
	contractsPath(...paths) {
		return this.makePath(this.rcFile.directories.contracts, ...paths);
	}
	/**
	* Makes path to the http controllers directory
	*
	* @param {...string} paths - Path segments to append to http controllers directory
	* @returns {string} The constructed http controllers directory path
	*/
	httpControllersPath(...paths) {
		return this.makePath(this.rcFile.directories.httpControllers, ...paths);
	}
	/**
	* Makes path to the models directory
	*
	* @param {...string} paths - Path segments to append to models directory
	* @returns {string} The constructed models directory path
	*/
	modelsPath(...paths) {
		return this.makePath(this.rcFile.directories.models, ...paths);
	}
	/**
	* Makes path to the services directory
	*
	* @param {...string} paths - Path segments to append to services directory
	* @returns {string} The constructed services directory path
	*/
	servicesPath(...paths) {
		return this.makePath(this.rcFile.directories.services, ...paths);
	}
	/**
	* Makes path to the exceptions directory
	*
	* @param {...string} paths - Path segments to append to exceptions directory
	* @returns {string} The constructed exceptions directory path
	*/
	exceptionsPath(...paths) {
		return this.makePath(this.rcFile.directories.exceptions, ...paths);
	}
	/**
	* Makes path to the mailers directory
	*
	* @param {...string} paths - Path segments to append to mailers directory
	* @returns {string} The constructed mailers directory path
	*/
	mailersPath(...paths) {
		return this.makePath(this.rcFile.directories.mailers, ...paths);
	}
	/**
	* Makes path to the mails directory
	*
	* @param {...string} paths - Path segments to append to mails directory
	* @returns {string} The constructed mails directory path
	*/
	mailsPath(...paths) {
		return this.makePath(this.rcFile.directories.mails, ...paths);
	}
	/**
	* Makes path to the middleware directory
	*
	* @param {...string} paths - Path segments to append to middleware directory
	* @returns {string} The constructed middleware directory path
	*/
	middlewarePath(...paths) {
		return this.makePath(this.rcFile.directories.middleware, ...paths);
	}
	/**
	* Makes path to the policies directory
	*
	* @param {...string} paths - Path segments to append to policies directory
	* @returns {string} The constructed policies directory path
	*/
	policiesPath(...paths) {
		return this.makePath(this.rcFile.directories.policies, ...paths);
	}
	/**
	* Makes path to the validators directory
	*
	* @param {...string} paths - Path segments to append to validators directory
	* @returns {string} The constructed validators directory path
	*/
	validatorsPath(...paths) {
		return this.makePath(this.rcFile.directories.validators, ...paths);
	}
	/**
	* Makes path to the commands directory
	*
	* @param {...string} paths - Path segments to append to commands directory
	* @returns {string} The constructed commands directory path
	*/
	commandsPath(...paths) {
		return this.makePath(this.rcFile.directories.commands, ...paths);
	}
	/**
	* Makes path to the events directory
	*
	* @param {...string} paths - Path segments to append to events directory
	* @returns {string} The constructed events directory path
	*/
	eventsPath(...paths) {
		return this.makePath(this.rcFile.directories.events, ...paths);
	}
	/**
	* Makes path to the listeners directory
	*
	* @param {...string} paths - Path segments to append to listeners directory
	* @returns {string} The constructed listeners directory path
	*/
	listenersPath(...paths) {
		return this.makePath(this.rcFile.directories.listeners, ...paths);
	}
	/**
	* Makes path to the transformers directory
	*
	* @param {...string} paths - Path segments to append to transformers directory
	* @returns {string} The constructed transformers directory path
	*/
	transformersPath(...paths) {
		return this.makePath(this.rcFile.directories.transformers, ...paths);
	}
	/**
	* Makes path to the client directory for writing generated
	* output
	*
	* @param {...string} paths - Path segments to append to events directory
	* @returns {string} The constructed directory path
	*/
	generatedClientPath(...paths) {
		return this.makePath(this.rcFile.directories.generatedClient, ...paths);
	}
	/**
	* Makes path to the server directory for writing generated
	* output
	*
	* @param {...string} paths - Path segments to append to events directory
	* @returns {string} The constructed directory path
	*/
	generatedServerPath(...paths) {
		return this.makePath(this.rcFile.directories.generatedServer, ...paths);
	}
	/**
	* Import a module by identifier. This method uses the importer function
	* defined at the time of creating the application instance and throws
	* an error if no importer was defined.
	*
	* @param {string} moduleIdentifier - The module identifier to import
	* @returns {any} The imported module
	* @throws {RuntimeException} When no importer function is defined
	*/
	import(moduleIdentifier) {
		if (!this.#importer) throw new RuntimeException(`Cannot import "${moduleIdentifier}". Register a module importer with the application first.`);
		return this.#importer(moduleIdentifier);
	}
	/**
	* Import a module by identifier and return its default export. This method uses the importer function
	* defined at the time of creating the application instance and throws
	* an error if no importer was defined.
	*
	* @template T - The type of the default export
	* @param {string} moduleIdentifier - The module identifier to import
	* @returns The default export of the imported module
	* @throws {RuntimeException} When no importer function is defined
	*/
	importDefault(moduleIdentifier) {
		if (!this.#importer) throw new RuntimeException(`Cannot import "${moduleIdentifier}". Register a module importer with the application first.`);
		return importDefault(() => this.#importer(moduleIdentifier));
	}
	/**
	* JSON representation of the application
	*
	* @returns The application state as a JSON object
	*/
	toJSON() {
		return {
			isReady: this.isReady,
			isTerminating: this.isTerminating,
			environment: this.#environment,
			nodeEnvironment: this.nodeEnvironment,
			appName: this.appName,
			version: this.version ? this.version.toString() : null,
			adonisVersion: this.adonisVersion ? this.adonisVersion.toString() : null
		};
	}
};
//#endregion
export { generators as a, RcFileParser as i, FeatureFlags as n, debug_default as o, tracing_channels_exports as r, errors_exports as s, Application as t };
