@pachca/cli 2026.9.1 → 2026.10.1

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.
Files changed (76) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +17 -5
  3. package/dist/base-command.js +47 -0
  4. package/dist/client.js +2 -1
  5. package/dist/commands/auth/login.js +4 -4
  6. package/dist/commands/bots/create-token.js +84 -0
  7. package/dist/commands/bots/create.js +33 -6
  8. package/dist/commands/bots/delete-token.js +46 -0
  9. package/dist/commands/bots/delete.js +1 -1
  10. package/dist/commands/bots/get.js +1 -1
  11. package/dist/commands/bots/list-company.js +1 -1
  12. package/dist/commands/bots/list-events.js +1 -1
  13. package/dist/commands/bots/list-scopes.js +32 -0
  14. package/dist/commands/bots/list-tokens.js +94 -0
  15. package/dist/commands/bots/list.js +3 -3
  16. package/dist/commands/bots/recreate-token-self.js +1 -1
  17. package/dist/commands/bots/recreate-token.js +2 -2
  18. package/dist/commands/bots/reissue-token.js +37 -0
  19. package/dist/commands/bots/remove-avatar.js +42 -0
  20. package/dist/commands/bots/remove-event.js +1 -1
  21. package/dist/commands/bots/rotate-client-secret.js +30 -0
  22. package/dist/commands/bots/update-avatar.js +51 -0
  23. package/dist/commands/bots/update-token.js +60 -0
  24. package/dist/commands/bots/update.js +37 -8
  25. package/dist/commands/chats/create.js +1 -0
  26. package/dist/commands/chats/download-export.js +1 -1
  27. package/dist/commands/chats/get.js +1 -1
  28. package/dist/commands/chats/list-company.js +1 -1
  29. package/dist/commands/chats/list.js +1 -1
  30. package/dist/commands/chats/mark-unread.js +44 -0
  31. package/dist/commands/chats/remove-avatar.js +45 -0
  32. package/dist/commands/chats/request-export.js +4 -2
  33. package/dist/commands/chats/update-avatar.js +54 -0
  34. package/dist/commands/drafts/create.js +1 -1
  35. package/dist/commands/drafts/list.js +1 -1
  36. package/dist/commands/drafts/update.js +1 -1
  37. package/dist/commands/files/direct-url.js +8 -4
  38. package/dist/commands/group-tags/get.js +1 -1
  39. package/dist/commands/group-tags/list-users.js +2 -2
  40. package/dist/commands/group-tags/list.js +3 -3
  41. package/dist/commands/members/add.js +2 -2
  42. package/dist/commands/members/list.js +2 -2
  43. package/dist/commands/members/remove-group-tag.js +1 -1
  44. package/dist/commands/members/remove.js +1 -1
  45. package/dist/commands/members/update.js +1 -1
  46. package/dist/commands/messages/create.js +9 -10
  47. package/dist/commands/messages/get.js +1 -1
  48. package/dist/commands/messages/list.js +1 -1
  49. package/dist/commands/messages/update.js +2 -2
  50. package/dist/commands/profile/update-status.js +3 -32
  51. package/dist/commands/reactions/list.js +1 -1
  52. package/dist/commands/read-member/list-readers.js +1 -1
  53. package/dist/commands/search/list-chats.js +2 -2
  54. package/dist/commands/search/list-messages.js +6 -6
  55. package/dist/commands/search/list-users.js +4 -4
  56. package/dist/commands/security/list.js +2 -2
  57. package/dist/commands/tasks/create.js +1 -1
  58. package/dist/commands/tasks/get.js +1 -1
  59. package/dist/commands/tasks/list.js +6 -6
  60. package/dist/commands/tasks/update.js +1 -1
  61. package/dist/commands/threads/get.js +1 -1
  62. package/dist/commands/threads/list.js +2 -2
  63. package/dist/commands/upload.js +5 -2
  64. package/dist/commands/users/create.js +1 -1
  65. package/dist/commands/users/get.js +1 -1
  66. package/dist/commands/users/list.js +1 -1
  67. package/dist/commands/users/update-status.js +3 -32
  68. package/dist/commands/users/update.js +2 -2
  69. package/dist/commands/views/open.js +2 -2
  70. package/dist/data/alternatives.json +17 -5
  71. package/dist/data/changelog.json +146 -0
  72. package/dist/data/endpoints.json +1 -1
  73. package/dist/data/workflows.json +60 -9
  74. package/dist/oauth.js +28 -3
  75. package/oclif.manifest.json +1 -1
  76. package/package.json +1 -1
