@ikatec/digisac-api-sdk 4.11.0 → 4.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apis/absence/AbsenceApi.cjs +46 -2
- package/dist/apis/absence/AbsenceApi.cjs.map +1 -1
- package/dist/apis/absence/AbsenceApi.d.ts +38 -4
- package/dist/apis/absence/AbsenceApi.d.ts.map +1 -1
- package/dist/apis/absence/AbsenceApi.mjs +46 -2
- package/dist/apis/absence/AbsenceApi.mjs.map +1 -1
- package/dist/apis/absence/types.d.ts +51 -2
- package/dist/apis/absence/types.d.ts.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.cjs +10 -1
- package/dist/apis/activityLog/ActivityLogApi.cjs.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.d.ts +10 -3
- package/dist/apis/activityLog/ActivityLogApi.d.ts.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.mjs +10 -1
- package/dist/apis/activityLog/ActivityLogApi.mjs.map +1 -1
- package/dist/apis/activityLog/types.d.ts +48 -8
- package/dist/apis/activityLog/types.d.ts.map +1 -1
- package/dist/apis/categories/types.d.ts +1 -0
- package/dist/apis/categories/types.d.ts.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.cjs +31 -2
- package/dist/apis/creditMovements/CreditMovementsApi.cjs.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.d.ts +21 -3
- package/dist/apis/creditMovements/CreditMovementsApi.d.ts.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.mjs +31 -2
- package/dist/apis/creditMovements/CreditMovementsApi.mjs.map +1 -1
- package/dist/apis/creditMovements/types.d.ts +73 -2
- package/dist/apis/creditMovements/types.d.ts.map +1 -1
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.cjs +15 -0
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.cjs.map +1 -1
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.d.ts +13 -0
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.d.ts.map +1 -1
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.mjs +15 -0
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.mjs.map +1 -1
- package/dist/apis/interactiveMessages/types.d.ts +8 -2
- package/dist/apis/interactiveMessages/types.d.ts.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.cjs +27 -0
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.cjs.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.d.ts +22 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.d.ts.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.mjs +27 -0
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.mjs.map +1 -1
- package/dist/apis/knowledgeBase/types.d.ts +56 -2
- package/dist/apis/knowledgeBase/types.d.ts.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.cjs +26 -0
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.cjs.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.d.ts +24 -0
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.d.ts.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.mjs +26 -0
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.mjs.map +1 -1
- package/dist/apis/knowledgeBaseItem/types.d.ts +23 -6
- package/dist/apis/knowledgeBaseItem/types.d.ts.map +1 -1
- package/dist/apis/me/MeApi.cjs +36 -29
- package/dist/apis/me/MeApi.cjs.map +1 -1
- package/dist/apis/me/MeApi.d.ts +33 -22
- package/dist/apis/me/MeApi.d.ts.map +1 -1
- package/dist/apis/me/MeApi.mjs +36 -29
- package/dist/apis/me/MeApi.mjs.map +1 -1
- package/dist/apis/me/types.d.ts +67 -4
- package/dist/apis/me/types.d.ts.map +1 -1
- package/dist/apis/notifications/NotificationsApi.cjs +50 -2
- package/dist/apis/notifications/NotificationsApi.cjs.map +1 -1
- package/dist/apis/notifications/NotificationsApi.d.ts +41 -3
- package/dist/apis/notifications/NotificationsApi.d.ts.map +1 -1
- package/dist/apis/notifications/NotificationsApi.mjs +50 -2
- package/dist/apis/notifications/NotificationsApi.mjs.map +1 -1
- package/dist/apis/notifications/types.d.ts +54 -8
- package/dist/apis/notifications/types.d.ts.map +1 -1
- package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.cjs.map +1 -1
- package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.d.ts +4 -1
- package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.d.ts.map +1 -1
- package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.mjs.map +1 -1
- package/dist/apis/serviceAccessManagement/types.d.ts +3 -0
- package/dist/apis/serviceAccessManagement/types.d.ts.map +1 -1
- package/dist/apis/stickerUsers/StickerUsersApi.cjs.map +1 -1
- package/dist/apis/stickerUsers/StickerUsersApi.d.ts +3 -1
- package/dist/apis/stickerUsers/StickerUsersApi.d.ts.map +1 -1
- package/dist/apis/stickerUsers/StickerUsersApi.mjs.map +1 -1
- package/dist/apis/stickerUsers/types.d.ts +4 -0
- package/dist/apis/stickerUsers/types.d.ts.map +1 -1
- package/dist/apis/stickers/StickersApi.cjs +27 -3
- package/dist/apis/stickers/StickersApi.cjs.map +1 -1
- package/dist/apis/stickers/StickersApi.d.ts +24 -4
- package/dist/apis/stickers/StickersApi.d.ts.map +1 -1
- package/dist/apis/stickers/StickersApi.mjs +27 -3
- package/dist/apis/stickers/StickersApi.mjs.map +1 -1
- package/dist/apis/stickers/types.d.ts +28 -4
- package/dist/apis/stickers/types.d.ts.map +1 -1
- package/dist/apis/transcripts/TranscriptsApi.cjs +12 -2
- package/dist/apis/transcripts/TranscriptsApi.cjs.map +1 -1
- package/dist/apis/transcripts/TranscriptsApi.d.ts +11 -5
- package/dist/apis/transcripts/TranscriptsApi.d.ts.map +1 -1
- package/dist/apis/transcripts/TranscriptsApi.mjs +12 -2
- package/dist/apis/transcripts/TranscriptsApi.mjs.map +1 -1
- package/dist/apis/transcripts/types.d.ts +4 -0
- package/dist/apis/transcripts/types.d.ts.map +1 -1
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.cjs +51 -0
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.cjs.map +1 -1
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.d.ts +44 -2
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.d.ts.map +1 -1
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.mjs +51 -0
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.mjs.map +1 -1
- package/dist/apis/whatsappBusinessTemplates/types.d.ts +34 -1
- package/dist/apis/whatsappBusinessTemplates/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/apis/absence/AbsenceApi.test.ts +65 -0
- package/src/apis/absence/AbsenceApi.ts +77 -4
- package/src/apis/absence/types.ts +53 -2
- package/src/apis/activityLog/ActivityLogApi.test.ts +44 -0
- package/src/apis/activityLog/ActivityLogApi.ts +22 -3
- package/src/apis/activityLog/types.ts +47 -8
- package/src/apis/categories/types.ts +1 -0
- package/src/apis/creditMovements/CreditMovementsApi.test.ts +88 -0
- package/src/apis/creditMovements/CreditMovementsApi.ts +73 -2
- package/src/apis/creditMovements/types.ts +74 -2
- package/src/apis/interactiveMessages/InteractiveMessagesApi.test.ts +59 -0
- package/src/apis/interactiveMessages/InteractiveMessagesApi.ts +26 -0
- package/src/apis/interactiveMessages/types.ts +8 -2
- package/src/apis/knowledgeBase/KnowledgeBaseApi.test.ts +54 -0
- package/src/apis/knowledgeBase/KnowledgeBaseApi.ts +61 -1
- package/src/apis/knowledgeBase/types.ts +62 -2
- package/src/apis/knowledgeBaseItem/KnowledgeBaseItemApi.test.ts +57 -0
- package/src/apis/knowledgeBaseItem/KnowledgeBaseItemApi.ts +45 -0
- package/src/apis/knowledgeBaseItem/types.ts +23 -6
- package/src/apis/me/MeApi.test.ts +45 -1
- package/src/apis/me/MeApi.ts +83 -28
- package/src/apis/me/types.ts +75 -4
- package/src/apis/notifications/NotificationsApi.test.ts +74 -0
- package/src/apis/notifications/NotificationsApi.ts +88 -3
- package/src/apis/notifications/types.ts +65 -7
- package/src/apis/payloads.test-d.ts +82 -2
- package/src/apis/serviceAccessManagement/ServiceAccessManagementApi.ts +4 -1
- package/src/apis/serviceAccessManagement/types.ts +3 -0
- package/src/apis/stickerUsers/StickerUsersApi.ts +3 -1
- package/src/apis/stickerUsers/types.ts +4 -0
- package/src/apis/stickers/StickersApi.test.ts +58 -0
- package/src/apis/stickers/StickersApi.ts +46 -4
- package/src/apis/stickers/types.ts +29 -4
- package/src/apis/transcripts/TranscriptsApi.test.ts +14 -21
- package/src/apis/transcripts/TranscriptsApi.ts +15 -6
- package/src/apis/transcripts/types.ts +4 -0
- package/src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.test.ts +86 -0
- package/src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.ts +74 -1
- package/src/apis/whatsappBusinessTemplates/types.ts +38 -1
package/src/apis/me/MeApi.ts
CHANGED
|
@@ -2,6 +2,11 @@ import { BaseApi } from '../../core/BaseApi'
|
|
|
2
2
|
import type { Account } from '../accounts/types'
|
|
3
3
|
import type { User } from '../users/types'
|
|
4
4
|
import type {
|
|
5
|
+
AccountAmounts,
|
|
6
|
+
AccountAmountsQuery,
|
|
7
|
+
MeAccountQuery,
|
|
8
|
+
MeQuery,
|
|
9
|
+
MeStatusResponse,
|
|
5
10
|
RegisterTokenPayload,
|
|
6
11
|
SetOtpSecretKeyPayload,
|
|
7
12
|
TakeoverPayload,
|
|
@@ -10,30 +15,74 @@ import type {
|
|
|
10
15
|
UpdateMeStatusPayload,
|
|
11
16
|
} from './types'
|
|
12
17
|
|
|
18
|
+
/**
|
|
19
|
+
* A query object always has an array or an object among its values; the headers only have strings (a header that
|
|
20
|
+
* comes as `undefined` at runtime stays a header). That tells the two apart in the methods that took only the
|
|
21
|
+
* headers before and now take a query first.
|
|
22
|
+
*/
|
|
23
|
+
function splitQueryAndHeaders<TQuery extends object>(
|
|
24
|
+
queryOrHeaders: TQuery | Record<string, string> | undefined,
|
|
25
|
+
headers: Record<string, string> | undefined,
|
|
26
|
+
): [TQuery | undefined, Record<string, string> | undefined] {
|
|
27
|
+
const isQuery =
|
|
28
|
+
!!queryOrHeaders &&
|
|
29
|
+
Object.values(queryOrHeaders).some((value) => typeof value === 'object' && value !== null)
|
|
30
|
+
return isQuery
|
|
31
|
+
? [queryOrHeaders as TQuery, headers]
|
|
32
|
+
: [undefined, queryOrHeaders as Record<string, string> | undefined]
|
|
33
|
+
}
|
|
34
|
+
|
|
13
35
|
export class MeApi extends BaseApi {
|
|
14
36
|
/**
|
|
15
|
-
* Returns the currently authenticated user
|
|
37
|
+
* Returns the currently authenticated user. Without `include`, the user comes without relations (roles,
|
|
38
|
+
* departments, timetable, account).
|
|
16
39
|
* @permissions users.view
|
|
17
40
|
*/
|
|
18
|
-
getMe(headers?: Record<string, string>): Promise<User>
|
|
19
|
-
|
|
41
|
+
getMe(headers?: Record<string, string>): Promise<User>
|
|
42
|
+
getMe(query: MeQuery, headers?: Record<string, string>): Promise<User>
|
|
43
|
+
getMe(
|
|
44
|
+
queryOrHeaders?: MeQuery | Record<string, string>,
|
|
45
|
+
headers?: Record<string, string>,
|
|
46
|
+
): Promise<User> {
|
|
47
|
+
const [query, sent] = splitQueryAndHeaders<MeQuery>(queryOrHeaders, headers)
|
|
48
|
+
return this.client.get<User>(`/me${this.toQueryString(query)}`, sent)
|
|
20
49
|
}
|
|
21
50
|
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Returns the account of the current user. Send `where.id` with the `accountId` of the user (what the web app
|
|
53
|
+
* does): without it, the route answers 500.
|
|
54
|
+
*/
|
|
55
|
+
getAccount(headers?: Record<string, string>): Promise<Account>
|
|
56
|
+
getAccount(query: MeAccountQuery, headers?: Record<string, string>): Promise<Account>
|
|
57
|
+
getAccount(
|
|
58
|
+
queryOrHeaders?: MeAccountQuery | Record<string, string>,
|
|
59
|
+
headers?: Record<string, string>,
|
|
60
|
+
): Promise<Account> {
|
|
61
|
+
const [query, sent] = splitQueryAndHeaders<MeAccountQuery>(queryOrHeaders, headers)
|
|
62
|
+
return this.client.get<Account>(`/me/account${this.toQueryString(query)}`, sent)
|
|
25
63
|
}
|
|
26
64
|
|
|
27
65
|
/**
|
|
28
|
-
* Returns
|
|
29
|
-
*
|
|
66
|
+
* Returns the amounts of the current account named in `filter` (services and/or users). The credit amounts are
|
|
67
|
+
* never answered here. An account without credits control answers 400.
|
|
30
68
|
*/
|
|
31
|
-
getAccountAmounts(headers?: Record<string, string>): Promise<
|
|
32
|
-
|
|
69
|
+
getAccountAmounts(headers?: Record<string, string>): Promise<AccountAmounts>
|
|
70
|
+
getAccountAmounts(
|
|
71
|
+
query: AccountAmountsQuery,
|
|
72
|
+
headers?: Record<string, string>,
|
|
73
|
+
): Promise<AccountAmounts>
|
|
74
|
+
getAccountAmounts(
|
|
75
|
+
queryOrHeaders?: AccountAmountsQuery | Record<string, string>,
|
|
76
|
+
headers?: Record<string, string>,
|
|
77
|
+
): Promise<AccountAmounts> {
|
|
78
|
+
const [query, sent] = splitQueryAndHeaders<AccountAmountsQuery>(queryOrHeaders, headers)
|
|
79
|
+
const queryString = query ? this.toQueryString({ filter: query.filter.join(',') }) : ''
|
|
80
|
+
return this.client.get<AccountAmounts>(`/me/get-account-amounts${queryString}`, sent)
|
|
33
81
|
}
|
|
34
82
|
|
|
35
83
|
/**
|
|
36
|
-
* Returns a URL to the Agnus billing/plan management page for the current account.
|
|
84
|
+
* Returns a URL to the Agnus billing/plan management page for the current account. Calls Agnus (an external
|
|
85
|
+
* service) and, for accounts without credits control, reports the consumption to it first.
|
|
37
86
|
* @permissions myAccount.myPlan
|
|
38
87
|
*/
|
|
39
88
|
getAgnusMyPlanUrl(headers?: Record<string, string>): Promise<{ url: string }> {
|
|
@@ -41,39 +90,45 @@ export class MeApi extends BaseApi {
|
|
|
41
90
|
}
|
|
42
91
|
|
|
43
92
|
/**
|
|
44
|
-
* Updates the current user's profile fields such as name, language, and preferences
|
|
45
|
-
*
|
|
46
|
-
* and
|
|
93
|
+
* Updates the current user's profile fields such as name, language, and preferences (`data` and `preferences`
|
|
94
|
+
* replace the stored objects). A new `password` needs `currentPassword` and a recent login, is validated against
|
|
95
|
+
* the last 6 passwords, and revokes the access tokens with an expiration — including the one of this request.
|
|
47
96
|
*/
|
|
48
97
|
updateMe(body: UpdateMePayload, headers?: Record<string, string>): Promise<User> {
|
|
49
98
|
return this.client.put<User, UpdateMePayload>('/me', body, headers)
|
|
50
99
|
}
|
|
51
100
|
|
|
52
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Updates account-level settings such as name, settings object, wizard progress, and default department. It
|
|
103
|
+
* applies to the whole account; the default department is required while the tickets are enabled.
|
|
104
|
+
*/
|
|
53
105
|
updateAccount(body: UpdateMeAccountPayload, headers?: Record<string, string>): Promise<Account> {
|
|
54
106
|
return this.client.put<Account, UpdateMeAccountPayload>('/me/account', body, headers)
|
|
55
107
|
}
|
|
56
108
|
|
|
57
109
|
/**
|
|
58
|
-
* Updates the presence status of the current user (`online`, `offline`, or `away`)
|
|
110
|
+
* Updates the presence status of the current user (`online`, `offline`, or `away`) for a `client`.
|
|
59
111
|
* If setting to `online`, validates the user's timetable first — if outside working hours,
|
|
60
|
-
* the status is set to `offline` instead.
|
|
112
|
+
* the status is set to `offline` instead. Resolves the status fields of the user.
|
|
61
113
|
*/
|
|
62
|
-
updateStatus(
|
|
63
|
-
|
|
114
|
+
updateStatus(
|
|
115
|
+
body: UpdateMeStatusPayload,
|
|
116
|
+
headers?: Record<string, string>,
|
|
117
|
+
): Promise<MeStatusResponse> {
|
|
118
|
+
return this.client.put<MeStatusResponse, UpdateMeStatusPayload>('/me/status', body, headers)
|
|
64
119
|
}
|
|
65
120
|
|
|
66
121
|
/**
|
|
67
|
-
* Extends the grace period for the current account when it has expired or is about to expire
|
|
68
|
-
* Returns the updated account.
|
|
122
|
+
* Extends the grace period for the current account when it has expired or is about to expire, and notifies the
|
|
123
|
+
* billing webhook. Returns the updated account; an account not in a grace period answers 400.
|
|
69
124
|
*/
|
|
70
125
|
extendAccountGracePeriod(headers?: Record<string, string>): Promise<Account> {
|
|
71
126
|
return this.client.post<Account>('/me/account/extend-grace-period', undefined, headers)
|
|
72
127
|
}
|
|
73
128
|
|
|
74
129
|
/**
|
|
75
|
-
* Registers
|
|
76
|
-
*
|
|
130
|
+
* Registers the push notification tokens of the current user (`data` replaces the whole `data` of the user).
|
|
131
|
+
* Resolves with no body.
|
|
77
132
|
*/
|
|
78
133
|
registerToken(body: RegisterTokenPayload, headers?: Record<string, string>): Promise<void> {
|
|
79
134
|
return this.client.post<void, RegisterTokenPayload>(
|
|
@@ -89,8 +144,8 @@ export class MeApi extends BaseApi {
|
|
|
89
144
|
}
|
|
90
145
|
|
|
91
146
|
/**
|
|
92
|
-
* Sets the current user's status to `online` for the given client and emits a takeover
|
|
93
|
-
* which signals other connected sessions to yield control to this one.
|
|
147
|
+
* Sets the current user's status to `online` for the given client (`'web'` by default) and emits a takeover
|
|
148
|
+
* event, which signals other connected sessions to yield control to this one. Resolves with no body.
|
|
94
149
|
*/
|
|
95
150
|
takeover(body?: TakeoverPayload, headers?: Record<string, string>): Promise<void> {
|
|
96
151
|
return this.client.post<void, TakeoverPayload>('/me/takeover', body, headers)
|
|
@@ -107,9 +162,9 @@ export class MeApi extends BaseApi {
|
|
|
107
162
|
/**
|
|
108
163
|
* Activates OTP (two-factor) authentication for the current user.
|
|
109
164
|
* Requires the `x-digisac-otp` header with a valid TOTP token generated from the secret key
|
|
110
|
-
* previously set via `setOtpSecretKey`.
|
|
165
|
+
* previously set via `setOtpSecretKey`. Resolves the text `'OK'`.
|
|
111
166
|
*/
|
|
112
|
-
activateOtpAuth(headers?: Record<string, string>): Promise<
|
|
113
|
-
return this.client.post<
|
|
167
|
+
activateOtpAuth(headers?: Record<string, string>): Promise<'OK'> {
|
|
168
|
+
return this.client.post<'OK'>('/me/activate-otp-auth', undefined, headers)
|
|
114
169
|
}
|
|
115
170
|
}
|
package/src/apis/me/types.ts
CHANGED
|
@@ -2,9 +2,68 @@ import type { AccountSettings } from '../accounts/types'
|
|
|
2
2
|
import type { UserPreferences } from '../users/types'
|
|
3
3
|
import type { UserStatus } from '../users/types'
|
|
4
4
|
|
|
5
|
+
/** The client of the session that sets the status: the web app or the mobile app. */
|
|
6
|
+
export type MeClient = 'web' | 'app'
|
|
7
|
+
|
|
8
|
+
/** Query of `GET /me`: without `include`, the user comes without relations. */
|
|
9
|
+
export type MeQuery = {
|
|
10
|
+
include?: (
|
|
11
|
+
| 'roles'
|
|
12
|
+
| 'departments'
|
|
13
|
+
| 'timetable'
|
|
14
|
+
| 'account'
|
|
15
|
+
| 'permissions'
|
|
16
|
+
| 'organizations'
|
|
17
|
+
| (string & {})
|
|
18
|
+
)[]
|
|
19
|
+
attributes?: string[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Query of `GET /me/account`: `where.id` is the id of the account of the user (`accountId` of `getMe`). */
|
|
23
|
+
export type MeAccountQuery = {
|
|
24
|
+
where: { id: string }
|
|
25
|
+
include?: string[]
|
|
26
|
+
attributes?: string[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type AccountAmountsFilter = 'services.amounts' | 'users.amounts'
|
|
30
|
+
|
|
31
|
+
/** Query of `GET /me/get-account-amounts`: which amounts to answer (the credit amounts are never answered). */
|
|
32
|
+
export type AccountAmountsQuery = {
|
|
33
|
+
filter: AccountAmountsFilter[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type UsersAmounts = {
|
|
37
|
+
planBase: number
|
|
38
|
+
additional: number
|
|
39
|
+
totalContracted: number
|
|
40
|
+
planBaseConsumed: number
|
|
41
|
+
additionalConsumed: number
|
|
42
|
+
totalConsumed: number
|
|
43
|
+
available: number
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type AccountAmounts = {
|
|
47
|
+
accountId: string
|
|
48
|
+
servicesAmounts?: Record<string, unknown>
|
|
49
|
+
usersAmounts?: UsersAmounts
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** What `updateStatus` answers: the status fields of the user, not the whole user. */
|
|
53
|
+
export type MeStatusResponse = {
|
|
54
|
+
id: string
|
|
55
|
+
updatedAt: string
|
|
56
|
+
status: UserStatus
|
|
57
|
+
clientsStatus: Partial<Record<MeClient, UserStatus>>
|
|
58
|
+
language: string
|
|
59
|
+
account?: unknown
|
|
60
|
+
}
|
|
61
|
+
|
|
5
62
|
export type UpdateMePayload = {
|
|
6
63
|
name?: string
|
|
7
64
|
password?: string
|
|
65
|
+
/** Required with `password`: the current password of the user. */
|
|
66
|
+
currentPassword?: string
|
|
8
67
|
language?: string
|
|
9
68
|
preferences?: UserPreferences
|
|
10
69
|
otpAuthActive?: boolean
|
|
@@ -14,22 +73,34 @@ export type UpdateMePayload = {
|
|
|
14
73
|
|
|
15
74
|
export type UpdateMeStatusPayload = {
|
|
16
75
|
status: UserStatus
|
|
17
|
-
|
|
76
|
+
/** Required by the backend (400 without it). */
|
|
77
|
+
client?: MeClient
|
|
18
78
|
}
|
|
19
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Merged over the account. The default department is required while the tickets are enabled
|
|
82
|
+
* (`settings.ticketsEnabled`; 400 `DEFAULT_DEPARTMENT_REQUIRED`).
|
|
83
|
+
*/
|
|
20
84
|
export type UpdateMeAccountPayload = {
|
|
21
85
|
name?: string
|
|
22
86
|
settings?: Partial<AccountSettings>
|
|
23
|
-
wizardProgress?: string
|
|
87
|
+
wizardProgress?: 'notStarted' | 'started' | 'finished' | (string & {})
|
|
24
88
|
defaultDepartmentId?: string
|
|
89
|
+
defaultDepartment?: { id: string }
|
|
25
90
|
}
|
|
26
91
|
|
|
27
92
|
export type TakeoverPayload = {
|
|
28
|
-
|
|
93
|
+
/** Defaults to `'web'`. */
|
|
94
|
+
client?: MeClient
|
|
29
95
|
}
|
|
30
96
|
|
|
31
97
|
export type SetOtpSecretKeyPayload = {
|
|
32
98
|
secretKey: string
|
|
33
99
|
}
|
|
34
100
|
|
|
35
|
-
|
|
101
|
+
/** The push tokens of the user. `data` REPLACES the whole `data` of the user (it is not merged). */
|
|
102
|
+
export type RegisterTokenPayload = {
|
|
103
|
+
data?: { oneSignalToken?: string; expoPushToken?: string | null; fromApp?: boolean }
|
|
104
|
+
/** The backend ignores the call when it is `true`. */
|
|
105
|
+
isClientUser?: boolean
|
|
106
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { NotificationsApi } from './NotificationsApi'
|
|
3
|
+
import type { ApiClient } from '../../core/ApiClient'
|
|
4
|
+
|
|
5
|
+
// ── Mock client factory ──────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
function createMockClient(): ApiClient {
|
|
8
|
+
return {
|
|
9
|
+
setAccessToken: vi.fn().mockReturnThis(),
|
|
10
|
+
request: vi.fn(),
|
|
11
|
+
requestRaw: vi.fn(),
|
|
12
|
+
get: vi.fn(),
|
|
13
|
+
post: vi.fn(),
|
|
14
|
+
put: vi.fn(),
|
|
15
|
+
patch: vi.fn(),
|
|
16
|
+
delete: vi.fn(),
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
describe('NotificationsApi', () => {
|
|
23
|
+
let client: ReturnType<typeof createMockClient>
|
|
24
|
+
let api: NotificationsApi
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
client = createMockClient()
|
|
28
|
+
api = new NotificationsApi(client)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('count posts to /notifications/count and resolves the counts as text', async () => {
|
|
32
|
+
const counts = { count: { total: '3', read: '1', unread: '2' } }
|
|
33
|
+
vi.mocked(client.post).mockResolvedValue(counts)
|
|
34
|
+
await expect(api.count()).resolves.toEqual(counts)
|
|
35
|
+
expect(client.post).toHaveBeenCalledWith('/notifications/count', undefined, undefined)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('read puts to /notifications/:id/read', async () => {
|
|
39
|
+
await api.read('n-1')
|
|
40
|
+
expect(client.put).toHaveBeenCalledWith('/notifications/n-1/read', undefined, undefined)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('unread puts to /notifications/:id/unread', async () => {
|
|
44
|
+
await api.unread('n-1')
|
|
45
|
+
expect(client.put).toHaveBeenCalledWith('/notifications/n-1/unread', undefined, undefined)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('readMany posts the ids as the body', async () => {
|
|
49
|
+
await api.readMany(['n-1', 'n-2'])
|
|
50
|
+
expect(client.post).toHaveBeenCalledWith('/notifications/read-many', ['n-1', 'n-2'], undefined)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('readAll calls client.get with /notifications/read-all', async () => {
|
|
54
|
+
vi.mocked(client.get).mockResolvedValue({ total: 2, read: 2, unread: 0 })
|
|
55
|
+
await expect(api.readAll()).resolves.toEqual({ total: 2, read: 2, unread: 0 })
|
|
56
|
+
expect(client.get).toHaveBeenCalledWith('/notifications/read-all', undefined)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('resetBadgeCount posts to /notifications/reset-badge-count', async () => {
|
|
60
|
+
vi.mocked(client.post).mockResolvedValue({ success: true })
|
|
61
|
+
await expect(api.resetBadgeCount()).resolves.toEqual({ success: true })
|
|
62
|
+
expect(client.post).toHaveBeenCalledWith(
|
|
63
|
+
'/notifications/reset-badge-count',
|
|
64
|
+
undefined,
|
|
65
|
+
undefined,
|
|
66
|
+
)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('sendAll posts the announcement to /notifications/send-all', async () => {
|
|
70
|
+
const body = { text: 'Aviso', to: 'admin' as const }
|
|
71
|
+
await api.sendAll(body)
|
|
72
|
+
expect(client.post).toHaveBeenCalledWith('/notifications/send-all', body, undefined)
|
|
73
|
+
})
|
|
74
|
+
})
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import type { ListQuery } from '../../core/types'
|
|
3
3
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
Notification,
|
|
6
|
+
CreateNotificationPayload,
|
|
7
|
+
UpdateNotificationPayload,
|
|
8
|
+
NotificationCountsResponse,
|
|
9
|
+
NotificationReadAllResponse,
|
|
10
|
+
SendAllNotificationsPayload,
|
|
11
|
+
} from './types'
|
|
5
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Notifications of the current user (all of the account with `notification.view.all`). Some types open a modal in the web app as soon as they arrive (`announcement`, `credits-90`,
|
|
15
|
+
* `credits-100`, `smart-summary`, `warn-service-reconnect`).
|
|
16
|
+
*/
|
|
6
17
|
export class NotificationsApi extends BaseCrudApi<
|
|
7
18
|
Notification,
|
|
8
19
|
CreateNotificationPayload,
|
|
@@ -15,10 +26,84 @@ export class NotificationsApi extends BaseCrudApi<
|
|
|
15
26
|
}
|
|
16
27
|
|
|
17
28
|
/**
|
|
18
|
-
* Deletes a notification. Resolves the text `'OK'`; an unknown id answers 500.
|
|
19
|
-
* no permission.
|
|
29
|
+
* Deletes a notification. Resolves the text `'OK'`; an unknown id answers 500.
|
|
20
30
|
*/
|
|
21
31
|
override deleteById(id: string, headers?: Record<string, string>): Promise<'OK'> {
|
|
22
32
|
return super.deleteById(id, headers)
|
|
23
33
|
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Counts the notifications the user sees: `{ count: { total, read, unread } }`, as TEXT.
|
|
37
|
+
*/
|
|
38
|
+
count(headers?: Record<string, string>): Promise<NotificationCountsResponse> {
|
|
39
|
+
return this.client.post<NotificationCountsResponse>(
|
|
40
|
+
`${this.basePath}/count`,
|
|
41
|
+
undefined,
|
|
42
|
+
headers,
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Marks a notification as read for the current user and resolves the new counts. An unknown id answers
|
|
48
|
+
* 400 `Notification not found.`.
|
|
49
|
+
*/
|
|
50
|
+
read(id: string, headers?: Record<string, string>): Promise<NotificationCountsResponse> {
|
|
51
|
+
return this.client.put<NotificationCountsResponse>(
|
|
52
|
+
`${this.basePath}/${id}/read`,
|
|
53
|
+
undefined,
|
|
54
|
+
headers,
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Marks a notification as unread for the current user and resolves the new counts. An unknown id
|
|
60
|
+
* answers 400 `Notification not found.`.
|
|
61
|
+
*/
|
|
62
|
+
unread(id: string, headers?: Record<string, string>): Promise<NotificationCountsResponse> {
|
|
63
|
+
return this.client.put<NotificationCountsResponse>(
|
|
64
|
+
`${this.basePath}/${id}/unread`,
|
|
65
|
+
undefined,
|
|
66
|
+
headers,
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Marks the notifications of `ids` as read. Resolves with no body; a body that is not an array answers
|
|
72
|
+
* 500 `Body must be an array of notification IDs`.
|
|
73
|
+
*/
|
|
74
|
+
readMany(ids: string[], headers?: Record<string, string>): Promise<void> {
|
|
75
|
+
return this.client.post<void, string[]>(`${this.basePath}/read-many`, ids, headers)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Marks every notification the user sees as read (a GET that writes: it recreates the read receipts of
|
|
80
|
+
* the user) and resolves the counts, as numbers.
|
|
81
|
+
*/
|
|
82
|
+
readAll(headers?: Record<string, string>): Promise<NotificationReadAllResponse> {
|
|
83
|
+
return this.client.get<NotificationReadAllResponse>(`${this.basePath}/read-all`, headers)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Clears the push badge counter of the current user. Resolves `{ success: true }`. */
|
|
87
|
+
resetBadgeCount(headers?: Record<string, string>): Promise<{ success: true }> {
|
|
88
|
+
return this.client.post<{ success: true }>(
|
|
89
|
+
`${this.basePath}/reset-badge-count`,
|
|
90
|
+
undefined,
|
|
91
|
+
headers,
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* SENDS an announcement (`type: 'announcement'`, which opens a modal in the web app) to every user of
|
|
97
|
+
* the account, or only to the admins with `to: 'admin'`. Resolves `{ message: 'Notificações enviadas' }` before the notifications are created.
|
|
98
|
+
*/
|
|
99
|
+
sendAll(
|
|
100
|
+
body: SendAllNotificationsPayload,
|
|
101
|
+
headers?: Record<string, string>,
|
|
102
|
+
): Promise<{ message: string }> {
|
|
103
|
+
return this.client.post<{ message: string }, SendAllNotificationsPayload>(
|
|
104
|
+
`${this.basePath}/send-all`,
|
|
105
|
+
body,
|
|
106
|
+
headers,
|
|
107
|
+
)
|
|
108
|
+
}
|
|
24
109
|
}
|
|
@@ -13,46 +13,104 @@ export type NotificationType =
|
|
|
13
13
|
| 'undefined'
|
|
14
14
|
| 'waba-health-warning'
|
|
15
15
|
| 'waba-health-block'
|
|
16
|
+
| 'kanban-board-initialized'
|
|
17
|
+
| 'users-bulk-archive-blocked'
|
|
18
|
+
| 'user-import'
|
|
19
|
+
| 'credits-90'
|
|
20
|
+
| 'credits-100'
|
|
21
|
+
| 'smart-summary'
|
|
22
|
+
| 'warn-service-reconnect'
|
|
16
23
|
|
|
17
|
-
/**
|
|
24
|
+
/** Extra data of the notification; the pipeline notifications carry the pipeline ids. */
|
|
18
25
|
export type NotificationConfig = {
|
|
19
|
-
pipelineId
|
|
20
|
-
pipelineAutomationId
|
|
26
|
+
pipelineId?: string
|
|
27
|
+
pipelineAutomationId?: string
|
|
28
|
+
[key: string]: unknown
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The read receipt of a notification for the current user. */
|
|
32
|
+
export type NotificationRead = {
|
|
33
|
+
id: string
|
|
34
|
+
notificationId: string
|
|
35
|
+
userId: string
|
|
36
|
+
readAt: string | null
|
|
37
|
+
createdAt: string
|
|
38
|
+
updatedAt: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Counts of the notifications the user sees (all of the account with `notification.view.all`).
|
|
43
|
+
* They come as TEXT: the backend answers the `COUNT` of the database as is (e.g. `"43"`).
|
|
44
|
+
*/
|
|
45
|
+
export type NotificationCounts = {
|
|
46
|
+
total: string
|
|
47
|
+
read: string
|
|
48
|
+
unread: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** What `read`, `unread` and `count` answer. */
|
|
52
|
+
export type NotificationCountsResponse = {
|
|
53
|
+
count: NotificationCounts
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** What `readAll` answers: the counts after marking everything as read, as numbers. */
|
|
57
|
+
export type NotificationReadAllResponse = {
|
|
58
|
+
total: number
|
|
59
|
+
read: number
|
|
60
|
+
unread: number
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The body of `sendAll`: `to: 'admin'` sends only to the admins; any other value sends to every user. */
|
|
64
|
+
export type SendAllNotificationsPayload = {
|
|
65
|
+
/** Up to 255 characters. */
|
|
66
|
+
text: string
|
|
67
|
+
to: 'admin' | 'all' | (string & {})
|
|
68
|
+
image?: string
|
|
21
69
|
}
|
|
22
70
|
|
|
23
71
|
export type Notification = {
|
|
24
72
|
id: string
|
|
25
73
|
text: string
|
|
26
74
|
type: NotificationType | null
|
|
27
|
-
read
|
|
75
|
+
/** `null` on the announcements of `sendAll` until they are read. */
|
|
76
|
+
read: boolean | null
|
|
28
77
|
image: string | null
|
|
29
78
|
label: string | null
|
|
30
79
|
config: NotificationConfig | null
|
|
31
80
|
attachedType: string | null
|
|
81
|
+
attachedId: string | null
|
|
82
|
+
notificationReadId: string | null
|
|
32
83
|
contactId: string | null
|
|
33
84
|
userId: string
|
|
34
85
|
accountId: string
|
|
35
86
|
scheduleId: string | null
|
|
36
87
|
createdAt: string
|
|
37
88
|
updatedAt: string
|
|
38
|
-
|
|
89
|
+
/** @deprecated Not answered: the transformer of the backend does not send it. */
|
|
90
|
+
deletedAt?: string | null
|
|
39
91
|
// relationships
|
|
40
92
|
user?: User
|
|
41
93
|
schedule?: Schedule | null
|
|
94
|
+
/** @deprecated Not served: the model has no such association, so it never comes. */
|
|
42
95
|
contact?: Contact | null
|
|
96
|
+
notificationRead?: NotificationRead | null
|
|
43
97
|
}
|
|
44
98
|
|
|
45
|
-
|
|
99
|
+
/** The backend serves `user`, `schedule` and `notificationRead` (`contact` is never answered). */
|
|
100
|
+
export type NotificationRelationships = 'user' | 'schedule' | 'contact' | 'notificationRead'
|
|
46
101
|
|
|
47
102
|
export type CreateNotificationPayload = {
|
|
103
|
+
/** Up to 255 characters. */
|
|
48
104
|
text: string
|
|
49
|
-
|
|
105
|
+
/** Ignored: the backend creates the notification for the current user. */
|
|
106
|
+
userId?: string
|
|
50
107
|
type?: NotificationType
|
|
51
108
|
label?: string
|
|
52
109
|
config?: NotificationConfig
|
|
53
110
|
attachedType?: string
|
|
54
111
|
contactId?: string
|
|
55
112
|
scheduleId?: string
|
|
113
|
+
image?: string
|
|
56
114
|
}
|
|
57
115
|
|
|
58
116
|
export type UpdateNotificationPayload = {
|