From ab4a5b9ecc549fbf81f916da0555199f1d1fcae3 Mon Sep 17 00:00:00 2001 From: Neel Kamath Date: Tue, 6 Apr 2021 19:49:57 +0530 Subject: [PATCH] Release v0.11.0 (#14) * Fix * Fix * Update to Omni Chat Backend 0.18.0 --- CHANGELOG.md | 79 +++++- README.md | 11 +- package.json | 2 +- src/__tests__/validators.test.ts | 2 +- src/graphql-api/fragments.ts | 218 +++++++++----- src/graphql-api/models.ts | 265 +++++++++--------- .../mutations/createActionMessage.ts | 3 +- src/graphql-api/mutations/createContact.ts | 33 +++ src/graphql-api/mutations/createContacts.ts | 32 --- .../mutations/createGroupChatInviteMessage.ts | 3 +- .../mutations/createPollMessage.ts | 3 +- .../mutations/createTextMessage.ts | 5 +- src/graphql-api/mutations/deleteContact.ts | 32 +++ src/graphql-api/mutations/deleteContacts.ts | 32 --- src/graphql-api/mutations/forwardMessage.ts | 3 +- src/graphql-api/mutations/index.ts | 4 +- src/graphql-api/mutations/unblockUser.ts | 4 +- src/graphql-api/queries/index.ts | 1 + src/graphql-api/queries/readChats.ts | 15 +- src/graphql-api/queries/readStars.ts | 20 +- src/graphql-api/queries/searchBlockedUsers.ts | 38 +++ src/graphql-api/queries/searchChats.ts | 15 +- src/graphql-api/queries/searchMessages.ts | 15 +- src/graphql-api/queries/searchPublicChats.ts | 16 +- src/graphql-api/scalars.ts | 2 +- src/index.ts | 4 +- 26 files changed, 538 insertions(+), 319 deletions(-) create mode 100644 src/graphql-api/mutations/createContact.ts delete mode 100644 src/graphql-api/mutations/createContacts.ts create mode 100644 src/graphql-api/mutations/deleteContact.ts delete mode 100644 src/graphql-api/mutations/deleteContacts.ts create mode 100644 src/graphql-api/queries/searchBlockedUsers.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e16a536..d76d124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,80 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.10.0](https://github.com/neelkamath/omni-chat-js/releases/tag/v0.7.0) - 2020-03-25 +## [0.11.0](https://github.com/neelkamath/omni-chat-js/releases/tag/v0.11.0) - 2020-04-06 + +### Added + +- `searchBlockedUsers()` +- `interface DeletedAccount` +- `createContact()` +- `deleteContact()` +- `interface StarredMessagesConnection` +- `interface StarredMessageEdge` +- `interface ChatMessagesConnection` +- `interface ChatMessagesEdge` +- `interface ChatsConnection` +- `interface ChatEdge` +- `interface GroupChatsConnection` +- `interface GroupChatEdge` + +### Changed + +- `interface AccountInput` +- Rename `chatId` to `id` in `interface UnstarredChat`. +- `scalar Username` +- Add `interface DeletedAccount` to `interface AccountsSubscription`. +- Return a `boolean` instead of a `Placeholder` from `unblockUser()` to indicate whether the user got unblocked. +- Use GitHub Flavored Markdown instead of CommonMark (update `type Bio`, `type GroupChatDescription`, and `type MessageText` accordingly). +- Paginate `readStars()`. +- Paginate `searchMessages()`. +- Paginate `readChats()`. +- Paginate `searchChats()`. +- Paginate `searchPublicChats()`. +- Remove the `dateTimes` field, and add the `sent` field to the following: + - `interface NewMessage` + - `interface NewTextMessage` + - `interface NewActionMessage` + - `interface NewPicMessage` + - `interface NewPollMessage` + - `interface NewAudioMessage` + - `interface NewGroupChatInviteMessage` + - `interface NewDocMessage` + - `interface NewVideoMessage` +- Remove the `dateTimes` field, and add the `sent` and `statuses` fields to the following: + - `interface Message` + - `interface TextMessage` + - `interface ActionMessage` + - `interface PicMessage` + - `interface PollMessage` + - `interface AudioMessage` + - `interface GroupChatInviteMessage` + - `interface DocMessage` + - `interface VideoMessage` + - `interface StarredMessage` + - `interface StarredTextMessage` + - `interface StarredActionMessage` + - `interface StarredPicMessage` + - `interface StarredPollMessage` + - `interface StarredAudioMessage` + - `interface StarredGroupChatInviteMessage` + - `interface StarredDocMessage` + - `interface StarredVideoMessage` + +### Removed + +- Remove `createContacts()` in favor of `createContact()`. +- Remove `deleteContacts()` in favor of `deleteContact()`. +- `interface BareMessage` +- `interface BareChatMessage` +- `interface MessageDateTimes` + +### Fixed + +- Fix pagination bugs. +- `createTextMessage()` + +## [0.10.0](https://github.com/neelkamath/omni-chat-js/releases/tag/v0.10.0) - 2020-03-25 ### Added @@ -32,7 +105,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `searchChatMessages()` - `subscribeToMessages()` -## [0.9.0](https://github.com/neelkamath/omni-chat-js/releases/tag/v0.7.0) - 2020-03-21 +## [0.9.0](https://github.com/neelkamath/omni-chat-js/releases/tag/v0.9.0) - 2020-03-21 ### Added @@ -76,7 +149,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `class NameScalarError` - `class DateTimeScalarError` -## [0.8.0](https://github.com/neelkamath/omni-chat-js/releases/tag/v0.7.0) - 2020-03-20 +## [0.8.0](https://github.com/neelkamath/omni-chat-js/releases/tag/v0.8.0) - 2020-03-20 ### Added diff --git a/README.md b/README.md index 06873a2..9f48d5c 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,12 @@ Official [Omni Chat API](https://github.com/neelkamath/omni-chat-backend) JavaSc This table shows which versions of Omni Chat JS support which versions of Omni Chat Backend: -| Omni Chat JS | Omni Chat Backend | -| :-------------: | :---------------: | -| 0.8.0 or higher | 0.17.0 | -| 0.5.0 - 0.7.0 | 0.16.0 | -| 0.1.0 - 0.4.0 | 0.15.0 | +| Omni Chat JS | Omni Chat Backend | +| :--------------: | :---------------: | +| 0.11.0 or higher | 0.18.0 | +| 0.8.0 - 0.10.0 | 0.17.0 | +| 0.5.0 - 0.7.0 | 0.16.0 | +| 0.1.0 - 0.4.0 | 0.15.0 | ``` npm i @neelkamath/omni-chat diff --git a/package.json b/package.json index 2a5c2e5..c83eb80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@neelkamath/omni-chat", - "version": "0.10.0", + "version": "0.11.0", "description": "Official Omni Chat API wrapper library", "scripts": { "test": "jest", diff --git a/src/__tests__/validators.test.ts b/src/__tests__/validators.test.ts index 5a278ed..051d6ef 100644 --- a/src/__tests__/validators.test.ts +++ b/src/__tests__/validators.test.ts @@ -11,7 +11,7 @@ import { } from '../graphql-api'; describe('isValidUsernameScalar()', () => { - test('username must be valid', () => expect(isValidUsernameScalar('username')).toBe(true)); + test('username must be valid', () => expect(isValidUsernameScalar('a0._')).toBe(true)); test('username cannot contain whitespace', () => expect(isValidUsernameScalar('user name')).toBe(false)); diff --git a/src/graphql-api/fragments.ts b/src/graphql-api/fragments.ts index aea2baa..0911df6 100644 --- a/src/graphql-api/fragments.ts +++ b/src/graphql-api/fragments.ts @@ -126,16 +126,6 @@ export const MESSAGE_DATE_TIME_STATUS_FRAGMENT = ` } `; -export const MESSAGE_DATE_TIMES_FRAGMENT = ` - ... on MessageDateTimes { - __typename - sent - statuses { - ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} - } - } -`; - export const MESSAGE_CONTEXT_FRAGMENT = ` ... on MessageContext { __typename @@ -152,8 +142,9 @@ export const TEXT_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -172,8 +163,9 @@ export const ACTION_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -194,8 +186,9 @@ export const AUDIO_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -227,8 +220,9 @@ export const GROUP_CHAT_INVITE_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -247,8 +241,9 @@ export const DOC_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -266,8 +261,9 @@ export const VIDEO_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -285,8 +281,9 @@ export const PIC_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -323,8 +320,9 @@ export const POLL_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -420,9 +418,7 @@ export const NEW_TEXT_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} - } + sent context { ${MESSAGE_CONTEXT_FRAGMENT} } @@ -440,9 +436,7 @@ export const NEW_ACTION_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} - } + sent context { ${MESSAGE_CONTEXT_FRAGMENT} } @@ -462,9 +456,7 @@ export const NEW_PIC_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} - } + sent context { ${MESSAGE_CONTEXT_FRAGMENT} } @@ -482,9 +474,7 @@ export const NEW_AUDIO_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} - } + sent context { ${MESSAGE_CONTEXT_FRAGMENT} } @@ -501,9 +491,7 @@ export const NEW_GROUP_CHAT_INVITE_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} - } + sent context { ${MESSAGE_CONTEXT_FRAGMENT} } @@ -521,9 +509,7 @@ export const NEW_DOC_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} - } + sent context { ${MESSAGE_CONTEXT_FRAGMENT} } @@ -540,9 +526,7 @@ export const NEW_VIDEO_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} - } + sent context { ${MESSAGE_CONTEXT_FRAGMENT} } @@ -559,9 +543,7 @@ export const NEW_POLL_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} - } + sent context { ${MESSAGE_CONTEXT_FRAGMENT} } @@ -709,8 +691,9 @@ export const STARRED_TEXT_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -729,8 +712,9 @@ export const STARRED_ACTION_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -751,8 +735,9 @@ export const STARRED_PIC_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -771,8 +756,9 @@ export const STARRED_POLL_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -793,8 +779,9 @@ export const STARRED_AUDIO_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -812,8 +799,9 @@ export const STARRED_GROUP_CHAT_INVITE_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -832,8 +820,9 @@ export const STARRED_DOC_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -851,8 +840,9 @@ export const STARRED_VIDEO_MESSAGE_FRAGMENT = ` ${ACCOUNT_FRAGMENT} } state - dateTimes { - ${MESSAGE_DATE_TIMES_FRAGMENT} + sent + statuses { + ${MESSAGE_DATE_TIME_STATUS_FRAGMENT} } context { ${MESSAGE_CONTEXT_FRAGMENT} @@ -872,6 +862,13 @@ export const STARRED_MESSAGE_FRAGMENT = ` ${STARRED_VIDEO_MESSAGE_FRAGMENT} `; +export const DELETED_ACCOUNT_FRAGMENT = ` + ... on DeletedAccount { + __typename + id + } +`; + export const ACCOUNTS_SUBSCRIPTION_FRAGMENT = ` ${CREATED_SUBSCRIPTION_FRAGMENT} ${NEW_CONTACT_FRAGMENT} @@ -880,6 +877,7 @@ export const ACCOUNTS_SUBSCRIPTION_FRAGMENT = ` ${DELETED_CONTACT_FRAGMENT} ${BLOCKED_ACCOUNT_FRAGMENT} ${UNBLOCKED_ACCOUNT_FRAGMENT} + ${DELETED_ACCOUNT_FRAGMENT} `; export const TYPING_USERS_FRAGMENT = ` @@ -1155,7 +1153,7 @@ export const CANNOT_LEAVE_CHAT_FRAGMENT = ` export const UNSTARRED_CHAT_FRAGMENT = ` ... on UnstarredChat { __typename - chatId + id } `; @@ -1205,3 +1203,89 @@ export const ONLINE_STATUSES_SUBSCRIPTION_FRAGMENT = ` ${CREATED_SUBSCRIPTION_FRAGMENT} ${ONLINE_STATUS_FRAGMENT} `; + +export const STARRED_MESSAGES_CONNECTION_FRAGMENT = ` + ... on StarredMessagesConnection { + __typename + edges { + ${STARRED_MESSAGE_FRAGMENT} + pageInfo { + ${PAGE_INFO_FRAGMENT} + } + } +`; + +export const STARRED_MESSAGE_EDGE_FRAGMENT = ` + ... on StarredMessageEdge { + __typename + node { + ${STARRED_MESSAGE_FRAGMENT} + } + cursor + } +`; + +export const CHAT_MESSAGES_EDGE_FRAGMENT = ` + ... on ChatMessageEdge { + node { + ${CHAT_MESSAGES_FRAGMENT} + } + cursor + } +`; + +export const CHAT_MESSAGES_CONNECTION_FRAGMENT = ` + ... on ChatMessagesConnection { + __typename + edges { + ${CHAT_MESSAGES_EDGE_FRAGMENT} + } + pageInfo { + ${PAGE_INFO_FRAGMENT} + } + } +`; + +export const CHAT_EDGE_FRAGMENT = ` + ... on ChatEdge { + __typename + node { + ${CHAT_FRAGMENT} + } + cursor + } +`; + +export const CHATS_CONNECTION_FRAGMENT = ` + ... on ChatsConnection { + __typename + edges { + ${CHAT_EDGE_FRAGMENT} + } + pageInfo { + ${PAGE_INFO_FRAGMENT} + } + } +`; + +export const GROUP_CHAT_EDGE_FRAGMENT = ` + ... on GroupChatEdge { + __typename + node { + ${GROUP_CHAT_FRAGMENT} + } + cursor + } +`; + +export const GROUP_CHATS_CONNECTION_FRAGMENT = ` + ... on GroupChatsConnection { + __typename + edges { + ${GROUP_CHAT_EDGE_FRAGMENT} + } + pageInfo { + ${PAGE_INFO_FRAGMENT} + } + } +`; diff --git a/src/graphql-api/models.ts b/src/graphql-api/models.ts index 5147dfa..927cd0a 100644 --- a/src/graphql-api/models.ts +++ b/src/graphql-api/models.ts @@ -13,7 +13,8 @@ export type AccountsSubscription = | UpdatedProfilePic | DeletedContact | BlockedAccount - | UnblockedAccount; + | UnblockedAccount + | DeletedAccount; export type MessagesSubscription = | CreatedSubscription @@ -68,14 +69,18 @@ export type DateTime = string; /** A cursor for pagination. */ export type Cursor = string; -/** A username must not contain whitespace, must be lowercase, and must be 1-30 characters long. */ +/** + * A username must be 1-30 characters long. Only lowercase English letters (a-z), English numbers (0-9), periods, and + * underscores are allowed. + */ export type Username = string; /** A name must neither contain whitespace nor exceed 30 characters. */ export type Name = string; /** - * A user's bio which cannot exceed 2,500 characters, disallows leading and trailing whitespace, and uses CommonMark. + * A user's bio which cannot exceed 2,500 characters, disallows leading and trailing whitespace, and uses GitHub + * Flavored Markdown. */ export type Bio = string; @@ -85,12 +90,12 @@ export type Password = string; /** 1-70 characters, of which at least one isn't whitespace. Leading and trailing whitespace is disallowed. */ export type GroupChatTitle = string; -/** At most 1,000 characters, disallows leading and trailing whitespace, and uses CommonMark. */ +/** At most 1,000 characters, disallows leading and trailing whitespace, and uses GitHub Flavored Markdown. */ export type GroupChatDescription = string; /** - * 1-10,000 characters, of which at least one isn't whitespace. Uses CommonMark. Leading and trailing whitespace is - * disallowed. + * 1-10,000 characters, of which at least one isn't whitespace. Uses GitHub Flavored Markdown. Leading and trailing + * whitespace is disallowed. */ export type MessageText = string; @@ -103,6 +108,12 @@ export interface CreatedSubscription { readonly placeholder: Placeholder; } +/** The {@link id} of the user who deleted their account. */ +export interface DeletedAccount { + readonly __typename: 'DeletedAccount'; + readonly id: number; +} + /** Only non-`null` fields will be updated. */ export interface AccountUpdate { readonly __typename: 'AccountUpdate'; @@ -114,14 +125,15 @@ export interface AccountUpdate { readonly bio: Bio | null; } +/** The server will use an empty string for fields which are `undefined`. */ export interface AccountInput { readonly __typename: 'AccountInput'; readonly username: Username; readonly password: Password; readonly emailAddress: string; - readonly firstName: Name | null; - readonly lastName: Name | null; - readonly bio: Bio | null; + readonly firstName?: Name; + readonly lastName?: Name; + readonly bio?: Bio; } export interface Login { @@ -247,47 +259,13 @@ export interface MessageEdge { readonly cursor: Cursor; } -export interface BareMessage { - readonly __typename: - | 'TextMessage' - | 'ActionMessage' - | 'PicMessage' - | 'PollMessage' - | 'AudioMessage' - | 'GroupChatInviteMessage' - | 'DocMessage' - | 'VideoMessage' - | 'StarredTextMessage' - | 'StarredActionMessage' - | 'StarredPicMessage' - | 'StarredPollMessage' - | 'StarredAudioMessage' - | 'StarredGroupChatInviteMessage' - | 'StarredDocMessage' - | 'StarredVideoMessage' - | 'NewTextMessage' - | 'NewActionMessage' - | 'NewPicMessage' - | 'NewPollMessage' - | 'NewAudioMessage' - | 'NewGroupChatInviteMessage' - | 'NewDocMessage' - | 'NewVideoMessage'; - readonly messageId: number; - readonly sender: Account; - readonly state: MessageState; - readonly dateTimes: MessageDateTimes; - readonly context: MessageContext; - readonly isForwarded: boolean; -} - /** The {@link id} of the group chat whose pic was updated. */ export interface UpdatedGroupChatPic { readonly __typename: 'UpdatedGroupChatPic'; readonly id: number; } -export interface Message extends BareMessage { +export interface Message { readonly __typename: | 'TextMessage' | 'ActionMessage' @@ -300,18 +278,13 @@ export interface Message extends BareMessage { readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; } -export interface MessageDateTimes { - readonly __typename: 'MessageDateTimes'; - readonly sent: DateTime; - readonly statuses: MessageDateTimeStatus[]; -} - export type MessageStatus = 'DELIVERED' | 'READ'; /** @@ -514,7 +487,7 @@ export interface UpdatedMessage { /** Every message in the chat has been unstarred by the user. */ export interface UnstarredChat { readonly __typename: 'UnstarredChat'; - readonly chatId: number; + readonly id: number; } /** The {@link dateTime} the {@link user} created the {@link status}. */ @@ -727,128 +700,109 @@ export interface GroupChatInfo extends BareGroupChat { readonly publicity: GroupChatPublicity; } -export interface TextMessage extends BareMessage, Message { +export interface TextMessage extends Message { readonly __typename: 'TextMessage'; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; readonly textMessage: MessageText; } -export interface ActionMessage extends BareMessage, Message { +export interface ActionMessage extends Message { readonly __typename: 'ActionMessage'; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; readonly actionableMessage: ActionableMessage; } -export interface PicMessage extends BareMessage, Message { +export interface PicMessage extends Message { readonly __typename: 'PicMessage'; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; readonly caption: MessageText | null; } -export interface PollMessage extends BareMessage, Message { +export interface PollMessage extends Message { readonly __typename: 'PollMessage'; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; readonly poll: Poll; } -export interface AudioMessage extends BareMessage, Message { +export interface AudioMessage extends Message { readonly __typename: 'AudioMessage'; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; } -export interface GroupChatInviteMessage extends BareMessage, Message { +export interface GroupChatInviteMessage extends Message { readonly __typename: 'GroupChatInviteMessage'; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; readonly inviteCode: Uuid; } -export interface DocMessage extends BareMessage, Message { +export interface DocMessage extends Message { readonly __typename: 'DocMessage'; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; } -export interface VideoMessage extends BareMessage, Message { +export interface VideoMessage extends Message { readonly __typename: 'VideoMessage'; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly hasStar: boolean; } -export interface BareChatMessage extends BareMessage { - readonly __typename: - | 'StarredTextMessage' - | 'StarredActionMessage' - | 'StarredPicMessage' - | 'StarredPollMessage' - | 'StarredAudioMessage' - | 'StarredGroupChatInviteMessage' - | 'StarredDocMessage' - | 'StarredVideoMessage' - | 'NewTextMessage' - | 'NewActionMessage' - | 'NewPicMessage' - | 'NewPollMessage' - | 'NewAudioMessage' - | 'NewGroupChatInviteMessage' - | 'NewDocMessage' - | 'NewVideoMessage'; - readonly chatId: number; - readonly messageId: number; - readonly sender: Account; - readonly state: MessageState; - readonly dateTimes: MessageDateTimes; - readonly context: MessageContext; - readonly isForwarded: boolean; -} - /** The message which the user starred. */ -export interface StarredMessage extends BareChatMessage, BareMessage { +export interface StarredMessage { readonly __typename: | 'StarredTextMessage' | 'StarredActionMessage' @@ -862,105 +816,114 @@ export interface StarredMessage extends BareChatMessage, BareMessage { readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; } -export interface StarredTextMessage extends StarredMessage, BareChatMessage, BareMessage { +export interface StarredTextMessage extends StarredMessage { readonly __typename: 'StarredTextMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly textMessage: MessageText; } -export interface StarredActionMessage extends StarredMessage, BareChatMessage, BareMessage { +export interface StarredActionMessage extends StarredMessage { readonly __typename: 'StarredActionMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly actionableMessage: ActionableMessage; } -export interface StarredPicMessage extends StarredMessage, BareChatMessage, BareMessage { +export interface StarredPicMessage extends StarredMessage { readonly __typename: 'StarredPicMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly caption: MessageText | null; } -export interface StarredPollMessage extends StarredMessage, BareChatMessage, BareMessage { +export interface StarredPollMessage extends StarredMessage { readonly __typename: 'StarredPollMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly poll: Poll; } -export interface StarredAudioMessage extends StarredMessage, BareChatMessage, BareMessage { +export interface StarredAudioMessage extends StarredMessage { readonly __typename: 'StarredAudioMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; } -export interface StarredGroupChatInviteMessage extends StarredMessage, BareChatMessage, BareMessage { +export interface StarredGroupChatInviteMessage extends StarredMessage { readonly __typename: 'StarredGroupChatInviteMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; readonly inviteCode: Uuid; } -export interface StarredDocMessage extends StarredMessage, BareChatMessage, BareMessage { +export interface StarredDocMessage extends StarredMessage { readonly __typename: 'StarredDocMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; } -export interface StarredVideoMessage extends StarredMessage, BareChatMessage, BareMessage { +export interface StarredVideoMessage extends StarredMessage { readonly __typename: 'StarredVideoMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; + readonly statuses: MessageDateTimeStatus[]; readonly context: MessageContext; readonly isForwarded: boolean; } -export interface NewMessage extends BareChatMessage, BareMessage { +export interface NewMessage { readonly __typename: | 'NewTextMessage' | 'NewActionMessage' @@ -974,100 +937,100 @@ export interface NewMessage extends BareChatMessage, BareMessage { readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; } -export interface NewTextMessage extends NewMessage, BareChatMessage, BareMessage { +export interface NewTextMessage extends NewMessage { readonly __typename: 'NewTextMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; readonly textMessage: MessageText; } -export interface NewActionMessage extends NewMessage, BareChatMessage, BareMessage { +export interface NewActionMessage extends NewMessage { readonly __typename: 'NewActionMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; readonly actionableMessage: ActionableMessage; } -export interface NewPicMessage extends NewMessage, BareChatMessage, BareMessage { +export interface NewPicMessage extends NewMessage { readonly __typename: 'NewPicMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; readonly caption: MessageText | null; } -export interface NewPollMessage extends NewMessage, BareChatMessage, BareMessage { +export interface NewPollMessage extends NewMessage { readonly __typename: 'NewPollMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; readonly poll: Poll; } -export interface NewAudioMessage extends NewMessage, BareChatMessage, BareMessage { +export interface NewAudioMessage extends NewMessage { readonly __typename: 'NewAudioMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; } -export interface NewGroupChatInviteMessage extends NewMessage, BareChatMessage, BareMessage { +export interface NewGroupChatInviteMessage extends NewMessage { readonly __typename: 'NewGroupChatInviteMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; readonly inviteCode: Uuid; } -export interface NewDocMessage extends NewMessage, BareChatMessage, BareMessage { +export interface NewDocMessage extends NewMessage { readonly __typename: 'NewDocMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; } -export interface NewVideoMessage extends NewMessage, BareChatMessage, BareMessage { +export interface NewVideoMessage extends NewMessage { readonly __typename: 'NewVideoMessage'; readonly chatId: number; readonly messageId: number; readonly sender: Account; readonly state: MessageState; - readonly dateTimes: MessageDateTimes; + readonly sent: DateTime; readonly context: MessageContext; readonly isForwarded: boolean; } @@ -1081,3 +1044,43 @@ export interface GroupChatInput { readonly isBroadcast: boolean; readonly publicity: GroupChatPublicity; } + +export interface StarredMessagesConnection { + readonly edges: StarredMessageEdge[]; + readonly pageInfo: PageInfo; +} + +export interface StarredMessageEdge { + readonly node: StarredMessage; + readonly cursor: Cursor; +} + +export interface ChatMessagesConnection { + readonly edges: ChatMessagesEdge[]; + readonly pageInfo: PageInfo; +} + +export interface ChatMessagesEdge { + readonly node: ChatMessages; + readonly cursor: Cursor; +} + +export interface ChatsConnection { + readonly edges: ChatEdge[]; + readonly pageInfo: PageInfo; +} + +export interface ChatEdge { + readonly node: Chat; + readonly cursor: Cursor; +} + +export interface GroupChatsConnection { + readonly edges: GroupChatEdge[]; + readonly pageInfo: PageInfo; +} + +export interface GroupChatEdge { + readonly node: GroupChat; + readonly cursor: Cursor; +} diff --git a/src/graphql-api/mutations/createActionMessage.ts b/src/graphql-api/mutations/createActionMessage.ts index e17dc9d..7977b73 100644 --- a/src/graphql-api/mutations/createActionMessage.ts +++ b/src/graphql-api/mutations/createActionMessage.ts @@ -1,6 +1,5 @@ import { ActionMessageInput, CreateActionMessageResult } from '../models'; import { HttpApiConfig } from '../../config'; -import { ContextMessageId } from '../../rest-api'; import { GraphQlResponse, queryOrMutate } from '../operator'; import { CREATE_ACTION_MESSAGE_RESULT_FRAGMENT } from '../fragments'; @@ -30,7 +29,7 @@ export async function createActionMessage( accessToken: string, chatId: number, message: ActionMessageInput, - contextMessageId?: ContextMessageId, + contextMessageId?: number, ): Promise> { const { __typename, ...input } = message; return await queryOrMutate( diff --git a/src/graphql-api/mutations/createContact.ts b/src/graphql-api/mutations/createContact.ts new file mode 100644 index 0000000..f1be992 --- /dev/null +++ b/src/graphql-api/mutations/createContact.ts @@ -0,0 +1,33 @@ +import { HttpApiConfig } from '../../config'; +import { GraphQlResponse, queryOrMutate } from '../operator'; + +export interface CreateContact { + readonly createContact: boolean; +} + +/** + * Saves the `id` as a contact. + * @returns `true` if the contact got saved. `false` if the `id` was either a preexisting contact or a nonexistent user + * ID. + * @throws {@link InternalServerError} + * @throws {@link ConnectionError} + * @throws {@link UnauthorizedError} + */ +export async function createContact( + config: HttpApiConfig, + accessToken: string, + id: number, +): Promise> { + return await queryOrMutate( + config, + { + query: ` + mutation CreateContact($id: Int!) { + createContact(id: $id) + } + `, + variables: { id }, + }, + accessToken, + ); +} diff --git a/src/graphql-api/mutations/createContacts.ts b/src/graphql-api/mutations/createContacts.ts deleted file mode 100644 index 6d7c36f..0000000 --- a/src/graphql-api/mutations/createContacts.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Placeholder } from '../models'; -import { GraphQlResponse, queryOrMutate } from '../operator'; -import { HttpApiConfig } from '../../config'; - -export interface CreateContactsData { - readonly createContacts: Placeholder; -} - -/** - * Saves contacts. Previously saved contacts, nonexistent users, and the user's own ID will be ignored. - * @throws {@link InternalServerError} - * @throws {@link ConnectionError} - * @throws {@link UnauthorizedError} - */ -export async function createContacts( - config: HttpApiConfig, - accessToken: string, - idList: number[], -): Promise> { - return await queryOrMutate( - config, - { - query: ` - mutation CreateContacts($idList: [Int!]!) { - createContacts(idList: $idList) - } - `, - variables: { idList }, - }, - accessToken, - ); -} diff --git a/src/graphql-api/mutations/createGroupChatInviteMessage.ts b/src/graphql-api/mutations/createGroupChatInviteMessage.ts index d1b47a1..82df672 100644 --- a/src/graphql-api/mutations/createGroupChatInviteMessage.ts +++ b/src/graphql-api/mutations/createGroupChatInviteMessage.ts @@ -1,6 +1,5 @@ import { CREATE_GROUP_CHAT_INVITE_MESSAGE_RESULT_FRAGMENT } from '../fragments'; import { HttpApiConfig } from '../../config'; -import { ContextMessageId } from '../../rest-api'; import { GraphQlResponse, queryOrMutate } from '../operator'; import { CreateGroupChatInviteMessageResult } from '../models'; @@ -28,7 +27,7 @@ export async function createGroupChatInviteMessage( accessToken: string, chatId: number, invitedChatId: number, - contextMessageId?: ContextMessageId, + contextMessageId?: number, ): Promise> { return await queryOrMutate( config, diff --git a/src/graphql-api/mutations/createPollMessage.ts b/src/graphql-api/mutations/createPollMessage.ts index 18eeabb..a715563 100644 --- a/src/graphql-api/mutations/createPollMessage.ts +++ b/src/graphql-api/mutations/createPollMessage.ts @@ -1,6 +1,5 @@ import { HttpApiConfig } from '../../config'; import { CreatePollMessageResult, PollInput } from '../models'; -import { ContextMessageId } from '../../rest-api'; import { GraphQlResponse, queryOrMutate } from '../operator'; import { CREATE_POLL_MESSAGE_RESULT_FRAGMENT } from '../fragments'; @@ -24,7 +23,7 @@ export async function createPollMessage( accessToken: string, chatId: number, poll: PollInput, - contextMessageId?: ContextMessageId, + contextMessageId?: number, ): Promise> { const { __typename, ...input } = poll; return await queryOrMutate( diff --git a/src/graphql-api/mutations/createTextMessage.ts b/src/graphql-api/mutations/createTextMessage.ts index 94ba88f..0c048a1 100644 --- a/src/graphql-api/mutations/createTextMessage.ts +++ b/src/graphql-api/mutations/createTextMessage.ts @@ -1,6 +1,5 @@ import { CreateTextMessageResult, MessageText } from '../models'; import { HttpApiConfig } from '../../config'; -import { ContextMessageId } from '../../rest-api'; import { GraphQlResponse, queryOrMutate } from '../operator'; import { CREATE_TEXT_MESSAGE_RESULT_FRAGMENT } from '../fragments'; @@ -23,13 +22,13 @@ export async function createTextMessage( accessToken: string, chatId: number, text: MessageText, - contextMessageId?: ContextMessageId, + contextMessageId?: number, ): Promise> { return await queryOrMutate( config, { query: ` - mutation CreateTextMessage($chatId: Int!, $text: MessageText!, $contextMessageId: Int!) { + mutation CreateTextMessage($chatId: Int!, $text: MessageText!, $contextMessageId: Int) { createTextMessage(chatId: $chatId, text: $text, contextMessageId: $contextMessageId) { ${CREATE_TEXT_MESSAGE_RESULT_FRAGMENT} } diff --git a/src/graphql-api/mutations/deleteContact.ts b/src/graphql-api/mutations/deleteContact.ts new file mode 100644 index 0000000..94320f9 --- /dev/null +++ b/src/graphql-api/mutations/deleteContact.ts @@ -0,0 +1,32 @@ +import { HttpApiConfig } from '../../config'; +import { GraphQlResponse, queryOrMutate } from '../operator'; + +export interface DeleteContact { + readonly deleteContact: boolean; +} + +/** + * Deletes the specified user from the user's contacts. + * @returns `true` if the contact got deleted. `false` if the `id` was either not a contact or a nonexistent user ID. + * @throws {@link InternalServerError} + * @throws {@link ConnectionError} + * @throws {@link UnauthorizedError} + */ +export async function deleteContact( + config: HttpApiConfig, + accessToken: string, + id: number, +): Promise> { + return await queryOrMutate( + config, + { + query: ` + mutation DeleteContact($id: Int!) { + deleteContact(id: $id) + } + `, + variables: { id }, + }, + accessToken, + ); +} diff --git a/src/graphql-api/mutations/deleteContacts.ts b/src/graphql-api/mutations/deleteContacts.ts deleted file mode 100644 index 6fe2b43..0000000 --- a/src/graphql-api/mutations/deleteContacts.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Placeholder } from '../models'; -import { GraphQlResponse, queryOrMutate } from '../operator'; -import { HttpApiConfig } from '../../config'; - -export interface DeleteContactsData { - readonly deleteContacts: Placeholder; -} - -/** - * Remove saved contacts. Invalid contacts (e.g., invalid user IDs, unsaved contacts) will be ignored. - * @throws {@link InternalServerError} - * @throws {@link ConnectionError} - * @throws {@link UnauthorizedError} - */ -export async function deleteContacts( - config: HttpApiConfig, - accessToken: string, - idList: number[], -): Promise> { - return await queryOrMutate( - config, - { - query: ` - mutation DeleteContacts($idList: [Int!]!) { - deleteContacts(idList: $idList) - } - `, - variables: { idList }, - }, - accessToken, - ); -} diff --git a/src/graphql-api/mutations/forwardMessage.ts b/src/graphql-api/mutations/forwardMessage.ts index 51b82c4..0b22727 100644 --- a/src/graphql-api/mutations/forwardMessage.ts +++ b/src/graphql-api/mutations/forwardMessage.ts @@ -1,6 +1,5 @@ import { ForwardMessageResult } from '../models'; import { HttpApiConfig } from '../../config'; -import { ContextMessageId } from '../../rest-api'; import { GraphQlResponse, queryOrMutate } from '../operator'; import { FORWARD_MESSAGE_RESULT_FRAGMENT } from '../fragments'; @@ -25,7 +24,7 @@ export async function forwardMessage( accessToken: string, chatId: number, messageId: number, - contextMessageId?: ContextMessageId, + contextMessageId?: number, ): Promise> { return await queryOrMutate( config, diff --git a/src/graphql-api/mutations/index.ts b/src/graphql-api/mutations/index.ts index 7be6318..b9843a2 100644 --- a/src/graphql-api/mutations/index.ts +++ b/src/graphql-api/mutations/index.ts @@ -18,14 +18,14 @@ export * from './setInvitability'; export * from './updateGroupChatDescription'; export * from './createAccount'; export * from './deleteAccount'; +export * from './deleteContact'; export * from './setOnline'; export * from './updateGroupChatTitle'; export * from './createActionMessage'; -export * from './deleteContacts'; +export * from './createContact'; export * from './joinGroupChat'; export * from './setPollVote'; export * from './verifyEmailAddress'; -export * from './createContacts'; export * from './deleteGroupChatPic'; export * from './joinPublicChat'; export * from './setTyping'; diff --git a/src/graphql-api/mutations/unblockUser.ts b/src/graphql-api/mutations/unblockUser.ts index 63eba68..5a87eef 100644 --- a/src/graphql-api/mutations/unblockUser.ts +++ b/src/graphql-api/mutations/unblockUser.ts @@ -1,13 +1,13 @@ -import { Placeholder } from '../models'; import { GraphQlResponse, queryOrMutate } from '../operator'; import { HttpApiConfig } from '../../config'; export interface UnblockUserData { - readonly unblockUser: Placeholder; + readonly unblockUser: boolean; } /** * Unblocks the specified user. Does nothing if the they weren't blocked. + * @returns `true` if the user got unblocked. `false` if either the user wasn't blocked or the `id` doesn't exist. * @throws {@link InternalServerError} * @throws {@link ConnectionError} * @throws {@link UnauthorizedError} diff --git a/src/graphql-api/queries/index.ts b/src/graphql-api/queries/index.ts index f2f8129..61ffe91 100644 --- a/src/graphql-api/queries/index.ts +++ b/src/graphql-api/queries/index.ts @@ -8,6 +8,7 @@ export * from './readBlockedUsers'; export * from './readContacts'; export * from './readStars'; export * from './requestTokenSet'; +export * from './searchBlockedUsers'; export * from './searchContacts'; export * from './searchUsers'; export * from './readChat'; diff --git a/src/graphql-api/queries/readChats.ts b/src/graphql-api/queries/readChats.ts index 13c2b57..4900469 100644 --- a/src/graphql-api/queries/readChats.ts +++ b/src/graphql-api/queries/readChats.ts @@ -1,11 +1,11 @@ -import { CHAT_FRAGMENT } from '../fragments'; +import { CHATS_CONNECTION_FRAGMENT } from '../fragments'; import { GraphQlResponse, queryOrMutate } from '../operator'; -import { Chat } from '../models'; +import { ChatsConnection } from '../models'; import { BackwardPagination, ForwardPagination } from '../pagination'; import { HttpApiConfig } from '../../config'; export interface ReadChatsData { - readonly readChats: Chat[]; + readonly readChats: ChatsConnection; } /** @@ -17,6 +17,7 @@ export interface ReadChatsData { export async function readChats( config: HttpApiConfig, accessToken: string, + pagination?: ForwardPagination, privateChatMessagesPagination?: BackwardPagination, groupChatUsersPagination?: ForwardPagination, groupChatMessagesPagination?: BackwardPagination, @@ -26,6 +27,8 @@ export async function readChats( { query: ` query ReadChats( + $first: Int + $after: Cursor $privateChat_messages_last: Int $privateChat_messages_before: Cursor $groupChat_users_first: Int @@ -33,12 +36,14 @@ export async function readChats( $groupChat_messages_last: Int $groupChat_messages_before: Cursor ) { - readChats { - ${CHAT_FRAGMENT} + readChats(first: $first, after: $after) { + ${CHATS_CONNECTION_FRAGMENT} } } `, variables: { + first: pagination?.first, + after: pagination?.after, privateChat_messages_last: privateChatMessagesPagination?.last, privateChat_messages_before: privateChatMessagesPagination?.before, groupChat_users_first: groupChatUsersPagination?.first, diff --git a/src/graphql-api/queries/readStars.ts b/src/graphql-api/queries/readStars.ts index 8b9bba7..2e8e1f5 100644 --- a/src/graphql-api/queries/readStars.ts +++ b/src/graphql-api/queries/readStars.ts @@ -1,10 +1,11 @@ -import { StarredMessage } from '../models'; +import { StarredMessagesConnection } from '../models'; import { HttpApiConfig } from '../../config'; import { GraphQlResponse, queryOrMutate } from '../operator'; -import { STARRED_MESSAGE_FRAGMENT } from '../fragments'; +import { STARRED_MESSAGES_CONNECTION_FRAGMENT } from '../fragments'; +import { ForwardPagination } from '../pagination'; export interface ReadStarsData { - readonly readStars: StarredMessage[]; + readonly readStars: StarredMessagesConnection; } /** @@ -13,17 +14,22 @@ export interface ReadStarsData { * @throws {@link ConnectionError} * @throws {@link UnauthorizedError} */ -export async function readStars(config: HttpApiConfig, accessToken: string): Promise> { +export async function readStars( + config: HttpApiConfig, + accessToken: string, + pagination?: ForwardPagination, +): Promise> { return await queryOrMutate( config, { query: ` - query ReadStars { - readStars { - ${STARRED_MESSAGE_FRAGMENT} + query ReadStars($first: Int, $after: Cursor) { + readStars(first: $first, after: $after) { + ${STARRED_MESSAGES_CONNECTION_FRAGMENT} } } `, + variables: { first: pagination?.first, after: pagination?.after }, }, accessToken, ); diff --git a/src/graphql-api/queries/searchBlockedUsers.ts b/src/graphql-api/queries/searchBlockedUsers.ts new file mode 100644 index 0000000..0a2e11a --- /dev/null +++ b/src/graphql-api/queries/searchBlockedUsers.ts @@ -0,0 +1,38 @@ +import { AccountsConnection } from '../models'; +import { HttpApiConfig } from '../../config'; +import { GraphQlResponse, queryOrMutate } from '../operator'; +import { ACCOUNTS_CONNECTION_FRAGMENT } from '../fragments'; +import { ForwardPagination } from '../pagination'; + +export interface SearchBlockedUsers { + readonly searchBlockedUsers: AccountsConnection; +} + +/** + * Searches blocked users. The `query` is case-insensitively matched against users' usernames, email addresses, first + * names, and last names. + * @throws {@link ConnectionError} + * @throws {@link InternalServerError} + * @throws {@link UnauthorizedError} + */ +export async function searchBlockedUsers( + config: HttpApiConfig, + accessToken: string, + query: string, + pagination?: ForwardPagination, +): Promise> { + return await queryOrMutate( + config, + { + query: ` + query SearchBlockedUsers($query: String!, $first: Int, $after: Cursor) { + searchBlockedUsers(query: $query, first: $first, after: $after) { + ${ACCOUNTS_CONNECTION_FRAGMENT} + } + } + `, + variables: { query, first: pagination?.first, after: pagination?.after }, + }, + accessToken, + ); +} diff --git a/src/graphql-api/queries/searchChats.ts b/src/graphql-api/queries/searchChats.ts index d299b44..95d05e9 100644 --- a/src/graphql-api/queries/searchChats.ts +++ b/src/graphql-api/queries/searchChats.ts @@ -1,11 +1,11 @@ -import { Chat } from '../models'; +import { ChatsConnection } from '../models'; import { HttpApiConfig } from '../../config'; import { BackwardPagination, ForwardPagination } from '../pagination'; import { GraphQlResponse, queryOrMutate } from '../operator'; -import { CHAT_FRAGMENT } from '../fragments'; +import { CHATS_CONNECTION_FRAGMENT } from '../fragments'; export interface SearchChatsData { - readonly searchChats: Chat[]; + readonly searchChats: ChatsConnection; } /** @@ -20,6 +20,7 @@ export async function searchChats( config: HttpApiConfig, accessToken: string, query: string, + pagination?: ForwardPagination, privateChatMessagesPagination?: BackwardPagination, groupChatUsersPagination?: ForwardPagination, groupChatMessagesPagination?: BackwardPagination, @@ -30,6 +31,8 @@ export async function searchChats( query: ` query SearchChats( $query: String! + $first: Int + $after: Cursor $privateChat_messages_last: Int $privateChat_messages_before: Cursor $groupChat_users_first: Int @@ -37,13 +40,15 @@ export async function searchChats( $groupChat_messages_last: Int $groupChat_messages_before: Cursor ) { - searchChats(query: $query) { - ${CHAT_FRAGMENT} + searchChats(query: $query, first: $first, after: $after) { + ${CHATS_CONNECTION_FRAGMENT} } } `, variables: { query, + first: pagination?.first, + after: pagination?.after, privateChat_messages_last: privateChatMessagesPagination?.last, privateChat_messages_before: privateChatMessagesPagination?.before, groupChat_users_first: groupChatUsersPagination?.first, diff --git a/src/graphql-api/queries/searchMessages.ts b/src/graphql-api/queries/searchMessages.ts index ce64b2a..4405945 100644 --- a/src/graphql-api/queries/searchMessages.ts +++ b/src/graphql-api/queries/searchMessages.ts @@ -1,11 +1,11 @@ -import { ChatMessages } from '../models'; +import { ChatMessagesConnection } from '../models'; import { HttpApiConfig } from '../../config'; import { BackwardPagination, ForwardPagination } from '../pagination'; import { GraphQlResponse, queryOrMutate } from '../operator'; -import { CHAT_MESSAGES_FRAGMENT } from '../fragments'; +import { CHAT_MESSAGES_CONNECTION_FRAGMENT } from '../fragments'; export interface SearchMessagesData { - readonly searchMessages: ChatMessages[]; + readonly searchMessages: ChatMessagesConnection; } /** @@ -21,6 +21,7 @@ export async function searchMessages( config: HttpApiConfig, accessToken: string, query: string, + pagination?: ForwardPagination, privateChatMessagesPagination?: BackwardPagination, groupChatUsersPagination?: ForwardPagination, groupChatMessagesPagination?: BackwardPagination, @@ -31,6 +32,8 @@ export async function searchMessages( query: ` query SearchMessages( $query: String! + $first: Int + $after: Cursor $privateChat_messages_last: Int $privateChat_messages_before: Cursor $groupChat_users_first: Int @@ -38,13 +41,15 @@ export async function searchMessages( $groupChat_messages_last: Int $groupChat_messages_before: Cursor ) { - searchMessages(query: $query) { - ${CHAT_MESSAGES_FRAGMENT} + searchMessages(query: $query, first: $first, after: $after) { + ${CHAT_MESSAGES_CONNECTION_FRAGMENT} } } `, variables: { query, + first: pagination?.first, + after: pagination?.after, privateChat_messages_last: privateChatMessagesPagination?.last, privateChat_messages_before: privateChatMessagesPagination?.before, groupChat_users_first: groupChatUsersPagination?.first, diff --git a/src/graphql-api/queries/searchPublicChats.ts b/src/graphql-api/queries/searchPublicChats.ts index 9b0d133..1b61e4b 100644 --- a/src/graphql-api/queries/searchPublicChats.ts +++ b/src/graphql-api/queries/searchPublicChats.ts @@ -1,10 +1,11 @@ -import { GroupChat } from '../models'; +import { GroupChatsConnection } from '../models'; import { HttpApiConfig } from '../../config'; import { GraphQlResponse, queryOrMutate } from '../operator'; -import { GROUP_CHAT_FRAGMENT } from '../fragments'; +import { GROUP_CHATS_CONNECTION_FRAGMENT } from '../fragments'; +import { ForwardPagination } from '../pagination'; export interface SearchPublicChatsData { - readonly searchPublicChats: GroupChat[]; + readonly searchPublicChats: GroupChatsConnection; } /** @@ -15,15 +16,16 @@ export interface SearchPublicChatsData { export async function searchPublicChats( config: HttpApiConfig, query: string, + pagination?: ForwardPagination, ): Promise> { return await queryOrMutate(config, { query: ` - query SearchPublicChats($query: String!) { - searchPublicChats(query: $query) { - ${GROUP_CHAT_FRAGMENT} + query SearchPublicChats($query: String!, $first: Int, $after: Cursor) { + searchPublicChats(query: $query, first: $first, after: $after) { + ${GROUP_CHATS_CONNECTION_FRAGMENT} } } `, - variables: { query }, + variables: { query, first: pagination?.first, after: pagination?.after }, }); } diff --git a/src/graphql-api/scalars.ts b/src/graphql-api/scalars.ts index c9fc5e5..d92341d 100644 --- a/src/graphql-api/scalars.ts +++ b/src/graphql-api/scalars.ts @@ -1,6 +1,6 @@ /** @returns Whether the value is a valid {@link Username}. */ export function isValidUsernameScalar(value: string): boolean { - return value.match(/\s/) === null && value.match(/[A-Z]/) === null && value.length > 0 && value.length < 31; + return value.length > 0 && value.length < 31 && value.match(/[^a-z0-9_.]/) === null; } /** @returns Whether the value is a valid {@link Name}. */ diff --git a/src/index.ts b/src/index.ts index 6d07056..8d6e5ac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ /** * Official [Omni Chat API](https://github.com/neelkamath/omni-chat-backend) JavaScript wrapper library. * - * The Omni Chat API consists of a REST and GraphQL API. + * The Omni Chat API consists of a REST API, and a GraphQL API. * * The REST API is used for tasks not well suited for GraphQL such as image uploads. Use the wrapper functions which * have the same name as the operation name in Omni Chat Backend's REST API docs (e.g., {@link getProfilePic}) to @@ -20,7 +20,7 @@ * functions to handle queries and mutations, and subscriptions respectively. These functions allow you to pass your own * GraphQL queries so that you can only select the fields you need to retrieve. * - * Use the `isValid*Scalar()` (e.g., {@link isValidUsernameScalar}) functions to validate inputs. + * Use the `isValid*Scalar()` (e.g., {@link isValidUsernameScalar}) functions to validate GraphQL scalars. * @packageDocumentation */