SettingGateway v2.1 #179
SettingGateway v2.1 #179
Changes from 8 commits
d89ea96
783a2c7
1d5c940
d29b9e7
596cc50
39c6606
25e43ed
d51dc6c
4f00b79
e149295
156890c
b875eac
379e089
9f888cd
b58902a
7a4e081
80209f1
8584951
4bd6f4c
77fb2e4
c3e5e91
1a7a8d4
6b54a74
8aebcca
2ae8c11
baae345
74846a5
f71d42f
eca5fd4
ffdbe34
d8b7c6d
12005d8
2e4f237
6d7a91f
c4a653e
22ec3d5
a43bbba
c000551
0797361
2848ddc
26095d4
c686e16
a016927
72c0cdf
1f07d15
f2d8f34
4427dca
17c5094
c4248ef
0f85f86
bd6040a
ff927c1
3b8944e
982c4a1
3d24e03
4c78f13
ed97624
d191462
72d9e84
861efbf
be7d9e8
bead707
67aa0f1
1fe5c56
3eac3ab
9c00073
e46b259
78d8895
a2840d3
5014d9e
2f4309b
540f975
abe0ddc
9c745d9
983794d
4d3bf30
fa13068
cad228d
fbc9625
2f7d631
58a2109
a4d6db2
c1953c5
e9f54f0
484177a
120970c
f61d9e2
352b505
4816162
fe4b1ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Updating your configuration | ||
|
||
Once we have our schema done with all the keys, folders and types needed, we may want to update our configuration via SettingGateway, all of this is done via {@link Configuration#update}. However, how can I update it? Use any of the following code snippets: | ||
|
||
```javascript | ||
// Updating the value of a key | ||
// This key is contained in the roles folder, and the second value is a role id, we also need | ||
// to pass a GuildResolvable. | ||
msg.guild.configs.update('roles.administrator', '339943234405007361', msg.guild); | ||
|
||
// Updating an array | ||
// userBlacklist, as mentioned in another tutorial, it's a piece with an array or users. Using | ||
// the following code will add or remove it, depending on the existence of the key in the configuration. | ||
msg.guild.configs.update('userBlacklist', '272689325521502208'); | ||
|
||
// Ensuring the function call adds (error if it exists) | ||
msg.guild.configs.update('userBlacklist', '272689325521502208', { action: 'add' }); | ||
|
||
// Ensuring the function call removes (error if it not exists) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. error if it doesn't exist |
||
msg.guild.configs.update('userBlacklist', '272689325521502208', { action: 'remove' }); | ||
|
||
// Updating it with a json object | ||
// It's the same as the first code snippet. However, this pattern is slower. | ||
msg.guild.configs.update({ roles: { administrator: '339943234405007361' } }, msg.guild); | ||
|
||
// Updating multiple keys (only possible with json object) | ||
msg.guild.configs.update({ prefix: 'k!', language: 'es-ES' }); | ||
``` | ||
|
||
> **Note**: Some types require a Guild instance to work, for example, *channels*, *roles* and *members*. | ||
|
||
> Additionally, if no 'action' option is passed to {@link Configuration.ConfigurationUpdateOptions}, it'll assume the `auto` mode, which will add or remove depending on the existence of the key. | ||
|
||
## Further Reading: | ||
|
||
- {@tutorial UnderstandingSchemaPieces} | ||
- {@tutorial UnderstandingSchemaFolders} | ||
- {@tutorial SettingGatewayKeyTypes} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# SettingGateway's Types | ||
|
||
By default, there are several built-in types that the developer can use, and with the possibility to add custom types via {@link Extendable}s as explained below. The built-in types are: | ||
|
||
| Name | Type | Description | | ||
| :-----------------: | :------------------------------------------------ | ---------------------------------------------------------------------------------------- | | ||
| **any** | Anything, no type restriction | Resolves anything, even objects, the usage of this type will make a key unconfigurable | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolves anything, even objects. The usage of this type will make a key unconfigurable |
||
| **boolean** | A {@link Boolean} resolvable | Resolves a boolean primitive value | | ||
| **categorychannel** | A {@link external:CategoryChannel} instance or id | Resolves a CategoryChannel | | ||
| **channel** | A {@link external:Channel} instance or id | Resolves a channel. Be careful with using this, as it accepts any type of channel | | ||
| **command** | A {@link Command} instance or name | Resolves a Command | | ||
| **emoji** | An {@link external:Emoji} instance or name | Resolves a custom emoji | | ||
| **float** | A floating point number | Resolves a [float](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) | | ||
| **guild** | A {@link KlasaGuild} instance or id | Resolves a KlasaGuild (which extends Guild) | | ||
| **integer** | An integer number | Resolves an [integer](https://en.wikipedia.org/wiki/Integer) number | | ||
| **language** | A {@link Language} instance or name | Resolves a language | | ||
| **member** | A {@link external:GuildMember} instance or id | Resolves a GuildMember | | ||
| **msg** | A {@link KlasaMessage} instance or id | Resolves a KlasaMessage (which extends Message) | | ||
| **role** | A {@link external:Role} instance or id | Resolves a Role | | ||
| **string** | A {@link external:StringResolvable} | Resolves a string | | ||
| **textchannel** | A {@link external:TextChannel} instance or id | Resolves a TextChannel | | ||
| **url** | An URL resolvable | Resolves a URL with Node.js' URL parser | | ||
| **user** | A {@link KlasaUser} instance or id | Resolves a KlasaUser (which extends User) | | ||
| **voicechannel** | A {@link external:VoiceChannel} instance or id | Resolves a VoiceChannel | | ||
|
||
## Adding new types | ||
|
||
To add new keys, you use an {@link Extendable} extending {@link SettingResolver}. If you don't know how to create an extendable, check the following tutorial: {@tutorial CreatingExtendables}. The following extendable is a template for this: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To add new types, not keys, since the title is Adding new types |
||
|
||
```javascript | ||
const { Extendable } = require('klasa'); | ||
|
||
module.exports = class extends Extendable { | ||
|
||
constructor(...args) { | ||
super(...args, ['SettingResolver'], { | ||
name: 'typeName', | ||
klasa: true | ||
}); | ||
} | ||
|
||
/** | ||
* Resolves my custom type! | ||
* @param {*} data The data to resolve | ||
* @param {KlasaGuild} guild The guild to resolve for | ||
* @param {string} name The name of the key being resolved | ||
* @param {Object} [minMax={}] The minimum and maximum | ||
* @param {?number} minMax.min The minimum value | ||
* @param {?number} minMax.max The maximum value | ||
* @returns {Promise<*>} | ||
*/ | ||
async extend(data, guild, name, { min, max } = {}) { | ||
// The content | ||
return data; | ||
} | ||
|
||
}; | ||
``` | ||
|
||
> **Note**: If a type does not load, you can add the type name to {@link GatewayDriver#types}, but it must be before the {@link SchemaPiece}s init as they check if the type is included in that Set. | ||
|
||
## Further Reading: | ||
|
||
- {@tutorial UnderstandingSchemaPieces} | ||
- {@tutorial UnderstandingSchemaFolders} | ||
- {@tutorial SettingGatewayConfigurationUpdate} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
# Understanding Schema | ||
|
||
A schema works like a diagram or a blueprint, in SettingGateway, the schema defines the keys present in the configuration for a specific gateway. This feature serves multiple purposes: | ||
|
||
1. Define what keys does the {@link Gateway} manage and their properties. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Define what keys |
||
1. Define what type the keys must hold. | ||
1. Define the SQL schema when using a SQL database. | ||
1. Speed up performance when iterating over keys. | ||
|
||
## Adding keys | ||
|
||
Adding keys with the schema is like adding a piece into a box, but you can also have boxes inside another boxes. That being said, you get the box you want to modify and insert the new pieces or boxes into it. The methods to achieve that are {@link SchemaFolder#addKey} to add pieces (keys) and {@link SchemaFolder#addFolder} to add boxes (more folders). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can also have boxes inside other boxes To add pieces (keys) and {@link SchemaFolder#addFolder} to add boxes ( |
||
|
||
You would normally use these two methods using the following snippet: | ||
|
||
```javascript | ||
// Add a new key | ||
this.client.gateways.gatewayName.schema.addKey(name, options, force); | ||
|
||
// Add a new folder | ||
this.client.gateways.gatewayName.schema.addFolder(name, options, force); | ||
``` | ||
|
||
The parameters are: | ||
|
||
- **name**: The name of the new key. If it conflicts with a pre-existent key, this will error. | ||
- **options**: The options for the new key or folder. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably should throw in a link for all the available options here... imo |
||
- **force**: Whether this change should affect all entries. It requires a lot of processing but ensures the changes are correctly applied in both cache and database. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In both the cache and database. |
||
|
||
You can also extend any of the three built-in {@link Gateway}s from Klasa, for example, if you want to add a new key called **modlogs** that accepts only text channels, for your guild configs, you would use the following code: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. from Klasa. For example, .... |
||
|
||
```javascript | ||
this.client.gateways.guilds.schema.addKey('modlogs', { type: 'TextChannel' }); | ||
``` | ||
|
||
Where you're doing the following steps: | ||
|
||
1. Access to {@link KlasaClient#gateways}, type of {@link GatewayDriver}, which holds all gateways. | ||
1. Access to the guilds' {@link Gateway}, which manages the per-guild configuration. | ||
1. Access to the guilds' schema via {@link Gateway#schema}, which manages the gateway's schema. | ||
1. Add a new key called **modlogs** in the root of the schema, with type of **TextChannel**. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. with a type of TextChannel |
||
|
||
And you would have a perfectly configured modlogs key in your configs. However, you can also have an array of the same type. For example, you want to have a configurable array of users blacklisted in a guild, in a key named **userBlacklist**: | ||
|
||
```javascript | ||
this.client.gateways.guilds.schema.addKey('userBlacklist', { type: 'User', array: true }); | ||
``` | ||
|
||
And now you can access to any of them in your guild configs like in the following snippet! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And now you can have access |
||
|
||
```javascript | ||
msg.guild.configs.modlogs; | ||
// null | ||
msg.guild.configs.userBlacklist; | ||
// [] | ||
``` | ||
|
||
## Removing keys | ||
|
||
Removing keys with the schema is quite easy, as you would access to the {@link SchemaFolder} that holds it and remove it by its name (remember that `force` is optional and defaults to `true`) using {@link SchemaFolder#removeKey} as the following example: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as you would have access to the.... as in the following example: |
||
|
||
```javascript | ||
this.client.gateways.gatewayName.schema.removeKey(name, force); | ||
``` | ||
|
||
In case you have a key you do not longer use and you want to get rid of it, for example, the recently created **userBlacklist** key for guild configs, you would run the following code: | ||
|
||
```javascript | ||
this.client.gateways.guilds.schema.removeKey('userBlacklist'); | ||
``` | ||
|
||
And the property `userBlacklist` for all guild configs will be deleted, that being said: | ||
|
||
```javascript | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think it is necessary to have prove that the key no longer exists in that code snippet, I feel it is good enough saying that the key will no longer exist |
||
msg.guild.configs.userBlacklist; | ||
// undefined | ||
'userBlacklist' in msg.guild.configs; | ||
// false | ||
``` | ||
|
||
## Adding folders | ||
|
||
Folder creation is very similar to key creation, but with one key difference: it has no options for itself, but instead, it can create its children keys (like you can add a box with another boxes and pieces, into another). You can add a new key inside a new folder in two different ways: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (just like you can add a box with other boxes and pieces, into another) |
||
|
||
### Slower | ||
|
||
You can create a folder, then create the keys, however, this will iterate over all entries twice: | ||
|
||
```javascript | ||
async function init() { | ||
const { schema } = this.client.gateways.guilds; | ||
|
||
await schema.addFolder('channels'); | ||
await schema.channels.addKey('modlogs', { type: 'TextChannel' }); | ||
console.log(schema.channels.modlogs.toJSON()); | ||
// { | ||
// type: 'textchannel', | ||
// array: false, | ||
// default: null, | ||
// min: null, | ||
// max: null, | ||
// configurable: true | ||
// } | ||
} | ||
``` | ||
|
||
### Faster | ||
|
||
However, it's possible to create a folder with all the sub-keys (and even more nested folders) with the folder creation. | ||
|
||
```javascript | ||
async function init() { | ||
const { schema } = this.client.gateways.guilds; | ||
|
||
await schema.addFolder('channels', { modlogs: { type: 'TextChannel' } }); | ||
console.log(schema.channels.modlogs.toJSON()); | ||
// { | ||
// type: 'textchannel', | ||
// array: false, | ||
// default: null, | ||
// min: null, | ||
// max: null, | ||
// configurable: true | ||
// } | ||
} | ||
``` | ||
|
||
> **Reminder**: To access to a key inside a folder in your configuration command, you use the access operator (`.`). For example: *k!conf set channels.modlogs #modlogs* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To access |
||
|
||
## Removing folders | ||
|
||
It's exactly the same as {@link SchemaFolder#removeKey}, but using {@link SchemaFolder#removeFolder} instead. With the following syntax: | ||
|
||
```javascript | ||
this.client.gateways.gatewayName.schema.removeFolder(name, force); | ||
``` | ||
|
||
To remove a folder, like the aforementioned **channels** folder, you would run the following code: | ||
|
||
```javascript | ||
this.client.gateways.guilds.schema.removeFolder('channels'); | ||
``` | ||
|
||
This will remove all the data from all the sub-keys and sub-folders, even very nested ones. | ||
|
||
## Ensuring the existence of a key. | ||
|
||
In [Klasa-Pieces](https://github.com/dirigeants/klasa-pieces/), specially, some pieces require a key from the configuration to work, however, the creator of the pieces does not know if the user who downloads the piece has it, so this function becomes useful in this case. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In Klasa-Pieces [REMOVE THE COMMA] especially, |
||
|
||
```javascript | ||
async function init() { | ||
const { schema } = this.client.gateways.guilds; | ||
|
||
if (!schema.hasKey('modlog')) { | ||
await schema.addKey('modlog', { type: 'TextChannel' }); | ||
} | ||
} | ||
``` | ||
|
||
## Further Reading: | ||
|
||
- {@tutorial UnderstandingSchemaPieces} | ||
- {@tutorial SettingGatewayKeyTypes} | ||
- {@tutorial SettingGatewayConfigurationUpdate} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
array of users not or