📝 Write doc

This commit is contained in:
Freeze455
2021-08-17 18:23:42 +02:00
parent 7e2ad399a2
commit 5fc6a66179
8 changed files with 297 additions and 18 deletions

View File

@@ -0,0 +1,165 @@
<template>
<Documentation title="Environment">
<p>
The environment file contains information confidential to your application such as your token. You must not disclose it under any circumstances.
The Discord Factory framework offers you the possibility to choose between 3 types of files :
</p>
<ul>
<li> Env</li>
<li> Json</li>
<li> Yaml</li>
</ul>
<p>
In order to meet the widest variety of needs, each environment file can be extended by adding your own elements such as messages, etc...
</p>
<h2>Why an environment file</h2>
<p>
The environment file is crucial for several reasons, it contains all the sensitive information of the project and should never be versioned on git.
The use of an environment file allows when using container managers (such as docker, kubernetes) to adapt the startup data to the production environment.
</p>
<p>
When you create a new project, you can choose between three types of environment :
</p>
<div>
<h3>.env</h3>
<CodeHighlight :code="env" />
</div>
<div>
<h3>json</h3>
<CodeHighlight :code="json" />
</div>
<div>
<h3>yaml</h3>
<CodeHighlight :code="yaml" />
</div>
<h2>Retrieving environment variables</h2>
<CodeHighlight :code="getClient" />
</Documentation>
</template>
<script setup lang="ts">
import Documentation from '../../../../components/Documentation.vue'
import CodeHighlight from '../../../../components/CodeHighlight.vue'
import Divider from '../../../../components/Divider.vue'
import LinkExternal from '../../../../components/LinkExternal.vue'
import AlertWarn from '../../../../components/AlertWarn.vue'
import AlertSuccess from '../../../../components/AlertSuccess.vue'
import AlertInfo from '../../../../components/AlertInfo.vue'
const env = `
APP_PREFIX = "your prefix"
APP_TOKEN = "your token"
PRESET_COMMAND_AUTO_REMOVE = true
PARTIAL_MESSAGE = true
PARTIAL_CHANNEL = true
PARTIAL_REACTION = true
INTENT_GUILDS = true
INTENT_GUILD_MEMBERS = true
INTENT_GUILD_BANS = true
INTENT_GUILD_EMOJIS_AND_STICKERS = true
INTENT_GUILD_INTEGRATIONS = true
INTENT_GUILD_WEBHOOKS = true
INTENT_GUILD_INVITES = true
INTENT_GUILD_VOICE_STATES = true
INTENT_GUILD_PRESENCES = true
INTENT_GUILD_MESSAGES = true
INTENT_GUILD_MESSAGE_REACTIONS = true
INTENT_GUILD_MESSAGE_TYPING = true
INTENT_DIRECT_MESSAGES = true
INTENT_DIRECT_MESSAGE_REACTIONS = true
INTENT_DIRECT_MESSAGE_TYPING = true
MESSAGE_COMMAND_MISSING_PERMISSION = "You're not authorized to execute this command"
MESSAGE_COMMAND_MISSING_ROLES = "You're not authorized to execute this command"
MESSAGE_ENVIRONMENT_FILE_PREFIX_MISSING = "The prefix is missing in the environment file."
MESSAGE_ENVIRONMENT_FILE_TOKEN_MISSING = "The token is missing in the environment file."
MESSAGE_ENVIRONMENT_FILE_MISSING = "Environment file is missing, please create one."
`
const json = `
{
"APP_TOKEN": "your prefix",
"APP_PREFIX": "your token",
"PARTIALS": [
"MESSAGE",
"CHANNEl",
"REACTION"
],
"INTENTS": [
"GUILDS",
"GUILD_MEMBERS",
"GUILD_BANS",
"GUILD_EMOJIS_AND_STICKERS",
"GUILD_INTEGRATIONS",
"GUILD_WEBHOOKS",
"GUILD_INVITES",
"GUILD_VOICE_STATES",
"GUILD_PRESENCES",
"GUILD_MESSAGES",
"GUILD_MESSAGE_REACTIONS",
"GUILD_MESSAGE_TYPING",
"DIRECT_MESSAGES",
"DIRECT_MESSAGE_REACTIONS",
"DIRECT_MESSAGE_TYPING",
],
"PRESETS": {
"COMMAND_AUTO_REMOVE": true
},
"MESSAGES": {
"COMMAND_MISSING_PERMISSION": "You're not authorized to execute this command",
"COMMAND_MISSING_ROLES": "You're not authorized to execute this command",
"ENVIRONMENT_FILE_PREFIX_MISSING": "The prefix is missing in the environment file.",
"ENVIRONMENT_FILE_TOKEN_MISSING": "The token is missing in the environment file.",
"ENVIRONMENT_FILE_MISSING": "Environment file is missing, please create one."
}
}
`
const yaml = `
APP_TOKEN: your token
APP_PREFIX: your prefix
PARTIALS:
- MESSAGE
- CHANNEL
- REACTION
INTENTS:
- GUILDS
- GUILD_MEMBERS
- GUILD_BANS
- GUILD_EMOJIS_AND_STICKERS
- GUILD_INTEGRATIONS
- GUILD_WEBHOOKS
- GUILD_INVITES
- GUILD_VOICE_STATES
- GUILD_PRESENCES
- GUILD_MESSAGES
- GUILD_MESSAGE_REACTIONS
- GUILD_MESSAGE_TYPING
- DIRECT_MESSAGES
- DIRECT_MESSAGE_REACTIONS
- DIRECT_MESSAGE_TYPING
PRESETS:
COMMAND_AUTO_REMOVE: true
MESSAGES:
COMMAND_MISSING_PERMISSION: You're not authorized to execute this command
COMMAND_MISSING_ROLES: You're not authorized to execute this command
ENVIRONMENT_FILE_PREFIX_MISSING: The prefix is missing in the environment file.
ENVIRONMENT_FILE_TOKEN_MISSING: The token is missing in the environment file.
ENVIRONMENT_FILE_MISSING: Environment file is missing, please create one.
DATABASE:
DRIVER: SQLite
PATH: database.sql`
const getClient = `
import { Application } from '@discord-factory/core'
const environment = Application.getEnvironment('APP_PREFIX')
console.log(environment) // '!'
`
</script>