@@ -9,7 +9,7 @@ export default class FilesDirectUrl extends BaseCommand {
9
9
  static hiddenAliases = ["common:direct-url"];
10
10
  static apiMethod = "POST";
11
11
  static apiPath = "/direct_url";
12
- static requiredFlags = ["content-disposition", "acl", "policy", "x-amz-credential", "x-amz-algorithm", "x-amz-date", "x-amz-signature", "key"];
12
+ static requiredFlags = ["content-disposition", "policy", "x-amz-credential", "x-amz-algorithm", "x-amz-date", "x-amz-signature", "key"];
13
13
  static args = {};
14
14
  static flags = {
15
15
  ...BaseCommand.baseFlags,
@@ -21,7 +21,7 @@ export default class FilesDirectUrl extends BaseCommand {
21
21
  description: "Параметр Content-Disposition, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)",
22
22
  }),
23
23
  'acl': Flags.string({
24
- description: "Параметр acl, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)",
24
+ description: "Параметр acl, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads). Передаётся, если пришёл в ответе.",
25
25
  }),
26
26
  'policy': Flags.string({
27
27
  description: "Параметр policy, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)",
@@ -41,6 +41,9 @@ export default class FilesDirectUrl extends BaseCommand {
41
41
  'key': Flags.string({
42
42
  description: "Параметр key, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)",
43
43
  }),
44
+ 'bucket': Flags.string({
45
+ description: "Параметр bucket, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads). Передаётся, если пришёл в ответе.",
46
+ }),
44
47
  file: Flags.string({
45
48
  description: "Файл для загрузки",
46
49
  }),
@@ -50,7 +53,6 @@ export default class FilesDirectUrl extends BaseCommand {
50
53
  this.parsedFlags = flags;
51
54
  const missingRequired = [
52
55
  { flag: 'content-disposition', label: "Параметр Content-Disposition, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
53
- { flag: 'acl', label: "Параметр acl, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
54
56
  { flag: 'policy', label: "Параметр policy, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
55
57
  { flag: 'x-amz-credential', label: "Параметр x-amz-credential, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
56
58
  { flag: 'x-amz-algorithm', label: "Параметр x-amz-algorithm, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
@@ -78,7 +80,7 @@ export default class FilesDirectUrl extends BaseCommand {
78
80
  }
79
81
  }
80
82
  else {
81
- this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --content-disposition <string>, --acl <string>, --policy <string>, --x-amz-credential <string>, --x-amz-algorithm <string>, --x-amz-date <string>, --x-amz-signature <string>, --key <string>. pachca introspect files direct-url" });
83
+ this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --content-disposition <string>, --policy <string>, --x-amz-credential <string>, --x-amz-algorithm <string>, --x-amz-date <string>, --x-amz-signature <string>, --key <string>. pachca introspect files direct-url" });
82
84
  }
83
85
  }
84
86
  let formData;
@@ -100,6 +102,8 @@ export default class FilesDirectUrl extends BaseCommand {
100
102
  formData.append('x-amz-signature', String(flags['x-amz-signature']));
101
103
  if (flags['key'])
102
104
  formData.append('key', String(flags['key']));
105
+ if (flags['bucket'])
106
+ formData.append('bucket', String(flags['bucket']));
103
107
  if (flags.file === '-') {
104
108
  const chunks = [];
105
109
  for await (const chunk of process.stdin)
@@ -9,7 +9,7 @@ export default class GroupTagsGet extends BaseCommand {
9
9
  static defaultColumns = ["id", "name", "users_count"];
10
10
  static args = {
11
11
  id: Args.integer({
12
- description: "Идентификатор тега",
12
+ description: "Идентификатор тега: в ссылке веб-приложения это число из параметра `tag_id`",
13
13
  required: true,
14
14
  }),
15
15
  };
@@ -12,7 +12,7 @@ export default class GroupTagsListUsers extends BaseCommand {
12
12
  static defaultColumns = ["id", "title", "first_name", "last_name", "email"];
13
13
  static args = {
14
14
  id: Args.integer({
15
- description: "Идентификатор тега",
15
+ description: "Идентификатор тега: в ссылке веб-приложения это число из параметра `tag_id`",
16
16
  required: true,
17
17
  }),
18
18
  };
@@ -52,7 +52,7 @@ export default class GroupTagsListUsers extends BaseCommand {
52
52
  const paginate = meta?.paginate;
53
53
  nextCursor = paginate?.next_page;
54
54
  pages++;
55
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
55
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
56
56
  const hasNext = paginate?.has_next;
57
57
  if (typeof hasNext === 'boolean') {
58
58
  if (!hasNext)
@@ -38,7 +38,7 @@ export default class GroupTagsList extends BaseCommand {
38
38
  const seenCursors = new Set();
39
39
  while (pages < 500) {
40
40
  const query = {
41
- names: flags['names']?.split(','),
41
+ 'names[]': flags['names']?.split(','),
42
42
  limit: flags.limit,
43
43
  cursor: nextCursor,
44
44
  };
@@ -51,7 +51,7 @@ export default class GroupTagsList extends BaseCommand {
51
51
  const paginate = meta?.paginate;
52
52
  nextCursor = paginate?.next_page;
53
53
  pages++;
54
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
54
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
55
55
  const hasNext = paginate?.has_next;
56
56
  if (typeof hasNext === 'boolean') {
57
57
  if (!hasNext)
@@ -85,7 +85,7 @@ export default class GroupTagsList extends BaseCommand {
85
85
  method: 'GET',
86
86
  path: '/group_tags',
87
87
  query: {
88
- names: flags['names']?.split(','),
88
+ 'names[]': flags['names']?.split(','),
89
89
  limit: flags.limit,
90
90
  cursor: flags.cursor,
91
91
  },
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
3
3
  import { BaseCommand } from '../../base-command.js';
4
4
  import * as clack from '@clack/prompts';
5
5
  export default class MembersAdd extends BaseCommand {
6
- static description = "Добавление пользователей";
6
+ static description = "Добавление участников";
7
7
  static examples = [
8
8
  "Подписаться на тред сообщения — Добавь бота в участники чата треда:\n $ pachca members add",
9
9
  "Создать канал и пригласить участников — Или добавь участников позже:\n $ pachca members add",
@@ -25,7 +25,7 @@ export default class MembersAdd extends BaseCommand {
25
25
  description: "Массив идентификаторов пользователей, которые станут участниками",
26
26
  }),
27
27
  'silent': Flags.boolean({
28
- description: "Не создавать в чате системное сообщение о добавлении участника",
28
+ description: "При `true` в чат не приходит системное сообщение о добавлении, а добавленные сотрудники не получают письмо с приглашением. Сообщение бывает только в закрытой беседе, письмо — в беседах и каналах у тех, кто не отключил такие письма. В треде параметр ничего не меняет.",
29
29
  allowNo: true,
30
30
  }),
31
31
  };
@@ -20,7 +20,7 @@ export default class MembersList extends BaseCommand {
20
20
  static flags = {
21
21
  ...BaseCommand.baseFlags,
22
22
  'role': Flags.string({
23
- description: "Роль в чате",
23
+ description: "Роль в чате. В канале пишут создатель, админы и редакторы, а участник там — подписчик.",
24
24
  options: ["all", "owner", "admin", "editor", "member"],
25
25
  default: "all",
26
26
  }),
@@ -59,7 +59,7 @@ export default class MembersList extends BaseCommand {
59
59
  const paginate = meta?.paginate;
60
60
  nextCursor = paginate?.next_page;
61
61
  pages++;
62
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
62
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
63
63
  const hasNext = paginate?.has_next;
64
64
  if (typeof hasNext === 'boolean') {
65
65
  if (!hasNext)
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
3
3
  import { BaseCommand } from '../../base-command.js';
4
4
  import * as clack from '@clack/prompts';
5
5
  export default class MembersRemoveGroupTag extends BaseCommand {
6
- static description = "Исключение тега";
6
+ static description = "Исключение тега из чата";
7
7
  static scope = "chat_members:write";
8
8
  static apiMethod = "DELETE";
9
9
  static apiPath = "/chats/{id}/group_tags/{tag_id}";
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
3
3
  import { BaseCommand } from '../../base-command.js';
4
4
  import * as clack from '@clack/prompts';
5
5
  export default class MembersRemove extends BaseCommand {
6
- static description = "Исключение пользователя";
6
+ static description = "Исключение участника";
7
7
  static examples = [
8
8
  "Архивация и управление чатом — Удалить участника:\n $ pachca members remove"
9
9
  ];
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
3
3
  import { BaseCommand } from '../../base-command.js';
4
4
  import * as clack from '@clack/prompts';
5
5
  export default class MembersUpdate extends BaseCommand {
6
- static description = "Редактирование роли";
6
+ static description = "Редактирование роли участника";
7
7
  static examples = [
8
8
  "Архивация и управление чатом — Изменить роль участника:\n $ pachca members update"
9
9
  ];
@@ -13,7 +13,7 @@ export default class MessagesCreate extends BaseCommand {
13
13
  static apiMethod = "POST";
14
14
  static apiPath = "/messages";
15
15
  static defaultColumns = ["id", "content", "created_at", "entity_type", "entity_id"];
16
- static requiredFlags = ["entity-id", "content"];
16
+ static requiredFlags = ["entity-id"];
17
17
  static args = {};
18
18
  static flags = {
19
19
  ...BaseCommand.baseFlags,
@@ -21,28 +21,28 @@ export default class MessagesCreate extends BaseCommand {
21
21
  description: "Тип сущности. Регистр значения не учитывается. Значение вне списка возвращает `400` с кодом `invalid`.",
22
22
  }),
23
23
  'entity-id': Flags.integer({
24
- description: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо сотрудника. (pachca chats list | pachca users list)",
24
+ description: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо пользователя. У треда их два: `id` треда указывают с `entity_type: \"thread\"`, а его `chat_id` — с `discussion`, как у любого чата. (pachca chats list | pachca users list)",
25
25
  }),
26
26
  'content': Flags.string({
27
- description: "Текст сообщения. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`).",
27
+ description: "Текст сообщения. Обязателен, если к сообщению не приложены файлы. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`). `@all` упоминает всех участников чата, `@here` — тех, кто сейчас в сети, а `@` с названием тега без пробелов — сотрудников этого тега. Имя без `@` и упоминание внутри строчного кода или блока кода упоминанием не считаются. У мульти-гостя `<@user_id>` недоступного ему сотрудника остаётся в тексте как есть. До 40 000 байт в UTF-8, для кириллицы это около 20 000 символов. В пространстве с продвинутым шифрованием — до 27 000 байт. Сообщение уходит под именем владельца токена, у бота — с бейджем «Бот».",
28
28
  }),
29
29
  'files': Flags.string({
30
30
  description: "Прикрепляемые файлы",
31
31
  }),
32
32
  'buttons': Flags.string({
33
- description: "Массив строк, каждая из которых представлена массивом кнопок. Максимум 100 кнопок у сообщения, до 8 кнопок в строке.",
33
+ description: "Массив строк, каждая из которых представлена массивом кнопок. Максимум 100 кнопок у сообщения, до 8 кнопок в строке. Кнопки показываются под текстом и работают только у сообщений, отправленных токеном бота: нажатие на кнопку с `data` приходит событием `button_click` тому самому боту, а вместе с ним `trigger_id` — на открытие формы по нему есть 3 секунды, метод [Открытие представления](POST /views/open). Кнопка с `url` просто ведёт по ссылке и события не создаёт. Подробности — в разделе [Кнопки](https://dev.pachca.com/guides/buttons).",
34
34
  }),
35
35
  'parent-message-id': Flags.integer({
36
- description: "Идентификатор сообщения, на которое отвечаете. Ответ появится прямо в ленте чата, а не в треде: для треда отправляйте сообщение с `entity_type: \"thread\"`.",
36
+ description: "Идентификатор сообщения, на которое вы отвечаете с цитатой. Ответить можно на сообщение в любом чате, в том числе в треде: ответ отправляют в тот же чат или тред, где лежит это сообщение, иначе запрос вернёт ошибку `422`. Чтобы написать в тред под сообщением, укажите `entity_type: \"thread\"` и `id` треда в `entity_id`.",
37
37
  }),
38
38
  'display-avatar-url': Flags.string({
39
39
  description: "Ссылка на специальную аватарку отправителя для этого сообщения. Использование этого поля возможно только с access_token бота. (макс. 255 символов)",
40
40
  }),
41
41
  'display-name': Flags.string({
42
- description: "Полное специальное имя отправителя для этого сообщения. Использование этого поля возможно только с access_token бота. (макс. 255 символов)",
42
+ description: "Полное специальное имя отправителя для этого сообщения. Вместе с `display_avatar_url` бот подписывает сообщение чужим именем и аватаром, и только это сообщение. Бейдж «Бот» остаётся, а в профиле отправителя видно настоящего бота. Так показывают автора из другой системы, когда переносят в Пачку чужую переписку. С личным токеном поле недоступно, ответ `403`. Подробности — в разделе [Боты](https://dev.pachca.com/guides/bots/overview). (макс. 255 символов)",
43
43
  }),
44
44
  'skip-invite-mentions': Flags.boolean({
45
- description: "Пропуск добавления упоминаемых пользователей в тред. Работает только при отправке сообщения в тред.",
45
+ description: "Пропуск добавления упомянутых сотрудников в тред. В треде упоминание работает ещё и как приглашение: упомянутого сотрудника, которого в треде нет, Пачка туда добавляет, и он получает доступ к треду и родительскому сообщению. В беседе и канале упоминание никого не добавляет, и этот параметр там ничего не меняет.",
46
46
  allowNo: true,
47
47
  }),
48
48
  'link-preview': Flags.boolean({
@@ -62,8 +62,7 @@ export default class MessagesCreate extends BaseCommand {
62
62
  flags['content'] = Buffer.concat(chunks).toString('utf-8').trimEnd();
63
63
  }
64
64
  const missingRequired = [
65
- { flag: 'entity-id', label: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо сотрудника.", type: 'integer' },
66
- { flag: 'content', label: "Текст сообщения. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`).", type: 'string' },
65
+ { flag: 'entity-id', label: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо пользователя. У треда их два: `id` треда указывают с `entity_type: \"thread\"`, а его `chat_id` — с `discussion`, как у любого чата.", type: 'integer' },
67
66
  ].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
68
67
  if (missingRequired.length > 0) {
69
68
  if (this.isInteractive()) {
@@ -85,7 +84,7 @@ export default class MessagesCreate extends BaseCommand {
85
84
  }
86
85
  }
87
86
  else {
88
- this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --entity-id <integer>, --content <string>. pachca introspect messages create" });
87
+ this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --entity-id <integer>. pachca introspect messages create" });
89
88
  }
90
89
  }
91
90
  const validationErrors = [];
@@ -14,7 +14,7 @@ export default class MessagesGet extends BaseCommand {
14
14
  static defaultColumns = ["id", "content", "created_at", "entity_type", "entity_id"];
15
15
  static args = {
16
16
  id: Args.integer({
17
- description: "Идентификатор сообщения (pachca messages list)",
17
+ description: "Идентификатор сообщения. Ссылка веб-приложения указывает на сообщение параметром `sidebar_message`, а без него — параметром `message`. Число из `thread_message_id` — сообщение, под которым висит тред. (pachca messages list)",
18
18
  required: true,
19
19
  }),
20
20
  };
@@ -100,7 +100,7 @@ export default class MessagesList extends BaseCommand {
100
100
  const paginate = meta?.paginate;
101
101
  nextCursor = paginate?.next_page;
102
102
  pages++;
103
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
103
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
104
104
  const hasNext = paginate?.has_next;
105
105
  if (typeof hasNext === 'boolean') {
106
106
  if (!hasNext)
@@ -21,10 +21,10 @@ export default class MessagesUpdate extends BaseCommand {
21
21
  static flags = {
22
22
  ...BaseCommand.baseFlags,
23
23
  'content': Flags.string({
24
- description: "Текст сообщения. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`).",
24
+ description: "Текст сообщения. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`). У мульти-гостя `<@user_id>` недоступного ему сотрудника остаётся в тексте как есть. До 40 000 байт в UTF-8, для кириллицы это около 20 000 символов. В пространстве с продвинутым шифрованием — до 27 000 байт.",
25
25
  }),
26
26
  'files': Flags.string({
27
- description: "Прикрепляемые файлы",
27
+ description: "Прикрепляемые файлы. Переданный набор заменяет прежний: чтобы оставить уже приложенный файл, передайте его снова с тем же `key`.",
28
28
  }),
29
29
  'buttons': Flags.string({
30
30
  description: "Массив строк, каждая из которых представлена массивом кнопок. Максимум 100 кнопок у сообщения, до 8 кнопок в строке. Для удаления кнопок пришлите пустой массив.",
@@ -1,7 +1,6 @@
1
1
  // Auto-generated from openapi.yaml — DO NOT EDIT
2
2
  import { Flags } from '@oclif/core';
3
3
  import { BaseCommand } from '../../base-command.js';
4
- import * as clack from '@clack/prompts';
5
4
  export default class ProfileUpdateStatus extends BaseCommand {
6
5
  static description = "Новый свой статус";
7
6
  static examples = [
@@ -11,18 +10,17 @@ export default class ProfileUpdateStatus extends BaseCommand {
11
10
  static apiMethod = "PUT";
12
11
  static apiPath = "/profile/status";
13
12
  static defaultColumns = ["title", "emoji", "expires_at", "is_away"];
14
- static requiredFlags = ["emoji", "title"];
15
13
  static args = {};
16
14
  static flags = {
17
15
  ...BaseCommand.baseFlags,
18
16
  'emoji': Flags.string({
19
- description: "Emoji символ статуса",
17
+ description: "Emoji символ статуса. Обязателен, если статуса ещё нет.",
20
18
  }),
21
19
  'title': Flags.string({
22
- description: "Текст статуса (макс. 50 символов)",
20
+ description: "Текст статуса. Обязателен, если статуса ещё нет. (макс. 50 символов)",
23
21
  }),
24
22
  'expires-at': Flags.string({
25
- description: "Срок жизни статуса (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC. Сюда идёт срок, названный словами: «до трёх» это значение поля, а не часть подписи.",
23
+ description: "Срок жизни статуса (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC.",
26
24
  }),
27
25
  'is-away': Flags.boolean({
28
26
  description: "Режим «Нет на месте»",
@@ -35,33 +33,6 @@ export default class ProfileUpdateStatus extends BaseCommand {
35
33
  async run() {
36
34
  const { args, flags } = await this.parse(ProfileUpdateStatus);
37
35
  this.parsedFlags = flags;
38
- const missingRequired = [
39
- { flag: 'emoji', label: "Emoji символ статуса", type: 'string' },
40
- { flag: 'title', label: "Текст статуса", type: 'string' },
41
- ].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
42
- if (missingRequired.length > 0) {
43
- if (this.isInteractive()) {
44
- for (const field of missingRequired) {
45
- const value = await clack.text({ message: field.label, validate: (v) => v.length === 0 ? 'Обязательное поле' : undefined });
46
- if (clack.isCancel(value)) {
47
- process.stderr.write('Отменено.\n');
48
- this.exit(0);
49
- }
50
- if (field.type === 'integer') {
51
- flags[field.flag] = Number.parseInt(value, 10);
52
- }
53
- else if (field.type === 'boolean') {
54
- flags[field.flag] = value === 'true';
55
- }
56
- else {
57
- flags[field.flag] = value;
58
- }
59
- }
60
- }
61
- else {
62
- this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --emoji <string>, --title <string>. pachca introspect profile update-status" });
63
- }
64
- }
65
36
  const validationErrors = [];
66
37
  if (flags['title'] && String(flags['title']).length > 50) {
67
38
  validationErrors.push({ message: `--title: максимум 50 символов (передано: ${String(flags['title']).length})`, flag: 'title' });
@@ -49,7 +49,7 @@ export default class ReactionsList extends BaseCommand {
49
49
  const paginate = meta?.paginate;
50
50
  nextCursor = paginate?.next_page;
51
51
  pages++;
52
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
52
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
53
53
  const hasNext = paginate?.has_next;
54
54
  if (typeof hasNext === 'boolean') {
55
55
  if (!hasNext)
@@ -51,7 +51,7 @@ export default class ReadMemberListReaders extends BaseCommand {
51
51
  const paginate = meta?.paginate;
52
52
  nextCursor = paginate?.next_page;
53
53
  pages++;
54
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
54
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
55
55
  const hasNext = paginate?.has_next;
56
56
  if (typeof hasNext === 'boolean') {
57
57
  if (!hasNext)
@@ -16,7 +16,7 @@ export default class SearchListChats extends BaseCommand {
16
16
  static flags = {
17
17
  ...BaseCommand.baseFlags,
18
18
  'query': Flags.string({
19
- description: "Текст поискового запроса",
19
+ description: "Текст поискового запроса. Запрос длиннее 500 знаков обрезается.",
20
20
  }),
21
21
  'order': Flags.string({
22
22
  description: "Направление сортировки",
@@ -81,7 +81,7 @@ export default class SearchListChats extends BaseCommand {
81
81
  const paginate = meta?.paginate;
82
82
  nextCursor = paginate?.next_page;
83
83
  pages++;
84
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
84
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
85
85
  const hasNext = paginate?.has_next;
86
86
  if (typeof hasNext === 'boolean') {
87
87
  if (!hasNext)
@@ -14,7 +14,7 @@ export default class SearchListMessages extends BaseCommand {
14
14
  static flags = {
15
15
  ...BaseCommand.baseFlags,
16
16
  'query': Flags.string({
17
- description: "Текст поискового запроса",
17
+ description: "Текст поискового запроса. Без него сообщения отбираются только фильтрами. Запрос длиннее 500 знаков обрезается.",
18
18
  }),
19
19
  'order': Flags.string({
20
20
  description: "Направление сортировки",
@@ -68,8 +68,8 @@ export default class SearchListMessages extends BaseCommand {
68
68
  sort: flags['sort'],
69
69
  'created_from': flags['created-from'],
70
70
  'created_to': flags['created-to'],
71
- 'chat_ids': flags['chat-ids']?.split(','),
72
- 'user_ids': flags['user-ids']?.split(','),
71
+ 'chat_ids[]': flags['chat-ids']?.split(','),
72
+ 'user_ids[]': flags['user-ids']?.split(','),
73
73
  active: flags['active'],
74
74
  limit: flags.limit,
75
75
  cursor: nextCursor,
@@ -83,7 +83,7 @@ export default class SearchListMessages extends BaseCommand {
83
83
  const paginate = meta?.paginate;
84
84
  nextCursor = paginate?.next_page;
85
85
  pages++;
86
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
86
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
87
87
  const hasNext = paginate?.has_next;
88
88
  if (typeof hasNext === 'boolean') {
89
89
  if (!hasNext)
@@ -122,8 +122,8 @@ export default class SearchListMessages extends BaseCommand {
122
122
  sort: flags['sort'],
123
123
  'created_from': flags['created-from'],
124
124
  'created_to': flags['created-to'],
125
- 'chat_ids': flags['chat-ids']?.split(','),
126
- 'user_ids': flags['user-ids']?.split(','),
125
+ 'chat_ids[]': flags['chat-ids']?.split(','),
126
+ 'user_ids[]': flags['user-ids']?.split(','),
127
127
  active: flags['active'],
128
128
  limit: flags.limit,
129
129
  cursor: flags.cursor,
@@ -16,7 +16,7 @@ export default class SearchListUsers extends BaseCommand {
16
16
  static flags = {
17
17
  ...BaseCommand.baseFlags,
18
18
  'query': Flags.string({
19
- description: "Текст поискового запроса",
19
+ description: "Текст поискового запроса. Запрос длиннее 500 знаков обрезается.",
20
20
  }),
21
21
  'sort': Flags.string({
22
22
  description: "Сортировка результатов",
@@ -62,7 +62,7 @@ export default class SearchListUsers extends BaseCommand {
62
62
  order: flags['order'],
63
63
  'created_from': flags['created-from'],
64
64
  'created_to': flags['created-to'],
65
- 'company_roles': flags['company-roles']?.split(','),
65
+ 'company_roles[]': flags['company-roles']?.split(','),
66
66
  limit: flags.limit,
67
67
  cursor: nextCursor,
68
68
  };
@@ -75,7 +75,7 @@ export default class SearchListUsers extends BaseCommand {
75
75
  const paginate = meta?.paginate;
76
76
  nextCursor = paginate?.next_page;
77
77
  pages++;
78
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
78
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
79
79
  const hasNext = paginate?.has_next;
80
80
  if (typeof hasNext === 'boolean') {
81
81
  if (!hasNext)
@@ -114,7 +114,7 @@ export default class SearchListUsers extends BaseCommand {
114
114
  order: flags['order'],
115
115
  'created_from': flags['created-from'],
116
116
  'created_to': flags['created-to'],
117
- 'company_roles': flags['company-roles']?.split(','),
117
+ 'company_roles[]': flags['company-roles']?.split(','),
118
118
  limit: flags.limit,
119
119
  cursor: flags.cursor,
120
120
  },
@@ -24,7 +24,7 @@ export default class SecurityList extends BaseCommand {
24
24
  }),
25
25
  'event-key': Flags.string({
26
26
  description: "Фильтр по конкретному типу события",
27
- options: ["user_login", "user_logout", "user_2fa_fail", "user_2fa_success", "user_2fa_disabled", "user_created", "user_deleted", "user_role_changed", "user_updated", "tag_created", "tag_deleted", "user_added_to_tag", "user_removed_from_tag", "chat_created", "chat_renamed", "chat_permission_changed", "user_chat_join", "user_chat_leave", "tag_added_to_chat", "tag_removed_from_chat", "message_updated", "message_deleted", "message_created", "reaction_created", "reaction_deleted", "thread_created", "access_token_created", "access_token_updated", "access_token_destroy", "kms_encrypt", "kms_decrypt", "audit_events_accessed", "company_chats_accessed", "company_bots_accessed", "dlp_violation_detected", "search_users_api", "search_chats_api", "search_messages_api", "bot_scopes_updated", "bot_webhook_settings_updated", "bot_token_recreated", "bot_deleted", "bot_oauth_client_updated", "oauth_authorization_granted", "oauth_authorization_revoked", "oauth_device_authorization_approved", "oauth_device_authorization_denied", "video_call_started", "video_call_finished", "video_call_recording_ready", "exchange_disabled"],
27
+ options: ["user_login", "user_logout", "user_2fa_fail", "user_2fa_success", "user_2fa_disabled", "user_created", "user_deleted", "user_role_changed", "user_updated", "tag_created", "tag_deleted", "user_added_to_tag", "user_removed_from_tag", "chat_created", "chat_renamed", "chat_permission_changed", "user_chat_join", "user_chat_leave", "tag_added_to_chat", "tag_removed_from_chat", "message_updated", "message_deleted", "message_created", "reaction_created", "reaction_deleted", "thread_created", "access_token_created", "access_token_updated", "access_token_destroy", "kms_encrypt", "kms_decrypt", "audit_events_accessed", "company_chats_accessed", "company_bots_accessed", "dlp_violation_detected", "search_users_api", "search_chats_api", "search_messages_api", "bot_scopes_updated", "bot_webhook_settings_updated", "bot_token_recreated", "bot_deleted", "bot_oauth_client_updated", "bot_oauth_client_disabled", "bot_oauth_client_secret_rotated", "bot_oauth_client_secret_issued", "bot_token_created", "bot_token_updated", "bot_token_reissued", "bot_token_deleted", "oauth_authorization_granted", "oauth_authorization_revoked", "oauth_token_revoked", "oauth_device_authorization_approved", "oauth_device_authorization_denied", "video_call_started", "video_call_finished", "video_call_recording_ready", "exchange_disabled"],
28
28
  }),
29
29
  'actor-id': Flags.string({
30
30
  description: "Идентификатор пользователя, выполнившего действие",
@@ -79,7 +79,7 @@ export default class SecurityList extends BaseCommand {
79
79
  const paginate = meta?.paginate;
80
80
  nextCursor = paginate?.next_page;
81
81
  pages++;
82
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
82
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
83
83
  const hasNext = paginate?.has_next;
84
84
  if (typeof hasNext === 'boolean') {
85
85
  if (!hasNext)
@@ -21,7 +21,7 @@ export default class TasksCreate extends BaseCommand {
21
21
  description: "Тип",
22
22
  }),
23
23
  'content': Flags.string({
24
- description: "Описание (по умолчанию — название типа)",
24
+ description: "Описание, по умолчанию — название типа. До 40 000 байт в UTF-8.",
25
25
  }),
26
26
  'due-at': Flags.string({
27
27
  description: "Срок выполнения напоминания (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC. Секунды отбрасываются: срок встаёт на начало минуты. Исключение — ровно 23:59:59: такое напоминание создаётся на весь день, без указания времени.",
@@ -12,7 +12,7 @@ export default class TasksGet extends BaseCommand {
12
12
  static defaultColumns = ["id", "content", "created_at", "kind", "due_at"];
13
13
  static args = {
14
14
  id: Args.integer({
15
- description: "Идентификатор напоминания (pachca tasks list)",
15
+ description: "Идентификатор напоминания: в ссылке веб-приложения это число из пути `/tasks/{id}` или из параметра `task_id` (pachca tasks list)",
16
16
  required: true,
17
17
  }),
18
18
  };
@@ -20,7 +20,7 @@ export default class TasksList extends BaseCommand {
20
20
  options: ["done", "undone"],
21
21
  }),
22
22
  'chat-ids': Flags.string({
23
- description: "Фильтр по чатам, к которым привязаны напоминания. Доступными считаются чаты, где вы состоите участником, открытые беседы и каналы пространства, а также треды, доступные вам по родительскому чату. Остальные переданные идентификаторы игнорируются без ошибки. Не более 100 идентификаторов." + " (через запятую)",
23
+ description: "Фильтр по чатам, к которым привязаны напоминания. Доступными считаются чаты, где вы состоите участником, открытые беседы и каналы пространства, а также треды, доступные вам по родительскому чату. Мульти-гостю открытые беседы и каналы доступны, только если он в них участник. Остальные переданные идентификаторы игнорируются без ошибки. Не более 100 идентификаторов." + " (через запятую)",
24
24
  }),
25
25
  'performer-ids': Flags.string({
26
26
  description: "Фильтр по ответственным за напоминание. Не более 100 идентификаторов." + " (через запятую)",
@@ -51,8 +51,8 @@ export default class TasksList extends BaseCommand {
51
51
  while (pages < 500) {
52
52
  const query = {
53
53
  status: flags['status'],
54
- 'chat_ids': flags['chat-ids']?.split(','),
55
- 'performer_ids': flags['performer-ids']?.split(','),
54
+ 'chat_ids[]': flags['chat-ids']?.split(','),
55
+ 'performer_ids[]': flags['performer-ids']?.split(','),
56
56
  'author_id': flags['author-id'],
57
57
  limit: flags.limit,
58
58
  cursor: nextCursor,
@@ -66,7 +66,7 @@ export default class TasksList extends BaseCommand {
66
66
  const paginate = meta?.paginate;
67
67
  nextCursor = paginate?.next_page;
68
68
  pages++;
69
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
69
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
70
70
  const hasNext = paginate?.has_next;
71
71
  if (typeof hasNext === 'boolean') {
72
72
  if (!hasNext)
@@ -101,8 +101,8 @@ export default class TasksList extends BaseCommand {
101
101
  path: '/tasks',
102
102
  query: {
103
103
  status: flags['status'],
104
- 'chat_ids': flags['chat-ids']?.split(','),
105
- 'performer_ids': flags['performer-ids']?.split(','),
104
+ 'chat_ids[]': flags['chat-ids']?.split(','),
105
+ 'performer_ids[]': flags['performer-ids']?.split(','),
106
106
  'author_id': flags['author-id'],
107
107
  limit: flags.limit,
108
108
  cursor: flags.cursor,
@@ -23,7 +23,7 @@ export default class TasksUpdate extends BaseCommand {
23
23
  description: "Тип",
24
24
  }),
25
25
  'content': Flags.string({
26
- description: "Описание",
26
+ description: "Описание. До 40 000 байт в UTF-8.",
27
27
  }),
28
28
  'due-at': Flags.string({
29
29
  description: "Срок выполнения напоминания (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC. Секунды отбрасываются: срок встаёт на начало минуты. Исключение — ровно 23:59:59: такое напоминание создаётся на весь день, без указания времени.",
@@ -9,7 +9,7 @@ export default class ThreadsGet extends BaseCommand {
9
9
  static defaultColumns = ["id", "chat_id", "message_id", "message_chat_id", "updated_at"];
10
10
  static args = {
11
11
  id: Args.integer({
12
- description: "Идентификатор треда",
12
+ description: "Идентификатор треда: в ссылке веб-приложения это число из параметра `thread_id`",
13
13
  required: true,
14
14
  }),
15
15
  };
@@ -5,7 +5,7 @@ export default class ThreadsList extends BaseCommand {
5
5
  static description = "Список тредов";
6
6
  static examples = [
7
7
  "Получить список активных тредов за период — Запроси список тредов с фильтром по времени последнего сообщения и нужным `--limit`:\n $ pachca threads list",
8
- "Получить список активных тредов за период — Если в ответе `meta.paginate.next_page` — пройди по страницам через `--cursor`:\n $ pachca threads list"
8
+ "Получить список активных тредов за период — Пока `meta.paginate.has_next` равен `true`, бери следующую страницу через `--cursor=<next_page>`:\n $ pachca threads list"
9
9
  ];
10
10
  static scope = "threads:read";
11
11
  static apiMethod = "GET";
@@ -56,7 +56,7 @@ export default class ThreadsList extends BaseCommand {
56
56
  const paginate = meta?.paginate;
57
57
  nextCursor = paginate?.next_page;
58
58
  pages++;
59
- // Условие конца: списочные методы — has_next === false; методы поиска и /users?query= (без has_next) — пустой data
59
+ // Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
60
60
  const hasNext = paginate?.has_next;
61
61
  if (typeof hasNext === 'boolean') {
62
62
  if (!hasNext)