@grammyjs/commands 0.10.0 → 0.11.0

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.
@@ -70,6 +70,12 @@ export declare class CommandGroup<C extends Context> {
70
70
  * @returns An instance of the `Command` class
71
71
  */
72
72
  command(name: string | RegExp, description: string, options?: Partial<CommandOptions>): Command<C>;
73
+ /**
74
+ * Registers a Command that was created by it's own.
75
+ *
76
+ * @param command the command or list of commands being added to the group
77
+ */
78
+ add(command: Command<C> | Command<C>[]): this;
73
79
  /**
74
80
  * Serializes the commands into multiple objects that can each be passed to a `setMyCommands` call.
75
81
  *
@@ -5,20 +5,7 @@ const mod_js_1 = require("./mod.js");
5
5
  const deps_node_js_1 = require("./deps.node.js");
6
6
  const array_js_1 = require("./utils/array.js");
7
7
  const set_bot_commands_js_1 = require("./utils/set-bot-commands.js");
8
- const isMiddleware = (obj) => {
9
- if (!obj)
10
- return false;
11
- if (Array.isArray(obj))
12
- return obj.every(isMiddleware);
13
- const objType = typeof obj;
14
- switch (objType) {
15
- case "function":
16
- return true;
17
- case "object":
18
- return Object.keys(obj).includes("middleware");
19
- }
20
- return false;
21
- };
8
+ const checks_js_1 = require("./utils/checks.js");
22
9
  /**
23
10
  * Central class that manages all registered commands.
24
11
  * This is the starting point for the plugin, and this is what you should pass to `bot.use` so your commands get properly registered.
@@ -34,6 +21,7 @@ const isMiddleware = (obj) => {
34
21
  */
35
22
  class CommandGroup {
36
23
  constructor(options = {}) {
24
+ var _a;
37
25
  this._languages = new Set();
38
26
  this._scopes = new Map();
39
27
  this._commands = [];
@@ -41,6 +29,9 @@ class CommandGroup {
41
29
  this._cachedComposerInvalidated = false;
42
30
  this._commandOptions = {};
43
31
  this._commandOptions = options;
32
+ if (((_a = this._commandOptions.prefix) === null || _a === void 0 ? void 0 : _a.trim()) === "") {
33
+ this._commandOptions.prefix = "/";
34
+ }
44
35
  }
45
36
  _addCommandToScope(scope, command) {
46
37
  var _a;
@@ -60,20 +51,27 @@ class CommandGroup {
60
51
  });
61
52
  }
62
53
  command(name, description, handlerOrOptions, _options) {
63
- var _a;
64
- const handler = isMiddleware(handlerOrOptions)
54
+ const handler = (0, checks_js_1.isMiddleware)(handlerOrOptions)
65
55
  ? handlerOrOptions
66
56
  : undefined;
67
- const options = handler
68
- ? _options !== null && _options !== void 0 ? _options : this._commandOptions
69
- : (_a = handlerOrOptions) !== null && _a !== void 0 ? _a : this._commandOptions;
70
- const command = new mod_js_1.Command(name, description, options);
71
- if (handler)
72
- command.addToScope({ type: "default" }, handler);
57
+ const options = !handler && (0, checks_js_1.isCommandOptions)(handlerOrOptions)
58
+ ? { ...this._commandOptions, ...handlerOrOptions }
59
+ : { ...this._commandOptions, ..._options };
60
+ const command = new mod_js_1.Command(name, description, handler, options);
73
61
  this._commands.push(command);
74
62
  this._cachedComposerInvalidated = true;
75
63
  return command;
76
64
  }
65
+ /**
66
+ * Registers a Command that was created by it's own.
67
+ *
68
+ * @param command the command or list of commands being added to the group
69
+ */
70
+ add(command) {
71
+ this._commands.push(...(0, array_js_1.ensureArray)(command));
72
+ this._cachedComposerInvalidated = true;
73
+ return this;
74
+ }
77
75
  /**
78
76
  * Serializes the commands into multiple objects that can each be passed to a `setMyCommands` call.
79
77
  *
package/out/command.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { type BotCommand, type BotCommandScope, type BotCommandScopeAllChatAdministrators, type BotCommandScopeAllGroupChats, type BotCommandScopeAllPrivateChats, type ChatTypeMiddleware, type Context, type LanguageCode, type Middleware, type MiddlewareObj } from "./deps.node.js";
1
+ import { type BotCommand, type BotCommandScope, type BotCommandScopeAllChatAdministrators, type BotCommandScopeAllGroupChats, type BotCommandScopeAllPrivateChats, type ChatTypeMiddleware, CommandContext, type Context, type LanguageCode, type Middleware, type MiddlewareObj } from "./deps.node.js";
2
2
  import type { CommandOptions } from "./types.js";
3
3
  import { type MaybeArray } from "./utils/array.js";
4
4
  type BotCommandGroupsScope = BotCommandScopeAllGroupChats | BotCommandScopeAllChatAdministrators;
5
- export declare const matchesPattern: (value: string, pattern: string | RegExp, ignoreCase?: boolean) => boolean;
6
5
  /**
7
6
  * Class that represents a single command and allows you to configure it.
8
7
  */
@@ -10,17 +9,46 @@ export declare class Command<C extends Context = Context> implements MiddlewareO
10
9
  private _scopes;
11
10
  private _languages;
12
11
  private _composer;
12
+ private _defaultScopeComposer;
13
13
  private _options;
14
14
  /**
15
- * Constructor for the `Command` class.
16
- * Do not call this directly. Instead, use the `command` method from the `Commands` class
15
+ * Initialize a new command with a default handler.
16
+ *
17
+ * [!IMPORTANT] This class by its own does nothing. It needs to be imported into a `CommandGroup`
18
+ * via the `add` method.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const sayHi = new Command("hi","say hi", (ctx) => ctx.reply("hi"))
23
+ * const myCmds = new CommandGroup().add(sayHi)
24
+ * ```
25
+ *
26
+ * @param name Default command name
27
+ * @param description Default command description
28
+ * @param handler Default command handler
29
+ * @param options Extra options that should apply only to this command
30
+ * @returns An instance of the `Command` class
31
+ */
32
+ constructor(name: string | RegExp, description: string, handler: MaybeArray<Middleware<CommandContext<C>>>, options?: Partial<CommandOptions>);
33
+ /**
34
+ * Initialize a new command with no handlers.
35
+ *
36
+ * [!IMPORTANT] This class by its own does nothing. It needs to be imported into a `CommandGroup`
37
+ * via the `add` method
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const sayHi = new Command("hi","say hi", (ctx) => ctx.reply("hi") )
42
+ * const myCmds = new CommandGroup().add(sayHi)
43
+ * ```
17
44
  *
18
45
  * @param name Default command name
19
46
  * @param description Default command description
20
- * @param options Options object that should apply to this command only
21
- * @access package
47
+ * @param options Extra options that should apply only to this command
48
+ * @returns An instance of the `Command` class
22
49
  */
23
50
  constructor(name: string | RegExp, description: string, options?: Partial<CommandOptions>);
51
+ constructor(name: string | RegExp, description: string, handlerOrOptions?: MaybeArray<Middleware<CommandContext<C>>> | Partial<CommandOptions>, options?: Partial<CommandOptions>);
24
52
  /**
25
53
  * Whether the command has a custom prefix
26
54
  */
@@ -86,9 +114,9 @@ export declare class Command<C extends Context = Context> implements MiddlewareO
86
114
  * @param middleware The handler for this command on the specified scope
87
115
  * @param options Additional options that should apply only to this scope
88
116
  */
89
- addToScope(scope: BotCommandGroupsScope, middleware: MaybeArray<ChatTypeMiddleware<C, "group" | "supergroup">>, options?: Partial<CommandOptions>): this;
90
- addToScope(scope: BotCommandScopeAllPrivateChats, middleware: MaybeArray<ChatTypeMiddleware<C, "private">>, options?: Partial<CommandOptions>): this;
91
- addToScope(scope: BotCommandScope, middleware: MaybeArray<Middleware<C>>, options?: Partial<CommandOptions>): this;
117
+ addToScope(scope: BotCommandGroupsScope, middleware?: MaybeArray<ChatTypeMiddleware<C, "group" | "supergroup">>, options?: Partial<CommandOptions>): this;
118
+ addToScope(scope: BotCommandScopeAllPrivateChats, middleware?: MaybeArray<ChatTypeMiddleware<C, "private">>, options?: Partial<CommandOptions>): this;
119
+ addToScope(scope: BotCommandScope, middleware?: MaybeArray<Middleware<C>>, options?: Partial<CommandOptions>): this;
92
120
  /**
93
121
  * Creates a matcher for the given command that can be used in filtering operations
94
122
  *
package/out/command.js CHANGED
@@ -1,50 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Command = exports.matchesPattern = void 0;
3
+ exports.Command = void 0;
4
4
  const deps_node_js_1 = require("./deps.node.js");
5
5
  const errors_js_1 = require("./utils/errors.js");
6
6
  const array_js_1 = require("./utils/array.js");
7
- const isAdmin = (ctx) => ctx
8
- .getAuthor()
9
- .then((author) => ["administrator", "creator"].includes(author.status));
10
- const matchesPattern = (value, pattern, ignoreCase = false) => {
11
- const transformedValue = ignoreCase ? value.toLowerCase() : value;
12
- const transformedPattern = pattern instanceof RegExp && ignoreCase && !pattern.flags.includes("i")
13
- ? new RegExp(pattern, pattern.flags + "i")
14
- : pattern;
15
- return typeof transformedPattern === "string"
16
- ? transformedValue === transformedPattern
17
- : transformedPattern.test(transformedValue);
18
- };
19
- exports.matchesPattern = matchesPattern;
7
+ const checks_js_1 = require("./utils/checks.js");
20
8
  const NOCASE_COMMAND_NAME_REGEX = /^[0-9a-z_]+$/i;
21
9
  /**
22
10
  * Class that represents a single command and allows you to configure it.
23
11
  */
24
12
  class Command {
25
- /**
26
- * Constructor for the `Command` class.
27
- * Do not call this directly. Instead, use the `command` method from the `Commands` class
28
- *
29
- * @param name Default command name
30
- * @param description Default command description
31
- * @param options Options object that should apply to this command only
32
- * @access package
33
- */
34
- constructor(name, description, options = {}) {
13
+ constructor(name, description, handlerOrOptions, options) {
14
+ var _a;
35
15
  this._scopes = [];
36
16
  this._languages = new Map();
37
17
  this._composer = new deps_node_js_1.Composer();
18
+ this._defaultScopeComposer = new deps_node_js_1.Composer();
38
19
  this._options = {
39
20
  prefix: "/",
40
21
  matchOnlyAtStart: true,
41
22
  targetedCommands: "optional",
42
23
  ignoreCase: false,
43
24
  };
25
+ const handler = (0, checks_js_1.isMiddleware)(handlerOrOptions)
26
+ ? handlerOrOptions
27
+ : undefined;
28
+ options = !handler && (0, checks_js_1.isCommandOptions)(handlerOrOptions)
29
+ ? handlerOrOptions
30
+ : options;
44
31
  this._options = { ...this._options, ...options };
45
- if (this._options.prefix === "")
32
+ if (((_a = this._options.prefix) === null || _a === void 0 ? void 0 : _a.trim()) === "")
46
33
  this._options.prefix = "/";
47
34
  this._languages.set("default", { name: name, description });
35
+ if (handler) {
36
+ this.addToScope({ type: "default" }, handler);
37
+ }
38
+ return this;
48
39
  }
49
40
  /**
50
41
  * Whether the command has a custom prefix
@@ -121,53 +112,55 @@ class Command {
121
112
  return this._options.prefix;
122
113
  }
123
114
  addToScope(scope, middleware, options = this._options) {
124
- const middlewareArray = (0, array_js_1.ensureArray)(middleware);
115
+ const middlewareArray = middleware ? (0, array_js_1.ensureArray)(middleware) : undefined;
125
116
  const optionsObject = { ...this._options, ...options };
126
- switch (scope.type) {
127
- case "default":
128
- this._composer
129
- .filter(Command.hasCommand(this.names, optionsObject))
130
- .use(...middlewareArray);
131
- break;
132
- case "all_chat_administrators":
133
- this._composer
134
- .filter(Command.hasCommand(this.names, optionsObject))
135
- .filter(isAdmin)
136
- .use(...middlewareArray);
137
- break;
138
- case "all_private_chats":
139
- this._composer
140
- .filter(Command.hasCommand(this.names, optionsObject))
141
- .chatType("private")
142
- .use(...middlewareArray);
143
- break;
144
- case "all_group_chats":
145
- this._composer
146
- .filter(Command.hasCommand(this.names, optionsObject))
147
- .chatType(["group", "supergroup"])
148
- .use(...middlewareArray);
149
- break;
150
- case "chat":
151
- case "chat_administrators":
152
- if (scope.chat_id) {
117
+ if (middlewareArray) {
118
+ switch (scope.type) {
119
+ case "default":
120
+ this._defaultScopeComposer
121
+ .filter(Command.hasCommand(this.names, optionsObject))
122
+ .use(...middlewareArray);
123
+ break;
124
+ case "all_chat_administrators":
153
125
  this._composer
154
126
  .filter(Command.hasCommand(this.names, optionsObject))
155
- .filter((ctx) => { var _a; return ((_a = ctx.chat) === null || _a === void 0 ? void 0 : _a.id) === scope.chat_id; })
156
- .filter(isAdmin)
127
+ .filter(checks_js_1.isAdmin)
157
128
  .use(...middlewareArray);
158
- }
159
- break;
160
- case "chat_member":
161
- if (scope.chat_id && scope.user_id) {
129
+ break;
130
+ case "all_private_chats":
162
131
  this._composer
163
132
  .filter(Command.hasCommand(this.names, optionsObject))
164
- .filter((ctx) => { var _a; return ((_a = ctx.chat) === null || _a === void 0 ? void 0 : _a.id) === scope.chat_id; })
165
- .filter((ctx) => { var _a; return ((_a = ctx.from) === null || _a === void 0 ? void 0 : _a.id) === scope.user_id; })
133
+ .chatType("private")
166
134
  .use(...middlewareArray);
167
- }
168
- break;
169
- default:
170
- throw new errors_js_1.InvalidScopeError(scope);
135
+ break;
136
+ case "all_group_chats":
137
+ this._composer
138
+ .filter(Command.hasCommand(this.names, optionsObject))
139
+ .chatType(["group", "supergroup"])
140
+ .use(...middlewareArray);
141
+ break;
142
+ case "chat":
143
+ case "chat_administrators":
144
+ if (scope.chat_id) {
145
+ this._composer
146
+ .filter(Command.hasCommand(this.names, optionsObject))
147
+ .filter((ctx) => { var _a; return ((_a = ctx.chat) === null || _a === void 0 ? void 0 : _a.id) === scope.chat_id; })
148
+ .filter(checks_js_1.isAdmin)
149
+ .use(...middlewareArray);
150
+ }
151
+ break;
152
+ case "chat_member":
153
+ if (scope.chat_id && scope.user_id) {
154
+ this._composer
155
+ .filter(Command.hasCommand(this.names, optionsObject))
156
+ .filter((ctx) => { var _a; return ((_a = ctx.chat) === null || _a === void 0 ? void 0 : _a.id) === scope.chat_id; })
157
+ .filter((ctx) => { var _a; return ((_a = ctx.from) === null || _a === void 0 ? void 0 : _a.id) === scope.user_id; })
158
+ .use(...middlewareArray);
159
+ }
160
+ break;
161
+ default:
162
+ throw new errors_js_1.InvalidScopeError(scope);
163
+ }
171
164
  }
172
165
  this._scopes.push(scope);
173
166
  return this;
@@ -208,7 +201,7 @@ class Command {
208
201
  continue;
209
202
  if (username && username !== ctx.me.username)
210
203
  continue;
211
- if (commandNames.some((name) => (0, exports.matchesPattern)(command.replace(prefix, ""), name, options.ignoreCase))) {
204
+ if (commandNames.some((name) => (0, checks_js_1.matchesPattern)(command.replace(prefix, ""), name, options.ignoreCase))) {
212
205
  return true;
213
206
  }
214
207
  }
@@ -271,7 +264,8 @@ class Command {
271
264
  };
272
265
  }
273
266
  middleware() {
274
- return this._composer.middleware();
267
+ return new deps_node_js_1.Composer(this._composer, this._defaultScopeComposer)
268
+ .middleware();
275
269
  }
276
270
  }
277
271
  exports.Command = Command;
@@ -0,0 +1,7 @@
1
+ import { Context, Middleware } from "../deps.node.js";
2
+ import { CommandOptions } from "../types.js";
3
+ import { MaybeArray } from "./array.js";
4
+ export declare function isAdmin(ctx: Context): Promise<boolean>;
5
+ export declare function isMiddleware<C extends Context = Context>(obj: unknown): obj is MaybeArray<Middleware<C>>;
6
+ export declare function isCommandOptions(obj: unknown): obj is Partial<CommandOptions>;
7
+ export declare function matchesPattern(value: string, pattern: string | RegExp, ignoreCase?: boolean): boolean;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.matchesPattern = exports.isCommandOptions = exports.isMiddleware = exports.isAdmin = void 0;
4
+ function isAdmin(ctx) {
5
+ return ctx
6
+ .getAuthor()
7
+ .then((author) => ["administrator", "creator"].includes(author.status));
8
+ }
9
+ exports.isAdmin = isAdmin;
10
+ function isMiddleware(obj) {
11
+ if (!obj)
12
+ return false;
13
+ if (Array.isArray(obj))
14
+ return obj.every(isMiddleware);
15
+ const objType = typeof obj;
16
+ switch (objType) {
17
+ case "function":
18
+ return true;
19
+ case "object":
20
+ return Object.keys(obj).includes("middleware");
21
+ }
22
+ return false;
23
+ }
24
+ exports.isMiddleware = isMiddleware;
25
+ function isCommandOptions(obj) {
26
+ if (typeof obj !== "object" || !obj)
27
+ return false;
28
+ const { prefix, matchOnlyAtStart, targetedCommands, ignoreCase } = obj;
29
+ if (typeof prefix === "string")
30
+ return true;
31
+ if (typeof matchOnlyAtStart === "boolean")
32
+ return true;
33
+ if (targetedCommands &&
34
+ ["ignored", "optional", "required"].includes(targetedCommands))
35
+ return true;
36
+ if (typeof ignoreCase === "boolean")
37
+ return true;
38
+ return false;
39
+ }
40
+ exports.isCommandOptions = isCommandOptions;
41
+ function matchesPattern(value, pattern, ignoreCase = false) {
42
+ const transformedValue = ignoreCase ? value.toLowerCase() : value;
43
+ const transformedPattern = pattern instanceof RegExp && ignoreCase && !pattern.flags.includes("i")
44
+ ? new RegExp(pattern, pattern.flags + "i")
45
+ : pattern;
46
+ return typeof transformedPattern === "string"
47
+ ? transformedValue === transformedPattern
48
+ : transformedPattern.test(transformedValue);
49
+ }
50
+ exports.matchesPattern = matchesPattern;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grammyjs/commands",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "grammY Commands Plugin",
5
5
  "main": "out/mod.js",
6
6
  "scripts": {