View File

@@ -0,0 +1,30 @@
<template>
<Documentation title="Getting started">
<p>
Are you tired of reinventing the wheel at the start of each project, and of spending too much time on how your bot will work?
</p>
<p>
The Discord Factory framework offers you a completely free development structure. You choose how you organize your application.
</p>
<p>
Creation, Structural, Behavioural or even Singleton, you can finally choose your own design pattern without being forced to modify the whole functioning of your project.
</p>
<ul>
<li>🧪 Mode flexibility, no limits. You are free to create your own architecture.</li>
<li> Factory includes "in memory" compilation to make the compilation of your application more efficient.</li>
<li>📦 Learn and create in a powerful development environment with the various tools Discord Factory offers.</li>
</ul>
<p>
It's now up to you!
</p>
</Documentation>
</template>
<script setup lang="ts">
import Documentation from '../../../../components/Documentation.vue'
</script>
<style>
</style>

View File

@@ -0,0 +1,88 @@
<template>
<Documentation title="Starting">
<p>
Installing a framework to use it is not always obvious because of the configuration that the developer must make.
</p>
<p>
Unfortunately there is currently no equivalent to automatically create the project. (But we are thinking about it! 😐)
</p>
<h2>Factory, the interactive ordering guest</h2>
<p>
Let's get to the heart of the matter.<br>
In order to develop with the framework, you need to have
<LinkExternal url="https://nodejs.org/en/download/current">NodeJS (<span class="font-extrabold">v.16+</span>)</LinkExternal>
installed on your development environment. Then, globally install the CLI Architect of the bot.
</p>
<div class="flex items-center space-x-5">
<CodeHighlight code="npm install -g @discord-factory/command" />
<p class="text-gray-800">or</p>
<CodeHighlight code="yarn global add @discord-factory/command" />
</div>
<AlertWarn>
<template v-slot:label>
Warn
</template>
<template v-slot:message>
It's possible that using YARN to add the CLI globally does not work correctly, in this case please use NPM.
</template>
</AlertWarn>
<h2>Create your first project</h2>
<p>
The <span class="font-bold">@discord-factory/command</span> module is a CLI which, in the same way as Artisan for Laravel, will allow you to interact quickly with the bot's functionalities.
You can now initialize a project very easily with the following command
</p>
<CodeHighlight class="w-min" code="$ factory create-project" />
<p>
Answer the questions and a blank project will be initialized according to the elements you have defined.
An .env file will be created, this file must have at least the following data :
</p>
<AlertInfo>
<template v-slot:label>
Info
</template>
<template v-slot:message>
The <span class="font-bold">prefix</span> key represents the prefix that each message must have in order to be recognised as a command.
</template>
</AlertInfo>
<AlertInfo>
<template v-slot:label>
Info
</template>
<template v-slot:message>
The <span class="font-bold">token</span> key is the token of your bot. It should never be disclosed or sent on a versioning platform such as github. An article is available here to know how to recover the token of its bot.
</template>
</AlertInfo>
<h2>Starting your project</h2>
<p>All you have to do is install the dependencies with the following commands</p>
<div class="flex items-center space-x-5">
<CodeHighlight code="$ npm install" />
<p class="text-gray-800">or</p>
<CodeHighlight code="$ yarn install" />
</div>
<p>
The Factory framework uses in memory compilation allowing typescript code to be executed directly by ts-node without having to go through a build folder.
Furthermore, this hot compile allows you to reduce your CPU usage by almost 4 times by reducing the memory cost from <span class="font-bold">~600MB</span> to <span class="font-bold">~170MB</span>.
</p>
<div class="flex items-center space-x-5">
<CodeHighlight code="$ npm run dev" />
<p class="text-gray-800">or</p>
<CodeHighlight code="$ yarn dev" />
</div>
</Documentation>
</template>
<script setup lang="ts">
import Documentation from '../../../../components/Documentation.vue'
import CodeHighlight from '../../../../components/CodeHighlight.vue'
import Divider from '../../../../components/Divider.vue'
import LinkExternal from '../../../../components/LinkExternal.vue'
import AlertWarn from '../../../../components/AlertWarn.vue'
import AlertSuccess from '../../../../components/AlertSuccess.vue'
import AlertInfo from '../../../../components/AlertInfo.vue'
</script>

