@grammyjs/commands 0.6.1 → 0.8.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.
- package/out/command.d.ts +14 -10
- package/out/command.js +15 -7
- package/out/commands.d.ts +30 -12
- package/out/commands.js +43 -6
- package/out/context.d.ts +80 -3
- package/out/context.js +115 -6
- package/out/deps.node.d.ts +2 -1
- package/out/deps.node.js +3 -1
- package/out/jaro-winkler.d.ts +12 -3
- package/out/jaro-winkler.js +22 -10
- package/out/types.d.ts +8 -0
- package/out/utils.d.ts +2 -0
- package/out/utils.js +5 -0
- package/package.json +2 -1
package/out/command.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type BotCommand, type BotCommandScope, type BotCommandScopeAllChatAdministrators, type BotCommandScopeAllGroupChats, type BotCommandScopeAllPrivateChats, type ChatTypeMiddleware, type Context, type Middleware, type MiddlewareObj } from "./deps.node.js";
|
|
2
|
-
import { CommandOptions } from "./types.js";
|
|
3
|
-
|
|
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";
|
|
2
|
+
import type { CommandOptions } from "./types.js";
|
|
3
|
+
import { type MaybeArray } from "./utils.js";
|
|
4
4
|
type BotCommandGroupsScope = BotCommandScopeAllGroupChats | BotCommandScopeAllChatAdministrators;
|
|
5
5
|
export declare const matchesPattern: (value: string, pattern: string | RegExp) => boolean;
|
|
6
6
|
/**
|
|
@@ -28,7 +28,7 @@ export declare class Command<C extends Context = Context> implements MiddlewareO
|
|
|
28
28
|
/**
|
|
29
29
|
* Get registered languages for this command
|
|
30
30
|
*/
|
|
31
|
-
get languages(): Map<
|
|
31
|
+
get languages(): Map<LanguageCode | "default", {
|
|
32
32
|
name: string | RegExp;
|
|
33
33
|
description: string;
|
|
34
34
|
}>;
|
|
@@ -44,6 +44,10 @@ export declare class Command<C extends Context = Context> implements MiddlewareO
|
|
|
44
44
|
* Get the default description for this command
|
|
45
45
|
*/
|
|
46
46
|
get description(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Get the prefix for this command
|
|
49
|
+
*/
|
|
50
|
+
get prefix(): string;
|
|
47
51
|
/**
|
|
48
52
|
* Registers the command to a scope to allow it to be handled and used with `setMyCommands`.
|
|
49
53
|
* This will automatically apply filtering middlewares for you, so the handler only runs on the specified scope.
|
|
@@ -76,7 +80,7 @@ export declare class Command<C extends Context = Context> implements MiddlewareO
|
|
|
76
80
|
* ```ts
|
|
77
81
|
* bot
|
|
78
82
|
* .filter(
|
|
79
|
-
* Command.hasCommand(
|
|
83
|
+
* Command.hasCommand(/delete_(.*)/),
|
|
80
84
|
* (ctx) => ctx.reply(`Deleting ${ctx.message?.text?.split("_")[1]}`)
|
|
81
85
|
* )
|
|
82
86
|
* ```
|
|
@@ -96,23 +100,23 @@ export declare class Command<C extends Context = Context> implements MiddlewareO
|
|
|
96
100
|
* .localize("pt", "iniciar", "Inicia a configuração do bot")
|
|
97
101
|
* ```
|
|
98
102
|
*
|
|
99
|
-
* @param languageCode Language this translation applies to
|
|
103
|
+
* @param languageCode Language this translation applies to. @see https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
|
|
100
104
|
* @param name Localized command name
|
|
101
105
|
* @param description Localized command description
|
|
102
106
|
*/
|
|
103
|
-
localize(languageCode:
|
|
107
|
+
localize(languageCode: LanguageCode, name: string | RegExp, description: string): this;
|
|
104
108
|
/**
|
|
105
109
|
* Gets the localized command name of an existing translation
|
|
106
110
|
* @param languageCode Language to get the name for
|
|
107
111
|
* @returns Localized command name
|
|
108
112
|
*/
|
|
109
|
-
getLocalizedName(languageCode:
|
|
113
|
+
getLocalizedName(languageCode: LanguageCode | "default"): string | RegExp;
|
|
110
114
|
/**
|
|
111
115
|
* Gets the localized command name of an existing translation
|
|
112
116
|
* @param languageCode Language to get the name for
|
|
113
117
|
* @returns Localized command name
|
|
114
118
|
*/
|
|
115
|
-
getLocalizedDescription(languageCode:
|
|
119
|
+
getLocalizedDescription(languageCode: LanguageCode | "default"): string;
|
|
116
120
|
/**
|
|
117
121
|
* Converts command to an object representation.
|
|
118
122
|
* Useful for JSON serialization.
|
|
@@ -120,7 +124,7 @@ export declare class Command<C extends Context = Context> implements MiddlewareO
|
|
|
120
124
|
* @param languageCode If specified, uses localized versions of the command name and description
|
|
121
125
|
* @returns Object representation of this command
|
|
122
126
|
*/
|
|
123
|
-
toObject(languageCode?:
|
|
127
|
+
toObject(languageCode?: LanguageCode | "default"): BotCommand;
|
|
124
128
|
middleware(): import("grammy").MiddlewareFn<C>;
|
|
125
129
|
}
|
|
126
130
|
export {};
|
package/out/command.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Command = exports.matchesPattern = void 0;
|
|
4
4
|
const deps_node_js_1 = require("./deps.node.js");
|
|
5
5
|
const errors_js_1 = require("./errors.js");
|
|
6
|
-
const
|
|
6
|
+
const utils_js_1 = require("./utils.js");
|
|
7
7
|
const isAdmin = (ctx) => ctx
|
|
8
8
|
.getAuthor()
|
|
9
9
|
.then((author) => ["administrator", "creator"].includes(author.status));
|
|
@@ -66,8 +66,14 @@ class Command {
|
|
|
66
66
|
get description() {
|
|
67
67
|
return this._languages.get("default").description;
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the prefix for this command
|
|
71
|
+
*/
|
|
72
|
+
get prefix() {
|
|
73
|
+
return this._options.prefix;
|
|
74
|
+
}
|
|
69
75
|
addToScope(scope, middleware, options = this._options) {
|
|
70
|
-
const middlewareArray = ensureArray(middleware);
|
|
76
|
+
const middlewareArray = (0, utils_js_1.ensureArray)(middleware);
|
|
71
77
|
const optionsObject = { ...this._options, ...options };
|
|
72
78
|
switch (scope.type) {
|
|
73
79
|
case "default":
|
|
@@ -125,7 +131,7 @@ class Command {
|
|
|
125
131
|
* ```ts
|
|
126
132
|
* bot
|
|
127
133
|
* .filter(
|
|
128
|
-
* Command.hasCommand(
|
|
134
|
+
* Command.hasCommand(/delete_(.*)/),
|
|
129
135
|
* (ctx) => ctx.reply(`Deleting ${ctx.message?.text?.split("_")[1]}`)
|
|
130
136
|
* )
|
|
131
137
|
* ```
|
|
@@ -142,7 +148,7 @@ class Command {
|
|
|
142
148
|
if (matchOnlyAtStart && !ctx.msg.text.startsWith(prefix)) {
|
|
143
149
|
return false;
|
|
144
150
|
}
|
|
145
|
-
const commandNames = ensureArray(command);
|
|
151
|
+
const commandNames = (0, utils_js_1.ensureArray)(command);
|
|
146
152
|
const commands = prefix === "/"
|
|
147
153
|
? ctx.entities("bot_command")
|
|
148
154
|
: ctx.msg.text.split(prefix).map((text) => ({ text }));
|
|
@@ -171,13 +177,13 @@ class Command {
|
|
|
171
177
|
* .localize("pt", "iniciar", "Inicia a configuração do bot")
|
|
172
178
|
* ```
|
|
173
179
|
*
|
|
174
|
-
* @param languageCode Language this translation applies to
|
|
180
|
+
* @param languageCode Language this translation applies to. @see https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
|
|
175
181
|
* @param name Localized command name
|
|
176
182
|
* @param description Localized command description
|
|
177
183
|
*/
|
|
178
184
|
localize(languageCode, name, description) {
|
|
179
185
|
this._languages.set(languageCode, {
|
|
180
|
-
name:
|
|
186
|
+
name: name,
|
|
181
187
|
description,
|
|
182
188
|
});
|
|
183
189
|
return this;
|
|
@@ -210,7 +216,9 @@ class Command {
|
|
|
210
216
|
toObject(languageCode = "default") {
|
|
211
217
|
const localizedName = this.getLocalizedName(languageCode);
|
|
212
218
|
return {
|
|
213
|
-
command: localizedName instanceof RegExp
|
|
219
|
+
command: localizedName instanceof RegExp
|
|
220
|
+
? localizedName.source
|
|
221
|
+
: localizedName,
|
|
214
222
|
description: this.getLocalizedDescription(languageCode),
|
|
215
223
|
};
|
|
216
224
|
}
|
package/out/commands.d.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import { Command
|
|
2
|
-
import { Api, BotCommand, BotCommandScope, CommandContext, Context, Middleware } from "./deps.node.js";
|
|
3
|
-
import { CommandOptions } from "./types.js";
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Command } from "./command.js";
|
|
2
|
+
import { Api, BotCommand, BotCommandScope, CommandContext, Context, type LanguageCode, Middleware } from "./deps.node.js";
|
|
3
|
+
import type { CommandElementals, CommandOptions } from "./types.js";
|
|
4
|
+
import { type MaybeArray } from "./utils.js";
|
|
5
|
+
/**
|
|
6
|
+
* Interface for grouping {@link BotCommand}s that might (or not)
|
|
7
|
+
* be related to each other by scope and/or language.
|
|
8
|
+
*/
|
|
9
|
+
export type SetMyCommandsParams = {
|
|
10
|
+
/** If defined: scope on which the commands will take effect */
|
|
8
11
|
scope?: BotCommandScope;
|
|
9
|
-
|
|
12
|
+
/** If defined: Language on which the commands will take effect.
|
|
13
|
+
* Two letter abbreviation in ISO_639 standard: https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
|
|
14
|
+
*/
|
|
15
|
+
language_code?: LanguageCode;
|
|
16
|
+
/** Commands that can be each one passed to a SetMyCommands Call */
|
|
10
17
|
commands: BotCommand[];
|
|
11
18
|
};
|
|
12
19
|
/**
|
|
@@ -51,7 +58,6 @@ export declare class Commands<C extends Context> {
|
|
|
51
58
|
command(name: string | RegExp, description: string, options?: Partial<CommandOptions>): Command<C>;
|
|
52
59
|
/**
|
|
53
60
|
* Serializes the commands into multiple objects that can each be passed to a `setMyCommands` call.
|
|
54
|
-
*
|
|
55
61
|
* @returns One item for each combination of command + scope + language
|
|
56
62
|
*/
|
|
57
63
|
toArgs(): SetMyCommandsParams[];
|
|
@@ -66,19 +72,31 @@ export declare class Commands<C extends Context> {
|
|
|
66
72
|
* Registers all commands to be displayed by clients according to their scopes and languages
|
|
67
73
|
* Calls `setMyCommands` for each language of each scope of each command.
|
|
68
74
|
*
|
|
75
|
+
* [!IMPORTANT]
|
|
76
|
+
* Calling this method with upperCased command names registered, will throw
|
|
77
|
+
* @see https://core.telegram.org/bots/api#botcommand
|
|
78
|
+
* @see https://core.telegram.org/method/bots.setBotCommands
|
|
79
|
+
*
|
|
69
80
|
* @param Instance of `bot` or { api: bot.api }
|
|
70
81
|
*/
|
|
71
82
|
setCommands({ api }: {
|
|
72
83
|
api: Api;
|
|
73
84
|
}): Promise<void>;
|
|
74
85
|
/**
|
|
75
|
-
*
|
|
86
|
+
* Serialize all register commands into it's name, prefix and language
|
|
87
|
+
*
|
|
88
|
+
* @param filterLanguage if undefined, it returns all names
|
|
89
|
+
* else get only the locales for the given filterLanguage
|
|
90
|
+
* fallbacks to "default"
|
|
91
|
+
*
|
|
92
|
+
* @returns an array of {@link CommandElementals}
|
|
93
|
+
*
|
|
94
|
+
* Note: mainly used to serialize for {@link FuzzyMatch}
|
|
76
95
|
*/
|
|
77
|
-
|
|
96
|
+
toElementals(filterLanguage?: LanguageCode | "default"): CommandElementals[];
|
|
78
97
|
/**
|
|
79
98
|
* @returns A JSON serialized version of all the currently registered commands
|
|
80
99
|
*/
|
|
81
100
|
toString(): string;
|
|
82
101
|
middleware(): import("grammy").MiddlewareFn<C>;
|
|
83
102
|
}
|
|
84
|
-
export {};
|
package/out/commands.js
CHANGED
|
@@ -77,7 +77,6 @@ class Commands {
|
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
79
|
* Serializes the commands into multiple objects that can each be passed to a `setMyCommands` call.
|
|
80
|
-
*
|
|
81
80
|
* @returns One item for each combination of command + scope + language
|
|
82
81
|
*/
|
|
83
82
|
toArgs() {
|
|
@@ -90,8 +89,9 @@ class Commands {
|
|
|
90
89
|
language_code: language === "default"
|
|
91
90
|
? undefined
|
|
92
91
|
: language,
|
|
93
|
-
commands: commands
|
|
94
|
-
.filter((
|
|
92
|
+
commands: commands
|
|
93
|
+
.filter((command) => typeof command.name === "string")
|
|
94
|
+
.map((command) => command.toObject(language)),
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -112,6 +112,7 @@ class Commands {
|
|
|
112
112
|
language_code: language === "default" ? undefined : language,
|
|
113
113
|
commands: this._commands
|
|
114
114
|
.filter((command) => command.scopes.length)
|
|
115
|
+
.filter((command) => typeof command.name === "string")
|
|
115
116
|
.map((command) => command.toObject(language)),
|
|
116
117
|
});
|
|
117
118
|
}
|
|
@@ -121,16 +122,52 @@ class Commands {
|
|
|
121
122
|
* Registers all commands to be displayed by clients according to their scopes and languages
|
|
122
123
|
* Calls `setMyCommands` for each language of each scope of each command.
|
|
123
124
|
*
|
|
125
|
+
* [!IMPORTANT]
|
|
126
|
+
* Calling this method with upperCased command names registered, will throw
|
|
127
|
+
* @see https://core.telegram.org/bots/api#botcommand
|
|
128
|
+
* @see https://core.telegram.org/method/bots.setBotCommands
|
|
129
|
+
*
|
|
124
130
|
* @param Instance of `bot` or { api: bot.api }
|
|
125
131
|
*/
|
|
126
132
|
async setCommands({ api }) {
|
|
127
133
|
await Promise.all(this.toArgs().map((args) => api.raw.setMyCommands(args)));
|
|
128
134
|
}
|
|
129
135
|
/**
|
|
130
|
-
*
|
|
136
|
+
* Serialize all register commands into it's name, prefix and language
|
|
137
|
+
*
|
|
138
|
+
* @param filterLanguage if undefined, it returns all names
|
|
139
|
+
* else get only the locales for the given filterLanguage
|
|
140
|
+
* fallbacks to "default"
|
|
141
|
+
*
|
|
142
|
+
* @returns an array of {@link CommandElementals}
|
|
143
|
+
*
|
|
144
|
+
* Note: mainly used to serialize for {@link FuzzyMatch}
|
|
131
145
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
146
|
+
toElementals(filterLanguage) {
|
|
147
|
+
this._populateMetadata();
|
|
148
|
+
return Array.from(this._scopes.values())
|
|
149
|
+
.flat()
|
|
150
|
+
.flatMap((command) => {
|
|
151
|
+
const elements = [];
|
|
152
|
+
for (const [language, local] of command.languages.entries()) {
|
|
153
|
+
elements.push({
|
|
154
|
+
name: local.name instanceof RegExp
|
|
155
|
+
? local.name.source
|
|
156
|
+
: local.name,
|
|
157
|
+
language,
|
|
158
|
+
prefix: command.prefix,
|
|
159
|
+
scopes: command.scopes,
|
|
160
|
+
description: command.getLocalizedDescription(language),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if (filterLanguage) {
|
|
164
|
+
const filtered = elements.filter((command) => command.language === filterLanguage);
|
|
165
|
+
const defaulted = elements.filter((command) => command.language === "default");
|
|
166
|
+
return filtered.length ? filtered[0] : defaulted[0];
|
|
167
|
+
}
|
|
168
|
+
else
|
|
169
|
+
return elements;
|
|
170
|
+
});
|
|
134
171
|
}
|
|
135
172
|
/**
|
|
136
173
|
* @returns A JSON serialized version of all the currently registered commands
|
package/out/context.d.ts
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
import { Commands } from "./commands.js";
|
|
2
|
-
import { Context, NextFunction } from "./deps.node.js";
|
|
2
|
+
import { BotCommandScopeChat, Context, NextFunction } from "./deps.node.js";
|
|
3
3
|
import { JaroWinklerOptions } from "./jaro-winkler.js";
|
|
4
|
+
import { SetMyCommandsParams } from "./mod.js";
|
|
4
5
|
export interface CommandsFlavor<C extends Context = Context> extends Context {
|
|
5
6
|
/**
|
|
6
7
|
* Sets the provided commands for the current chat.
|
|
7
8
|
* Cannot be called on updates that don't have a `chat` property.
|
|
8
9
|
*
|
|
10
|
+
* [!IMPORTANT]
|
|
11
|
+
* Calling this method with upperCased command names registered, will throw
|
|
12
|
+
* @see https://core.telegram.org/bots/api#botcommand
|
|
13
|
+
* @see https://core.telegram.org/method/bots.setBotCommands
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* bot.hears("sudo", (ctx) =>
|
|
18
|
+
* ctx.setMyCommands(userCommands, adminCommands));
|
|
19
|
+
* bot.hears("logout", (ctx) =>
|
|
20
|
+
* ctx.setMyCommands(userCommands));
|
|
21
|
+
* bot.hears("example", (ctx) =>
|
|
22
|
+
* ctx.setMyCommands([aCommands, bCommands, cCommands]));
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
9
25
|
* @param commands List of available commands
|
|
10
26
|
* @returns Promise with the result of the operations
|
|
11
27
|
*/
|
|
12
|
-
setMyCommands: (commands: Commands<C>) => Promise<void>;
|
|
28
|
+
setMyCommands: (commands: Commands<C> | Commands<C>[], ...moreCommands: Commands<C>[]) => Promise<void>;
|
|
13
29
|
/**
|
|
14
30
|
* Returns the nearest command to the user input.
|
|
15
31
|
* If no command is found, returns `null`.
|
|
@@ -18,9 +34,70 @@ export interface CommandsFlavor<C extends Context = Context> extends Context {
|
|
|
18
34
|
* @param options Options for the Jaro-Winkler algorithm
|
|
19
35
|
* @returns The nearest command or `null`
|
|
20
36
|
*/
|
|
21
|
-
getNearestCommand: (commands: Commands<C
|
|
37
|
+
getNearestCommand: (commands: Commands<C> | Commands<C>[], options?: Omit<Partial<JaroWinklerOptions>, "language">) => string | null;
|
|
22
38
|
}
|
|
23
39
|
/**
|
|
24
40
|
* Installs the commands flavor into the context.
|
|
25
41
|
*/
|
|
26
42
|
export declare function commands<C extends Context>(): (ctx: CommandsFlavor<C>, next: NextFunction) => Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Static class for getting and manipulating {@link SetMyCommandsParams}.
|
|
45
|
+
* The main function is {@link from}
|
|
46
|
+
*/
|
|
47
|
+
export declare class MyCommandParams {
|
|
48
|
+
/**
|
|
49
|
+
* Merges and serialize one or more Commands instances into a single array
|
|
50
|
+
* of commands params that can be used to set the commands menu displayed to the user.
|
|
51
|
+
* @example
|
|
52
|
+
```ts
|
|
53
|
+
const adminCommands = new Commands();
|
|
54
|
+
const userCommands = new Commands();
|
|
55
|
+
adminCommands
|
|
56
|
+
.command("do a",
|
|
57
|
+
"a description",
|
|
58
|
+
(ctx) => ctx.doA());
|
|
59
|
+
userCommands
|
|
60
|
+
.command("do b",
|
|
61
|
+
"b description",
|
|
62
|
+
(ctx) => ctx.doB());
|
|
63
|
+
const mergedParams =
|
|
64
|
+
MyCommandParams.from([a, b], someChatId);
|
|
65
|
+
```
|
|
66
|
+
* @param commands An array of one or more Commands instances.
|
|
67
|
+
* @returns an array of {@link SetMyCommandsParams} grouped by language
|
|
68
|
+
*/
|
|
69
|
+
static from<C extends Context>(commands: Commands<C>[], chat_id: BotCommandScopeChat["chat_id"]): SetMyCommandsParams[];
|
|
70
|
+
/**
|
|
71
|
+
* Serializes one or multiple {@link Commands} instances, each one into their respective
|
|
72
|
+
* single scoped SetMyCommandsParams version.
|
|
73
|
+
* @example
|
|
74
|
+
```ts
|
|
75
|
+
const adminCommands = new Commands();
|
|
76
|
+
// add to scope, localize, etc
|
|
77
|
+
const userCommands = new Commands();
|
|
78
|
+
// add to scope, localize, etc
|
|
79
|
+
const [
|
|
80
|
+
singleScopedAdminParams,
|
|
81
|
+
singleScopedUserParams
|
|
82
|
+
] = MyCommandsParams.serialize([adminCommands,userCommands])
|
|
83
|
+
```
|
|
84
|
+
* @param commandsArr an array of one or more commands instances
|
|
85
|
+
* @param chat_id the chat id relative to the message update, coming from the ctx object.
|
|
86
|
+
* @returns an array of scoped {@link SetMyCommandsParams} mapped from their respective Commands instances
|
|
87
|
+
*/
|
|
88
|
+
static _serialize<C extends Context>(commandsArr: Commands<C>[], chat_id: BotCommandScopeChat["chat_id"]): SetMyCommandsParams[][];
|
|
89
|
+
/**
|
|
90
|
+
* Lexicographically sorts commandParams based on their language code.
|
|
91
|
+
* @returns the sorted array
|
|
92
|
+
*/
|
|
93
|
+
static _sortByLanguage(params: SetMyCommandsParams[]): SetMyCommandsParams[];
|
|
94
|
+
/**
|
|
95
|
+
* Iterates over an array of CommandsParams
|
|
96
|
+
* merging their respective {@link SetMyCommandsParams.commands}
|
|
97
|
+
* when they are from the same language, separating when they are not.
|
|
98
|
+
*
|
|
99
|
+
* @param params a flattened array of commands params coming from one or more Commands instances
|
|
100
|
+
* @returns an array containing all commands grouped by language
|
|
101
|
+
*/
|
|
102
|
+
private static mergeByLanguage;
|
|
103
|
+
}
|
package/out/context.js
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.commands = void 0;
|
|
3
|
+
exports.MyCommandParams = exports.commands = void 0;
|
|
4
4
|
const jaro_winkler_js_1 = require("./jaro-winkler.js");
|
|
5
|
+
const utils_js_1 = require("./utils.js");
|
|
5
6
|
/**
|
|
6
7
|
* Installs the commands flavor into the context.
|
|
7
8
|
*/
|
|
8
9
|
function commands() {
|
|
9
10
|
return (ctx, next) => {
|
|
10
|
-
ctx.setMyCommands = async (commands) => {
|
|
11
|
+
ctx.setMyCommands = async (commands, ...moreCommands) => {
|
|
11
12
|
if (!ctx.chat) {
|
|
12
13
|
throw new Error("cannot call `ctx.setMyCommands` on an update with no `chat` property");
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
commands = (0, utils_js_1.ensureArray)(commands).concat(moreCommands);
|
|
16
|
+
await Promise.all(MyCommandParams.from(commands, ctx.chat.id)
|
|
16
17
|
.map((args) => ctx.api.raw.setMyCommands(args)));
|
|
17
18
|
};
|
|
18
19
|
ctx.getNearestCommand = (commands, options) => {
|
|
19
20
|
var _a;
|
|
20
21
|
if ((_a = ctx.msg) === null || _a === void 0 ? void 0 : _a.text) {
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
commands = (0, utils_js_1.ensureArray)(commands);
|
|
23
|
+
const results = commands.map((commands) => {
|
|
24
|
+
var _a;
|
|
25
|
+
const userInput = ctx.msg.text.substring(1);
|
|
26
|
+
const result = (0, jaro_winkler_js_1.fuzzyMatch)(userInput, commands, {
|
|
27
|
+
...options,
|
|
28
|
+
language: !(options === null || options === void 0 ? void 0 : options.ignoreLocalization)
|
|
29
|
+
? (_a = ctx.from) === null || _a === void 0 ? void 0 : _a.language_code
|
|
30
|
+
: undefined,
|
|
31
|
+
});
|
|
32
|
+
return result;
|
|
33
|
+
}).sort((a, b) => { var _a, _b; return ((_a = b === null || b === void 0 ? void 0 : b.similarity) !== null && _a !== void 0 ? _a : 0) - ((_b = a === null || a === void 0 ? void 0 : a.similarity) !== null && _b !== void 0 ? _b : 0); });
|
|
34
|
+
const result = results[0];
|
|
35
|
+
if (!result || !result.command)
|
|
36
|
+
return null;
|
|
37
|
+
return result.command.prefix + result.command.name;
|
|
23
38
|
}
|
|
24
39
|
return null;
|
|
25
40
|
};
|
|
@@ -27,3 +42,97 @@ function commands() {
|
|
|
27
42
|
};
|
|
28
43
|
}
|
|
29
44
|
exports.commands = commands;
|
|
45
|
+
/**
|
|
46
|
+
* Static class for getting and manipulating {@link SetMyCommandsParams}.
|
|
47
|
+
* The main function is {@link from}
|
|
48
|
+
*/
|
|
49
|
+
class MyCommandParams {
|
|
50
|
+
/**
|
|
51
|
+
* Merges and serialize one or more Commands instances into a single array
|
|
52
|
+
* of commands params that can be used to set the commands menu displayed to the user.
|
|
53
|
+
* @example
|
|
54
|
+
```ts
|
|
55
|
+
const adminCommands = new Commands();
|
|
56
|
+
const userCommands = new Commands();
|
|
57
|
+
adminCommands
|
|
58
|
+
.command("do a",
|
|
59
|
+
"a description",
|
|
60
|
+
(ctx) => ctx.doA());
|
|
61
|
+
userCommands
|
|
62
|
+
.command("do b",
|
|
63
|
+
"b description",
|
|
64
|
+
(ctx) => ctx.doB());
|
|
65
|
+
const mergedParams =
|
|
66
|
+
MyCommandParams.from([a, b], someChatId);
|
|
67
|
+
```
|
|
68
|
+
* @param commands An array of one or more Commands instances.
|
|
69
|
+
* @returns an array of {@link SetMyCommandsParams} grouped by language
|
|
70
|
+
*/
|
|
71
|
+
static from(commands, chat_id) {
|
|
72
|
+
const commandsParams = this._serialize(commands, chat_id).flat();
|
|
73
|
+
if (!commandsParams.length)
|
|
74
|
+
return [];
|
|
75
|
+
return this.mergeByLanguage(commandsParams);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Serializes one or multiple {@link Commands} instances, each one into their respective
|
|
79
|
+
* single scoped SetMyCommandsParams version.
|
|
80
|
+
* @example
|
|
81
|
+
```ts
|
|
82
|
+
const adminCommands = new Commands();
|
|
83
|
+
// add to scope, localize, etc
|
|
84
|
+
const userCommands = new Commands();
|
|
85
|
+
// add to scope, localize, etc
|
|
86
|
+
const [
|
|
87
|
+
singleScopedAdminParams,
|
|
88
|
+
singleScopedUserParams
|
|
89
|
+
] = MyCommandsParams.serialize([adminCommands,userCommands])
|
|
90
|
+
```
|
|
91
|
+
* @param commandsArr an array of one or more commands instances
|
|
92
|
+
* @param chat_id the chat id relative to the message update, coming from the ctx object.
|
|
93
|
+
* @returns an array of scoped {@link SetMyCommandsParams} mapped from their respective Commands instances
|
|
94
|
+
*/
|
|
95
|
+
static _serialize(commandsArr, chat_id) {
|
|
96
|
+
return commandsArr.map((commands) => commands.toSingleScopeArgs({
|
|
97
|
+
type: "chat",
|
|
98
|
+
chat_id,
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Lexicographically sorts commandParams based on their language code.
|
|
103
|
+
* @returns the sorted array
|
|
104
|
+
*/
|
|
105
|
+
static _sortByLanguage(params) {
|
|
106
|
+
return params.sort((a, b) => {
|
|
107
|
+
if (!a.language_code)
|
|
108
|
+
return -1;
|
|
109
|
+
if (!b.language_code)
|
|
110
|
+
return 1;
|
|
111
|
+
return a.language_code.localeCompare(b.language_code);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Iterates over an array of CommandsParams
|
|
116
|
+
* merging their respective {@link SetMyCommandsParams.commands}
|
|
117
|
+
* when they are from the same language, separating when they are not.
|
|
118
|
+
*
|
|
119
|
+
* @param params a flattened array of commands params coming from one or more Commands instances
|
|
120
|
+
* @returns an array containing all commands grouped by language
|
|
121
|
+
*/
|
|
122
|
+
static mergeByLanguage(params) {
|
|
123
|
+
const sorted = this._sortByLanguage(params);
|
|
124
|
+
return sorted.reduce((result, current, i, arr) => {
|
|
125
|
+
if (i === 0 || current.language_code !== arr[i - 1].language_code) {
|
|
126
|
+
result.push(current);
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
result[result.length - 1].commands = result[result.length - 1]
|
|
131
|
+
.commands
|
|
132
|
+
.concat(current.commands);
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
}, []);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.MyCommandParams = MyCommandParams;
|
package/out/deps.node.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { Api, Bot, type ChatTypeContext, type ChatTypeMiddleware, type CommandContext, type CommandMiddleware, Composer, Context, type Middleware, type MiddlewareObj, type NextFunction, } from "grammy";
|
|
2
|
-
export type { BotCommand, BotCommandScope, BotCommandScopeAllChatAdministrators, BotCommandScopeAllGroupChats, BotCommandScopeAllPrivateChats, Chat, } from "
|
|
2
|
+
export type { BotCommand, BotCommandScope, BotCommandScopeAllChatAdministrators, BotCommandScopeAllGroupChats, BotCommandScopeAllPrivateChats, BotCommandScopeChat, Chat, LanguageCode, } from "@grammyjs/types";
|
|
3
|
+
export { LanguageCodes } from "@grammyjs/types";
|
package/out/deps.node.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Context = exports.Composer = exports.Bot = exports.Api = void 0;
|
|
3
|
+
exports.LanguageCodes = exports.Context = exports.Composer = exports.Bot = exports.Api = void 0;
|
|
4
4
|
var grammy_1 = require("grammy");
|
|
5
5
|
Object.defineProperty(exports, "Api", { enumerable: true, get: function () { return grammy_1.Api; } });
|
|
6
6
|
Object.defineProperty(exports, "Bot", { enumerable: true, get: function () { return grammy_1.Bot; } });
|
|
7
7
|
Object.defineProperty(exports, "Composer", { enumerable: true, get: function () { return grammy_1.Composer; } });
|
|
8
8
|
Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return grammy_1.Context; } });
|
|
9
|
+
var types_1 = require("@grammyjs/types");
|
|
10
|
+
Object.defineProperty(exports, "LanguageCodes", { enumerable: true, get: function () { return types_1.LanguageCodes; } });
|
package/out/jaro-winkler.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { Commands } from "./commands.js";
|
|
2
|
-
import { Context } from "./deps.node.js";
|
|
2
|
+
import { Context, LanguageCode } from "./deps.node.js";
|
|
3
|
+
import type { CommandElementals } from "./types.js";
|
|
3
4
|
export declare function distance(s1: string, s2: string): number;
|
|
4
5
|
export type JaroWinklerOptions = {
|
|
5
6
|
ignoreCase?: boolean;
|
|
6
7
|
similarityThreshold?: number;
|
|
8
|
+
language?: LanguageCode | string;
|
|
9
|
+
ignoreLocalization?: boolean;
|
|
7
10
|
};
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
type CommandSimilarity = {
|
|
12
|
+
command: CommandElementals | null;
|
|
13
|
+
similarity: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function JaroWinklerDistance(s1: string, s2: string, options: Pick<Partial<JaroWinklerOptions>, "ignoreCase">): number;
|
|
16
|
+
export declare function isLanguageCode(value: string | undefined): value is LanguageCode;
|
|
17
|
+
export declare function fuzzyMatch<C extends Context>(userInput: string, commands: Commands<C>, options: Partial<JaroWinklerOptions>): CommandSimilarity | null;
|
|
18
|
+
export {};
|
package/out/jaro-winkler.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fuzzyMatch = exports.JaroWinklerDistance = exports.distance = void 0;
|
|
3
|
+
exports.fuzzyMatch = exports.isLanguageCode = exports.JaroWinklerDistance = exports.distance = void 0;
|
|
4
|
+
const deps_node_js_1 = require("./deps.node.js");
|
|
4
5
|
function distance(s1, s2) {
|
|
5
6
|
if (s1.length === 0 || s2.length === 0) {
|
|
6
7
|
return 0;
|
|
@@ -87,23 +88,34 @@ function JaroWinklerDistance(s1, s2, options) {
|
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
exports.JaroWinklerDistance = JaroWinklerDistance;
|
|
91
|
+
function isLanguageCode(value) {
|
|
92
|
+
return Object.values(deps_node_js_1.LanguageCodes).includes(value);
|
|
93
|
+
}
|
|
94
|
+
exports.isLanguageCode = isLanguageCode;
|
|
90
95
|
function fuzzyMatch(userInput, commands, options) {
|
|
91
|
-
|
|
96
|
+
var _a;
|
|
97
|
+
const defaultSimilarityThreshold = 0.82;
|
|
92
98
|
const similarityThreshold = options.similarityThreshold ||
|
|
93
99
|
defaultSimilarityThreshold;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
/**
|
|
101
|
+
* ctx.from.id is IETF
|
|
102
|
+
* https://en.wikipedia.org/wiki/IETF_language_tag
|
|
103
|
+
*/
|
|
104
|
+
const possiblyISO639 = (_a = options.language) === null || _a === void 0 ? void 0 : _a.split("-")[0];
|
|
105
|
+
const language = isLanguageCode(possiblyISO639)
|
|
106
|
+
? possiblyISO639
|
|
107
|
+
: undefined;
|
|
108
|
+
const cmds = options.ignoreLocalization
|
|
109
|
+
? commands.toElementals()
|
|
110
|
+
: commands.toElementals(language);
|
|
111
|
+
const bestMatch = cmds.reduce((best, command) => {
|
|
112
|
+
const similarity = JaroWinklerDistance(userInput, command.name, {
|
|
99
113
|
...options,
|
|
100
114
|
});
|
|
101
115
|
return similarity > best.similarity
|
|
102
116
|
? { command, similarity }
|
|
103
117
|
: best;
|
|
104
118
|
}, { command: null, similarity: 0 });
|
|
105
|
-
return bestMatch.similarity > similarityThreshold
|
|
106
|
-
? bestMatch.command
|
|
107
|
-
: null;
|
|
119
|
+
return bestMatch.similarity > similarityThreshold ? bestMatch : null;
|
|
108
120
|
}
|
|
109
121
|
exports.fuzzyMatch = fuzzyMatch;
|
package/out/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BotCommandScope, LanguageCode } from "./deps.node.js";
|
|
1
2
|
/**
|
|
2
3
|
* Supported command options
|
|
3
4
|
*/
|
|
@@ -22,3 +23,10 @@ export interface CommandOptions {
|
|
|
22
23
|
*/
|
|
23
24
|
targetedCommands: "ignored" | "optional" | "required";
|
|
24
25
|
}
|
|
26
|
+
export interface CommandElementals {
|
|
27
|
+
name: string;
|
|
28
|
+
prefix: string;
|
|
29
|
+
language: LanguageCode | "default";
|
|
30
|
+
scopes: BotCommandScope[];
|
|
31
|
+
description: string;
|
|
32
|
+
}
|
package/out/utils.d.ts
ADDED
package/out/utils.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grammyjs/commands",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "grammY Commands Plugin",
|
|
5
5
|
"main": "out/mod.js",
|
|
6
6
|
"scripts": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"author": "Roz <roz@rjmunhoz.me>",
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"dependencies": {
|
|
19
|
+
"@grammyjs/types": "^3.8.1",
|
|
19
20
|
"grammy": "^1.17.1",
|
|
20
21
|
"ts-pattern": "^5.0.1"
|
|
21
22
|
},
|