This commit is contained in:
Tutur33
2023-11-24 22:35:41 +01:00
parent 3c0b507a93
commit 7644b2a0f7
45165 changed files with 4803356 additions and 3 deletions
+313
View File
@@ -0,0 +1,313 @@
/// <reference path="../adonis-typings/application.d.ts" />
import { RcFile, SemverNode, PreloadNode, AppEnvironments, ApplicationStates, ApplicationContract, AssetsDriver } from '@ioc:Adonis/Core/Application';
import { Logger } from '@adonisjs/logger';
import { Config } from '@adonisjs/config';
import { Profiler } from '@adonisjs/profiler';
import { Env } from '@adonisjs/env';
import * as helpers from '@poppinss/utils/build/helpers';
/**
* The main application instance to know about the environment, filesystem
* in which your AdonisJs app is running
*/
export declare class Application implements ApplicationContract {
readonly appRoot: string;
environment: AppEnvironments;
helpers: typeof helpers;
/**
* Available after setup call
*/
logger: Logger;
profiler: Profiler;
env: Env;
config: Config;
/**
* Available after registerProviders call
*/
private registrar;
/**
* An array of providers with ready and shutdown hooks.
*/
private providersWithReadyHook;
private providersWithShutdownHook;
state: ApplicationStates;
/**
* Current working directory for the CLI and not the build directory
* The `ADONIS_CLI_CWD` is set by the cli
*/
readonly cliCwd?: string;
/**
* The name of the application picked from `.adonisrc.json` file. This can
* be used to prefix logs.
*/
readonly appName: string;
/**
* The application version. Again picked from `.adonisrc.json` file
*/
readonly version: SemverNode | null;
/**
* `@adonisjs/core` version
*/
readonly adonisVersion: SemverNode | null;
/**
* Reference to fully parser rcFile
*/
readonly rcFile: RcFile;
/**
* The typescript flag indicates a couple of things, which can help tweak the tooling
* and runtime behavior of the application as well.
*
* 1. When `typescript=true`, it means that the project is written using typescript.
* 2. After compiling to Javascript, AdonisJs will set this value to `false` in the build folder.
* 3. At runtime when `typescript=true`, it means the app is using ts-node to start.
*/
readonly typescript: boolean;
/**
* A boolean to know if application has bootstrapped successfully
*/
get isReady(): boolean;
/**
* A boolean to know if app is preparing to shutdown
*/
isShuttingDown: boolean;
/**
* The namespace of exception handler that will handle exceptions
*/
exceptionHandlerNamespace?: string;
/**
* The driver to use for assets bundling
*/
assetsDriver?: AssetsDriver;
/**
* It is unknown until the `setup` method is called
*/
nodeEnvironment: 'unknown' | 'development' | 'production' | 'test' | string;
/**
* An array of files to be preloaded
*/
preloads: PreloadNode[];
/**
* A map of pre-configured directories
*/
directoriesMap: Map<string, string>;
/**
* A map of directories aliases
*/
aliasesMap: Map<string, string>;
/**
* A map of namespaces that different parts of apps
* can use
*/
namespacesMap: Map<string, string>;
/**
* Reference to the IoC container for the application
*/
container: ApplicationContract['container'];
constructor(appRoot: string, environment: AppEnvironments, rcContents?: any);
/**
* Verify the node version when defined under "engines" object in
* "packages.json" file.
*/
private verifyNodeEngine;
/**
* Resolve a given module from the application root. The callback is invoked
* when the module is missing
*/
private resolveModule;
/**
* Loads the rc file from the application root
*/
private loadRcFile;
/**
* Loads the package.json file from the application root. Swallows
* the exception when file is missing
*/
private loadAppPackageJson;
/**
* Loads the package.json file for the "@adonisjs/core" package. Swallows
* the exception when file is missing
*/
private loadCorePackageJson;
/**
* Parses version string to an object.
*/
private parseVersion;
/**
* Sets env variables based upon the provided application info.
*/
private setEnvVars;
/**
* Setup container globals to easily resolve bindings
*/
private setupGlobals;
/**
* Registering itself to the container
*/
private registerItselfToTheContainer;
/**
* Normalizes node env
*/
private normalizeNodeEnv;
/**
* Registering directory aliases
*/
private registerAliases;
/**
* Loads the environment variables by reading and parsing the
* `.env` and `.env.testing` files.
*/
private loadEnvironmentVariables;
/**
* Load config and define the container binding
*/
private loadConfig;
/**
* Setup logger
*/
private setupLogger;
/**
* Setup profiler
*/
private setupProfiler;
/**
* Setup helpers
*/
private setupHelpers;
/**
* Return true when `this.nodeEnvironment === 'production'`
*/
get inProduction(): boolean;
/**
* Opposite of [[this.isProduction]]
*/
get inDev(): boolean;
/**
* Returns true when `this.nodeEnvironment === 'test'`
*/
get inTest(): boolean;
/**
* Returns path for a given namespace by replacing the base namespace
* with the defined directories map inside the rc file.
*
* The method returns a relative path from the application root. You can
* use join it with the [[this.appRoot]] to make the absolute path
*/
resolveNamespaceDirectory(namespaceFor: string): string | null;
/**
* Make path to a file or directory relative from
* the application path
*/
makePath(...paths: string[]): string;
/**
* Makes the path to a directory from `cliCwd` vs the `appRoot`. This is
* helpful when we want path inside the project root and not the
* build directory
* @deprecated Use `makePath` instead
*/
makePathFromCwd(...paths: string[]): string;
/**
* Make path to a file or directory relative from
* the config directory
*/
configPath(...paths: string[]): string;
/**
* Make path to a file or directory relative from
* the public path
*/
publicPath(...paths: string[]): string;
/**
* Make path to a file or directory relative from
* the providers path
*/
providersPath(...paths: string[]): string;
/**
* Make path to a file or directory relative from
* the database path
*/
databasePath(...paths: string[]): string;
/**
* Make path to a file or directory relative from
* the migrations path
*/
migrationsPath(...paths: string[]): string;
/**
* Make path to a file or directory relative from
* the seeds path
*/
seedsPath(...paths: string[]): string;
/**
* Make path to a file or directory relative from
* the resources path
*/
resourcesPath(...paths: string[]): string;
/**
* Make path to a file or directory relative from
* the views path
*/
viewsPath(...paths: string[]): string;
/**
* Makes path to the start directory
*/
startPath(...paths: string[]): string;
/**
* Makes path to the tests directory
*/
testsPath(...paths: string[]): string;
/**
* Makes path to the tmp directory. Since the tmp path is used for
* writing at the runtime, we use `cwd` path to the write to the
* source and not the build directory.
*/
tmpPath(...paths: string[]): string;
/**
* Serialized output
*/
toJSON(): {
isReady: boolean;
isShuttingDown: boolean;
environment: AppEnvironments;
nodeEnvironment: string;
appName: string;
version: string | null;
adonisVersion: string | null;
};
/**
* Switch application environment. Only allowed before the setup
* is called
*/
switchEnvironment(environment: AppEnvironments): this;
/**
* Performs the initial setup. This is the time, when we configure the
* app to be able to boot itself. For example:
*
* - Loading environment variables
* - Loading config
* - Setting up the logger
* - Registering directory aliases
*
* Apart from the providers, most of the app including the container
* is ready at this stage
*/
setup(): Promise<void>;
/**
* Register providers
*/
registerProviders(): Promise<void>;
/**
* Booted providers
*/
bootProviders(): Promise<void>;
/**
* Require files registered as preloads inside `.adonisrc.json` file
*/
requirePreloads(): Promise<void>;
/**
* Start the application. At this time we execute the provider's
* ready hooks
*/
start(): Promise<void>;
/**
* Prepare the application for shutdown. At this time we execute the
* provider's shutdown hooks
*/
shutdown(): Promise<void>;
}
+622
View File
@@ -0,0 +1,622 @@
"use strict";
/*
* @adonisjs/application
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Application = void 0;
const path_1 = require("path");
const logger_1 = require("@adonisjs/logger");
const config_1 = require("@adonisjs/config");
const profiler_1 = require("@adonisjs/profiler");
const utils_1 = require("@poppinss/utils");
const fold_1 = require("@adonisjs/fold");
const env_1 = require("@adonisjs/env");
const helpers = __importStar(require("@poppinss/utils/build/helpers"));
const semver_1 = require("semver");
const rcParser_1 = require("./rcParser");
/**
* Aliases for different environments
*/
const DEV_ENVS = ['dev', 'develop', 'development'];
const PROD_ENVS = ['prod', 'production'];
const TEST_ENVS = ['test', 'testing'];
/**
* The main application instance to know about the environment, filesystem
* in which your AdonisJs app is running
*/
class Application {
/**
* A boolean to know if application has bootstrapped successfully
*/
get isReady() {
return this.state === 'ready' && !this.isShuttingDown;
}
constructor(appRoot, environment, rcContents) {
this.appRoot = appRoot;
this.environment = environment;
this.helpers = helpers;
/**
* An array of providers with ready and shutdown hooks.
*/
this.providersWithReadyHook = [];
this.providersWithShutdownHook = [];
this.state = 'initiated';
/**
* Current working directory for the CLI and not the build directory
* The `ADONIS_CLI_CWD` is set by the cli
*/
this.cliCwd = process.env.ADONIS_ACE_CWD;
/**
* A boolean to know if app is preparing to shutdown
*/
this.isShuttingDown = false;
/**
* It is unknown until the `setup` method is called
*/
this.nodeEnvironment = 'unknown';
/**
* An array of files to be preloaded
*/
this.preloads = [];
/**
* A map of pre-configured directories
*/
this.directoriesMap = new Map();
/**
* A map of directories aliases
*/
this.aliasesMap = new Map();
/**
* A map of namespaces that different parts of apps
* can use
*/
this.namespacesMap = new Map();
/**
* Reference to the IoC container for the application
*/
this.container = new fold_1.Ioc();
this.rcFile = (0, rcParser_1.parse)(rcContents || this.loadRcFile());
this.typescript = this.rcFile.typescript;
/**
* Loads the package.json files to collect optional
* info about the app.
*/
const pkgFile = this.loadAppPackageJson();
const corePkgFile = this.loadCorePackageJson();
this.verifyNodeEngine(pkgFile.engines);
/**
* Fetching following info from the package file
*/
this.appName = pkgFile.name;
this.version = this.parseVersion(pkgFile.version);
this.adonisVersion = corePkgFile.version ? this.parseVersion(corePkgFile.version) : null;
/**
* Fetching following info from the `.adonisrc.json` file.
*/
this.preloads = this.rcFile.preloads;
this.exceptionHandlerNamespace = this.rcFile.exceptionHandlerNamespace;
this.assetsDriver = this.rcFile.assetsDriver;
this.directoriesMap = new Map(Object.entries(this.rcFile.directories));
this.aliasesMap = new Map(Object.entries(this.rcFile.aliases));
this.namespacesMap = new Map(Object.entries(this.rcFile.namespaces));
this.setEnvVars();
this.setupGlobals();
this.registerItselfToTheContainer();
this.setupHelpers();
}
/**
* Verify the node version when defined under "engines" object in
* "packages.json" file.
*/
verifyNodeEngine(engines) {
const nodeEngine = engines?.node;
if (!nodeEngine) {
return;
}
if (!(0, semver_1.satisfies)(process.version, nodeEngine)) {
throw new utils_1.Exception(`The installed Node.js version "${process.version}" does not satisfy the expected version "${nodeEngine}" defined inside package.json file`, 500);
}
}
/**
* Resolve a given module from the application root. The callback is invoked
* when the module is missing
*/
resolveModule(modulePath, onMissingCallback) {
let filePath;
try {
filePath = helpers.resolveFrom(this.appRoot, modulePath);
return require(filePath);
}
catch (error) {
if (['ENOENT', 'MODULE_NOT_FOUND'].includes(error.code) &&
(!filePath || filePath === error.path)) {
return onMissingCallback(error);
}
else {
throw error;
}
}
}
/**
* Loads the rc file from the application root
*/
loadRcFile() {
return this.resolveModule('./.adonisrc.json', () => {
throw new Error('AdonisJS expects ".adonisrc.json" file to exist in the application root');
});
}
/**
* Loads the package.json file from the application root. Swallows
* the exception when file is missing
*/
loadAppPackageJson() {
const pkgFile = this.resolveModule('./package.json', () => {
return {};
});
return {
name: pkgFile.name || 'adonis-app',
version: pkgFile.version || '0.0.0',
engines: pkgFile.engines,
};
}
/**
* Loads the package.json file for the "@adonisjs/core" package. Swallows
* the exception when file is missing
*/
loadCorePackageJson() {
const pkgFile = this.resolveModule('@adonisjs/core/package.json', () => {
return {};
});
return {
version: pkgFile.version,
};
}
/**
* Parses version string to an object.
*/
parseVersion(version) {
const parsed = (0, semver_1.parse)(version);
if (!parsed) {
return null;
}
return {
major: parsed.major,
minor: parsed.minor,
patch: parsed.patch,
prerelease: parsed.prerelease.map((release) => release),
version: parsed.version,
toString() {
return this.version;
},
};
}
/**
* Sets env variables based upon the provided application info.
*/
setEnvVars() {
process.env.APP_NAME = this.appName;
if (this.version) {
process.env.APP_VERSION = this.version.toString();
}
if (this.adonisVersion) {
process.env.ADONIS_VERSION = this.adonisVersion.toString();
}
}
/**
* Setup container globals to easily resolve bindings
*/
setupGlobals() {
global[Symbol.for('ioc.use')] = this.container.use.bind(this.container);
global[Symbol.for('ioc.make')] = this.container.make.bind(this.container);
global[Symbol.for('ioc.call')] = this.container.call.bind(this.container);
}
/**
* Registering itself to the container
*/
registerItselfToTheContainer() {
this.container.singleton('Adonis/Core/Application', () => this);
}
/**
* Normalizes node env
*/
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;
}
/**
* Registering directory aliases
*/
registerAliases() {
this.aliasesMap.forEach((toPath, alias) => {
this.container.alias((0, path_1.join)(this.appRoot, toPath), alias);
});
}
/**
* Loads the environment variables by reading and parsing the
* `.env` and `.env.testing` files.
*/
loadEnvironmentVariables() {
/**
* Load `.env` and `.env.testing` files from the application root. The
* env loader handles the additional flags like
*
* ENV_SILENT = 'do not load the .env file'
* ENV_PATH = 'load .env file from given path'
* NODE_ENV = 'testing' will trigger optional loading of `.env.testing` file
*/
const { envContents, testEnvContent } = (0, env_1.envLoader)(this.appRoot);
/**
* Create instance of the Env class
*/
this.env = new env_1.Env([
{ values: new env_1.EnvParser(true).parse(envContents), overwriteExisting: false },
{ values: new env_1.EnvParser(false).parse(testEnvContent), overwriteExisting: true },
]);
this.container.singleton('Adonis/Core/Env', () => this.env);
/**
* Attempt to load `env.(ts|js)` files to setup the validation rules
*/
this.resolveModule('./env', () => { });
/**
* Process environment variables. This will trigger validations as well
*/
this.env.process();
/**
* Update node environment
*/
this.nodeEnvironment = this.normalizeNodeEnv(this.env.get('NODE_ENV'));
}
/**
* Load config and define the container binding
*/
loadConfig() {
this.config = new config_1.Config(helpers.requireAll(this.configPath()));
this.container.singleton('Adonis/Core/Config', () => this.config);
}
/**
* Setup logger
*/
setupLogger() {
const config = this.container.resolveBinding('Adonis/Core/Config').get('app.logger', {});
this.logger = new logger_1.Logger(config);
this.container.singleton('Adonis/Core/Logger', () => this.logger);
}
/**
* Setup profiler
*/
setupProfiler() {
const config = this.container.resolveBinding('Adonis/Core/Config').get('app.profiler', {});
const logger = this.container.resolveBinding('Adonis/Core/Logger');
this.profiler = new profiler_1.Profiler(this.appRoot, logger, config);
this.container.singleton('Adonis/Core/Profiler', () => this.profiler);
}
/**
* Setup helpers
*/
setupHelpers() {
this.container.bind('Adonis/Core/Helpers', () => helpers);
}
/**
* Return true when `this.nodeEnvironment === 'production'`
*/
get inProduction() {
return this.nodeEnvironment === 'production';
}
/**
* Opposite of [[this.isProduction]]
*/
get inDev() {
return !this.inProduction;
}
/**
* Returns true when `this.nodeEnvironment === 'test'`
*/
get inTest() {
return this.nodeEnvironment === 'test';
}
/**
* Returns path for a given namespace by replacing the base namespace
* with the defined directories map inside the rc file.
*
* The method returns a relative path from the application root. You can
* use join it with the [[this.appRoot]] to make the absolute path
*/
resolveNamespaceDirectory(namespaceFor) {
/**
* Return null when rcfile doesn't have a special
* entry for namespaces
*/
if (!this.rcFile.namespaces[namespaceFor]) {
return null;
}
let output = null;
Object.keys(this.rcFile.aliases).forEach((baseNamespace) => {
const autoloadPath = this.rcFile.aliases[baseNamespace];
if (this.rcFile.namespaces[namespaceFor].startsWith(`${baseNamespace}/`) ||
this.rcFile.namespaces[namespaceFor] === baseNamespace) {
output = this.rcFile.namespaces[namespaceFor].replace(baseNamespace, autoloadPath);
}
});
return output;
}
/**
* Make path to a file or directory relative from
* the application path
*/
makePath(...paths) {
return (0, path_1.join)(this.appRoot, ...paths);
}
/**
* Makes the path to a directory from `cliCwd` vs the `appRoot`. This is
* helpful when we want path inside the project root and not the
* build directory
* @deprecated Use `makePath` instead
*/
makePathFromCwd(...paths) {
process.emitWarning('DeprecationWarning', 'application.makePathFromCwd() is deprecated. Use application.makePath() instead');
return (0, path_1.join)(this.cliCwd || this.appRoot, ...paths);
}
/**
* Make path to a file or directory relative from
* the config directory
*/
configPath(...paths) {
return this.makePath(this.directoriesMap.get('config'), ...paths);
}
/**
* Make path to a file or directory relative from
* the public path
*/
publicPath(...paths) {
return this.makePath(this.directoriesMap.get('public'), ...paths);
}
/**
* Make path to a file or directory relative from
* the providers path
*/
providersPath(...paths) {
return this.makePath(this.directoriesMap.get('providers'), ...paths);
}
/**
* Make path to a file or directory relative from
* the database path
*/
databasePath(...paths) {
return this.makePath(this.directoriesMap.get('database'), ...paths);
}
/**
* Make path to a file or directory relative from
* the migrations path
*/
migrationsPath(...paths) {
return this.makePath(this.directoriesMap.get('migrations'), ...paths);
}
/**
* Make path to a file or directory relative from
* the seeds path
*/
seedsPath(...paths) {
return this.makePath(this.directoriesMap.get('seeds'), ...paths);
}
/**
* Make path to a file or directory relative from
* the resources path
*/
resourcesPath(...paths) {
return this.makePath(this.directoriesMap.get('resources'), ...paths);
}
/**
* Make path to a file or directory relative from
* the views path
*/
viewsPath(...paths) {
return this.makePath(this.directoriesMap.get('views'), ...paths);
}
/**
* Makes path to the start directory
*/
startPath(...paths) {
return this.makePath(this.directoriesMap.get('start'), ...paths);
}
/**
* Makes path to the tests directory
*/
testsPath(...paths) {
return this.makePath(this.directoriesMap.get('tests'), ...paths);
}
/**
* Makes path to the tmp directory. Since the tmp path is used for
* writing at the runtime, we use `cwd` path to the write to the
* source and not the build directory.
*/
tmpPath(...paths) {
return this.makePath(this.directoriesMap.get('tmp'), ...paths);
}
/**
* Serialized output
*/
toJSON() {
return {
isReady: this.isReady,
isShuttingDown: this.isShuttingDown,
environment: this.environment,
nodeEnvironment: this.nodeEnvironment,
appName: this.appName,
version: this.version ? this.version.toString() : null,
adonisVersion: this.adonisVersion ? this.adonisVersion.toString() : null,
};
}
/**
* Switch application environment. Only allowed before the setup
* is called
*/
switchEnvironment(environment) {
if (this.state !== 'initiated') {
throw new Error(`Cannot switch application environment in "${this.state}" state`);
}
this.environment = environment;
return this;
}
/**
* Performs the initial setup. This is the time, when we configure the
* app to be able to boot itself. For example:
*
* - Loading environment variables
* - Loading config
* - Setting up the logger
* - Registering directory aliases
*
* Apart from the providers, most of the app including the container
* is ready at this stage
*/
async setup() {
if (this.state !== 'initiated') {
return;
}
this.state = 'setup';
this.registerAliases();
this.loadEnvironmentVariables();
this.loadConfig();
this.setupLogger();
this.setupProfiler();
}
/**
* Register providers
*/
async registerProviders() {
if (this.state !== 'setup') {
return;
}
this.state = 'registered';
await this.profiler.profile('providers:register', {}, async () => {
const providers = this.rcFile.providers
.concat(this.rcFile.aceProviders)
.concat(this.inTest ? this.rcFile.testProviders : []);
this.logger.trace('registering providers', providers);
this.registrar = new fold_1.Registrar([this], this.appRoot);
const registeredProviders = await this.registrar
.useProviders(providers, (provider) => {
return new provider(this);
})
.register();
/**
* Keep reference of providers that are using ready or shutdown hooks
*/
registeredProviders.forEach((provider) => {
if (typeof provider.shutdown === 'function') {
this.providersWithShutdownHook.push(provider);
}
if (typeof provider.ready === 'function') {
this.providersWithReadyHook.push(provider);
}
});
});
}
/**
* Booted providers
*/
async bootProviders() {
if (this.state !== 'registered') {
return;
}
this.state = 'booted';
await this.profiler.profileAsync('providers:boot', {}, async () => {
this.logger.trace('booting providers');
await this.registrar.boot();
});
}
/**
* Require files registered as preloads inside `.adonisrc.json` file
*/
async requirePreloads() {
this.preloads
.filter((node) => {
if (!node.environment || this.environment === 'unknown') {
return true;
}
return node.environment.indexOf(this.environment) > -1;
})
.forEach((node) => {
this.profiler.profile('file:preload', node, () => {
this.logger.trace(node, 'file:preload');
this.resolveModule(node.file, (error) => {
if (!node.optional) {
throw error;
}
});
});
});
}
/**
* Start the application. At this time we execute the provider's
* ready hooks
*/
async start() {
if (this.state !== 'booted') {
return;
}
this.state = 'ready';
await this.profiler.profileAsync('providers:ready', {}, async () => {
this.logger.trace('executing providers ready hook');
await Promise.all(this.providersWithReadyHook.map((provider) => provider.ready()));
});
this.providersWithReadyHook = [];
}
/**
* Prepare the application for shutdown. At this time we execute the
* provider's shutdown hooks
*/
async shutdown() {
if (['initiated', 'setup'].includes(this.state)) {
return;
}
this.isShuttingDown = true;
this.state = 'shutdown';
await this.profiler.profileAsync('providers:shutdown', {}, async () => {
this.logger.trace('executing providers shutdown hook');
await Promise.all(this.providersWithShutdownHook.map((provider) => provider.shutdown()));
});
this.providersWithShutdownHook = [];
}
}
exports.Application = Application;
+9
View File
@@ -0,0 +1,9 @@
/// <reference path="../adonis-typings/application.d.ts" />
import { RcFile } from '@ioc:Adonis/Core/Application';
/**
* Parses the contents of `.adonisrc.json` file and merges it with the
* defaults
*/
export declare function parse(contents: {
[key: string]: any;
}): RcFile;
+138
View File
@@ -0,0 +1,138 @@
"use strict";
/*
* @adonisjs/application
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = void 0;
/// <reference path="../adonis-typings/application.ts" />
const utils_1 = require("@poppinss/utils");
/**
* Default set of directories for AdonisJs
* applications
*/
const DEFAULT_DIRECTORIES = {
config: 'config',
public: 'public',
contracts: 'contracts',
providers: 'providers',
database: 'database',
migrations: 'database/migrations',
seeds: 'database/seeders',
resources: 'resources',
views: 'resources/views',
start: 'start',
tmp: 'tmp',
tests: 'tests',
};
/**
* A list of default namespaces.
*/
const DEFAULT_NAMESPACES = {
models: 'App/Models',
middleware: 'App/Middleware',
exceptions: 'App/Exceptions',
validators: 'App/Validators',
httpControllers: 'App/Controllers/Http',
eventListeners: 'App/Listeners',
redisListeners: 'App/Listeners',
};
/**
* Parses the contents of `.adonisrc.json` file and merges it with the
* defaults
*/
function parse(contents) {
const normalizedContents = Object.assign({
typescript: true,
directories: {},
namespaces: {},
preloads: [],
aliases: {},
commandsAliases: {},
metaFiles: [],
commands: [],
providers: [],
aceProviders: [],
testProviders: [],
tests: {
suites: [],
timeout: 2000,
forceExit: true,
},
}, contents);
/**
* Validate the assetsDriver value
*/
const { assetsDriver } = normalizedContents;
if (assetsDriver && !['vite', 'encore', 'fake'].includes(assetsDriver)) {
throw new utils_1.Exception(`Invalid assets driver "${assetsDriver}" defined in .adonisrc.json file`, 500, 'E_INVALID_ASSETS_DRIVER');
}
return {
typescript: normalizedContents.typescript,
...(assetsDriver ? { assetsDriver } : {}),
directories: Object.assign({}, DEFAULT_DIRECTORIES, normalizedContents.directories),
...(normalizedContents.exceptionHandlerNamespace
? { exceptionHandlerNamespace: normalizedContents.exceptionHandlerNamespace }
: {}),
preloads: normalizedContents.preloads.map((preload, index) => {
if (typeof preload === 'string') {
return {
file: preload,
optional: false,
environment: ['web', 'console', 'test', 'repl'],
};
}
if (!preload.file) {
throw new utils_1.Exception(`Invalid value for preloads[${index}]`, 500, 'E_PRELOAD_MISSING_FILE_PROPERTY');
}
return {
file: preload.file,
optional: preload.optional === undefined ? false : preload.optional,
environment: preload.environment === undefined
? ['web', 'console', 'test', 'repl']
: preload.environment,
};
}),
namespaces: Object.assign({}, DEFAULT_NAMESPACES, normalizedContents.namespaces),
aliases: Object.assign({}, normalizedContents.autoloads, normalizedContents.aliases),
metaFiles: normalizedContents.metaFiles.map((file, index) => {
if (typeof file === 'string') {
return {
pattern: file,
reloadServer: true,
};
}
const { pattern, reloadServer } = file;
if (!pattern) {
throw new utils_1.Exception(`Invalid value for metaFiles[${index}]`, 500, 'E_METAFILE_MISSING_PATTERN');
}
return {
pattern,
reloadServer: !!reloadServer,
};
}),
commands: normalizedContents.commands,
commandsAliases: normalizedContents.commandsAliases,
providers: normalizedContents.providers,
aceProviders: normalizedContents.aceProviders,
testProviders: normalizedContents.testProviders,
tests: {
suites: (normalizedContents.tests.suites || []).map((suite, index) => {
if (!suite.name || !suite.files) {
throw new utils_1.Exception(`Invalid value for "tests.suites[${index}]"`, 500, 'E_MISSING_SUITE_PROPERTIES');
}
return suite;
}),
timeout: normalizedContents.tests.timeout !== undefined ? normalizedContents.tests.timeout : 2000,
forceExit: normalizedContents.tests.forceExit !== undefined
? normalizedContents.tests.forceExit
: true,
},
raw: contents,
};
}
exports.parse = parse;