diff --git a/docs/architecture-concepts/application-lifecycle.mdx b/docs/architecture-concepts/application-lifecycle.mdx index 28b912de..e80de2a5 100644 --- a/docs/architecture-concepts/application-lifecycle.mdx +++ b/docs/architecture-concepts/application-lifecycle.mdx @@ -4,6 +4,7 @@ sidebar_position: 1 description: Understand each one of the Athenna applications lifecycles. --- +import Path from '@site/src/components/path' import ThemedImage from '@theme/ThemedImage' # Application Lifecycle @@ -32,7 +33,7 @@ application you are using. Meaning that no matter what is the type of application you are using to build your solution, the explanation bellow is valid for all of them. -The entry point of an Athenna application is the `Path.bootstrap('main.ts')`. +The entry point of an Athenna application is the . The first action taken by Athenna itself is to create an instance of the application and then boot it. @@ -78,7 +79,7 @@ configuration documentation section](/docs/getting-started/configuration#environ #### Configuration files Afterwards Athenna will load all the configuration files found inside -the path returned by the `Path.config` method. You can learn more about +the path returned by the method. You can learn more about what is and how to configure your configuration files in [the configuration files documentation section](/docs/getting-started/configuration#configuration-files). @@ -115,7 +116,7 @@ in the `.athennarc.json` in the `preloads` array. :::note The process of firing the Athenna foundation is triggered by the -`Ignite::fire()` static method. But if you check your `Path.bootstrap('main.ts')` +`Ignite::fire()` static method. But if you check your entrypoint file, you will see that this method is not called directly. The reason for this is that this method is called internally depending on the type of application you are using. Let's cover some examples @@ -138,7 +139,7 @@ the foundation will be fired before executing your command. ### Kernel The Kernel class is responsible by defining some bootstraps that will -be run before reading your `Path.routes('http.ts')` file. These bootstraps +be run before reading your file. These bootstraps configure error handling for requests, tracing and logging, detect the application environment, and perform other tasks that need to be done before the request is actually handled. Typically, these classes handle @@ -166,7 +167,7 @@ implementation code. ::: -Then, you can register your `CustomKernel` in your `Path.bootstrap('main.ts')` +Then, you can register your `CustomKernel` in your file: ```typescript @@ -174,19 +175,19 @@ import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url) -await ignite.httpServer({ kernelPath: '#app/http/CustomKernel' }) +await ignite.httpServer({ kernelPath: '#src/http/CustomKernel' }) ``` ### Routes -The `Path.routes('http.ts')` file is the entrypoint for all your http requests. +The file is the entrypoint for all your http requests. This file is responsible to create a contract between your client and your application. It Is in here that we define all our routes and the handlers/controllers who will handle the client request. One of the most important service providers in your application is the `HttpRouteProvider`. This service provider adds in the container the -`Route` class instance used inside `Path.routes('http.ts')` file. +`Route` class instance used inside file. When the client request arrives, the server first executes all your global middlewares, then it will execute all your route middlewares. @@ -274,7 +275,7 @@ kernel implementation taking a look at [ConsoleKernel](https://github.com/Athenn ::: Then, you can register your `CustomKernel` in your -`Path.bootstrap('main.ts')` or `Path.bootstrap('artisan.ts')` file: + or file: ```typescript import { Ignite } from '@athenna/core' @@ -284,13 +285,13 @@ const ignite = await new Ignite().load(import.meta.url, { }) await ignite.console(process.argv, { - kernelPath: '#app/http/CustomKernel' + kernelPath: '#src/http/CustomKernel' }) ``` ### Execution -The `Path.routes('console.ts')` and the `commands` property of +The and the `commands` property of `.athennarc.json` file is where that we define all ours commands and the handlers who will handle the terminal arguments. @@ -302,7 +303,7 @@ executed the `hello` command defined in our `.athennarc.json` file: { "commands": { "hello": { - "path": "#app/console/commands/HelloCommand", + "path": "#src/console/commands/HelloCommand", "env": "local", "loadApp": false, "stayAlive": false, diff --git a/docs/architecture-concepts/facades.mdx b/docs/architecture-concepts/facades.mdx index 4f342388..4730cfb5 100644 --- a/docs/architecture-concepts/facades.mdx +++ b/docs/architecture-concepts/facades.mdx @@ -140,8 +140,8 @@ node artisan make:provider HelperProvider Now let's register all of our helpers inside the `register()` method: ```typescript -import { File } from '#app/helpers/File' -import { String } from '#app/helpers/String' +import { File } from '#src/helpers/File' +import { String } from '#src/helpers/String' import { ServiceProvider } from '@athenna/ioc' export class HelperProvider extends ServiceProvider { @@ -172,7 +172,7 @@ generic type: ```typescript import { Facade } from '@athenna/ioc' -import { String as StringImpl } from '#app/helpers/String' +import { String as StringImpl } from '#src/helpers/String' export const String = Facade.createFor('App/Helpers/String') ``` @@ -181,7 +181,7 @@ Now we can start using our new `String` facade: ```typescript import { Route } from '@athenna/http' // Route Facade -import { String } from '#providers/facades/String' // String Facade +import { String } from '#src/facades/String' // String Facade Route.get('/welcome', ({ response }) => { return response diff --git a/docs/architecture-concepts/service-container.mdx b/docs/architecture-concepts/service-container.mdx index bbb1a8a8..245a420a 100644 --- a/docs/architecture-concepts/service-container.mdx +++ b/docs/architecture-concepts/service-container.mdx @@ -4,6 +4,8 @@ sidebar_position: 2 description: Understand the purpose and how to use the Athenna service container. --- +import Path from '@site/src/components/path' + # Service Container Understand the purpose and how to use the Athenna service container. @@ -19,7 +21,7 @@ Let's look at a simple example: ```typescript import { Controller, type Context } from '@athenna/http' -import { WelcomeService } from '#app/services/WelcomeService' +import { WelcomeService } from '#src/services/WelcomeService' @Controller() export class WelcomeController { @@ -50,7 +52,7 @@ itself. ## Simple resolution -You may place the following code in your `Path.routes('http.ts')` +You may place the following code in your file: ```typescript @@ -108,7 +110,7 @@ the container to write this code, it is managing the injection of their dependencies behind the scenes. ```typescript -import { AppService } from '#app/services/AppService' +import { AppService } from '#src/services/AppService' import { Controller, type Context } from '@athenna/http' @Controller() @@ -142,7 +144,7 @@ global property. We can register a binding using the `bind` method, passing the alias name that we wish to register along with our dependency: ```typescript -import { StringNormalizer } from '#app/helpers/StringNormalizer' +import { StringNormalizer } from '#src/helpers/StringNormalizer' ioc.bind('App/Helpers/StringNormalizer', StringNormalizer) ``` @@ -155,7 +157,7 @@ resolved, a new object instance will be returned on subsequent calls into the container: ```typescript -import { StringNormalizer } from '#app/helpers/StringNormalizer' +import { StringNormalizer } from '#src/helpers/StringNormalizer' ioc.transient('App/Helpers/StringNormalizer', StringNormalizer) ``` @@ -174,7 +176,7 @@ resolved one time. Once a singleton binding is resolved, the same object instance will be returned on subsequent calls into the container: ```typescript -import { StringNormalizer } from '#app/helpers/StringNormalizer' +import { StringNormalizer } from '#src/helpers/StringNormalizer' ioc.singleton('App/Helpers/StringNormalizer', StringNormalizer) ``` @@ -186,7 +188,7 @@ You may also bind an existing object instance into the container using the calls into the container: ```typescript -import { StringNormalizer } from '#app/helpers/StringNormalizer' +import { StringNormalizer } from '#src/helpers/StringNormalizer' ioc.instance('App/Helpers/StringNormalizer', new StringNormalizer()) ``` @@ -204,7 +206,7 @@ Let's create a simple service to understand how this annotation works: node artisan make:service StringNormalizer ``` -The command above will create the `Path.services('StringNormalizer.ts')` +The command above will create the file and will automatically register the service in the `services` property of the `.athennarc.json` file. @@ -254,7 +256,7 @@ resolve a class instance from the container. The use method accepts the alias of the dependency you wish to resolve: ```typescript -import { StringNormalizer } from '#app/helpers/StringNormalizer' +import { StringNormalizer } from '#src/helpers/StringNormalizer' const sn = ioc.use('App/Helpers/StringNormalizer') ``` @@ -275,7 +277,7 @@ constructor. The service will automatically be resolved and injected into the class: ```typescript -import { AppService } from '#app/services/AppService' +import { AppService } from '#src/services/AppService' import { Controller, type Context } from '@athenna/http' @Controller() @@ -298,7 +300,7 @@ camelCase name of your dependency as the property name to be resolved properly: ```typescript import { Inject } from '@athenna/ioc' -import { AppService } from '#app/services/AppService' +import { AppService } from '#src/services/AppService' import { Controller, type Context } from '@athenna/http' @Controller() @@ -319,7 +321,7 @@ specific alias to be resolved in the container: ```typescript import { Inject } from '@athenna/ioc' -import { AppService } from '#app/services/AppService' +import { AppService } from '#src/services/AppService' import { Controller, type Context } from '@athenna/http' @Controller() diff --git a/docs/architecture-concepts/service-providers.mdx b/docs/architecture-concepts/service-providers.mdx index c1374165..e4cae3ca 100644 --- a/docs/architecture-concepts/service-providers.mdx +++ b/docs/architecture-concepts/service-providers.mdx @@ -4,6 +4,8 @@ sidebar_position: 3 description: Understand the purpose and how to use the Athenna service providers. --- +import Path from '@site/src/components/path' + # Service Providers Understand the purpose and how to use the Athenna service providers. @@ -60,7 +62,7 @@ which provides access to the service container: ```typescript import { ServiceProvider } from '@athenna/ioc' -import { AppHelper } from '#app/helpers/AppHelper' +import { AppHelper } from '#src/helpers/AppHelper' export default class AppProvider extends ServiceProvider { public register() { @@ -83,7 +85,7 @@ the framework: ```typescript import { ServiceProvider } from '@athenna/ioc' -import { AppHelper } from '#app/helpers/AppHelper' +import { AppHelper } from '#src/helpers/AppHelper' export default class AppProvider extends ServiceProvider { public boot() { @@ -135,7 +137,7 @@ might need to register it manually, just add the path to it to the array: "providers": [ // Other service providers... - "#providers/AppProvider" + "#src/providers/AppProvider" ] } ``` @@ -169,8 +171,9 @@ The following environments are available by default in Athenna at this moment: - http - repl - console +- cron -You could also create your own environments. In your `Path.bootstrap('main.ts')` file +You could also create your own environments. In your file you can add an `environments` option when calling `Ignite.load()` method: ```typescript diff --git a/docs/cli-application/commands.mdx b/docs/cli-application/commands.mdx index c3873f86..2d876bd0 100644 --- a/docs/cli-application/commands.mdx +++ b/docs/cli-application/commands.mdx @@ -4,6 +4,7 @@ sidebar_position: 1 description: See how to create and configure your CLI commands. --- +import Path from '@site/src/components/path' import ReactPlayer from 'react-player' # Commands @@ -54,7 +55,7 @@ commands in `commands` object: { "commands": { "send:email": { 👈 - "path": "#app/console/commands/SendEmails", + "path": "#src/console/commands/SendEmails", "loadApp": true } } @@ -79,7 +80,7 @@ object: { "commands": { "sendEmails": { 👈 // All commands will be loaded - "path": "#app/console/commands/SendEmails", + "path": "#src/console/commands/SendEmails", "loadApp": true } } @@ -92,7 +93,7 @@ inside your command: ```typescript import { Inject } from '@athenna/ioc' -import { MailgunService } from '#app/services/MailgunService' +import { MailgunService } from '#src/services/MailgunService' import { Option, Artisan, Argument, BaseCommand } from '@athenna/artisan' export class SendEmails extends BaseCommand { @@ -141,7 +142,7 @@ setting in your command: { "commands": { "send:email": { - "path": "#app/console/commands/SendEmails", + "path": "#src/console/commands/SendEmails", "loadApp": true, "loadAllCommands": true 👈 // All commands will be loaded } @@ -200,7 +201,7 @@ and then execute the `handle` method: { "commands": { "sendEmails": { - "path": "#app/console/commands/SendEmails", + "path": "#src/console/commands/SendEmails", "loadApp": true 👈 } } @@ -213,7 +214,7 @@ the `@Inject()` annotation: ```typescript import { Inject } from '@athenna/ioc' import { BaseCommand } from '@athenna/artisan' -import { MailgunService } from '#app/services/MailgunService' +import { MailgunService } from '#src/services/MailgunService' export class SendEmails extends BaseCommand { public static signature(): string { @@ -246,7 +247,7 @@ your dependencies: ```typescript import { BaseCommand } from '@athenna/artisan' -import { MailgunService } from '#app/services/MailgunService' +import { MailgunService } from '#src/services/MailgunService' export class SendEmails extends BaseCommand { public static signature(): string { @@ -273,7 +274,7 @@ export class SendEmails extends BaseCommand { ```typescript import { BaseCommand } from '@athenna/artisan' -import type { MailgunService } from '#app/services/MailgunService' +import type { MailgunService } from '#src/services/MailgunService' export class SendEmails extends BaseCommand { public static signature(): string { @@ -314,7 +315,7 @@ annotations on your commands. See the example: ```typescript import { Inject } from '@athenna/ioc' -import { MailgunService } from '#app/services/MailgunService' +import { MailgunService } from '#src/services/MailgunService' import { Option, Argument, BaseCommand } from '@athenna/artisan' export class SendEmails extends BaseCommand { @@ -1285,7 +1286,7 @@ of the RC configuration file. ```typescript const rcKey = 'commands' const key = 'make:repository' -const value = '#app/console/commands/UserRepository' +const value = '#src/console/commands/UserRepository' this.rc.setTo(rcKey, key, value) ``` @@ -1297,7 +1298,7 @@ multiple properties at once: const rcKey = 'commands' this.rc.setTo(rcKey, { - 'make:repository': '#app/console/commands/UserRepository' + 'make:repository': '#src/console/commands/UserRepository' }) ``` @@ -1308,7 +1309,7 @@ Push a new value to some array property of the RC file: ```typescript const rcKey = 'services' -this.rc.pushTo(rcKey, '#app/repositories/MyRepository') +this.rc.pushTo(rcKey, '#src/repositories/MyRepository') ``` #### `this.rc.save()` @@ -1345,7 +1346,7 @@ assert.isTrue(stdout.includes('[ MAKING CONTROLLER ]')) assert.isUndefined(stderr) ``` -By default this method will look to the `Path.boostrap('artisan.ts')` +By default this method will look to the file to execute your command, but you can change the file to be used setting the path to it as second parameter: diff --git a/docs/cli-application/error-handling.mdx b/docs/cli-application/error-handling.mdx index 788ac0df..9bcc8967 100644 --- a/docs/cli-application/error-handling.mdx +++ b/docs/cli-application/error-handling.mdx @@ -4,6 +4,8 @@ sidebar_position: 4 description: Understand how you can handle the errors of the CLI Application. --- +import Path from '@site/src/components/path' + # Error Handling Understand how you can handle the errors of the CLI Application. @@ -26,7 +28,7 @@ the `handle()` method of commands and bellow that will be handled: ```typescript title="app/console/commands/AppCommand.ts" import { BaseCommand } from '@athenna/artisan' -import { AppService } from '#app/services/AppService' +import { AppService } from '#src/services/AppService' export class AppCommand extends BaseCommand { public static signature(): string { @@ -59,7 +61,7 @@ bootstrap failure has been found in your application. ## Configuration -The `debug` option in your `Path.config('app.ts')` configuration +The `debug` option in your configuration file determines how much information about an error is actually displayed to the user. By default, this option is set to respect the value of the `APP_DEBUG` environment @@ -74,13 +76,13 @@ users. Every error will be logged by default using the `console` driver from `@athenna/logger`. By default, Athenna uses the -`exception` channel of your `Path.config('logging.ts')` file to log +`exception` channel of your file to log all exceptions that happens in your application. :::tip You can change the driver and formatter of `exception` -channel inside `Path.config('logging.ts')` file. This way you can +channel inside file. This way you can send all your error logs to another provider and with a different formatter. @@ -98,7 +100,7 @@ node artisan make:exception BadCommandException Next, import and raise the exception as follows. ```typescript -import { BadCommandException } from '#app/exceptions/BadCommandException' +import { BadCommandException } from '#src/exceptions/BadCommandException' throw new BadCommandException('Your command is bad.') ``` @@ -156,9 +158,9 @@ export class Handler extends ConsoleExceptionHandler { Now you need to register your exception handler when bootstrapping your application: -```typescript title="Path.bootstrap('main.ts')" +```typescript title="Path.bin('main.ts')" await ignite.console(process.argv, { displayName: 'Athenna', - exceptionHandlerPath: '#app/console/exceptions/Handler', 👈 + exceptionHandlerPath: '#src/console/exceptions/Handler', 👈 }) ``` diff --git a/docs/cli-application/running.mdx b/docs/cli-application/running.mdx index 1d65b392..470d78fe 100644 --- a/docs/cli-application/running.mdx +++ b/docs/cli-application/running.mdx @@ -27,13 +27,13 @@ path to the entry point file of your CLI: ```json "bin": { - "yourCliCommand": "./bootstrap/main.js" + "yourCliCommand": "./bin/main.js" } ``` ## Entrypoint file -In our example we defined the `./bootstrap/main.js` +In our example we defined the `./bin/main.js` file as the entrypoint file of our CLI. By default, this file comes with the shebang line `#!/usr/bin/env node` in the top of the file. Without this line the `npm link` @@ -66,7 +66,7 @@ By default, Artisan always display the `Artisan` name, but you can change it for your own display name by setting the `displayName` property in `Ignite.console()` method: -```typescript title="Path.bootstrap('main.ts')" +```typescript title="Path.bin('main.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url) @@ -81,7 +81,7 @@ await ignite.console(process.argv, { If you wish to disable the display name, set the `displayName` as `null`: -```typescript title="Path.bootstrap('main.ts')" +```typescript title="Path.bin('main.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url) diff --git a/docs/cron-application/_category_.json b/docs/cron-application/_category_.json new file mode 100644 index 00000000..43d1d976 --- /dev/null +++ b/docs/cron-application/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "CRON Application", + "position": 8, + "collapsed": true, + "link": null +} diff --git a/docs/cron-application/schedulers.mdx b/docs/cron-application/schedulers.mdx new file mode 100644 index 00000000..491c92e4 --- /dev/null +++ b/docs/cron-application/schedulers.mdx @@ -0,0 +1,13 @@ +--- +title: Schedulers +sidebar_position: 1 +description: See how to create and configure your CRON job schedulers. +--- + +# Schedulers + +See how to create and configure your CRON job schedulers. + +## Introduction + +Coming soon... diff --git a/docs/database/_category_.json b/docs/database/_category_.json index 391aea86..1c56a2ca 100644 --- a/docs/database/_category_.json +++ b/docs/database/_category_.json @@ -1,6 +1,6 @@ { "label": "Database", - "position": 8, + "position": 9, "collapsed": true, "link": null } diff --git a/docs/database/getting-started.mdx b/docs/database/getting-started.mdx index 551eca33..c8ad573f 100644 --- a/docs/database/getting-started.mdx +++ b/docs/database/getting-started.mdx @@ -4,6 +4,8 @@ sidebar_position: 1 description: See how to create database connections in Athenna Framework. --- +import Path from '@site/src/components/path' + # Database: Getting Started See how to create database connections in Athenna Framework. @@ -42,7 +44,7 @@ database you selected. ## Configuration All the configuration options for your application's database -behavior is housed in the `Path.config('database.ts')` +behavior is housed in the configuration file. This file allows you to configure your application's database connections, so be sure to review each of the available connections and their options. We'll review @@ -54,7 +56,7 @@ Each database connection is powered by a "driver". The driver determines how and where the data is actually transported. The following database connection drivers are available in every Athenna application. An entry for most of these drivers -is already present in your application's `Path.config('database.ts')` +is already present in your application's configuration file, so be sure to review this file to become familiar with its contents: @@ -315,11 +317,11 @@ await query.whereBetween('id', [1, 10]).delete() ## Using multiple database connections If your application defines multiple connections in your -`Path.config('database.ts')` configuration file, you may access each + configuration file, you may access each connection via the `connection()` method provided by the `Database` facade. The connection name passed to the `connection()` method should correspond to one of the connections listed in your -`Path.config('database.ts')` configuration file. You also need + configuration file. You also need to explicit call the `connect()` method when working with other connection that is not the default: diff --git a/docs/database/migrations.mdx b/docs/database/migrations.mdx index 0fd639d8..19ce8d4f 100644 --- a/docs/database/migrations.mdx +++ b/docs/database/migrations.mdx @@ -4,6 +4,8 @@ sidebar_position: 3 description: See how to create and run database migrations in Athenna Framework. --- +import Path from '@site/src/components/path' + # Database: Migrations See how to create and run database migrations in Athenna Framework. @@ -20,7 +22,7 @@ solve. ## Generating migrations You may use the `make:migration` Artisan command to generate a database migration. The new migration will be placed in your -`Path.migrations()` directory. Each migration filename contains a + directory. Each migration filename contains a timestamp that allows Athenna to determine the order of the migrations: diff --git a/docs/database/seeding.mdx b/docs/database/seeding.mdx index e9ea054b..9bdb025f 100644 --- a/docs/database/seeding.mdx +++ b/docs/database/seeding.mdx @@ -4,6 +4,8 @@ sidebar_position: 4 description: See how to create and run database seeders. --- +import Path from '@site/src/components/path' + # Database: Seeding See how to create and run database seeders. @@ -11,13 +13,13 @@ See how to create and run database seeders. ## Introduction Athenna includes the ability to seed your database with data using -seed classes. All seed classes are stored in the `Path.seeders()` +seed classes. All seed classes are stored in the directory. ## Writing seeders To generate a seeder, execute the `make:seeder` Artisan command. All -seeders generated by the framework will be placed in the `Path.seeders()` +seeders generated by the framework will be placed in the directory: ```bash @@ -31,7 +33,7 @@ You may use the query builder to manually insert data, or you may use [the model factories](/docs/orm/getting-started): ```typescript -import { User } from '#app/models/user' +import { User } from '#src/models/user' import { BaseSeeder, type DatabaseImpl } from '@athenna/database' export class UserSeeder extends BaseSeeder { @@ -47,7 +49,7 @@ export class UserSeeder extends BaseSeeder { You may execute the `db:seed` Artisan command to seed your database. By default, the `db:seed` command will run all the seeders -inside the `Path.seeders()` folder, but you can run only one seeder +inside the folder, but you can run only one seeder using the `--classes` argument: ```bash diff --git a/docs/digging-deeper/graceful-shutdown.mdx b/docs/digging-deeper/graceful-shutdown.mdx index 93a1df19..38dcda21 100644 --- a/docs/digging-deeper/graceful-shutdown.mdx +++ b/docs/digging-deeper/graceful-shutdown.mdx @@ -4,6 +4,8 @@ sidebar_position: 2 description: See how to graceful shutdown any kind of Athenna application. --- +import Path from '@site/src/components/path' + # Graceful Shutdown See how to graceful shutdown any kind of Athenna application. @@ -104,7 +106,7 @@ listeners you want, this means that you can use the default your own. We recommend doing this implementation in the bootstrap file of your like application: -```typescript title="Path.bootstrap('main.ts')" +```typescript title="Path.bin('main.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url) @@ -122,7 +124,7 @@ process.on('SIGTERM', () => { If you wish to remove or change the default listeners of Athenna, or also listen to new signals, you can create -the `signals` property in the `Path.config('app.ts')` +the `signals` property in the file: ```typescript diff --git a/docs/digging-deeper/mail.mdx b/docs/digging-deeper/mail.mdx index 7d04d28f..df4428f3 100644 --- a/docs/digging-deeper/mail.mdx +++ b/docs/digging-deeper/mail.mdx @@ -4,6 +4,8 @@ sidebar_position: 4 description: See how to send emails in Athenna. --- +import Path from '@site/src/components/path' + # Mail See how to send emails in Athenna. @@ -37,7 +39,7 @@ your project: ## Configuration Athenna's email services may be configured via your application's -`Path.config('mail.ts')` configuration file. Each mailer configured + configuration file. Each mailer configured within this file may have its own unique configuration and even its own unique "transport", allowing your application to use different email services to send certain email messages. @@ -48,7 +50,7 @@ Each mailer is powered by a "driver". The driver determines how the mail will be transported. The following mail drivers are available in every Athenna application. An entry for most of these drivers is already present in your application's -`Path.config('mail.ts')` configuration file, so be sure to + configuration file, so be sure to review this file to become familiar with its contents: | Driver name | Website | Built with | diff --git a/docs/digging-deeper/repl.mdx b/docs/digging-deeper/repl.mdx index 106a6a2b..7d83f652 100644 --- a/docs/digging-deeper/repl.mdx +++ b/docs/digging-deeper/repl.mdx @@ -4,6 +4,8 @@ sidebar_position: 1 description: See how to create a REPL session with Athenna Framework ecosystem. --- +import Path from '@site/src/components/path' + # REPL See how to create a REPL session with Athenna Framework ecosystem. @@ -37,7 +39,7 @@ node artisan repl :::info When running this command, Athenna will use the -`Path.bootstrap('repl.ts')` file to execute your session. + file to execute your session. ::: @@ -47,7 +49,7 @@ To import modules inside REPL you need to use dynamic imports: ```typescript { Log } = await import('@athenna/logger') // Destructuring import -helpers = await import('#app/helpers/index') // Default import +helpers = await import('#src/helpers/index') // Default import ``` :::caution @@ -72,7 +74,7 @@ keep declaring the same variables over and over again. To avoid that you can use the `repl.setIntContext()` method, and it will be available in all your REPL sessions: -```typescript title="Path.bootstrap('repl.ts')" +```typescript title="Path.bin('repl.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url, { bootLogs: false }) @@ -88,7 +90,7 @@ repl.setInContext('appService', ioc.safeUse('App/Services/AppService')) You can create custom REPL commands like `.ls` and `.clean` to make your life easier when running your REPL session: -```typescript title="Path.bootstrap('repl.ts')" +```typescript title="Path.bin('repl.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url, { bootLogs: false }) @@ -165,7 +167,7 @@ Path.pwd() :::info -By default, your `Path.bootstrap('repl.ts')` file already +By default, your file already imports all the `@athenna/common` helpers to your REPL session 🤩. ::: diff --git a/docs/getting-started/athennarc-file.mdx b/docs/getting-started/athennarc-file.mdx index 761cf56f..7c9da4f1 100644 --- a/docs/getting-started/athennarc-file.mdx +++ b/docs/getting-started/athennarc-file.mdx @@ -34,7 +34,7 @@ also register it inside your `.athennarc.json` file: ```json { "services": [ - "#app/services/UserService" + "#src/services/UserService" ] } ``` @@ -46,11 +46,11 @@ create customized ones for each environement (`.athennarc.dev.json`, `.athennarc.prod.json`). To do that you need to set the new path to `Ignite::load()` static method: -```typescript title="Path.bootstrap('dev.ts')" +```typescript title="Path.bin('dev.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url, { - athennaRcPath: './bootstrap/athennadevrc.json' 👈 + athennaRcPath: './bin/athennadevrc.json' 👈 }) await ignite.httpServer() @@ -80,7 +80,7 @@ Athenna will check if the `athenna` property exists in your `package.json`: "@athenna/http/providers/HttpServerProvider" ], "directories": { - "bootstrap": "bin" + "bin": "bootstrap" } } } @@ -102,7 +102,7 @@ Log.info(`Hello from ${Config.get('app.name')} application!`) ```json { "preloads": [ - "./bootstrap/preloads/say-hello.js" + "./bin/preloads/say-hello.js" ] } ``` @@ -142,8 +142,8 @@ services in the container: ```json { "services": [ - "#app/services/AppService", - "./app/services/OtherService.js" + "#src/services/AppService", + "./src/services/OtherService.js" ] } ``` @@ -237,39 +237,45 @@ resolve the paths of your application: "bin": "bin", "src": "src", "app": "app", - "models": "app/models", - "services": "app/services", - "exceptions": "app/exceptions", - "repositories": "app/repositories", - "console": "app/console", - "commands": "app/console/commands", - "http": "app/http", - "controllers": "app/http/controllers", - "middlewares": "app/http/middlewares", - "interceptors": "app/http/interceptors", - "terminators": "app/http/terminators", "bootstrap": "bootstrap", - "config": "config", - "database": "database", - "seeders": "database/seeders", - "migrations": "database/migrations", - "lang": "lang", - "resources": "resources", - "views": "resources/views", - "locales": "resources/locales", - "nodeModules": "node_modules", - "nodeModulesBin": "node_modules/.bin", - "providers": "providers", - "facades": "providers/facades", "public": "public", "static": "public/static", "assets": "public/assets", - "routes": "routes", - "storage": "storage", - "logs": "storage/logs", + "nodeModules": "node_modules", + "nodeModulesBin": "node_modules/.bin", "tests": "tests", "stubs": "tests/stubs", - "fixtures": "tests/fixtures" + "fixtures": "tests/fixtures", + "models": "src/models", + "services": "src/services", + "jobs": "src/jobs", + "workers": "src/workers", + "exceptions": "src/exceptions", + "repositories": "src/repositories", + "console": "src/console", + "commands": "src/console/commands", + "http": "src/http", + "guards": "src/http/guards", + "controllers": "src/http/controllers", + "middlewares": "src/http/middlewares", + "interceptors": "src/http/interceptors", + "terminators": "src/http/terminators", + "validators": "src/validators", + "cron": "src/cron", + "schedulers": "src/cron/schedulers", + "config": "src/config", + "database": "src/database", + "seeders": "src/database/seeders", + "migrations": "src/database/migrations", + "lang": "src/lang", + "resources": "src/resources", + "views": "src/resources/views", + "locales": "src/resources/locales", + "providers": "src/providers", + "facades": "src/facades", + "routes": "src/routes", + "storage": "src/storage", + "logs": "src/storage/logs" } } ``` @@ -295,8 +301,8 @@ Route facade: ```json { "controllers": [ - "#app/http/controllers/AppController", - "./app/http/controllers/OtherController.js" + "#src/http/controllers/AppController", + "./src/http/controllers/OtherController.js" ] } ``` @@ -311,8 +317,8 @@ in the service container to be accessed easily by your ```json { "middlewares": [ - "#app/http/middlewares/AppMiddleware", - "./app/http/interceptors/AppInterceptor.js" + "#src/http/middlewares/AppMiddleware", + "./src/http/interceptors/AppInterceptor.js" ] } ``` @@ -348,8 +354,8 @@ in your route declaration: ```json { "namedMiddlewares": { - "app": "#app/http/middlewares/AppMiddleware", - "intercept": "./app/http/interceptors/AppInterceptor.js" + "app": "#src/http/middlewares/AppMiddleware", + "intercept": "./src/http/interceptors/AppInterceptor.js" } } ``` @@ -366,8 +372,8 @@ in any request of your application: ```json { "globalMiddlewares": [ - "#app/http/middlewares/AppMiddleware", - "./app/http/interceptors/AppInterceptor.js" + "#src/http/middlewares/AppMiddleware", + "./src/http/interceptors/AppInterceptor.js" ] } ``` diff --git a/docs/getting-started/configuration.mdx b/docs/getting-started/configuration.mdx index b8229d7a..076c9f48 100644 --- a/docs/getting-started/configuration.mdx +++ b/docs/getting-started/configuration.mdx @@ -4,6 +4,8 @@ sidebar_position: 4 description: Understand the initial configurations of your project. --- +import Path from '@site/src/components/path' + # Configuration Understand the initial configurations of your project. @@ -22,14 +24,6 @@ that defines many common environment variables. During the Athenna installation process, this file will automatically be copied to `.env` and `.env.test`. -:::note - -If you are not using the slim project structure, you can -create a `.env` file in the root path of your application -and Athenna will automatically resolve it for you. - -::: - Athenna default `.env` file contains some common configuration values that may differ based on whether your application is running locally or on a production. These values are then @@ -193,7 +187,7 @@ console.log(Env('APP_URL')) // "http://localhost:3000" You can also change the name and the path of your `.env` file. To do that you need to set the new path to `Ignite::load()` static method: -```typescript title="Path.bootstrap('dev.ts')" +```typescript title="Path.bin('dev.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url, { @@ -214,19 +208,10 @@ just like in the example above. ## Configuration files All the configuration files for the Athenna framework are -stored in the `config` directory if you are using the -default project template. Each option is documented, so +stored in the `src/config` directory. Each option is documented, so feel free to look through the files and get familiar with the options available to you. -:::info - -The slim template is configured to use `src/config` path -instead. But the folder does not exist in the project by -default. You can check how to change this path [in here](/docs/getting-started/configuration#define-my-own-configuration-path). - -::: - Athenna needs almost no additional configuration out of the box. You are free to get started developing! Each option is documented, so feel free to look through the @@ -359,7 +344,7 @@ Config.set('app.name', builders.functionCall('Env', ['MY_APP_NAME'])) await Config.rewrite('app') ``` -The example above will produce the following code in `Path.config('app.ts')`: +The example above will produce the following code in : ```typescript export default { @@ -443,7 +428,8 @@ file path: import { Path } from '@athenna/common' import { Config } from '@athenna/config' -await Config.load(Path.stubs('config/test.ts')) +const testConfig = Path.stubs('config/test.ts') // /path/to/your/project/tests/stubs/config/test.ts +await Config.load(testConfig) console.log(Config.get('test')) // { ... } ``` @@ -457,7 +443,8 @@ is not defined: import { Path } from '@athenna/common' import { Config } from '@athenna/config' -await Config.safeLoad(Path.stubs('config/app.js')) +const appConfig = Path.stubs('config/app.js') // /path/to/your/project/tests/stubs/config/app.js +await Config.safeLoad(appConfig) ``` #### `Config.loadAll()` @@ -469,7 +456,8 @@ configuration path: import { Path } from '@athenna/common' import { Config } from '@athenna/config' -await Config.loadAll(Path.stubs('config')) +const config = Path.stubs('config') // /path/to/your/project/tests/stubs/config +await Config.loadAll(config) ``` ### Get configuration with `@Value()` decorator @@ -500,63 +488,43 @@ when using the `@Value()` annotation: ### Define my own configuration path -If you are using the [slim](https://athenna.io/docs/getting-started/installation#project-structure) -project structure, or you are building your own project -structure, you are not going to have the `config` directory -in your project root path. - -You will have two options now: - -1. If you are using the [slim](https://athenna.io/docs/getting-started/installation#project-structure) -project structure, you can create the `config` directory inside your `src` folder. -2. Specify to Athenna a different path to your `config` directory. - -:::note - -The [slim](https://athenna.io/docs/getting-started/installation#project-structure) -project structure is using the second option above to -specify to Athenna that the configuration files will -be inside of `src/config` directory. Check the examples -bellow to see how this implementation works. - -::: +If you are building your own project structure you might want to +change the configurations directory from `src/config` to something +else. For this case you can specify to Athenna a different path to +what will resolve. To specify your application directories to Athenna, you can open the `.athennarc.json` file and add the `directories` -property to it. If you are using [slim](https://athenna.io/docs/getting-started/installation#project-structure) -project structure, you will already have this property -defined. - -The `directories` property is an object that maps the directory +property to it. The `directories` property is an object that maps the directory base path that the [`Path`](https://athenna.io/docs/digging-deeper/helpers#path) helper will use to resolve your application paths: ```typescript import { Path } from '@athenna/common' -console.log(Path.config()) // /path/to/your/project/config +console.log(Path.config()) // /path/to/your/project/src/config ``` All the `directories` key names follow the [`Path`](https://athenna.io/docs/digging-deeper/helpers#path) class methods names. This means that if you want to change -what is returned by the `Path.config()` method, you will +what is returned by the method, you will need to add the `config` key to the `directories` object: ```json { "directories": { - "config": "src/config" + "config": "src/app/config" } } ``` -Now when calling the `Path.config()` method, it will return +Now when calling the method, it will return a different path: ```typescript import { Path } from '@athenna/common' -console.log(Path.config()) // /path/to/your/project/src/config 👈 +console.log(Path.config()) // /path/to/your/project/src/app/config 👈 ``` Athenna always rely on [`Path`](https://athenna.io/docs/digging-deeper/helpers#path) @@ -583,7 +551,7 @@ your environment it could become one. To avoid reloading configuration files in these situations, you can set the `loadConfigSafe` option as `true` in `Ignite::load()` static method: -```typescript title="Path.bootstrap('main.ts')" +```typescript title="Path.bin('main.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url, { @@ -595,7 +563,7 @@ await ignite.httpServer() ## Debug mode -The `debug` option in your `Path.config('app.ts')` configuration +The `debug` option in your configuration file determines how much information about your application is actually displayed to you and for who is going to consume your application. By default, this option is set to respect diff --git a/docs/getting-started/directory-structure.mdx b/docs/getting-started/directory-structure.mdx index 34860bf6..94856376 100644 --- a/docs/getting-started/directory-structure.mdx +++ b/docs/getting-started/directory-structure.mdx @@ -4,6 +4,8 @@ sidebar_position: 5 description: Understand the directory structure of your project. --- +import Path from '@site/src/components/path' + # Directory Structure Understand the directory structure of your project. @@ -127,33 +129,24 @@ command. If your test file name does not end with `Test`, it will be ignored and the test class will not run. But, you can customize this behavior in the configure function of [Japa](https://japa.dev/docs) -inside your `Path.bootstrap('test.ts')` file. +inside your file. ::: -## Slim structure - -The slim project structure has only three folders when you -create the project: - -- The `bin` directory is the same as [bootstrap](/docs/getting-started/directory-structure#bootstrap). -- The `src` directory is used to store all the source code files of your applications. -- The `tests` directory is the same as [tests](/docs/getting-started/directory-structure#tests). - ## Do your own structure There are some files in your project that are crucial to keep in certain places. Let's analyze some of them: -- The `Path.bootstrap('main.ts')` file is the entry point of the +- The file is the entry point of the `node artisan serve` command. Every time that you run this command, Athenna will use this file to run your application. -- The `Path.bootstrap('artisan.ts')` file is the entry point of the +- The file is the entry point of the `artisan.js` script. -- The `config` path is where you are going to set up your +- The path is where you are going to set up your configuration files. You can learn more about configuration files at [the configuration documentation section](https://athenna.io/docs/getting-started/configuration). -- The `Path.routes('http.ts')` file is where you are going to register +- The file is where you are going to register your Http server routes. Athenna is a framework with a lot of opinions, with predefined diff --git a/docs/getting-started/installation.mdx b/docs/getting-started/installation.mdx index 4b24dd8b..251c18f4 100644 --- a/docs/getting-started/installation.mdx +++ b/docs/getting-started/installation.mdx @@ -4,6 +4,8 @@ sidebar_position: 1 description: How to install and set up your first Athenna project. --- +import Path from '@site/src/components/path' + # Installation How to install and set up your first Athenna project. @@ -62,7 +64,7 @@ easily scaled to handle hundreds of millions of requests per month. ### An agnostic framework Athenna is perpect for building modern software using microservices architecture. -No matter what type of application you are creating, be it a REST API, a CLI, a Cron Job, +No matter what type of application you are creating, be it a REST API, a CLI, a CRON Job, Athenna has a reliable solution foundation for each occasion, the only thing you will need to take care is how your application will communicate with the external world. @@ -85,8 +87,7 @@ We recommend using [nvm](https://github.com/nvm-sh/nvm) to do that. running on your machine.](https://github.com/nvm-sh/nvm#installing-and-updating) After you install `nvm`, we recommend you to install -Node.js v20.x or above, this is the current version that -the project is being developed, but you can still use +Node.js v20.x or above, but you can still use Node.js v16.x and above. Install Node.js v20.x by running: ```bash @@ -124,45 +125,41 @@ The installation process prompts for the following selections: using REST architecture. - `CLI` application is ideal for creating global CLI's to publish in some registry like npm. - -#### Project structure - -The installation process will ask if you want to create your -project with a `slim` project structure. All the Athenna -packages implementation assumes that you are using the default -project structure, but you will always be able to use your own -and configure the packages to work with it. +- `CRON` application is ideal for creating schedulers that will run +periodic jobs, such as for maintenance or calling third-party APIs +to collect up-to-date data. ## Running your application -To run your application in development mode, -run the following command: +To run your application in development mode, run the following +command: ```bash node artisan serve --watch ``` -- The `serve` command will look up for your `Path.bootstrap('main.ts')` +- The `serve` command will look up for your file to bootstrap your application with predefined configurations. - The `watch` flag is meant to watch the file system for changes and restart your application automatically when doing some change on it. -### What the 🤬 is `Path.boostrap('main.ts')`? +### What the 🤬 is `Path.bin('main.ts')`? Well, Athenna tries a lot to be a framework without opinion, one thing that some frameworks do that makes them to have a lot of opinion is defining crucial file paths where you can't touch that file without breaking everything. Athenna is not totally different from them in this aspect, as you can see, -the `node artisan serve` command depends on the existence of the `./bootstrap/main.ts` +the `node artisan serve` command depends on the existence of the `./bin/main.ts` file. To be able to be "opinion less" without losing DX (Developer Experience) we ensure that you can easily configure this path the way you want by doing two things: -1. In all places of our documentation you will see that we always use the [`Path`](/docs/the-basics/helpers#path) -helper to reference file paths, so your brain could detect that the directory path -you just see is configurable. +1. In all places of our documentation you will see that we always use the +[`Path`](/docs/the-basics/helpers#path) helper to reference file paths, this +way is easier for you to understand that the path directory you just see is +configurable. 2. Inside `.athennarc.json` file or the `athenna` property of your `package.json` you have the [`directories` property](/docs/getting-started/athennarc-file#the-directories-property) where you can modify any path supported by the [`Path`](/docs/the-basics/helpers#path) helper. @@ -173,13 +170,13 @@ gonna see later on this documentation page 😆. ## Initial configuration All of the configuration files for the Athenna framework are stored -in the `Path.config()` directory. Each option is documented, so feel +in the directory. Each option is documented, so feel free to look through the files and get familiar with the options available to you. Athenna needs almost no additional configuration out of the box. You are free to get started developing! However, you may wish to review the -`Path.config('app.ts')` file and its documentation. It contains several + file and its documentation. It contains several options such as locale that you may wish to change according to your application. @@ -269,3 +266,11 @@ advantage of all Athenna's powerful foundation. If this is how you plan to use Athenna, you may want to check out our documentation on [commands](/docs/cli-application/commands). + +### CRON Job application + +Use the CRON Job application to create schedulers for running periodic jobs, such +as for maintenance or calling third-party APIs to collect up-to-date data. + +If this is how you plan to use Athenna, you may want to check out our documentation +on [schedulers](/docs/cron-application/schedulers). diff --git a/docs/orm/_category_.json b/docs/orm/_category_.json index 175ca9c6..f8c6d98a 100644 --- a/docs/orm/_category_.json +++ b/docs/orm/_category_.json @@ -1,6 +1,6 @@ { "label": "ORM", - "position": 9, + "position": 10, "collapsed": true, "link": null } diff --git a/docs/orm/annotations.mdx b/docs/orm/annotations.mdx index f42f3396..4e099c33 100644 --- a/docs/orm/annotations.mdx +++ b/docs/orm/annotations.mdx @@ -260,7 +260,7 @@ The `@HasOne()` annotation marks a model property as an [one-to-one relation](/docs/orm/relationships#one-to-one): ```typescript -import { Pilot } from '#app/models/Pilot' +import { Pilot } from '#src/models/Pilot' import type { Relation } from '@athenna/database' import { Column, HasOne, BaseModel } from '@athenna/database' @@ -369,7 +369,7 @@ The `@HasMany()` annotation marks a model property as an [one-to-many relation](/docs/orm/relationships#one-to-many): ```typescript -import { Comment } from '#app/models/Comment' +import { Comment } from '#src/models/Comment' import type { Relation } from '@athenna/database' import { Column, HasOne, BaseModel } from '@athenna/database' @@ -479,7 +479,7 @@ an [one-to-one relation](/docs/orm/relationships#defining-the-inverse-of-the-rel the inverse side of an [one-to-many relation (many-to-one)](/docs/orm/relationships#defining-the-inverse-of-the-relationship-many-to-one): ```typescript -import { User } from '#app/models/User' +import { User } from '#src/models/User' import type { Relation } from '@athenna/database' import { Column, BelongsTo, BaseModel } from '@athenna/database' @@ -591,9 +591,9 @@ The `@BelongsToMany()` annotation marks a model property as a [many-to-many relation](/docs/orm/relationships#many-to-many): ```typescript -import { Role } from '#app/models/Role' +import { Role } from '#src/models/Role' import type { Relation } from '@athenna/database' -import { RolesUsers } from '#app/models/RolesUsers' +import { RolesUsers } from '#src/models/RolesUsers' import { Column, BaseModel, BelongsToMany } from '@athenna/database' export class User extends BaseModel { diff --git a/docs/orm/extending-models.mdx b/docs/orm/extending-models.mdx index ee117d65..880f52d6 100644 --- a/docs/orm/extending-models.mdx +++ b/docs/orm/extending-models.mdx @@ -120,7 +120,7 @@ posts if they are not loaded and also get the oldest post of the user: ```typescript -import { type Post } from '#app/models/Post' +import { type Post } from '#src/models/Post' import { BaseModel } from '@athenna/database' export class User extends BaseModel { diff --git a/docs/orm/factories.mdx b/docs/orm/factories.mdx index d5c96e33..c142798e 100644 --- a/docs/orm/factories.mdx +++ b/docs/orm/factories.mdx @@ -163,7 +163,7 @@ method, the only difference is that `returningAs()` forces the TypeScript return to be the same of the field you are returning: ```typescript -import { User } from '#app/models/User' +import { User } from '#src/models/User' import { BaseModel } from '@athenna/database' export class Post extends Model { diff --git a/docs/orm/getting-started.mdx b/docs/orm/getting-started.mdx index cf76888c..8bd48ca6 100644 --- a/docs/orm/getting-started.mdx +++ b/docs/orm/getting-started.mdx @@ -4,6 +4,8 @@ sidebar_position: 1 description: See how to create models in Athenna Framework. --- +import Path from '@site/src/components/path' + # ORM: Getting Started See how to create models in Athenna Framework. @@ -20,7 +22,7 @@ as well. :::tip Before getting started, be sure to configure a database connection in -your application's `Path.config('database.ts')` configuration file. +your application's configuration file. For more information on configuring your database, check out [`the database configuration documentation.`](/docs/database/getting-started) @@ -30,7 +32,7 @@ For more information on configuring your database, check out ## Generating models To get started, let's create a model. Models typically live in the -`app/models` directory (`Path.models()`) and extend the [`BaseModel`](https://github.com/AthennaIO/Database/blob/develop/src/models/BaseModel.ts) + and extend the [`BaseModel`](https://github.com/AthennaIO/Database/blob/develop/src/models/BaseModel.ts) class. You may use the `make:model` Artisan command to generate a new model: @@ -73,7 +75,7 @@ annotation documentation section](/docs/orm/annotations/#column). ## Model conventions Models generated by the `make:model` command will be placed in the -`Path.models()` directory. Let's examine a basic model class and + directory. Let's examine a basic model class and discuss some of Model's key conventions: ```typescript @@ -170,7 +172,7 @@ Athenna will call the `attributes()` method everytime that `create()`, this means that a new uuid will be generated for each call: ```typescript -import { Flight } from '#app/models/Flight' +import { Flight } from '#src/models/Flight' const flight1 = await Flight.create() const flight2 = await Flight.query().create() @@ -186,7 +188,7 @@ one of these methods, the `attributes()` method will not overwrite them: ```typescript -import { Flight } from '#app/models/Flight' +import { Flight } from '#src/models/Flight' // Setting my own id attribute const flight = await Flight.create({ diff --git a/docs/orm/query-builder.mdx b/docs/orm/query-builder.mdx index b429e246..61d4324e 100644 --- a/docs/orm/query-builder.mdx +++ b/docs/orm/query-builder.mdx @@ -27,7 +27,7 @@ fluently query the database table associated with the model. The model's associated database table: ```typescript -import { Flight } from '#app/models/Flight' +import { Flight } from '#src/models/Flight' const where = { active: 1 } const flights = await Flight.findMany(where) @@ -269,7 +269,7 @@ if (!flight.isPersisted()) { ::: In this example, we assign the `name` field to the name attribute of -the `#app/models/Flight` model instance. When we call the `save()` +the `#src/models/Flight` model instance. When we call the `save()` method, a record will be inserted into the database. The model's `createdAt` and `updatedAt` timestamps will automatically be set when the `save()` method is called, so there is no need to set them @@ -506,7 +506,7 @@ To delete a model, you may call the `delete()` method on the model instance: ```typescript -import { Flight } from '#app/models/Flight' +import { Flight } from '#src/models/Flight' const where = { id: 1 } await Flight.delete(where) @@ -515,7 +515,7 @@ await Flight.delete(where) You can also delete an instance directly: ```typescript -import { Flight } from '#app/models/Flight' +import { Flight } from '#src/models/Flight' const where = { id: 1 } const flight = await Flight.find(where) diff --git a/docs/orm/relationships.mdx b/docs/orm/relationships.mdx index 44d3c7f4..4767dded 100644 --- a/docs/orm/relationships.mdx +++ b/docs/orm/relationships.mdx @@ -28,11 +28,11 @@ import { type Relation, } from '@athenna/database' -import { Course } from '#app/models/Course' -import { Profile } from '#app/models/Profile' -import { Comment } from '#app/models/Comment' -import { Customer } from '#app/models/Customer' -import { UsersCourses } from '#app/models/UsersCourses' +import { Course } from '#src/models/Course' +import { Profile } from '#src/models/Profile' +import { Comment } from '#src/models/Comment' +import { Customer } from '#src/models/Customer' +import { UsersCourses } from '#src/models/UsersCourses' export class User extends BaseModel { @Column() @@ -78,7 +78,7 @@ To define this relationship, we will place a `phone` property on the `User` model and annotate it with the `@HasOne()` annotation: ```typescript -import { Phone } from '#app/models/Phone' +import { Phone } from '#src/models/Phone' import type { Relation } from '@athenna/database' import { Column, BaseModel, HasOne, type Relation } from '@athenna/database' @@ -154,7 +154,7 @@ the inverse of a `@HasOne()` relationship using the `@BelongsTo()` annotation: ```typescript -import { User } from '#app/models/User' +import { User } from '#src/models/User' import type { Relation } from '@athenna/database' import { Column, BelongsTo, BaseModel } from '@athenna/database' @@ -208,7 +208,7 @@ Athenna relationships, one-to-many relationships are defined by defining a `@HasMany()` annotation in your model class property: ```typescript -import { Comment } from '#app/models/Comment' +import { Comment } from '#src/models/Comment' import type { Relation } from '@athenna/database' import { Column, BaseModel, HasMany } from '@athenna/database' @@ -275,7 +275,7 @@ relationship property on the child model annotated with the `@BelongsTo()` annotation: ```typescript -import { Post } from '#app/models/Post' +import { Post } from '#src/models/Post' import type { Relation } from '@athenna/database' import { Column, BaseModel, BelongsTo } from '@athenna/database' @@ -381,8 +381,8 @@ with the `@BelongsToMany()` annotation. But before we check how to define this annotation, we need to first create our `RolesUsers` pivot model: ```typescript -import { Role } from '#app/models/Role' -import { User } from '#app/models/User' +import { Role } from '#src/models/Role' +import { User } from '#src/models/User' import type { Relation } from '@athenna/database' import { Column, BaseModel, BelongsTo } from '@athenna/database' @@ -410,9 +410,9 @@ model class and the second argument is a closure that returns the pivot model: ```typescript -import { Role } from '#app/models/Role' +import { Role } from '#src/models/Role' import type { Relation } from '@athenna/database' -import { RolesUsers } from '#app/models/RolesUsers' +import { RolesUsers } from '#src/models/RolesUsers' import { Column, BaseModel, BelongsToMany } from '@athenna/database' export class User extends BaseModel { @@ -479,9 +479,9 @@ user / role example, let's define the `users` property on the `Role` model: ```typescript -import { User } from '#app/models/User' +import { User } from '#src/models/User' import type { Relation } from '@athenna/database' -import { RolesUsers } from '#app/models/RolesUsers' +import { RolesUsers } from '#src/models/RolesUsers' import { Column, BaseModel, BelongsToMany } from '@athenna/database' export class Role extends BaseModel { @@ -524,7 +524,7 @@ Eager loading alleviates the "N + 1" query problem. To illustrate the N + 1 query problem, consider a `Book` model that "belongs to" to an `Author` model: ```typescript -import { Author } from '#app/models/Author' +import { Author } from '#src/models/Author' import type { Relation } from '@athenna/database' import { Column, BelongsTo, BaseModel } from '@athenna/database' @@ -697,9 +697,9 @@ When working with many-to-many relationships you need to use the pivot model to create the relation between the other two models: ```typescript -import { User } from '#app/models/User' -import { Role } from '#app/models/Role' -import { RolesUsers } from '#app/models/RolesUsers' +import { User } from '#src/models/User' +import { Role } from '#src/models/Role' +import { RolesUsers } from '#src/models/RolesUsers' const user = await User.find() const role = await Role.find() diff --git a/docs/rest-api-application/annotations.mdx b/docs/rest-api-application/annotations.mdx index 4343b02b..42f6ec98 100644 --- a/docs/rest-api-application/annotations.mdx +++ b/docs/rest-api-application/annotations.mdx @@ -75,7 +75,7 @@ Use this annotation to define all the metadata needed to register your middleware into the service container: ```typescript -import { User } from '#app/models/User' +import { User } from '#src/models/User' import { Middleware, type Context } from '@athenna/http' @Middleware() diff --git a/docs/rest-api-application/controllers.mdx b/docs/rest-api-application/controllers.mdx index f1a8902e..40de59a4 100644 --- a/docs/rest-api-application/controllers.mdx +++ b/docs/rest-api-application/controllers.mdx @@ -4,6 +4,8 @@ sidebar_position: 3 description: Understand how you can set up controllers in your REST API application. --- +import Path from '@site/src/components/path' + # Controllers Understand how you can set up controllers in your REST API @@ -18,7 +20,7 @@ related request handling logic into a single class. For example, a `UserController` class might handle all incoming requests related to users, including showing, creating, updating, and deleting users. By default, controllers are -stored in the `Path.controllers()` directory. +stored in the directory. ## Writing controllers @@ -71,10 +73,10 @@ node artisan make:controller PhotoController --resource ``` This command will generate a controller at -`Path.controllers('PhotoController.ts')`. The controller will -contain a method for each of the available resource -operations. Next, you may register a resource route that -points to the controller: +. +The controller will contain a method for each of the +available resource operations. Next, you may register a +resource route that points to the controller: ```typescript Route.resource('photos', 'PhotoController') @@ -131,8 +133,8 @@ a request from the server: ```typescript import { Inject } from '@athenna/ioc' import { Controller, type Context } from '@athenna/http' -import { UserService } from '#app/services/UserService' -import { ProfileService } from '#app/services/ProfileService' +import { UserService } from '#src/services/UserService' +import { ProfileService } from '#src/services/ProfileService' @Controller() export class UserController { diff --git a/docs/rest-api-application/error-handling.mdx b/docs/rest-api-application/error-handling.mdx index 5d59e4ff..f256d853 100644 --- a/docs/rest-api-application/error-handling.mdx +++ b/docs/rest-api-application/error-handling.mdx @@ -4,6 +4,8 @@ sidebar_position: 5 description: Understand how you can handle the errors of the REST API application. --- +import Path from '@site/src/components/path' + # Error Handling Understand how you can handle the errors of the REST API application. @@ -41,7 +43,7 @@ bootstrap failure has been found in your application. ## Configuration -The `debug` option in your `Path.config('app.ts')` configuration +The `debug` option in your configuration file determines how much information about an error is actually displayed to the user. By default, this option is set to respect the value of the `APP_DEBUG` environment @@ -56,13 +58,13 @@ users. Every error will be logged by default using the `console` driver from `@athenna/logger`. By default, Athenna uses the -`exception` channel of your `Path.config('logging.ts')` file to log +`exception` channel of your file to log all exceptions that happens in your application. :::tip You can change the driver and formatter of `exception` -channel inside `Path.config('logging.ts')` file. This way you can +channel inside file. This way you can send all your error logs to another provider and with a different formatter. @@ -118,7 +120,7 @@ export class PaymentRequiredException extends HttpException { You can ignore an exception from being logged if its status code or the code does not match your requirements. To do so you can add the following configurations to the `logger` -property in your `Path.config('http.ts')` configuration file: +property in your configuration file: ```typescript export default { @@ -146,7 +148,7 @@ node artisan make:exception NotFoundResourceException Next, import and raise the exception as follows. ```typescript -import { NotFoundResourceException } from '#app/exceptions/NotFoundResourceException' +import { NotFoundResourceException } from '#src/exceptions/NotFoundResourceException' throw new NotFoundResourceException('Your resource has not been found.') ``` @@ -179,8 +181,8 @@ export class Handler extends HttpExceptionHandler { Now you need to register your exception handler when bootstrapping your application: -```typescript title="Path.bootstrap('main.ts')" +```typescript title="Path.bin('main.ts')" await ignite.httpServer({ - exceptionHandlerPath: '#app/http/exceptions/Handler' 👈 + exceptionHandlerPath: '#src/http/exceptions/Handler' 👈 }) ``` diff --git a/docs/rest-api-application/middlewares.mdx b/docs/rest-api-application/middlewares.mdx index 0d28da87..470be0b3 100644 --- a/docs/rest-api-application/middlewares.mdx +++ b/docs/rest-api-application/middlewares.mdx @@ -4,6 +4,8 @@ sidebar_position: 2 description: Understand how you can set up middlewares in your REST API application. --- +import Path from '@site/src/components/path' + # Middlewares Understand how you can set up middlewares in your REST @@ -35,7 +37,7 @@ node artisan make:middleware EnsureApiKeyIsValid ``` This command will place a new `EnsureApiKeyIsValid` class -within your `Path.middlewares()` directory. In this +within your directory. In this middleware, we will only allow access to the route if the supplied api key input matches a specified value. Otherwise, we will throw an unauthorized exception: @@ -81,7 +83,7 @@ file: ```json { "middlewares": [ - "#app/http/middlewares/EnsureApiKeyIsValid" + "#src/http/middlewares/EnsureApiKeyIsValid" ] } ``` @@ -122,7 +124,7 @@ If you are not using TypeScript, you can use the ```json { "globalMiddlewares": [ - "#app/http/middlewares/EnsureApiKeyIsValid" + "#src/http/middlewares/EnsureApiKeyIsValid" ] } ``` @@ -155,7 +157,7 @@ If you are not using TypeScript, you can use the ```json { "namedMiddlewares": { - "auth": "#app/http/middlewares/EnsureApiKeyIsValid" + "auth": "#src/http/middlewares/EnsureApiKeyIsValid" } } ``` @@ -273,7 +275,7 @@ Route.get('/welcome', () => { :::info The requests log created by Athenna when the `logger` -property is true in your `Path.config('http.ts')` file are +property is true in your file are handled by a terminator middleware! You can see the code [here](https://github.com/AthennaIO/Http/blob/develop/src/kernels/HttpKernel.ts#L93). diff --git a/docs/rest-api-application/rate-limiting.mdx b/docs/rest-api-application/rate-limiting.mdx index b1e0ff33..5062da6c 100644 --- a/docs/rest-api-application/rate-limiting.mdx +++ b/docs/rest-api-application/rate-limiting.mdx @@ -4,6 +4,8 @@ sidebar_position: 7 description: See how to create rate limiting rules for Athenna REST API application. --- +import Path from '@site/src/components/path' + # Rate Limiting See how to create rate-limiting rules for Athenna REST API application. @@ -18,7 +20,7 @@ a user can request your application in a given time-frame. Athenna uses the [`@fastify/rate-limit`](https://github.com/fastify/fastify-rate-limit) plugin inside `HttpKernel`. All the configurations that -`@fastify/rate-limit` supports can be set inside `Path.config('http.ts')` +`@fastify/rate-limit` supports can be set inside file in the `rateLimit` object: ```typescript title="Path.config('http.ts')" @@ -40,7 +42,7 @@ export default { In Athenna you can set specific options of rate limit for specific routes. You can also disable the `global` -option of your `rateLimit` configuration in `Path.config('http.ts')` +option of your `rateLimit` configuration in and set different rules in your routes: ```typescript title="Path.route('http.ts')" diff --git a/docs/rest-api-application/routing.mdx b/docs/rest-api-application/routing.mdx index 5042a73d..3cbeec91 100644 --- a/docs/rest-api-application/routing.mdx +++ b/docs/rest-api-application/routing.mdx @@ -4,6 +4,8 @@ sidebar_position: 1 description: Understand how you can set up routes for your REST API application. --- +import Path from '@site/src/components/path' + # Routing Understand how you can set up routes for your REST API @@ -191,13 +193,13 @@ which a browser should permit loading resources. Athenna uses the [`@fastify/cors`](https://github.com/fastify/fastify-cors) plugin inside `HttpKernel`. All the configurations that -`@fastify/cors` supports can be set inside `Path.config('http.ts')` +`@fastify/cors` supports can be set inside file in the `cors` object. Cors plugin is registered in your http application by default, but you can remove it uninstalling `@fastify/cors` from your application, or removing the `cors` object key -from your `Path.config('http.ts')` file. +from your file. :::tip @@ -208,10 +210,10 @@ consult the [MDN web documentation on CORS](https://developer.mozilla.org/en-US/ ## Custom route file path -You can change the name and the path of your `Path.route('http.ts')` file. +You can change the name and the path of your file. To do that you need to set the new path to `Ignite.httpServer()` method: -```typescript title="Path.bootstrap('dev.ts')" +```typescript title="Path.bin('dev.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url) diff --git a/docs/rest-api-application/security-with-helmet.mdx b/docs/rest-api-application/security-with-helmet.mdx index fa1d6e8c..2424bf00 100644 --- a/docs/rest-api-application/security-with-helmet.mdx +++ b/docs/rest-api-application/security-with-helmet.mdx @@ -4,6 +4,8 @@ sidebar_position: 9 description: See how to improve the security of your REST API with Helmet in Athenna. --- +import Path from '@site/src/components/path' + # Security with Helmet See how to improve the security of your REST API with Helmet in Athenna. @@ -42,7 +44,7 @@ attacks, but makes things worse, so Helmet disables it. Athenna uses the [`@fastify/helmet`](https://github.com/fastify/helmet) plugin inside `HttpKernel`. All the configurations that -`@fastify/helmet` supports can be set inside `Path.config('http.ts')` +`@fastify/helmet` supports can be set inside file in the `helmet` object: ```typescript @@ -58,7 +60,7 @@ export default { In Athenna you can set specific options of helmet for specific routes. You can also disable the `global` -option of your `helmet` configuration in `Path.config('http.ts')` +option of your `helmet` configuration in and set different rules in your routes: ```typescript title="Path.route('http.ts')" diff --git a/docs/rest-api-application/static-files.mdx b/docs/rest-api-application/static-files.mdx index dd04075a..29d3a4e0 100644 --- a/docs/rest-api-application/static-files.mdx +++ b/docs/rest-api-application/static-files.mdx @@ -4,6 +4,8 @@ sidebar_position: 12 description: See how to serve static files in Athenna REST API application. --- +import Path from '@site/src/components/path' + # Static Files See how to serve static files in Athenna REST API application. @@ -17,7 +19,7 @@ files from a given directory. Athenna uses the [`@fastify/static`](https://github.com/fastify/fastify-static) plugins inside `HttpKernel`. All the configurations that `@fastify/static` -supports can be set inside `Path.config('http.ts')` file in the `static` +supports can be set inside file in the `static` object. ```typescript title="Path.config('http.ts')" @@ -33,7 +35,7 @@ export default { ``` Now you can use the `response.sendFile()` methods to serve -files from `Path.public()` directory: +files from directory: ```typescript title="Path.route('http.ts')" Route.get('/hello', ({ response }) => { diff --git a/docs/rest-api-application/swagger-documentation.mdx b/docs/rest-api-application/swagger-documentation.mdx index c7f0c813..46002712 100644 --- a/docs/rest-api-application/swagger-documentation.mdx +++ b/docs/rest-api-application/swagger-documentation.mdx @@ -4,6 +4,8 @@ sidebar_position: 10 description: See how to create the Swagger documentation for Athenna REST API application. --- +import Path from '@site/src/components/path' + # Swagger Documentation See how to create the Swagger documentation for Athenna REST API application. @@ -20,9 +22,9 @@ is the root of all awesomeness in Swagger. Athenna uses the [`@fastify/swagger`](https://github.com/fastify/fastify-swagger) and [`@fastify/swagger-ui`](https://github.com/fastify/fastify-swagger-ui) plugins inside `HttpKernel`. All the configurations that `@fastify/swagger` -supports can be set inside `Path.config('http.ts')` file in the `swagger.configurations` +supports can be set inside file in the `swagger.configurations` object. And all the configurations that `@fastify/swagger-ui` -supports can be set inside `Path.config('http.ts')` file in the `swagger.ui` object: +supports can be set inside file in the `swagger.ui` object: ```typescript title="Path.config('http.ts')" export default { diff --git a/docs/rest-api-application/tracing-requests.mdx b/docs/rest-api-application/tracing-requests.mdx index e1a65f62..8bfa008b 100644 --- a/docs/rest-api-application/tracing-requests.mdx +++ b/docs/rest-api-application/tracing-requests.mdx @@ -4,6 +4,8 @@ sidebar_position: 8 description: Understand how to trace requests in your REST API application of Athenna. --- +import Path from '@site/src/components/path' + # Tracing Requests Understand how to trace requests in your REST API application of Athenna. @@ -21,7 +23,7 @@ identify bottlenecks and focus on improving performance. Athenna uses the [`cls-rtracer`](https://github.com/puzpuzpuz/cls-rtracer) plugin inside `HttpKernel`. All the configurations that `cls-rtracer` supports can be set inside -`Path.config('http.ts')` file in the `rTracer` object: + file in the `rTracer` object: ```typescript title="Path.config('http.ts')" export default { @@ -83,7 +85,7 @@ export default { Or by setting the `trace` option as `false` when booting the server in `Ignite.httpServer()` method: -```typescript title="Path.bootstrap('main.ts')" +```typescript title="Path.bin('main.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url) diff --git a/docs/rest-api-application/views.mdx b/docs/rest-api-application/views.mdx index e1d4929c..4df0b892 100644 --- a/docs/rest-api-application/views.mdx +++ b/docs/rest-api-application/views.mdx @@ -4,6 +4,8 @@ sidebar_position: 11 description: Understand how you can use the Athenna view API for rendering HTML pages. --- +import Path from '@site/src/components/path' + # Views Understand how you can use the Athenna view API for rendering HTML pages. @@ -83,7 +85,7 @@ your project: ## Configuration All the configuration options for your application's views -behavior is housed in the `Path.config('view.ts')` +behavior is housed in the configuration file. We will see later on this documentation the purpose of each option: @@ -114,7 +116,7 @@ node artisan make:view greeting ``` This command will place a new `greeting.edge` template -within your `Path.views()` directory. In this view we +within your directory. In this view we will render a simple profile with an avatar and the user name: ```html title="Path.views('greeting.edge') @@ -155,7 +157,7 @@ await View.render('greeting') ``` As you can see, the first argument passed to the method corresponds -to the name of the view file in the `Path.views()` directory as defined +to the name of the view file in the directory as defined in the `disk` options of the [configuration file](/docs/rest-api-application/views#configuration) of the view package. The second argument is an object of data that should be made available to the view. In this case, we are passing @@ -165,7 +167,7 @@ the `name` variable, which is displayed in the view using [Edge syntax](https:// Views may also be nested within subdirectories of your views directory. "Slash" notation may be used to reference nested views. -For example, if your view is stored at `Path.views('admin/profile.edge')`, +For example, if your view is stored at , you may return it from one of your application's routes / controllers like so: @@ -193,7 +195,7 @@ as there are not associated with a unique path. ## Defining & rendering named disks -Named disks could be defined inside `Path.config('view.ts')` +Named disks could be defined inside file, in the `namedDisks` configuration: ```typescript @@ -229,7 +231,7 @@ return response.view('greeting', { name: 'Lenon' }) But sometimes you may need to share data with all views that are rendered by your application. You may do so by using the `properties` -option inside of the `Path.config('view.ts')` file: +option inside of the file: ```typescript export default { @@ -262,7 +264,7 @@ of your `disk` root path. This helps create a visual boundary between the components and the rest of the templates used by your application. Let's start by creating a button component. We will store it inside -the `Path.views('components/button.edge')` file: +the file: ```html {{ text }} @@ -306,7 +308,7 @@ page](https://edgejs.dev/docs/components/introduction#components). ### In-memory components You can register in-memory views components by defining them -in the `components` property of you `Path.config('view.ts')` +in the `components` property of you file. You can find it useful whenever you want to split a large template file into several smaller ones or also if you want to provide some templates as part of a npm package: @@ -356,7 +358,7 @@ time-consuming process, and hence it is recommended to cache the compiled templates in production. You can control the template caching using the `edge.cache` -property inside `Path.config('view.ts')` file. Just make sure to set +property inside file. Just make sure to set the value to `true` in the production environment: ```typescript @@ -399,7 +401,7 @@ node artisan template:customize ``` The customized templates will be located in the -`Path.resources('templates')` directory. Any change + directory. Any change you make to these files will be reflected when you generate their correspoding files using Artisan's `make` commands. diff --git a/docs/testing/_category_.json b/docs/testing/_category_.json index 1e1c2c9f..b33de98e 100644 --- a/docs/testing/_category_.json +++ b/docs/testing/_category_.json @@ -1,6 +1,6 @@ { "label": "Testing", - "position": 10, + "position": 11, "collapsed": true, "link": null } diff --git a/docs/testing/cli-tests.mdx b/docs/testing/cli-tests.mdx index 5244f4c6..6c91e4dc 100644 --- a/docs/testing/cli-tests.mdx +++ b/docs/testing/cli-tests.mdx @@ -4,6 +4,8 @@ sidebar_position: 4 description: See how to create tests for CLI applications in Athenna. --- +import Path from '@site/src/components/path' + # CLI Testing See how to create tests for CLI applications in Athenna. @@ -29,7 +31,7 @@ export default class ExampleTest extends BaseConsoleTest { ``` The `command.run()` method will run a child process using the -`Path.bootstrap('artisan.ts')` file to execute the `app` command + file to execute the `app` command and get the `stdout`, `stderr` and `exitCode` outputs, while the `assertSucceeded()` method asserts that the returned output should have a successful exit code (`0`). In addition @@ -52,7 +54,7 @@ going to cover how to register it manually if needed. Just call the `Runner.addPlugin()` static method to set up the request plugin imported from `@athenna/artisan/testing/plugins`: -```typescript title="Path.bootstrap('test.ts')" +```typescript title="Path.bin('test.ts')" import { Runner } from '@athenna/test' import { request } from '@athenna/http/testing/plugins' import { command } from '@athenna/artisan/testing/plugins' @@ -97,13 +99,13 @@ export default class ExampleTest extends BaseConsoleTest { ### Changing the default Artisan file path As mentioned previously, the `command.run()` method invokes -a child process using the `Path.bootstrap('artisan.ts')` file. +a child process using the file. But for some reason, you may want to change which file should be used to test your commands. To do so, you can call the `TestCommand.setArtisanPath()` static method before running your tests: -```typescript title="Path.bootstrap('test.ts')" +```typescript title="Path.bin('test.ts')" import { Runner } from '@athenna/test' import { request } from '@athenna/http/testing/plugins' import { command, TestCommand } from '@athenna/artisan/testing/plugins' diff --git a/docs/testing/mocking.mdx b/docs/testing/mocking.mdx index 936f83af..59cedf3e 100644 --- a/docs/testing/mocking.mdx +++ b/docs/testing/mocking.mdx @@ -530,7 +530,7 @@ of it (`prototype`). Let's see how to mock a single class instance: ```typescript -import { ApiHelper } from '#app/helpers/ApiHelper' +import { ApiHelper } from '#src/helpers/ApiHelper' import { Test, Mock, type Context } from '@athenna/test' export default class MockTest { @@ -553,7 +553,7 @@ To mock a class method for all instances of a given class, you need to mock the class `prototype`: ```typescript -import { ApiHelper } from '#app/helpers/ApiHelper' +import { ApiHelper } from '#src/helpers/ApiHelper' import { Test, Mock, type Context } from '@athenna/test' export default class MockTest { @@ -574,7 +574,7 @@ is the same process of mocking a simple class using the `prototype` property: ```typescript -import { AppService } from '#app/services/AppService' +import { AppService } from '#src/services/AppService' import { Test, Mock, type Context } from '@athenna/test' export default class MockTest { @@ -603,7 +603,7 @@ of the service within your test class, registering it in the service container and then mocking the method you want in each test case: ```typescript -import { AppService } from '#app/services/AppService' +import { AppService } from '#src/services/AppService' import { BaseHttpTest } from '@athenna/core/testing/BaseHttpTest' import { Test, type Context, BeforeAll, Mock } from '@athenna/test' @@ -643,7 +643,7 @@ With `ioc.instance()` method, you can also create an entire different implementation of your service that will be used only for testing: ```typescript title="Path.fixtures('services/FakeAppService.ts')" -import { AppServiceInterface } from '#app/interfaces/AppServiceInterface' +import { AppServiceInterface } from '#src/interfaces/AppServiceInterface' export class FakeAppService implements AppServiceInterface { public findOne() { @@ -1045,7 +1045,7 @@ that is responsible to find a user in database by the id using an `User` model. To mock this scenario, we could do the following: ```typescript -import { UserService } from '#app/services/UserService' +import { UserService } from '#src/services/UserService' import { Database, DatabaseProvider } from '@athenna/database' import { Test, Mock, BeforeAll, AfterEach, type Context } from '@athenna/test' @@ -1083,7 +1083,7 @@ that is responsible to create a user in database using an `User` model. To mock this scenario, we could do the following: ```typescript -import { UserService } from '#app/services/UserService' +import { UserService } from '#src/services/UserService' import { Database, DatabaseProvider } from '@athenna/database' import { Test, Mock, BeforeAll, AfterEach, type Context } from '@athenna/test' diff --git a/docs/testing/rest-api-testing.mdx b/docs/testing/rest-api-testing.mdx index 263fe645..613dff9d 100644 --- a/docs/testing/rest-api-testing.mdx +++ b/docs/testing/rest-api-testing.mdx @@ -51,7 +51,7 @@ to cover how to register it manually if needed. Just call the `Runner.addPlugin()` static method to setup the request plugin imported from `@athenna/http/testing/plugins`: -```typescript title="Path.bootstrap('test.ts')" +```typescript title="Path.bin('test.ts')" import { Runner } from '@athenna/test' import { request } from '@athenna/http/testing/plugins' import { command } from '@athenna/artisan/testing/plugins' diff --git a/docs/the-basics/helpers.mdx b/docs/the-basics/helpers.mdx index 379dfa34..b150a753 100644 --- a/docs/the-basics/helpers.mdx +++ b/docs/the-basics/helpers.mdx @@ -4,6 +4,8 @@ sidebar_position: 3 description: Understand how to use all the Athenna Helpers from @athenna/common and other packages. --- +import Path from '@site/src/components/path' + # Helpers Understand how to use all the Athenna Helpers from @athenna/common and other packages. @@ -495,7 +497,7 @@ console.log(paginateObject) #### `FakeApi::start()` Start the fake server on port `8989` and loading the path -`Path.resources('fake-api')`: +: ```typescript import { FakeApi } from '@athenna/common' @@ -561,7 +563,7 @@ import { FakeApi } from '@athenna/common' FakeApi.registerFile(Path.resources('fake-api/users.json')) ``` -Content of `Path.resources('fake-api/users.json')` file: +Content of file: ```json { @@ -4048,7 +4050,7 @@ Merge the project root path with `Path.dirs.app`: ```typescript import { Path } from '@athenna/common' -console.log(Path.app()) // /home/user/athenna-project/app +console.log(Path.app()) // /home/user/athenna-project/src ``` #### `Path::setApp()` @@ -4068,7 +4070,7 @@ Merge the project root path with `Path.dirs.models`: ```typescript import { Path } from '@athenna/common' -console.log(Path.models()) // /home/user/athenna-project/app/models +console.log(Path.models()) // /home/user/athenna-project/src/models ``` #### `Path::setModels()` @@ -4108,7 +4110,7 @@ Merge the project root path with `Path.dirs.config`: ```typescript import { Path } from '@athenna/common' -console.log(Path.config()) // /home/user/athenna-project/config +console.log(Path.config()) // /home/user/athenna-project/src/config ``` #### `Path::setConfig()` @@ -4128,7 +4130,7 @@ Merge the project root path with `Path.dirs.database`: ```typescript import { Path } from '@athenna/common' -console.log(Path.database()) // /home/user/athenna-project/database +console.log(Path.database()) // /home/user/athenna-project/src/database ``` #### `Path::setDatabase()` @@ -4148,7 +4150,7 @@ Merge the project root path with `Path.dirs.lang`: ```typescript import { Path } from '@athenna/common' -console.log(Path.lang()) // /home/user/athenna-project/lang +console.log(Path.lang()) // /home/user/athenna-project/src/lang ``` #### `Path::setLang()` @@ -4188,7 +4190,7 @@ Merge the project root path with `Path.dirs.providers`: ```typescript import { Path } from '@athenna/common' -console.log(Path.providers()) // /home/user/athenna-project/providers +console.log(Path.providers()) // /home/user/athenna-project/src/providers ``` #### `Path::setProviders()` @@ -4208,7 +4210,7 @@ Merge the project root path with `Path.dirs.facades`: ```typescript import { Path } from '@athenna/common' -console.log(Path.facades()) // /home/user/athenna-project/providers/facades +console.log(Path.facades()) // /home/user/athenna-project/src/facades ``` #### `Path::setFacades()` @@ -4248,7 +4250,7 @@ Merge the project root path with `Path.dirs.resources`: ```typescript import { Path } from '@athenna/common' -console.log(Path.resources()) // /home/user/athenna-project/resources +console.log(Path.resources()) // /home/user/athenna-project/src/resources ``` #### `Path::setResources()` @@ -4268,7 +4270,7 @@ Merge the project root path with `Path.dirs.routes`: ```typescript import { Path } from '@athenna/common' -console.log(Path.routes()) // /home/user/athenna-project/routes +console.log(Path.routes()) // /home/user/athenna-project/src/routes ``` #### `Path::setRoutes()` @@ -4288,7 +4290,7 @@ Merge the project root path with `Path.dirs.storage`: ```typescript import { Path } from '@athenna/common' -console.log(Path.storage()) // /home/user/athenna-project/storage +console.log(Path.storage()) // /home/user/athenna-project/src/storage ``` #### `Path::setStorage()` @@ -4328,7 +4330,7 @@ Merge the project root path with `Path.dirs.logs`: ```typescript import { Path } from '@athenna/common' -console.log(Path.logs()) // /home/user/athenna-project/storage/logs +console.log(Path.logs()) // /home/user/athenna-project/src/storage/logs ``` #### `Path::setLogs()` @@ -4348,7 +4350,7 @@ Merge the project root path with `Path.dirs.views`: ```typescript import { Path } from '@athenna/common' -console.log(Path.views()) // /home/user/athenna-project/resources/views +console.log(Path.views()) // /home/user/athenna-project/src/resources/views ``` #### `Path::setViews()` @@ -4408,7 +4410,7 @@ Merge the project root path with `Path.dirs.locales`: ```typescript import { Path } from '@athenna/common' -console.log(Path.locales()) // /home/user/athenna-project/resources/locales +console.log(Path.locales()) // /home/user/athenna-project/src/resources/locales ``` #### `Path::setLocales()` @@ -4468,7 +4470,7 @@ Merge the project root path with `Path.dirs.http`: ```typescript import { Path } from '@athenna/common' -console.log(Path.http()) // /home/user/athenna-project/app/http +console.log(Path.http()) // /home/user/athenna-project/src/http ``` #### `Path::setHttp()` @@ -4488,7 +4490,7 @@ Merge the project root path with `Path.dirs.console`: ```typescript import { Path } from '@athenna/common' -console.log(Path.console()) // /home/user/athenna-project/app/console +console.log(Path.console()) // /home/user/athenna-project/src/console ``` #### `Path::setConsole()` @@ -4501,6 +4503,26 @@ import { Path } from '@athenna/common' Path.setConsole('console/app') ``` +#### `Path::cron()` + +Merge the project root path with `Path.dirs.cron`: + +```typescript +import { Path } from '@athenna/common' + +console.log(Path.cron()) // /home/user/athenna-project/src/cron +``` + +#### `Path::setCron()` + +Set the `Path.dirs.cron` value: + +```typescript +import { Path } from '@athenna/common' + +Path.setCron('cron/app') +``` + #### `Path::services()` Merge the project root path with `Path.dirs.services`: @@ -4508,7 +4530,7 @@ Merge the project root path with `Path.dirs.services`: ```typescript import { Path } from '@athenna/common' -console.log(Path.services()) // /home/user/athenna-project/app/services +console.log(Path.services()) // /home/user/athenna-project/src/services ``` #### `Path::setServices()` @@ -4528,7 +4550,7 @@ Merge the project root path with `Path.dirs.jobs`: ```typescript import { Path } from '@athenna/common' -console.log(Path.jobs()) // /home/user/athenna-project/app/jobs +console.log(Path.jobs()) // /home/user/athenna-project/src/jobs ``` #### `Path::setJobs()` @@ -4548,7 +4570,7 @@ Merge the project root path with `Path.dirs.workers`: ```typescript import { Path } from '@athenna/common' -console.log(Path.workers()) // /home/user/athenna-project/appworkers/ +console.log(Path.workers()) // /home/user/athenna-project/src/workers ``` #### `Path::setWorkers()` @@ -4568,7 +4590,7 @@ Merge the project root path with `Path.dirs.repositories`: ```typescript import { Path } from '@athenna/common' -console.log(Path.repositories()) // /home/user/athenna-project/app/repositories +console.log(Path.repositories()) // /home/user/athenna-project/src/repositories ``` #### `Path::setRepositories()` @@ -4588,7 +4610,7 @@ Merge the project root path with `Path.dirs.commands`: ```typescript import { Path } from '@athenna/common' -console.log(Path.commands()) // /home/user/athenna-project/app/console/commands +console.log(Path.commands()) // /home/user/athenna-project/src/console/commands ``` #### `Path::setCommands()` @@ -4601,6 +4623,26 @@ import { Path } from '@athenna/common' Path.setCommands('commands/app') ``` +#### `Path::schedulers()` + +Merge the project root path with `Path.dirs.schedulers`: + +```typescript +import { Path } from '@athenna/common' + +console.log(Path.schedulers()) // /home/user/athenna-project/src/cron/schedulers +``` + +#### `Path::setSchedulers()` + +Set the `Path.dirs.schedulers` value: + +```typescript +import { Path } from '@athenna/common' + +Path.setSchedulers('schedulers/app') +``` + #### `Path::controllers()` Merge the project root path with `Path.dirs.controllers`: @@ -4608,7 +4650,7 @@ Merge the project root path with `Path.dirs.controllers`: ```typescript import { Path } from '@athenna/common' -console.log(Path.controllers()) // /home/user/athenna-project/app/http/controllers +console.log(Path.controllers()) // /home/user/athenna-project/src/http/controllers ``` #### `Path::setControllers()` @@ -4628,7 +4670,7 @@ Merge the project root path with `Path.dirs.guards`: ```typescript import { Path } from '@athenna/common' -console.log(Path.guards()) // /home/user/athenna-project/app/http/guards/ +console.log(Path.guards()) // /home/user/athenna-project/src/http/guards/ ``` #### `Path::setGuards()` @@ -4648,7 +4690,7 @@ Merge the project root path with `Path.dirs.exceptions`: ```typescript import { Path } from '@athenna/common' -console.log(Path.exceptions()) // /home/user/athenna-project/app/exceptions +console.log(Path.exceptions()) // /home/user/athenna-project/src/exceptions ``` #### `Path::setExceptions()` @@ -4668,7 +4710,7 @@ Merge the project root path with `Path.dirs.middlewares`: ```typescript import { Path } from '@athenna/common' -console.log(Path.middlewares()) // /home/user/athenna-project/app/http/middlewares +console.log(Path.middlewares()) // /home/user/athenna-project/src/http/middlewares ``` #### `Path::setMiddlewares()` @@ -4688,7 +4730,7 @@ Merge the project root path with `Path.dirs.interceptors`: ```typescript import { Path } from '@athenna/common' -console.log(Path.interceptors()) // /home/user/athenna-project/app/http/interceptors +console.log(Path.interceptors()) // /home/user/athenna-project/src/http/interceptors ``` #### `Path::setInterceptors()` @@ -4708,7 +4750,7 @@ Merge the project root path with `Path.dirs.terminators`: ```typescript import { Path } from '@athenna/common' -console.log(Path.terminators()) // /home/user/athenna-project/app/http/terminators +console.log(Path.terminators()) // /home/user/athenna-project/src/http/terminators ``` #### `Path::setTerminators()` @@ -4728,7 +4770,7 @@ Merge the project root path with `Path.dirs.migrations`: ```typescript import { Path } from '@athenna/common' -console.log(Path.migrations()) // /home/user/athenna-project/database/migrations +console.log(Path.migrations()) // /home/user/athenna-project/src/database/migrations ``` #### `Path::setMigrations()` @@ -4748,7 +4790,7 @@ Merge the project root path with `Path.dirs.seeders`: ```typescript import { Path } from '@athenna/common' -console.log(Path.seeders()) // /home/user/athenna-project/database/seeders +console.log(Path.seeders()) // /home/user/athenna-project/src/database/seeders ``` #### `Path::setSeeders()` @@ -4805,7 +4847,7 @@ console.log(Path.vmHome()) // /home/user Return the execution path of where this method is being called: -```typescript title="/home/user/athenna-project/app/logPath.ts" +```typescript title="/home/user/athenna-project/src/logPath.ts" import { Path } from '@athenna/common' export function logPath() { @@ -4813,10 +4855,10 @@ export function logPath() { } ``` -```typescript title="/home/user/athenna-project/bootstrap/index.ts" -import { logPath } from '#app/logPath' +```typescript title="/home/user/athenna-project/bin/index.ts" +import { logPath } from '#src/logPath' -logPath() // /home/user/athenna-project/app +logPath() // /home/user/athenna-project/src ``` ### Route diff --git a/docs/the-basics/logging.mdx b/docs/the-basics/logging.mdx index 725b0a7b..08624e66 100644 --- a/docs/the-basics/logging.mdx +++ b/docs/the-basics/logging.mdx @@ -4,6 +4,8 @@ sidebar_position: 1 description: Understand how you can use the Athenna logging API. --- +import Path from '@site/src/components/path' + # Logging Understand how you can use the Athenna logging API. @@ -24,7 +26,7 @@ the http requests that your application receives. ## Configuration All the configuration options for your application's logging -behavior are housed in the `Path.config('logging.ts')` configuration +behavior are housed in the configuration file. This file allows you to configure your application's log channels, so be sure to review each of the available channels and their options. We'll review a few common options @@ -36,7 +38,7 @@ Each log channel is powered by a "driver". The driver determines how and where the log message is actually transported. The following log channel drivers are available in every Athenna application. An entry for most of these drivers is already -present in your application's `Path.config('logging.ts')` configuration +present in your application's configuration file, so be sure to review this file to become familiar with its contents: @@ -54,7 +56,7 @@ its contents: Almost all channels doesn't need any additional configuration to work. But some of than need a couple of changes in -`Path.config('logging.ts')` file to be able to use. They are `slack`, + file to be able to use. They are `slack`, `discord` and `telegram`. #### Configuring the Slack channel @@ -154,7 +156,7 @@ import { DriverFactory } from '@athenna/logger' DriverFactory.createDriver('consoleLog', ConsoleLogDriver) ``` -Finally, we can start using our new driver in channels of `Path.config('logging.ts')`: +Finally, we can start using our new driver in channels of : ```typescript channels: { @@ -190,10 +192,10 @@ Log.fatal(message) You may call any of these methods to log a message for the corresponding level. By default, the message will be written to the default log channel as configured by your -`Path.config('logging.ts')` configuration file: + configuration file: ```typescript -import { WelcomeService } from '#app/services/WelcomeService' +import { WelcomeService } from '#src/services/WelcomeService' export class WelcomeController { @Inject() @@ -230,7 +232,7 @@ example configuration that you might see in a production application: Take note of the `level` configuration option present in -`slack` channel of your `Path.config('logging.ts')` file: +`slack` channel of your file: ```typescript channels: { @@ -318,7 +320,7 @@ Log.info(`${chalk.yellow.bold('Hello')} ${chalk.green.italic('World')}!`) It is also possible to set runtime configurations when using the `Log` facade. This way you will never be total -dependent from `Path.config('logging.ts')` configuration file. To +dependent from configuration file. To accomplish this, you may pass a configuration object to the `config` method of Log facade and then call the `channel` method again to set up the configurations for the specified @@ -340,7 +342,7 @@ Each log channel is powered by a "formatter". The formatter determines how the log message is actually formatted. The following log channel formatters are available in every Athenna application. An entry for most of these formatters is -already present in your application's `Path.config('logging.ts')` +already present in your application's configuration file, so be sure to review this file to become familiar with its contents: @@ -406,7 +408,7 @@ FormatterFactory.createFormatter('consoleLog', ConsoleLogFormatter) ``` Finally, we can start using our new formatter in channels -of `Path.config('logging.ts')`: +of : ```typescript channels: { @@ -431,7 +433,7 @@ down. If you wish to run your application in silent mode, you can disable this kind of logs using the `Ignite::load()` static method: -```typescript title="Path.bootstrap('main.ts')" +```typescript title="Path.bin('main.ts')" import { Ignite } from '@athenna/core' const ignite = await new Ignite().load(import.meta.url, { diff --git a/src/components/path.module.css b/src/components/path.module.css new file mode 100644 index 00000000..97af6eb8 --- /dev/null +++ b/src/components/path.module.css @@ -0,0 +1,43 @@ +/* Basic styling for the container and link */ +.hoverCardContainer { + position: relative; + display: inline-block; +} + +.hoverCardLink { + text-decoration: none; + color: #007BFF; + font-weight: bold; + cursor: pointer; +} + +/* Initial state of the card - hidden */ +.hoverCard { + position: absolute; + width: 200px; + padding: 10px; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 5px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + opacity: 0; + pointer-events: none; + transition: opacity 0.3s ease; + z-index: 1000; + top: auto; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + margin-bottom: 5px; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; +} + +.hoverCardContainer:hover .hoverCard { + opacity: 1; + pointer-events: auto; +} diff --git a/src/components/path.tsx b/src/components/path.tsx new file mode 100644 index 00000000..7f5fc321 --- /dev/null +++ b/src/components/path.tsx @@ -0,0 +1,95 @@ +import React from "react"; +import styles from './path.module.css' + +export default function Path(props: { father: string; child: string }) { + let father = props.father + + switch (props.father) { + case 'storage': + father = 'src/storage' + break + case 'logs': + father = 'src/storage/logs' + break + case 'views': + father = 'src/resources/views' + break + case 'locales': + father = 'src/resources/locales' + break + case 'static': + father = 'src/resources/static' + break + case 'config': + father = 'src/config' + break + case 'database': + father = 'src/database' + break + case 'seeders': + father = 'src/database/seeders' + break + case 'migrations': + father = 'src/database/migrations' + break + case 'console': + father = 'src/console' + break + case 'commands': + father = 'src/console/commands' + break + case 'cron': + father = 'src/cron' + break + case 'schedulers': + father = 'src/cron/schedulers' + break + case 'models': + father = 'src/models' + break + case 'services': + father = 'src/services' + break + case 'repositories': + father = 'src/repositories' + break + case 'http': + father = 'src/http' + break + case 'controllers': + father = 'src/http/controllers' + break + case 'middlewares': + father = 'src/http/middlewares' + break + case 'interceptors': + father = 'src/http/interceptors' + break + case 'terminators': + father = 'src/http/terminators' + break + case 'stubs': + father = 'tests/stubs' + break + case 'fixtures': + father = 'tests/fixtures' + break + case 'providers': + father = 'src/providers' + break + case 'facades': + father = 'src/facades' + break + } + + return ( + + + Path.{props.father}({props.child ? `'${props.child}'` : ''}) + + + ./{father}{props.child ? `/${props.child}` : ''} + + + ) +}
Path.{props.father}({props.child ? `'${props.child}'` : ''})
./{father}{props.child ? `/${props.child}` : ''}