View File

@@ -0,0 +1,194 @@
<template>
<Documentation title="Structure">
<p>
The framework offers a very modular way of structuring your files within your application, the only restriction is that they must be included in the src/ folder as this represents level 0 of your application (also called root directory).
</p>
<CodeHighlight :code="structure" />
<div class="space-y-5">
<h2>Folder start</h2>
<p>
This folder contains the files needed to start the application.<br>
You will find the index, the entry point of the application which initializes the application.
</p>
<CodeHighlight :code="startFolder" />
<AlertInfo>
<template v-slot:label>
Info
</template>
<template v-slot:message>
The <span class="font-bold">index.ts</span> file in the <span class="font-bold">start folder</span> is the entry point for your application.
</template>
</AlertInfo>
</div>
<div class="space-y-5">
<h2>Folder provider</h2>
<p>
Providers are files that have certain methods defined in advance.<br>
You can create them at will as long as they are built in the following way :
</p>
<CodeHighlight :code="providerFolder" />
<AlertInfo>
<template v-slot:label>
Info
</template>
<template v-slot:message>
You can create as many providers as you like, they will be executed in alphabetical order. You can learn more here.
</template>
</AlertInfo>
<p>
These files are read first, even before the recovery of the command files, events...
It can be very interesting to use them to record a default behaviour before the application is ready to run.
</p>
<p>
A concrete example would be the console display of the files instantiated in your application :
</p>
<CodeHighlight :code="providerFile" />
<p>
The <span class="font-bold">context</span> object collects the various file types in your application
</p>
</div>
<div class="space-y-5">
<h2>Folder application</h2>
<p>
The <code class="active">src/</code> folder is the base folder for your project.
This is where you will work.
Please consider this folder as the root of your application.
</p>
<p>
The advantage of considering the <code class="active">src/</code> folder as the base of your application is that you can structure it as you see fit.
It can be interesting to look at design patterns, here are some of them :
</p>
<ul>
<li> Monolithic Architecture vs Microservice</li>
<li> NodeTSkeleton, a clean architecture</li>
<li> Hexagonal Architecture</li>
</ul>
<p>
Please use the <code class="active">factory make:file</code> command to create a file quickly
</p>
</div>
<div class="space-y-5">
<h3>Import with alias</h3>
<p>
The <code class="active">src/</code> folder is the base folder for your project.<br>
To simplify the import of your files, the alias <code class="active">App/</code> is available.<br>
This alias refers to the root folder <code class="active">src/</code>.
</p>
<CodeHighlight :code="aliasImport" />
</div>
<div class="space-y-5">
<h2>Testing</h2>
<p>
It is very important to test your code using unit tests for small features or integration tests for large features.
his folder allows you to write tests on files named <code class="active">foo.spec.ts</code>.
The default test framework used in the Discord Factory framework is ava but you can replace it with any other.
</p>
<AlertWarn>
<template v-slot:label>
Warn
</template>
<template v-slot:message>
Do not neglect unit or integration testing. They are extremely useful in the medium/long term. Indeed, when you develop a new feature, it must not break the existing code, this is called regression.
</template>
</AlertWarn>
<p>
The strict minimum code is as follows :
</p>
<CodeHighlight :code="test" />
<p>
Then you can use the followed command to run your tests :
</p>
<div class="flex items-center space-x-5">
<CodeHighlight code="$ npm install" />
<p class="text-gray-800">or</p>
<CodeHighlight code="$ yarn install" />
</div>
</div>
</Documentation>
</template>
<script setup lang="ts">
import Documentation from '../../../../components/Documentation.vue'
import CodeHighlight from '../../../../components/CodeHighlight.vue'
import Divider from '../../../../components/Divider.vue'
import LinkExternal from '../../../../components/LinkExternal.vue'
import AlertWarn from '../../../../components/AlertWarn.vue'
const structure = `
|- node_modules
|- provider
|- src
|- start
|- test
.env
.eslintignore
.eslintrc
.npmignore
LICENSE
README.md
package.json
tsconfig.json`
const startFolder = `
import 'module-alias/register'
import { Factory } from '@discord-factory/core'
Factory.getInstance().setup()`
const providerFolder = `
import { Context, Provider } from '@discord-factory/core'
export default class AppProvider implements Provider {
public async boot(): Promise<void> {
// Your code here
}
public async loadFile(context: Context): Promise<void> {
// Your code here
}
public async ready(): Promise<void> {
// Your code here
}
}`
const providerFile = `
export default class AppProvider implements Provider {
public async boot(): Promise<void> {
// Your code here
}
public async loadFile(context: Context): Promise<void> {
// Create type wrapper
const fileType = {
event: () => console.log(\`The event \${(context as EventEntity).event} is loaded.\`),
command: () => console.log(\`The command \${(context as CommandEntity).label} is loaded.\`),
middleware: () => console.log(\`The middleware with pattern \${(context as MiddlewareEntity).pattern} is loaded.\`),
hook: () => console.log(\`The hook is bind in \${(context as HookEntity).hook} event.\`)
}
// Call the wrapper
fileType[file.type]()
}
public async ready(): Promise<void> {
// Your code here
}
}`
const aliasImport = `
- import Foo from '../../../Foo'
+ import Foo from 'App/Folder/Foo'`
const test = `
import test from 'ava'
test('foo', (t) => {
t.pass()
})`
</script>