@pachca/cli 2026.3.8 → 2026.3.10
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/CHANGELOG.md +12 -0
- package/dist/base-command.js +1 -43
- package/dist/commands/auth/list.js +0 -1
- package/dist/commands/auth/login.js +0 -9
- package/dist/commands/auth/status.js +0 -10
- package/dist/commands/bots/list-events.js +0 -1
- package/dist/commands/bots/remove-event.js +0 -1
- package/dist/commands/bots/update.js +0 -1
- package/dist/commands/chats/archive.js +0 -1
- package/dist/commands/chats/create.js +0 -1
- package/dist/commands/chats/get.js +0 -1
- package/dist/commands/chats/list.js +8 -9
- package/dist/commands/chats/unarchive.js +0 -1
- package/dist/commands/chats/update.js +0 -1
- package/dist/commands/commands.js +5 -12
- package/dist/commands/common/custom-properties.js +0 -1
- package/dist/commands/common/get-exports.js +0 -1
- package/dist/commands/common/request-export.js +0 -1
- package/dist/commands/common/uploads.js +0 -1
- package/dist/commands/group-tags/create.js +0 -1
- package/dist/commands/group-tags/delete.js +0 -1
- package/dist/commands/group-tags/get.js +0 -1
- package/dist/commands/group-tags/list-users.js +0 -1
- package/dist/commands/group-tags/list.js +0 -1
- package/dist/commands/group-tags/update.js +0 -1
- package/dist/commands/link-previews/add.js +0 -1
- package/dist/commands/members/add-group-tags.js +0 -1
- package/dist/commands/members/add.js +0 -1
- package/dist/commands/members/leave.js +0 -1
- package/dist/commands/members/list.js +0 -1
- package/dist/commands/members/remove-group-tag.js +0 -1
- package/dist/commands/members/remove.js +0 -1
- package/dist/commands/members/update.js +0 -1
- package/dist/commands/messages/create.js +9 -4
- package/dist/commands/messages/delete.js +0 -1
- package/dist/commands/messages/get.js +0 -1
- package/dist/commands/messages/list.js +9 -5
- package/dist/commands/messages/pin.js +0 -1
- package/dist/commands/messages/unpin.js +0 -1
- package/dist/commands/messages/update.js +0 -1
- package/dist/commands/profile/delete-status.js +0 -1
- package/dist/commands/profile/get-status.js +0 -1
- package/dist/commands/profile/get.js +0 -1
- package/dist/commands/profile/update-status.js +0 -1
- package/dist/commands/reactions/add.js +0 -1
- package/dist/commands/reactions/list.js +0 -1
- package/dist/commands/reactions/remove.js +0 -1
- package/dist/commands/read-member/list-readers.js +0 -1
- package/dist/commands/search/list-chats.js +0 -1
- package/dist/commands/search/list-messages.js +0 -1
- package/dist/commands/search/list-users.js +0 -1
- package/dist/commands/security/list.js +0 -30
- package/dist/commands/tasks/create.js +0 -1
- package/dist/commands/tasks/delete.js +0 -1
- package/dist/commands/tasks/get.js +0 -1
- package/dist/commands/tasks/list.js +0 -1
- package/dist/commands/tasks/update.js +0 -1
- package/dist/commands/threads/add.js +0 -1
- package/dist/commands/threads/get.js +0 -1
- package/dist/commands/upload.js +0 -1
- package/dist/commands/users/create.js +0 -1
- package/dist/commands/users/delete.js +0 -1
- package/dist/commands/users/get-status.js +0 -1
- package/dist/commands/users/get.js +0 -1
- package/dist/commands/users/list.js +0 -1
- package/dist/commands/users/remove-status.js +0 -1
- package/dist/commands/users/update-status.js +0 -1
- package/dist/commands/users/update.js +0 -1
- package/dist/commands/views/open.js +0 -1
- package/dist/data/changelog.json +42 -0
- package/dist/hooks/init.js +1 -20
- package/dist/profiles.js +0 -8
- package/oclif.manifest.json +1 -12709
- package/package.json +1 -1
- package/dist/commands/auth/refresh.js +0 -67
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026.3.10 (21 марта 2026)
|
|
4
|
+
|
|
5
|
+
- **Изменено** (messages create): Поле link_preview перемещено на верхний уровень тела запроса (раньше было внутри message)
|
|
6
|
+
- **Изменено** (security list): Параметры start-time и end-time стали необязательными
|
|
7
|
+
- **Изменено** (chats list, messages list): Сортировка через --sort и --order вместо --sort-id и --sort-last-message-at
|
|
8
|
+
|
|
9
|
+
## 2026.3.9 (19 марта 2026)
|
|
10
|
+
|
|
11
|
+
- **Изменено** (all): Убрана клиентская валидация скоупов — проверка разрешений теперь только на стороне API (403)
|
|
12
|
+
- **Изменено** (auth login): Профиль больше не сохраняет список скоупов — только тип, имя и email
|
|
13
|
+
- **Удалено** (auth refresh): Команда удалена — кеширование скоупов больше не используется
|
|
14
|
+
|
|
3
15
|
## 2026.3.8 (17 марта 2026)
|
|
4
16
|
|
|
5
17
|
- **Добавлено** (upgrade): Команда pachca upgrade — обновление CLI до последней версии
|
package/dist/base-command.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import { resolveToken, TokenNotFoundError, ProfileNotFoundError, getDefaults,
|
|
2
|
+
import { resolveToken, TokenNotFoundError, ProfileNotFoundError, getDefaults, } from './profiles.js';
|
|
3
3
|
import { ApiError, getExitCode, formatDryRun, request } from './client.js';
|
|
4
4
|
import { outputData, outputError, outputSuccess } from './output.js';
|
|
5
5
|
import { defaultOutputFormat, isInteractive } from './utils.js';
|
|
@@ -170,38 +170,6 @@ export class BaseCommand extends Command {
|
|
|
170
170
|
profile: this.parsedFlags.profile,
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
|
-
/**
|
|
174
|
-
* Check if the current profile has the required scope.
|
|
175
|
-
* Exits with error if scope is missing.
|
|
176
|
-
*/
|
|
177
|
-
checkScope(requiredScope) {
|
|
178
|
-
const { profileName, profile } = this.resolveAuth();
|
|
179
|
-
if (!profile || !profile.scopes || profile.scopes.length === 0)
|
|
180
|
-
return;
|
|
181
|
-
if (!profile.scopes.includes(requiredScope)) {
|
|
182
|
-
const format = this.getOutputFormat();
|
|
183
|
-
if (format === 'json' || !process.stderr.isTTY) {
|
|
184
|
-
outputError({
|
|
185
|
-
error: 'Insufficient scope',
|
|
186
|
-
code: null,
|
|
187
|
-
type: 'PACHCA_SCOPE_ERROR',
|
|
188
|
-
profile: profileName,
|
|
189
|
-
required_scope: requiredScope,
|
|
190
|
-
current_scopes: profile.scopes,
|
|
191
|
-
}, format);
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
process.stderr.write(`✗ Токен профиля ${profileName} не имеет скоупа ${requiredScope}\n\n`);
|
|
195
|
-
process.stderr.write(` Текущие скоупы: ${profile.scopes.join(', ')}\n`);
|
|
196
|
-
process.stderr.write(` Требуется: ${requiredScope}\n\n`);
|
|
197
|
-
process.stderr.write(` Используйте другой профиль:\n`);
|
|
198
|
-
process.stderr.write(` pachca auth switch <profile>\n`);
|
|
199
|
-
process.stderr.write(` Или проверьте актуальные скоупы:\n`);
|
|
200
|
-
process.stderr.write(` pachca auth refresh ${profileName}\n`);
|
|
201
|
-
}
|
|
202
|
-
this.exit(3);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
173
|
/**
|
|
206
174
|
* Make an authenticated API request.
|
|
207
175
|
*/
|
|
@@ -249,16 +217,6 @@ export class BaseCommand extends Command {
|
|
|
249
217
|
*/
|
|
250
218
|
async catch(err) {
|
|
251
219
|
if (err instanceof ApiError) {
|
|
252
|
-
// Invalidate cached scopes on 403 insufficient_scope
|
|
253
|
-
if (err.details.code === 403 && err.details.type === 'PACHCA_AUTH_ERROR' && err.details.message === 'insufficient_scope') {
|
|
254
|
-
const profileName = this.parsedFlags?.profile || process.env.PACHCA_PROFILE || getActiveProfile();
|
|
255
|
-
if (profileName) {
|
|
256
|
-
invalidateScopes(profileName);
|
|
257
|
-
}
|
|
258
|
-
err.details.hint = profileName
|
|
259
|
-
? `pachca auth refresh ${profileName}`
|
|
260
|
-
: 'pachca auth refresh';
|
|
261
|
-
}
|
|
262
220
|
outputError(err.details, this.getOutputFormat());
|
|
263
221
|
this.exit(getExitCode(err));
|
|
264
222
|
}
|
|
@@ -99,8 +99,6 @@ export default class AuthLogin extends BaseCommand {
|
|
|
99
99
|
catch {
|
|
100
100
|
// profile:read scope not available — use user_id from token info
|
|
101
101
|
}
|
|
102
|
-
// Determine scopes
|
|
103
|
-
const scopes = tokenInfo.scopes || [];
|
|
104
102
|
const profileType = isBot ? 'bot' : 'user';
|
|
105
103
|
// Save profile
|
|
106
104
|
const profile = {
|
|
@@ -108,8 +106,6 @@ export default class AuthLogin extends BaseCommand {
|
|
|
108
106
|
token,
|
|
109
107
|
user: isBot ? `${userName} (бот)` : userName,
|
|
110
108
|
email: userEmail,
|
|
111
|
-
scopes,
|
|
112
|
-
...(isBot ? { scopes_refreshed_at: new Date().toISOString() } : {}),
|
|
113
109
|
};
|
|
114
110
|
setProfile(profileName, profile);
|
|
115
111
|
// Set as active if no active profile
|
|
@@ -123,18 +119,13 @@ export default class AuthLogin extends BaseCommand {
|
|
|
123
119
|
type: profileType,
|
|
124
120
|
user: profile.user,
|
|
125
121
|
email: userEmail,
|
|
126
|
-
scopes,
|
|
127
122
|
});
|
|
128
123
|
}
|
|
129
124
|
else if (!flags.quiet) {
|
|
130
125
|
const typeLabel = profileType === 'bot' ? 'bot' : 'user';
|
|
131
126
|
const emailStr = userEmail ? ` (${userEmail})` : '';
|
|
132
127
|
process.stderr.write(`✔ Подключён как: ${profile.user}${emailStr} [${typeLabel}]\n`);
|
|
133
|
-
process.stderr.write(` Скоупы (${scopes.length}): ${scopes.join(' ')}\n`);
|
|
134
128
|
process.stderr.write(` Профиль сохранён [${profileName}]\n`);
|
|
135
|
-
if (isBot) {
|
|
136
|
-
process.stderr.write(` ℹ Скоупы бота обновляются автоматически раз в сутки (синхронно при запуске команды)\n`);
|
|
137
|
-
}
|
|
138
129
|
}
|
|
139
130
|
}
|
|
140
131
|
}
|
|
@@ -30,21 +30,11 @@ export default class AuthStatus extends BaseCommand {
|
|
|
30
30
|
type: profile.type,
|
|
31
31
|
user: profile.user,
|
|
32
32
|
email: profile.email || null,
|
|
33
|
-
scopes: profile.scopes || [],
|
|
34
33
|
});
|
|
35
34
|
}
|
|
36
35
|
else {
|
|
37
36
|
const emailStr = profile.email ? ` (${profile.email})` : '';
|
|
38
37
|
process.stderr.write(` Подключён как: ${profile.user}${emailStr} [${profile.type}, profile: ${profileName}]\n`);
|
|
39
|
-
if (profile.scopes?.length) {
|
|
40
|
-
process.stderr.write(` Скоупы:\n`);
|
|
41
|
-
// Print scopes in rows of 3
|
|
42
|
-
const scopes = profile.scopes;
|
|
43
|
-
for (let i = 0; i < scopes.length; i += 3) {
|
|
44
|
-
const row = scopes.slice(i, i + 3).map((s) => s.padEnd(20)).join(' ');
|
|
45
|
-
process.stderr.write(` ${row}\n`);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
38
|
}
|
|
49
39
|
}
|
|
50
40
|
}
|
|
@@ -27,7 +27,6 @@ export default class BotsListEvents extends BaseCommand {
|
|
|
27
27
|
async run() {
|
|
28
28
|
const { args, flags } = await this.parse(BotsListEvents);
|
|
29
29
|
this.parsedFlags = flags;
|
|
30
|
-
this.checkScope("webhooks:events:read");
|
|
31
30
|
if (flags.all) {
|
|
32
31
|
// Auto-pagination
|
|
33
32
|
const allData = [];
|
|
@@ -53,7 +53,6 @@ export default class BotsUpdate extends BaseCommand {
|
|
|
53
53
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --webhook <string>. pachca introspect bots update" });
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
this.checkScope("bots:write");
|
|
57
56
|
const body = { bot: {
|
|
58
57
|
webhook: flags['webhook'] ? this.parseJSON(flags['webhook'], 'webhook') : undefined,
|
|
59
58
|
} };
|
|
@@ -22,7 +22,6 @@ export default class ChatsArchive extends BaseCommand {
|
|
|
22
22
|
async run() {
|
|
23
23
|
const { args, flags } = await this.parse(ChatsArchive);
|
|
24
24
|
this.parsedFlags = flags;
|
|
25
|
-
this.checkScope("chats:archive");
|
|
26
25
|
const { data } = await this.apiRequest({
|
|
27
26
|
method: 'PUT',
|
|
28
27
|
path: `/chats/${args.id}/archive`,
|
|
@@ -64,7 +64,6 @@ export default class ChatsCreate extends BaseCommand {
|
|
|
64
64
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --name <string>. pachca introspect chats create" });
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
this.checkScope("chats:create");
|
|
68
67
|
const body = { chat: {
|
|
69
68
|
name: flags['name'],
|
|
70
69
|
member_ids: flags['member-ids'] ? this.parseJSON(flags['member-ids'], 'member-ids') : undefined,
|
|
@@ -22,7 +22,6 @@ export default class ChatsGet extends BaseCommand {
|
|
|
22
22
|
async run() {
|
|
23
23
|
const { args, flags } = await this.parse(ChatsGet);
|
|
24
24
|
this.parsedFlags = flags;
|
|
25
|
-
this.checkScope("chats:read");
|
|
26
25
|
const { data } = await this.apiRequest({
|
|
27
26
|
method: 'GET',
|
|
28
27
|
path: `/chats/${args.id}`,
|
|
@@ -15,11 +15,13 @@ export default class ChatsList extends BaseCommand {
|
|
|
15
15
|
static args = {};
|
|
16
16
|
static flags = {
|
|
17
17
|
...BaseCommand.baseFlags,
|
|
18
|
-
|
|
19
|
-
description: "
|
|
18
|
+
sort: Flags.string({
|
|
19
|
+
description: "Поле сортировки (id — идентификатор чата, last-message-at — дата и время создания последнего сообщения)",
|
|
20
|
+
options: ["id", "last-message-at"],
|
|
20
21
|
}),
|
|
21
|
-
|
|
22
|
-
description: "
|
|
22
|
+
order: Flags.string({
|
|
23
|
+
description: "Порядок сортировки",
|
|
24
|
+
options: ["asc", "desc"],
|
|
23
25
|
}),
|
|
24
26
|
'availability': Flags.string({
|
|
25
27
|
description: "Параметр, который отвечает за доступность и выборку чатов для пользователя",
|
|
@@ -48,7 +50,6 @@ export default class ChatsList extends BaseCommand {
|
|
|
48
50
|
async run() {
|
|
49
51
|
const { args, flags } = await this.parse(ChatsList);
|
|
50
52
|
this.parsedFlags = flags;
|
|
51
|
-
this.checkScope("chats:read");
|
|
52
53
|
if (flags.all) {
|
|
53
54
|
// Auto-pagination
|
|
54
55
|
const allData = [];
|
|
@@ -57,8 +58,7 @@ export default class ChatsList extends BaseCommand {
|
|
|
57
58
|
const seenCursors = new Set();
|
|
58
59
|
while (pages < 500) {
|
|
59
60
|
const query = {
|
|
60
|
-
|
|
61
|
-
'sort[last_message_at]': flags['sort-last-message-at'],
|
|
61
|
+
...(flags.sort ? { [`sort[${flags.sort.replace(/-/g, '_')}]`]: flags.order || 'desc' } : {}),
|
|
62
62
|
availability: flags['availability'],
|
|
63
63
|
'last_message_at_after': flags['last-message-at-after'],
|
|
64
64
|
'last_message_at_before': flags['last-message-at-before'],
|
|
@@ -100,8 +100,7 @@ export default class ChatsList extends BaseCommand {
|
|
|
100
100
|
method: 'GET',
|
|
101
101
|
path: '/chats',
|
|
102
102
|
query: {
|
|
103
|
-
|
|
104
|
-
'sort[last_message_at]': flags['sort-last-message-at'],
|
|
103
|
+
...(flags.sort ? { [`sort[${flags.sort.replace(/-/g, '_')}]`]: flags.order || 'desc' } : {}),
|
|
105
104
|
availability: flags['availability'],
|
|
106
105
|
'last_message_at_after': flags['last-message-at-after'],
|
|
107
106
|
'last_message_at_before': flags['last-message-at-before'],
|
|
@@ -21,7 +21,6 @@ export default class ChatsUnarchive extends BaseCommand {
|
|
|
21
21
|
async run() {
|
|
22
22
|
const { args, flags } = await this.parse(ChatsUnarchive);
|
|
23
23
|
this.parsedFlags = flags;
|
|
24
|
-
this.checkScope("chats:archive");
|
|
25
24
|
const { data } = await this.apiRequest({
|
|
26
25
|
method: 'PUT',
|
|
27
26
|
path: `/chats/${args.id}/unarchive`,
|
|
@@ -29,7 +29,6 @@ export default class ChatsUpdate extends BaseCommand {
|
|
|
29
29
|
async run() {
|
|
30
30
|
const { args, flags } = await this.parse(ChatsUpdate);
|
|
31
31
|
this.parsedFlags = flags;
|
|
32
|
-
this.checkScope("chats:update");
|
|
33
32
|
const body = { chat: {
|
|
34
33
|
name: flags['name'],
|
|
35
34
|
public: flags['public'],
|
|
@@ -39,20 +39,13 @@ export default class Commands extends BaseCommand {
|
|
|
39
39
|
this.output(commandList.map(({ command, summary }) => ({ command, summary })));
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
-
// --available: check token scopes
|
|
42
|
+
// --available: check token scopes via API
|
|
43
43
|
let tokenScopes = [];
|
|
44
44
|
try {
|
|
45
|
-
const { token
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
// Fetch from API
|
|
52
|
-
const response = await request({ method: 'GET', path: '/oauth/token/info', token }, { quiet: true });
|
|
53
|
-
const wrapper = response.data;
|
|
54
|
-
tokenScopes = wrapper.data.scopes || [];
|
|
55
|
-
}
|
|
45
|
+
const { token } = resolveToken({ token: flags.token, profile: flags.profile });
|
|
46
|
+
const response = await request({ method: 'GET', path: '/oauth/token/info', token }, { quiet: true });
|
|
47
|
+
const wrapper = response.data;
|
|
48
|
+
tokenScopes = wrapper.data.scopes || [];
|
|
56
49
|
}
|
|
57
50
|
catch (error) {
|
|
58
51
|
if (error instanceof TokenNotFoundError) {
|
|
@@ -49,7 +49,6 @@ export default class CommonCustomProperties extends BaseCommand {
|
|
|
49
49
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --entity-type <string>. pachca introspect common custom-properties" });
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
this.checkScope("custom_properties:read");
|
|
53
52
|
const { data } = await this.apiRequest({
|
|
54
53
|
method: 'GET',
|
|
55
54
|
path: '/custom_properties',
|
|
@@ -27,7 +27,6 @@ export default class CommonGetExports extends BaseCommand {
|
|
|
27
27
|
async run() {
|
|
28
28
|
const { args, flags } = await this.parse(CommonGetExports);
|
|
29
29
|
this.parsedFlags = flags;
|
|
30
|
-
this.checkScope("chat_exports:read");
|
|
31
30
|
const { data } = await this.apiRequest({
|
|
32
31
|
method: 'GET',
|
|
33
32
|
path: `/chats/exports/${args.id}`,
|
|
@@ -63,7 +63,6 @@ export default class CommonRequestExport extends BaseCommand {
|
|
|
63
63
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --start-at <string>, --end-at <string>, --webhook-url <string>. pachca introspect common request-export" });
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
this.checkScope("chat_exports:write");
|
|
67
66
|
const body = {
|
|
68
67
|
start_at: flags['start-at'],
|
|
69
68
|
end_at: flags['end-at'],
|
|
@@ -15,7 +15,6 @@ export default class CommonUploads extends BaseCommand {
|
|
|
15
15
|
async run() {
|
|
16
16
|
const { args, flags } = await this.parse(CommonUploads);
|
|
17
17
|
this.parsedFlags = flags;
|
|
18
|
-
this.checkScope("uploads:write");
|
|
19
18
|
const { data } = await this.apiRequest({
|
|
20
19
|
method: 'POST',
|
|
21
20
|
path: '/uploads',
|
|
@@ -49,7 +49,6 @@ export default class GroupTagsCreate extends BaseCommand {
|
|
|
49
49
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --name <string>. pachca introspect group-tags create" });
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
this.checkScope("group_tags:write");
|
|
53
52
|
const body = { group_tag: {
|
|
54
53
|
name: flags['name'],
|
|
55
54
|
} };
|
|
@@ -19,7 +19,6 @@ export default class GroupTagsGet extends BaseCommand {
|
|
|
19
19
|
async run() {
|
|
20
20
|
const { args, flags } = await this.parse(GroupTagsGet);
|
|
21
21
|
this.parsedFlags = flags;
|
|
22
|
-
this.checkScope("group_tags:read");
|
|
23
22
|
const { data } = await this.apiRequest({
|
|
24
23
|
method: 'GET',
|
|
25
24
|
path: `/group_tags/${args.id}`,
|
|
@@ -32,7 +32,6 @@ export default class GroupTagsListUsers extends BaseCommand {
|
|
|
32
32
|
async run() {
|
|
33
33
|
const { args, flags } = await this.parse(GroupTagsListUsers);
|
|
34
34
|
this.parsedFlags = flags;
|
|
35
|
-
this.checkScope("group_tags:read");
|
|
36
35
|
if (flags.all) {
|
|
37
36
|
// Auto-pagination
|
|
38
37
|
const allData = [];
|
|
@@ -31,7 +31,6 @@ export default class GroupTagsList extends BaseCommand {
|
|
|
31
31
|
async run() {
|
|
32
32
|
const { args, flags } = await this.parse(GroupTagsList);
|
|
33
33
|
this.parsedFlags = flags;
|
|
34
|
-
this.checkScope("group_tags:read");
|
|
35
34
|
if (flags.all) {
|
|
36
35
|
// Auto-pagination
|
|
37
36
|
const allData = [];
|
|
@@ -50,7 +50,6 @@ export default class GroupTagsUpdate extends BaseCommand {
|
|
|
50
50
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --name <string>. pachca introspect group-tags update" });
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
this.checkScope("group_tags:write");
|
|
54
53
|
const body = { group_tag: {
|
|
55
54
|
name: flags['name'],
|
|
56
55
|
} };
|
|
@@ -52,7 +52,6 @@ export default class LinkPreviewsAdd extends BaseCommand {
|
|
|
52
52
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --link-previews <string>. pachca introspect link-previews add" });
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
this.checkScope("link_previews:write");
|
|
56
55
|
const body = {
|
|
57
56
|
link_previews: flags['link-previews'] ? this.parseJSON(flags['link-previews'], 'link-previews') : undefined,
|
|
58
57
|
};
|
|
@@ -49,7 +49,6 @@ export default class MembersAddGroupTags extends BaseCommand {
|
|
|
49
49
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --group-tag-ids <string>. pachca introspect members add-group-tags" });
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
this.checkScope("chat_members:write");
|
|
53
52
|
const body = {
|
|
54
53
|
group_tag_ids: flags['group-tag-ids'] ? this.parseJSON(flags['group-tag-ids'], 'group-tag-ids') : undefined,
|
|
55
54
|
};
|
|
@@ -58,7 +58,6 @@ export default class MembersAdd extends BaseCommand {
|
|
|
58
58
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --member-ids <string>. pachca introspect members add" });
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
this.checkScope("chat_members:write");
|
|
62
61
|
const body = {
|
|
63
62
|
member_ids: flags['member-ids'] ? this.parseJSON(flags['member-ids'], 'member-ids') : undefined,
|
|
64
63
|
silent: flags['silent'],
|
|
@@ -37,7 +37,6 @@ export default class MembersList extends BaseCommand {
|
|
|
37
37
|
async run() {
|
|
38
38
|
const { args, flags } = await this.parse(MembersList);
|
|
39
39
|
this.parsedFlags = flags;
|
|
40
|
-
this.checkScope("chat_members:read");
|
|
41
40
|
if (flags.all) {
|
|
42
41
|
// Auto-pagination
|
|
43
42
|
const allData = [];
|
|
@@ -57,7 +57,6 @@ export default class MembersUpdate extends BaseCommand {
|
|
|
57
57
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --role <string>. pachca introspect members update" });
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
this.checkScope("chat_members:write");
|
|
61
60
|
const body = {
|
|
62
61
|
role: flags['role'],
|
|
63
62
|
};
|
|
@@ -98,8 +98,8 @@ export default class MessagesCreate extends BaseCommand {
|
|
|
98
98
|
if (validationErrors.length > 0) {
|
|
99
99
|
this.validationError(validationErrors);
|
|
100
100
|
}
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
const body = {
|
|
102
|
+
message: {
|
|
103
103
|
entity_type: flags['entity-type'],
|
|
104
104
|
entity_id: flags['entity-id'],
|
|
105
105
|
content: flags['content'],
|
|
@@ -109,14 +109,19 @@ export default class MessagesCreate extends BaseCommand {
|
|
|
109
109
|
display_avatar_url: flags['display-avatar-url'],
|
|
110
110
|
display_name: flags['display-name'],
|
|
111
111
|
skip_invite_mentions: flags['skip-invite-mentions'],
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
},
|
|
113
|
+
link_preview: flags['link-preview'],
|
|
114
|
+
};
|
|
114
115
|
// Clean undefined fields
|
|
115
116
|
const inner = body['message'];
|
|
116
117
|
for (const [k, v] of Object.entries(inner)) {
|
|
117
118
|
if (v === undefined)
|
|
118
119
|
delete inner[k];
|
|
119
120
|
}
|
|
121
|
+
for (const [k, v] of Object.entries(body)) {
|
|
122
|
+
if (k !== 'message' && v === undefined)
|
|
123
|
+
delete body[k];
|
|
124
|
+
}
|
|
120
125
|
const { data } = await this.apiRequest({
|
|
121
126
|
method: 'POST',
|
|
122
127
|
path: '/messages',
|
|
@@ -24,7 +24,6 @@ export default class MessagesGet extends BaseCommand {
|
|
|
24
24
|
async run() {
|
|
25
25
|
const { args, flags } = await this.parse(MessagesGet);
|
|
26
26
|
this.parsedFlags = flags;
|
|
27
|
-
this.checkScope("messages:read");
|
|
28
27
|
const { data } = await this.apiRequest({
|
|
29
28
|
method: 'GET',
|
|
30
29
|
path: `/messages/${args.id}`,
|
|
@@ -20,8 +20,13 @@ export default class MessagesList extends BaseCommand {
|
|
|
20
20
|
'chat-id': Flags.integer({
|
|
21
21
|
description: "Идентификатор чата (беседа, канал, диалог или чат треда)",
|
|
22
22
|
}),
|
|
23
|
-
|
|
24
|
-
description: "
|
|
23
|
+
sort: Flags.string({
|
|
24
|
+
description: "Поле сортировки (id — идентификатор сообщения)",
|
|
25
|
+
options: ["id"],
|
|
26
|
+
}),
|
|
27
|
+
order: Flags.string({
|
|
28
|
+
description: "Порядок сортировки",
|
|
29
|
+
options: ["asc", "desc"],
|
|
25
30
|
}),
|
|
26
31
|
limit: Flags.integer({
|
|
27
32
|
description: 'Количество результатов на страницу',
|
|
@@ -63,7 +68,6 @@ export default class MessagesList extends BaseCommand {
|
|
|
63
68
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --chat-id <integer>. pachca introspect messages list" });
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
|
-
this.checkScope("messages:read");
|
|
67
71
|
if (flags.all) {
|
|
68
72
|
// Auto-pagination
|
|
69
73
|
const allData = [];
|
|
@@ -73,7 +77,7 @@ export default class MessagesList extends BaseCommand {
|
|
|
73
77
|
while (pages < 500) {
|
|
74
78
|
const query = {
|
|
75
79
|
'chat_id': flags['chat-id'],
|
|
76
|
-
|
|
80
|
+
...(flags.sort ? { [`sort[${flags.sort.replace(/-/g, '_')}]`]: flags.order || 'desc' } : {}),
|
|
77
81
|
limit: flags.limit,
|
|
78
82
|
cursor: nextCursor,
|
|
79
83
|
};
|
|
@@ -112,7 +116,7 @@ export default class MessagesList extends BaseCommand {
|
|
|
112
116
|
path: '/messages',
|
|
113
117
|
query: {
|
|
114
118
|
'chat_id': flags['chat-id'],
|
|
115
|
-
|
|
119
|
+
...(flags.sort ? { [`sort[${flags.sort.replace(/-/g, '_')}]`]: flags.order || 'desc' } : {}),
|
|
116
120
|
limit: flags.limit,
|
|
117
121
|
cursor: flags.cursor,
|
|
118
122
|
},
|
|
@@ -22,7 +22,6 @@ export default class MessagesPin extends BaseCommand {
|
|
|
22
22
|
async run() {
|
|
23
23
|
const { args, flags } = await this.parse(MessagesPin);
|
|
24
24
|
this.parsedFlags = flags;
|
|
25
|
-
this.checkScope("pins:write");
|
|
26
25
|
const { data } = await this.apiRequest({
|
|
27
26
|
method: 'POST',
|
|
28
27
|
path: `/messages/${args.id}/pin`,
|
|
@@ -47,7 +47,6 @@ export default class MessagesUpdate extends BaseCommand {
|
|
|
47
47
|
}
|
|
48
48
|
flags['content'] = Buffer.concat(chunks).toString('utf-8').trimEnd();
|
|
49
49
|
}
|
|
50
|
-
this.checkScope("messages:update");
|
|
51
50
|
const body = { message: {
|
|
52
51
|
content: flags['content'],
|
|
53
52
|
files: flags['files'] ? this.parseJSON(flags['files'], 'files') : undefined,
|
|
@@ -16,7 +16,6 @@ export default class ProfileGetStatus extends BaseCommand {
|
|
|
16
16
|
async run() {
|
|
17
17
|
const { args, flags } = await this.parse(ProfileGetStatus);
|
|
18
18
|
this.parsedFlags = flags;
|
|
19
|
-
this.checkScope("profile_status:read");
|
|
20
19
|
const { data } = await this.apiRequest({
|
|
21
20
|
method: 'GET',
|
|
22
21
|
path: '/profile/status',
|
|
@@ -16,7 +16,6 @@ export default class ProfileGet extends BaseCommand {
|
|
|
16
16
|
async run() {
|
|
17
17
|
const { args, flags } = await this.parse(ProfileGet);
|
|
18
18
|
this.parsedFlags = flags;
|
|
19
|
-
this.checkScope("profile:read");
|
|
20
19
|
const { data } = await this.apiRequest({
|
|
21
20
|
method: 'GET',
|
|
22
21
|
path: '/profile',
|
|
@@ -70,7 +70,6 @@ export default class ProfileUpdateStatus extends BaseCommand {
|
|
|
70
70
|
if (validationErrors.length > 0) {
|
|
71
71
|
this.validationError(validationErrors);
|
|
72
72
|
}
|
|
73
|
-
this.checkScope("profile_status:write");
|
|
74
73
|
const body = { status: {
|
|
75
74
|
emoji: flags['emoji'],
|
|
76
75
|
title: flags['title'],
|
|
@@ -57,7 +57,6 @@ export default class ReactionsAdd extends BaseCommand {
|
|
|
57
57
|
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --code <string>. pachca introspect reactions add" });
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
this.checkScope("reactions:write");
|
|
61
60
|
const body = {
|
|
62
61
|
code: flags['code'],
|
|
63
62
|
name: flags['name'],
|