create-chapter 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-chapter",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,49 +0,0 @@
1
- import { button, command } from 'chapterjs';
2
- import { canPunish } from './checks';
3
-
4
- // A folder is only a folder: `(moderation)` groups what moderation needs,
5
- // and the framework reads what these files export, wherever they are.
6
- // /ban asks for a confirmation, then bans. The command and its button live
7
- // in the same file: the button is named by its export (`confirmBan`), and
8
- // `who: 'author'` keeps it for the person who used the command.
9
- export default command({
10
- name: 'ban',
11
- permissions: ['BanMembers'],
12
- ephemeral: true,
13
- options: {
14
- target: { type: 'user', required: true },
15
- reason: { type: 'string' },
16
- days: { type: 'integer', min: 0, max: 7 },
17
- },
18
- async run({ interaction, options, member, guild, t }) {
19
- const target = guild.members.get(options.target.id);
20
- if (target && !canPunish(member, target)) {
21
- await interaction.reply(t('cannotPunish', { user: target.displayName }));
22
- return;
23
- }
24
- await interaction.reply({
25
- content: t('ban.confirm', { user: options.target.username }),
26
- components: [
27
- confirmBan({
28
- userId: options.target.id,
29
- days: options.days ?? 0,
30
- reason: options.reason ?? '',
31
- }),
32
- ],
33
- });
34
- },
35
- });
36
-
37
- export const confirmBan = button({
38
- label: ({ t }) => t('ban.yes'),
39
- style: 'danger',
40
- who: 'author',
41
- data: { userId: 'string', days: 'number', reason: 'string' },
42
- async run({ interaction, data, guild, user, t }) {
43
- await guild.ban(data.userId, {
44
- reason: data.reason || t('ban.defaultReason', { by: user.username }),
45
- deleteMessageSeconds: data.days * 86_400,
46
- });
47
- await interaction.update({ content: t('ban.done'), components: [] });
48
- },
49
- });
@@ -1,19 +0,0 @@
1
- import type { GuildMember } from 'chapterjs';
2
-
3
- // Shared code: this file declares nothing, the commands import it. Nothing
4
- // survives a restart: a real bot keeps its warnings in a database.
5
- export function canPunish(by: GuildMember, target: GuildMember): boolean {
6
- return by.highestRole.position > target.highestRole.position;
7
- }
8
-
9
- const warnings = new Map<string, number>();
10
-
11
- export function addWarning(userId: string): number {
12
- const count = (warnings.get(userId) ?? 0) + 1;
13
- warnings.set(userId, count);
14
- return count;
15
- }
16
-
17
- export function warningsOf(userId: string): number {
18
- return warnings.get(userId) ?? 0;
19
- }
@@ -1,27 +0,0 @@
1
- import { command } from 'chapterjs';
2
-
3
- // /kick: the texts come from the language files, like every command here.
4
- import { canPunish } from './checks';
5
-
6
- export default command({
7
- name: 'kick',
8
- permissions: ['KickMembers'],
9
- ephemeral: true,
10
- options: {
11
- target: { type: 'user', required: true },
12
- reason: { type: 'string' },
13
- },
14
- async run({ interaction, options, member, guild, t }) {
15
- const target = guild.members.get(options.target.id);
16
- if (!target) {
17
- await interaction.reply(t('notHere', { user: options.target.username }));
18
- return;
19
- }
20
- if (!canPunish(member, target)) {
21
- await interaction.reply(t('cannotPunish', { user: target.displayName }));
22
- return;
23
- }
24
- await target.kick(options.reason);
25
- await interaction.reply(t('kick.done', { user: target.displayName }));
26
- },
27
- });
@@ -1,81 +0,0 @@
1
- import { language } from 'chapterjs';
2
-
3
- // A language may be declared in several places: these texts are added to the
4
- // en-US and fr of src/messages/, next to the commands that use them. What
5
- // says `default: true` there decides for the whole language.
6
- export const en = language({
7
- locale: 'en-US',
8
- texts: {
9
- cannotPunish: 'You can not act on {user}: their role is above yours.',
10
- notHere: '{user} is not in this server.',
11
- 'ban.confirm': 'Ban {user}?',
12
- 'ban.yes': 'Ban',
13
- 'ban.defaultReason': 'Banned by {by}',
14
- 'ban.done': 'Banned.',
15
- 'kick.done': '{user} was kicked.',
16
- 'warn.added': '{user} now has {count} warning(s).',
17
- // A plural: one form per quantity, picked by `count`.
18
- 'warn.count': {
19
- one: '{user} has {count} warning.',
20
- other: '{user} has {count} warnings.',
21
- },
22
- },
23
- // What Discord shows of these commands: their descriptions live here too.
24
- commands: {
25
- ban: {
26
- description: 'Bans a member, after a confirmation',
27
- options: {
28
- target: { description: 'Who to ban' },
29
- reason: { description: 'Why' },
30
- days: { description: 'Days of messages to delete' },
31
- },
32
- },
33
- kick: {
34
- description: 'Kicks a member',
35
- options: {
36
- target: { description: 'Who to kick' },
37
- reason: { description: 'Why' },
38
- },
39
- },
40
- 'warn add': {
41
- description: 'Warns a member',
42
- options: {
43
- target: { description: 'Who to warn' },
44
- reason: { description: 'Why' },
45
- },
46
- },
47
- 'warn list': {
48
- description: 'Counts the warnings of a member',
49
- options: { target: { description: 'Whose warnings' } },
50
- },
51
- },
52
- });
53
-
54
- export const fr = language({
55
- locale: 'fr',
56
- texts: {
57
- cannotPunish:
58
- 'Vous ne pouvez pas agir sur {user} : son rôle est au-dessus du vôtre.',
59
- notHere: '{user} n’est pas sur ce serveur.',
60
- 'ban.confirm': 'Bannir {user} ?',
61
- 'ban.yes': 'Bannir',
62
- 'ban.defaultReason': 'Banni par {by}',
63
- 'ban.done': 'Banni.',
64
- 'kick.done': '{user} a été expulsé.',
65
- 'warn.added': '{user} a maintenant {count} avertissement(s).',
66
- 'warn.count': {
67
- one: '{user} a {count} avertissement.',
68
- other: '{user} a {count} avertissements.',
69
- },
70
- },
71
- commands: {
72
- // A command can be renamed in a language too: /bannir for French users.
73
- ban: {
74
- name: 'bannir',
75
- description: 'Bannit un membre, après confirmation',
76
- },
77
- kick: { name: 'expulser', description: 'Expulse un membre' },
78
- 'warn add': { description: 'Avertit un membre' },
79
- 'warn list': { description: 'Compte les avertissements d’un membre' },
80
- },
81
- });
@@ -1,42 +0,0 @@
1
- import { command, event } from 'chapterjs';
2
- import { addWarning, warningsOf } from './checks';
3
-
4
- // Two subcommands in one file: /warn add and /warn list. A subcommand is a
5
- // matter of `name`, not of folder.
6
- export const add = command({
7
- name: 'warn add',
8
- permissions: ['ModerateMembers'],
9
- options: {
10
- target: { type: 'user', required: true },
11
- reason: { type: 'string', required: true },
12
- },
13
- async run({ interaction, options, t }) {
14
- const count = addWarning(options.target.id);
15
- await interaction.reply(
16
- t('warn.added', { user: options.target.username, count })
17
- );
18
- },
19
- });
20
-
21
- export const list = command({
22
- name: 'warn list',
23
- permissions: ['ModerateMembers'],
24
- ephemeral: true,
25
- options: { target: { type: 'user', required: true } },
26
- async run({ interaction, options, t }) {
27
- await interaction.reply(
28
- t('warn.count', {
29
- user: options.target.username,
30
- count: warningsOf(options.target.id),
31
- })
32
- );
33
- },
34
- });
35
-
36
- // The event that goes with moderation, next to the commands it follows.
37
- export const logged = event({
38
- name: 'banAdd',
39
- run({ user, guild }) {
40
- console.log(`${user.username} was banned from ${guild.name}`);
41
- },
42
- });