@ikatec/digisac-api-sdk 4.9.0 → 4.11.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/README.md +36 -12
- package/dist/apis/absence/AbsenceApi.cjs +12 -0
- package/dist/apis/absence/AbsenceApi.cjs.map +1 -1
- package/dist/apis/absence/AbsenceApi.d.ts +9 -0
- package/dist/apis/absence/AbsenceApi.d.ts.map +1 -1
- package/dist/apis/absence/AbsenceApi.mjs +12 -0
- package/dist/apis/absence/AbsenceApi.mjs.map +1 -1
- package/dist/apis/acceptanceTerms/AcceptanceTermsApi.cjs +8 -0
- package/dist/apis/acceptanceTerms/AcceptanceTermsApi.cjs.map +1 -1
- package/dist/apis/acceptanceTerms/AcceptanceTermsApi.d.ts +8 -1
- package/dist/apis/acceptanceTerms/AcceptanceTermsApi.d.ts.map +1 -1
- package/dist/apis/acceptanceTerms/AcceptanceTermsApi.mjs +8 -0
- package/dist/apis/acceptanceTerms/AcceptanceTermsApi.mjs.map +1 -1
- package/dist/apis/accounts/AccountsApi.cjs +5 -0
- package/dist/apis/accounts/AccountsApi.cjs.map +1 -1
- package/dist/apis/accounts/AccountsApi.d.ts +5 -0
- package/dist/apis/accounts/AccountsApi.d.ts.map +1 -1
- package/dist/apis/accounts/AccountsApi.mjs +5 -0
- package/dist/apis/accounts/AccountsApi.mjs.map +1 -1
- package/dist/apis/accounts/types.d.ts +2 -0
- package/dist/apis/accounts/types.d.ts.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.cjs +12 -0
- package/dist/apis/activityLog/ActivityLogApi.cjs.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.d.ts +8 -0
- package/dist/apis/activityLog/ActivityLogApi.d.ts.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.mjs +12 -0
- package/dist/apis/activityLog/ActivityLogApi.mjs.map +1 -1
- package/dist/apis/categories/CategoriesApi.cjs +7 -0
- package/dist/apis/categories/CategoriesApi.cjs.map +1 -1
- package/dist/apis/categories/CategoriesApi.d.ts +7 -1
- package/dist/apis/categories/CategoriesApi.d.ts.map +1 -1
- package/dist/apis/categories/CategoriesApi.mjs +7 -0
- package/dist/apis/categories/CategoriesApi.mjs.map +1 -1
- package/dist/apis/clientFeedback/ClientFeedbackApi.cjs +5 -1
- package/dist/apis/clientFeedback/ClientFeedbackApi.cjs.map +1 -1
- package/dist/apis/clientFeedback/ClientFeedbackApi.d.ts +5 -1
- package/dist/apis/clientFeedback/ClientFeedbackApi.d.ts.map +1 -1
- package/dist/apis/clientFeedback/ClientFeedbackApi.mjs +5 -1
- package/dist/apis/clientFeedback/ClientFeedbackApi.mjs.map +1 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.cjs +36 -0
- package/dist/apis/contactBlockLists/ContactBlockListsApi.cjs.map +1 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.d.ts +32 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.d.ts.map +1 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.mjs +36 -0
- package/dist/apis/contactBlockLists/ContactBlockListsApi.mjs.map +1 -1
- package/dist/apis/contactBlockLists/types.d.ts +6 -1
- package/dist/apis/contactBlockLists/types.d.ts.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.cjs +37 -0
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.cjs.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.d.ts +33 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.d.ts.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.mjs +37 -0
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.mjs.map +1 -1
- package/dist/apis/contactBlockListsControls/types.d.ts +7 -0
- package/dist/apis/contactBlockListsControls/types.d.ts.map +1 -1
- package/dist/apis/contacts/ContactsApi.cjs +16 -3
- package/dist/apis/contacts/ContactsApi.cjs.map +1 -1
- package/dist/apis/contacts/ContactsApi.d.ts +16 -5
- package/dist/apis/contacts/ContactsApi.d.ts.map +1 -1
- package/dist/apis/contacts/ContactsApi.mjs +16 -3
- package/dist/apis/contacts/ContactsApi.mjs.map +1 -1
- package/dist/apis/contacts/types.d.ts +6 -1
- package/dist/apis/contacts/types.d.ts.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.cjs +17 -0
- package/dist/apis/creditMovements/CreditMovementsApi.cjs.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.d.ts +11 -0
- package/dist/apis/creditMovements/CreditMovementsApi.d.ts.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.mjs +17 -0
- package/dist/apis/creditMovements/CreditMovementsApi.mjs.map +1 -1
- package/dist/apis/customFields/CustomFieldsApi.cjs +7 -0
- package/dist/apis/customFields/CustomFieldsApi.cjs.map +1 -1
- package/dist/apis/customFields/CustomFieldsApi.d.ts +7 -1
- package/dist/apis/customFields/CustomFieldsApi.d.ts.map +1 -1
- package/dist/apis/customFields/CustomFieldsApi.mjs +7 -0
- package/dist/apis/customFields/CustomFieldsApi.mjs.map +1 -1
- package/dist/apis/departments/DepartmentsApi.cjs +21 -0
- package/dist/apis/departments/DepartmentsApi.cjs.map +1 -1
- package/dist/apis/departments/DepartmentsApi.d.ts +20 -2
- package/dist/apis/departments/DepartmentsApi.d.ts.map +1 -1
- package/dist/apis/departments/DepartmentsApi.mjs +21 -0
- package/dist/apis/departments/DepartmentsApi.mjs.map +1 -1
- package/dist/apis/departments/types.d.ts +5 -0
- package/dist/apis/departments/types.d.ts.map +1 -1
- package/dist/apis/distribution/DistributionApi.cjs +32 -0
- package/dist/apis/distribution/DistributionApi.cjs.map +1 -1
- package/dist/apis/distribution/DistributionApi.d.ts +26 -1
- package/dist/apis/distribution/DistributionApi.d.ts.map +1 -1
- package/dist/apis/distribution/DistributionApi.mjs +32 -0
- package/dist/apis/distribution/DistributionApi.mjs.map +1 -1
- package/dist/apis/distribution/types.d.ts +18 -1
- package/dist/apis/distribution/types.d.ts.map +1 -1
- package/dist/apis/files/FilesApi.cjs +49 -0
- package/dist/apis/files/FilesApi.cjs.map +1 -1
- package/dist/apis/files/FilesApi.d.ts +45 -2
- package/dist/apis/files/FilesApi.d.ts.map +1 -1
- package/dist/apis/files/FilesApi.mjs +49 -0
- package/dist/apis/files/FilesApi.mjs.map +1 -1
- package/dist/apis/files/types.d.ts +45 -7
- package/dist/apis/files/types.d.ts.map +1 -1
- package/dist/apis/holiday/HolidayApi.cjs +7 -0
- package/dist/apis/holiday/HolidayApi.cjs.map +1 -1
- package/dist/apis/holiday/HolidayApi.d.ts +7 -1
- package/dist/apis/holiday/HolidayApi.d.ts.map +1 -1
- package/dist/apis/holiday/HolidayApi.mjs +7 -0
- package/dist/apis/holiday/HolidayApi.mjs.map +1 -1
- package/dist/apis/integrations/IntegrationsApi.cjs +24 -0
- package/dist/apis/integrations/IntegrationsApi.cjs.map +1 -1
- package/dist/apis/integrations/IntegrationsApi.d.ts +21 -2
- package/dist/apis/integrations/IntegrationsApi.d.ts.map +1 -1
- package/dist/apis/integrations/IntegrationsApi.mjs +24 -0
- package/dist/apis/integrations/IntegrationsApi.mjs.map +1 -1
- package/dist/apis/integrations/types.d.ts +15 -6
- package/dist/apis/integrations/types.d.ts.map +1 -1
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.cjs +7 -0
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.cjs.map +1 -1
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.d.ts +7 -1
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.d.ts.map +1 -1
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.mjs +7 -0
- package/dist/apis/interactiveMessages/InteractiveMessagesApi.mjs.map +1 -1
- package/dist/apis/kanbanBoards/KanbanBoardsApi.cjs +7 -0
- package/dist/apis/kanbanBoards/KanbanBoardsApi.cjs.map +1 -1
- package/dist/apis/kanbanBoards/KanbanBoardsApi.d.ts +7 -1
- package/dist/apis/kanbanBoards/KanbanBoardsApi.d.ts.map +1 -1
- package/dist/apis/kanbanBoards/KanbanBoardsApi.mjs +7 -0
- package/dist/apis/kanbanBoards/KanbanBoardsApi.mjs.map +1 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.cjs +7 -0
- package/dist/apis/kanbanCards/KanbanCardsApi.cjs.map +1 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.d.ts +7 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.d.ts.map +1 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.mjs +7 -0
- package/dist/apis/kanbanCards/KanbanCardsApi.mjs.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.cjs +8 -0
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.cjs.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.d.ts +8 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.d.ts.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.mjs +8 -0
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.mjs.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.cjs +8 -0
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.cjs.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.d.ts +8 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.d.ts.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.mjs +8 -0
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.mjs.map +1 -1
- package/dist/apis/messages/MessagesApi.cjs +23 -3
- package/dist/apis/messages/MessagesApi.cjs.map +1 -1
- package/dist/apis/messages/MessagesApi.d.ts +19 -3
- package/dist/apis/messages/MessagesApi.d.ts.map +1 -1
- package/dist/apis/messages/MessagesApi.mjs +23 -3
- package/dist/apis/messages/MessagesApi.mjs.map +1 -1
- package/dist/apis/messages/types.d.ts +3 -0
- package/dist/apis/messages/types.d.ts.map +1 -1
- package/dist/apis/notifications/NotificationsApi.cjs +7 -0
- package/dist/apis/notifications/NotificationsApi.cjs.map +1 -1
- package/dist/apis/notifications/NotificationsApi.d.ts +7 -1
- package/dist/apis/notifications/NotificationsApi.d.ts.map +1 -1
- package/dist/apis/notifications/NotificationsApi.mjs +7 -0
- package/dist/apis/notifications/NotificationsApi.mjs.map +1 -1
- package/dist/apis/organizations/OrganizationsApi.cjs +7 -0
- package/dist/apis/organizations/OrganizationsApi.cjs.map +1 -1
- package/dist/apis/organizations/OrganizationsApi.d.ts +7 -1
- package/dist/apis/organizations/OrganizationsApi.d.ts.map +1 -1
- package/dist/apis/organizations/OrganizationsApi.mjs +7 -0
- package/dist/apis/organizations/OrganizationsApi.mjs.map +1 -1
- package/dist/apis/people/PeopleApi.cjs +7 -0
- package/dist/apis/people/PeopleApi.cjs.map +1 -1
- package/dist/apis/people/PeopleApi.d.ts +7 -1
- package/dist/apis/people/PeopleApi.d.ts.map +1 -1
- package/dist/apis/people/PeopleApi.mjs +7 -0
- package/dist/apis/people/PeopleApi.mjs.map +1 -1
- package/dist/apis/planAiHistory/PlanAiHistoryApi.cjs +16 -0
- package/dist/apis/planAiHistory/PlanAiHistoryApi.cjs.map +1 -1
- package/dist/apis/planAiHistory/PlanAiHistoryApi.d.ts +10 -0
- package/dist/apis/planAiHistory/PlanAiHistoryApi.d.ts.map +1 -1
- package/dist/apis/planAiHistory/PlanAiHistoryApi.mjs +16 -0
- package/dist/apis/planAiHistory/PlanAiHistoryApi.mjs.map +1 -1
- package/dist/apis/roles/RolesApi.cjs +7 -0
- package/dist/apis/roles/RolesApi.cjs.map +1 -1
- package/dist/apis/roles/RolesApi.d.ts +6 -1
- package/dist/apis/roles/RolesApi.d.ts.map +1 -1
- package/dist/apis/roles/RolesApi.mjs +7 -0
- package/dist/apis/roles/RolesApi.mjs.map +1 -1
- package/dist/apis/services/ServicesApi.cjs +68 -0
- package/dist/apis/services/ServicesApi.cjs.map +1 -1
- package/dist/apis/services/ServicesApi.d.ts +53 -1
- package/dist/apis/services/ServicesApi.d.ts.map +1 -1
- package/dist/apis/services/ServicesApi.mjs +68 -0
- package/dist/apis/services/ServicesApi.mjs.map +1 -1
- package/dist/apis/services/types.d.ts +15 -0
- package/dist/apis/services/types.d.ts.map +1 -1
- package/dist/apis/stickers/StickersApi.cjs +20 -0
- package/dist/apis/stickers/StickersApi.cjs.map +1 -1
- package/dist/apis/stickers/StickersApi.d.ts +15 -0
- package/dist/apis/stickers/StickersApi.d.ts.map +1 -1
- package/dist/apis/stickers/StickersApi.mjs +20 -0
- package/dist/apis/stickers/StickersApi.mjs.map +1 -1
- package/dist/apis/tags/TagsApi.cjs +7 -0
- package/dist/apis/tags/TagsApi.cjs.map +1 -1
- package/dist/apis/tags/TagsApi.d.ts +7 -1
- package/dist/apis/tags/TagsApi.d.ts.map +1 -1
- package/dist/apis/tags/TagsApi.mjs +7 -0
- package/dist/apis/tags/TagsApi.mjs.map +1 -1
- package/dist/apis/timetable/TimetableApi.cjs +7 -0
- package/dist/apis/timetable/TimetableApi.cjs.map +1 -1
- package/dist/apis/timetable/TimetableApi.d.ts +7 -1
- package/dist/apis/timetable/TimetableApi.d.ts.map +1 -1
- package/dist/apis/timetable/TimetableApi.mjs +7 -0
- package/dist/apis/timetable/TimetableApi.mjs.map +1 -1
- package/dist/apis/users/UsersApi.cjs +8 -0
- package/dist/apis/users/UsersApi.cjs.map +1 -1
- package/dist/apis/users/UsersApi.d.ts +8 -1
- package/dist/apis/users/UsersApi.d.ts.map +1 -1
- package/dist/apis/users/UsersApi.mjs +8 -0
- package/dist/apis/users/UsersApi.mjs.map +1 -1
- package/dist/apis/users/types.d.ts +15 -0
- package/dist/apis/users/types.d.ts.map +1 -1
- package/dist/apis/webhooks/WebhooksApi.cjs +7 -0
- package/dist/apis/webhooks/WebhooksApi.cjs.map +1 -1
- package/dist/apis/webhooks/WebhooksApi.d.ts +7 -1
- package/dist/apis/webhooks/WebhooksApi.d.ts.map +1 -1
- package/dist/apis/webhooks/WebhooksApi.mjs +7 -0
- package/dist/apis/webhooks/WebhooksApi.mjs.map +1 -1
- package/dist/core/ApiClient.d.ts +14 -0
- package/dist/core/ApiClient.d.ts.map +1 -1
- package/dist/core/ArchivableCrudApi.cjs.map +1 -1
- package/dist/core/ArchivableCrudApi.d.ts +1 -1
- package/dist/core/ArchivableCrudApi.d.ts.map +1 -1
- package/dist/core/ArchivableCrudApi.mjs.map +1 -1
- package/dist/core/BaseApiClient.cjs +24 -3
- package/dist/core/BaseApiClient.cjs.map +1 -1
- package/dist/core/BaseApiClient.d.ts +14 -0
- package/dist/core/BaseApiClient.d.ts.map +1 -1
- package/dist/core/BaseApiClient.mjs +24 -3
- package/dist/core/BaseApiClient.mjs.map +1 -1
- package/dist/core/BaseCrudApi.cjs +3 -1
- package/dist/core/BaseCrudApi.cjs.map +1 -1
- package/dist/core/BaseCrudApi.d.ts +6 -4
- package/dist/core/BaseCrudApi.d.ts.map +1 -1
- package/dist/core/BaseCrudApi.mjs +3 -1
- package/dist/core/BaseCrudApi.mjs.map +1 -1
- package/dist/core/requestExternal.cjs +33 -0
- package/dist/core/requestExternal.cjs.map +1 -0
- package/dist/core/requestExternal.d.ts +9 -0
- package/dist/core/requestExternal.d.ts.map +1 -0
- package/dist/core/requestExternal.mjs +32 -0
- package/dist/core/requestExternal.mjs.map +1 -0
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/apis/absence/AbsenceApi.ts +19 -0
- package/src/apis/acceptanceTerms/AcceptanceTermsApi.ts +13 -1
- package/src/apis/accounts/AccountsApi.ts +5 -0
- package/src/apis/accounts/types.ts +2 -0
- package/src/apis/activityLog/ActivityLogApi.ts +18 -0
- package/src/apis/categories/CategoriesApi.ts +12 -1
- package/src/apis/clientFeedback/ClientFeedbackApi.ts +5 -1
- package/src/apis/contactBlockLists/ContactBlockListsApi.test.ts +57 -0
- package/src/apis/contactBlockLists/ContactBlockListsApi.ts +57 -1
- package/src/apis/contactBlockLists/types.ts +6 -1
- package/src/apis/contactBlockListsControls/ContactBlockListsControlsApi.test.ts +48 -0
- package/src/apis/contactBlockListsControls/ContactBlockListsControlsApi.ts +59 -1
- package/src/apis/contactBlockListsControls/types.ts +7 -0
- package/src/apis/contacts/ContactsApi.test.ts +20 -4
- package/src/apis/contacts/ContactsApi.ts +24 -5
- package/src/apis/contacts/types.ts +7 -1
- package/src/apis/creditMovements/CreditMovementsApi.ts +27 -0
- package/src/apis/customFields/CustomFieldsApi.ts +12 -1
- package/src/apis/departments/DepartmentsApi.test.ts +88 -0
- package/src/apis/departments/DepartmentsApi.ts +41 -2
- package/src/apis/departments/types.ts +6 -0
- package/src/apis/distribution/DistributionApi.test.ts +65 -0
- package/src/apis/distribution/DistributionApi.ts +50 -1
- package/src/apis/distribution/types.ts +17 -1
- package/src/apis/files/FilesApi.test.ts +122 -0
- package/src/apis/files/FilesApi.ts +107 -2
- package/src/apis/files/types.ts +48 -7
- package/src/apis/holiday/HolidayApi.ts +16 -1
- package/src/apis/integrations/IntegrationsApi.test.ts +42 -0
- package/src/apis/integrations/IntegrationsApi.ts +46 -2
- package/src/apis/integrations/types.ts +25 -6
- package/src/apis/interactiveMessages/InteractiveMessagesApi.ts +12 -1
- package/src/apis/kanbanBoards/KanbanBoardsApi.ts +12 -1
- package/src/apis/kanbanCards/KanbanCardsApi.ts +12 -1
- package/src/apis/knowledgeBase/KnowledgeBaseApi.ts +13 -1
- package/src/apis/knowledgeBaseItem/KnowledgeBaseItemApi.ts +13 -1
- package/src/apis/messages/MessagesApi.test.ts +13 -7
- package/src/apis/messages/MessagesApi.ts +29 -3
- package/src/apis/messages/types.ts +3 -0
- package/src/apis/notifications/NotificationsApi.ts +12 -1
- package/src/apis/organizations/OrganizationsApi.ts +12 -1
- package/src/apis/payloads.test-d.ts +172 -0
- package/src/apis/people/PeopleApi.ts +16 -1
- package/src/apis/planAiHistory/PlanAiHistoryApi.ts +26 -0
- package/src/apis/roles/RolesApi.ts +10 -1
- package/src/apis/services/ServicesApi.test.ts +45 -0
- package/src/apis/services/ServicesApi.ts +91 -1
- package/src/apis/services/types.ts +16 -0
- package/src/apis/stickers/StickersApi.ts +32 -0
- package/src/apis/tags/TagsApi.ts +16 -1
- package/src/apis/timetable/TimetableApi.ts +12 -1
- package/src/apis/users/UsersApi.ts +17 -1
- package/src/apis/users/types.ts +11 -0
- package/src/apis/webhooks/WebhooksApi.ts +16 -1
- package/src/core/ApiClient.ts +24 -0
- package/src/core/ArchivableCrudApi.ts +2 -1
- package/src/core/BaseApiClient.test.ts +98 -0
- package/src/core/BaseApiClient.ts +49 -4
- package/src/core/BaseCrudApi.test-d.ts +11 -1
- package/src/core/BaseCrudApi.ts +15 -6
- package/src/core/requestExternal.ts +43 -0
- package/src/core/types.ts +4 -2
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
|
+
import type { ListQuery } from '../../core/types'
|
|
2
3
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
4
|
import type { CustomField, CreateCustomFieldPayload, UpdateCustomFieldPayload } from './types'
|
|
4
5
|
|
|
5
6
|
export class CustomFieldsApi extends BaseCrudApi<
|
|
6
7
|
CustomField,
|
|
7
8
|
CreateCustomFieldPayload,
|
|
8
|
-
UpdateCustomFieldPayload
|
|
9
|
+
UpdateCustomFieldPayload,
|
|
10
|
+
ListQuery<CustomField>,
|
|
11
|
+
'OK'
|
|
9
12
|
> {
|
|
10
13
|
constructor(client: ApiClient) {
|
|
11
14
|
super(client, '/custom-fields')
|
|
12
15
|
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Deletes a custom field. Resolves the text `'OK'`.
|
|
19
|
+
* @permissions customFields.view OR customFields.destroy
|
|
20
|
+
*/
|
|
21
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<'OK'> {
|
|
22
|
+
return super.deleteById(id, headers)
|
|
23
|
+
}
|
|
13
24
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { DepartmentsApi } from './DepartmentsApi'
|
|
3
|
+
import type { ApiClient } from '../../core/ApiClient'
|
|
4
|
+
import type { Department } from './types'
|
|
5
|
+
|
|
6
|
+
// ── Mock client factory ──────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
function createMockClient(): ApiClient {
|
|
9
|
+
return {
|
|
10
|
+
setAccessToken: vi.fn().mockReturnThis(),
|
|
11
|
+
request: 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
|
+
const department: Department = {
|
|
21
|
+
id: 'dep-1',
|
|
22
|
+
name: 'Support',
|
|
23
|
+
accountId: 'acc-1',
|
|
24
|
+
distributionId: null,
|
|
25
|
+
archivedAt: '2026-01-01T00:00:00Z',
|
|
26
|
+
createdAt: '2026-01-01T00:00:00Z',
|
|
27
|
+
updatedAt: '2026-01-01T00:00:00Z',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
describe('DepartmentsApi', () => {
|
|
33
|
+
let client: ReturnType<typeof createMockClient>
|
|
34
|
+
let api: DepartmentsApi
|
|
35
|
+
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
client = createMockClient()
|
|
38
|
+
api = new DepartmentsApi(client)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe('archiveWithValidation', () => {
|
|
42
|
+
it('calls client.post with /departments/:id/archive and { archive: true }', async () => {
|
|
43
|
+
vi.mocked(client.post).mockResolvedValue(department)
|
|
44
|
+
const result = await api.archiveWithValidation('dep-1', { archive: true })
|
|
45
|
+
expect(client.post).toHaveBeenCalledWith(
|
|
46
|
+
'/departments/dep-1/archive',
|
|
47
|
+
{ archive: true },
|
|
48
|
+
undefined,
|
|
49
|
+
)
|
|
50
|
+
expect(result).toEqual(department)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('restores with { archive: false } and forwards custom headers', async () => {
|
|
54
|
+
const headers = { 'X-Custom': 'value' }
|
|
55
|
+
await api.archiveWithValidation('dep-1', { archive: false }, headers)
|
|
56
|
+
expect(client.post).toHaveBeenCalledWith(
|
|
57
|
+
'/departments/dep-1/archive',
|
|
58
|
+
{ archive: false },
|
|
59
|
+
headers,
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe('archive / unarchive (PUT { archivedAt })', () => {
|
|
65
|
+
it('archive sends the current time in archivedAt', async () => {
|
|
66
|
+
await api.archive('dep-1')
|
|
67
|
+
expect(client.put).toHaveBeenCalledWith(
|
|
68
|
+
'/departments/dep-1',
|
|
69
|
+
{ archivedAt: expect.any(String) },
|
|
70
|
+
undefined,
|
|
71
|
+
)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('unarchive sends archivedAt null', async () => {
|
|
75
|
+
await api.unarchive('dep-1')
|
|
76
|
+
expect(client.put).toHaveBeenCalledWith('/departments/dep-1', { archivedAt: null }, undefined)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
describe('deleteById', () => {
|
|
81
|
+
it("calls client.delete with /departments/:id and resolves 'OK'", async () => {
|
|
82
|
+
vi.mocked(client.delete).mockResolvedValue('OK')
|
|
83
|
+
const result = await api.deleteById('dep-1')
|
|
84
|
+
expect(client.delete).toHaveBeenCalledWith('/departments/dep-1', undefined)
|
|
85
|
+
expect(result).toBe('OK')
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
})
|
|
@@ -1,13 +1,52 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
|
+
import type { ListQuery } from '../../core/types'
|
|
2
3
|
import { ArchivableCrudApi } from '../../core/ArchivableCrudApi'
|
|
3
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
Department,
|
|
6
|
+
CreateDepartmentPayload,
|
|
7
|
+
UpdateDepartmentPayload,
|
|
8
|
+
ArchiveDepartmentPayload,
|
|
9
|
+
} from './types'
|
|
4
10
|
|
|
5
11
|
export class DepartmentsApi extends ArchivableCrudApi<
|
|
6
12
|
Department,
|
|
7
13
|
CreateDepartmentPayload,
|
|
8
|
-
UpdateDepartmentPayload
|
|
14
|
+
UpdateDepartmentPayload,
|
|
15
|
+
ListQuery<Department>,
|
|
16
|
+
'OK'
|
|
9
17
|
> {
|
|
10
18
|
constructor(client: ApiClient) {
|
|
11
19
|
super(client, '/departments')
|
|
12
20
|
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Archives (`archive: true`) or restores (`archive: false`) a department through the route used
|
|
24
|
+
* by the UI, which enforces what {@link archive}/{@link unarchive} (a plain `PUT { archivedAt }`)
|
|
25
|
+
* skip: archiving refuses (403 `Cannot archive department.`, with the reasons and the open
|
|
26
|
+
* tickets count) a department in use, and clears it as the default department of contacts and
|
|
27
|
+
* connections, marks its schedules as done and unlinks its users and quick replies. Resolves the
|
|
28
|
+
* stored department (not transformed); an unknown id answers 500.
|
|
29
|
+
* @permissions departments.view OR departments.archive
|
|
30
|
+
*/
|
|
31
|
+
archiveWithValidation(
|
|
32
|
+
id: string,
|
|
33
|
+
body: ArchiveDepartmentPayload,
|
|
34
|
+
headers?: Record<string, string>,
|
|
35
|
+
): Promise<Department> {
|
|
36
|
+
return this.client.post<Department, ArchiveDepartmentPayload>(
|
|
37
|
+
`${this.basePath}/${id}/archive`,
|
|
38
|
+
body,
|
|
39
|
+
headers,
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Deletes a department. Resolves the text `'OK'`; a department that is the default of the account
|
|
45
|
+
* or that is referenced in the attendant name visibility settings is refused, and an unknown id
|
|
46
|
+
* answers 500.
|
|
47
|
+
* @permissions departments.view OR departments.archive
|
|
48
|
+
*/
|
|
49
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<'OK'> {
|
|
50
|
+
return super.deleteById(id, headers)
|
|
51
|
+
}
|
|
13
52
|
}
|
|
@@ -26,3 +26,9 @@ export type UpdateDepartmentPayload = {
|
|
|
26
26
|
distributionId?: string | null
|
|
27
27
|
archivedAt?: string | null
|
|
28
28
|
}
|
|
29
|
+
|
|
30
|
+
/** Body of `DepartmentsApi.archiveWithValidation`. */
|
|
31
|
+
export type ArchiveDepartmentPayload = {
|
|
32
|
+
/** `true` archives, `false` restores. */
|
|
33
|
+
archive: boolean
|
|
34
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { DistributionApi } from './DistributionApi'
|
|
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
|
+
get: vi.fn(),
|
|
12
|
+
post: vi.fn(),
|
|
13
|
+
put: vi.fn(),
|
|
14
|
+
patch: vi.fn(),
|
|
15
|
+
delete: vi.fn(),
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
describe('DistributionApi', () => {
|
|
22
|
+
let client: ReturnType<typeof createMockClient>
|
|
23
|
+
let api: DistributionApi
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
client = createMockClient()
|
|
27
|
+
api = new DistributionApi(client)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
describe('create', () => {
|
|
31
|
+
it('posts the body, links included, to /distribution', async () => {
|
|
32
|
+
vi.mocked(client.post).mockResolvedValue(undefined)
|
|
33
|
+
const body = { name: 'QA', maxNum: 1, redistributeAll: false, departments: [{ id: 'dep-1' }] }
|
|
34
|
+
const result = await api.create(body)
|
|
35
|
+
expect(client.post).toHaveBeenCalledWith('/distribution', body, undefined)
|
|
36
|
+
expect(result).toBeUndefined()
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
describe('updateById', () => {
|
|
41
|
+
it('sends the id in the body too, which is where the backend reads it', async () => {
|
|
42
|
+
vi.mocked(client.put).mockResolvedValue([])
|
|
43
|
+
await api.updateById('dist-1', { name: 'QA', roles: [{ id: 'role-1' }] })
|
|
44
|
+
expect(client.put).toHaveBeenCalledWith(
|
|
45
|
+
'/distribution/dist-1',
|
|
46
|
+
{ name: 'QA', roles: [{ id: 'role-1' }], id: 'dist-1' },
|
|
47
|
+
undefined,
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('keeps the id of the URL over an id of the body and forwards custom headers', async () => {
|
|
52
|
+
const headers = { 'X-Custom': 'value' }
|
|
53
|
+
await api.updateById('dist-1', { id: 'other' } as never, headers)
|
|
54
|
+
expect(client.put).toHaveBeenCalledWith('/distribution/dist-1', { id: 'dist-1' }, headers)
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
describe('deleteById', () => {
|
|
59
|
+
it('calls client.delete with /distribution/:id', async () => {
|
|
60
|
+
vi.mocked(client.delete).mockResolvedValue(undefined)
|
|
61
|
+
await api.deleteById('dist-1')
|
|
62
|
+
expect(client.delete).toHaveBeenCalledWith('/distribution/dist-1', undefined)
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
})
|
|
@@ -1,13 +1,62 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
|
+
import type { ListQuery } from '../../core/types'
|
|
2
3
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
4
|
+
import type { Department } from '../departments/types'
|
|
3
5
|
import type { Distribution, CreateDistributionPayload, UpdateDistributionPayload } from './types'
|
|
4
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Ticket distribution rules. `getById` answers `null` for an unknown id and always includes `departments` and
|
|
9
|
+
* `roles` (the query is ignored).
|
|
10
|
+
*/
|
|
5
11
|
export class DistributionApi extends BaseCrudApi<
|
|
6
12
|
Distribution,
|
|
7
13
|
CreateDistributionPayload,
|
|
8
|
-
UpdateDistributionPayload
|
|
14
|
+
UpdateDistributionPayload,
|
|
15
|
+
ListQuery<Distribution>,
|
|
16
|
+
void,
|
|
17
|
+
Distribution | undefined,
|
|
18
|
+
Distribution | Department[]
|
|
9
19
|
> {
|
|
10
20
|
constructor(client: ApiClient) {
|
|
11
21
|
super(client, '/distribution')
|
|
12
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates a distribution. Resolves the distribution (without `departments`/`roles`), or no body
|
|
26
|
+
* (`undefined`) when `departments` is sent — find it by name with `getMany` in that case.
|
|
27
|
+
* @permissions distribution.create
|
|
28
|
+
*/
|
|
29
|
+
override create(
|
|
30
|
+
body: CreateDistributionPayload,
|
|
31
|
+
headers?: Record<string, string>,
|
|
32
|
+
): Promise<Distribution | undefined> {
|
|
33
|
+
return super.create(body, headers)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Updates a distribution. The backend reads the id from the body, so it is sent there too. It replaces
|
|
38
|
+
* the links: omitting `roles` or `departments` clears them. Resolves the stored distribution (with
|
|
39
|
+
* `deletedAt`, without the links) or, when `departments` is sent, the updated departments. An unknown id
|
|
40
|
+
* answers 500.
|
|
41
|
+
* @permissions distribution.view OR distribution.update
|
|
42
|
+
*/
|
|
43
|
+
override updateById(
|
|
44
|
+
id: string,
|
|
45
|
+
body: UpdateDistributionPayload,
|
|
46
|
+
headers?: Record<string, string>,
|
|
47
|
+
): Promise<Distribution | Department[]> {
|
|
48
|
+
return this.client.put<Distribution | Department[], UpdateDistributionPayload & { id: string }>(
|
|
49
|
+
`${this.basePath}/${id}`,
|
|
50
|
+
{ ...body, id },
|
|
51
|
+
headers,
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Deletes a distribution. Resolves with no body, also for an unknown id (200).
|
|
57
|
+
* @permissions distribution.view OR distribution.destroy
|
|
58
|
+
*/
|
|
59
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<void> {
|
|
60
|
+
return super.deleteById(id, headers)
|
|
61
|
+
}
|
|
13
62
|
}
|
|
@@ -11,7 +11,8 @@ export type Distribution = {
|
|
|
11
11
|
distributeQueue: boolean
|
|
12
12
|
accountId: string
|
|
13
13
|
archivedAt: string | null
|
|
14
|
-
|
|
14
|
+
/** Only in the answer of `updateById` (the stored model, not transformed). */
|
|
15
|
+
deletedAt?: string | null
|
|
15
16
|
createdAt: string
|
|
16
17
|
updatedAt: string
|
|
17
18
|
// relationships
|
|
@@ -21,6 +22,9 @@ export type Distribution = {
|
|
|
21
22
|
|
|
22
23
|
export type DistributionRelationships = 'departments' | 'roles'
|
|
23
24
|
|
|
25
|
+
/** A department or a role linked to a distribution (only the id is read). */
|
|
26
|
+
export type DistributionLink = { id: string }
|
|
27
|
+
|
|
24
28
|
export type CreateDistributionPayload = {
|
|
25
29
|
name: string
|
|
26
30
|
maxNum: number
|
|
@@ -28,8 +32,17 @@ export type CreateDistributionPayload = {
|
|
|
28
32
|
timeToRedistribute?: number
|
|
29
33
|
redistributeAssignedTickets?: boolean
|
|
30
34
|
distributeQueue?: boolean
|
|
35
|
+
/** An archived distribution is skipped by the distribution crons. */
|
|
36
|
+
archivedAt?: string | null
|
|
37
|
+
/** Departments to distribute; a department has at most one distribution. */
|
|
38
|
+
departments?: DistributionLink[]
|
|
39
|
+
roles?: DistributionLink[]
|
|
31
40
|
}
|
|
32
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The update replaces the links: send `departments` and `roles` again to keep them — omitting them
|
|
44
|
+
* clears them.
|
|
45
|
+
*/
|
|
33
46
|
export type UpdateDistributionPayload = {
|
|
34
47
|
name?: string
|
|
35
48
|
maxNum?: number
|
|
@@ -37,4 +50,7 @@ export type UpdateDistributionPayload = {
|
|
|
37
50
|
timeToRedistribute?: number
|
|
38
51
|
redistributeAssignedTickets?: boolean
|
|
39
52
|
distributeQueue?: boolean
|
|
53
|
+
archivedAt?: string | null
|
|
54
|
+
departments?: DistributionLink[]
|
|
55
|
+
roles?: DistributionLink[]
|
|
40
56
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { FilesApi } from './FilesApi'
|
|
3
|
+
import type { ApiClient } from '../../core/ApiClient'
|
|
4
|
+
import { ApiConnectionError, ApiError } from '../../core/errors'
|
|
5
|
+
import type { CreateToUploadResult } from './types'
|
|
6
|
+
|
|
7
|
+
// ── Mock client factory ──────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
function createMockClient(): ApiClient {
|
|
10
|
+
return {
|
|
11
|
+
setAccessToken: vi.fn().mockReturnThis(),
|
|
12
|
+
request: vi.fn(),
|
|
13
|
+
get: vi.fn(),
|
|
14
|
+
post: vi.fn(),
|
|
15
|
+
put: vi.fn(),
|
|
16
|
+
patch: vi.fn(),
|
|
17
|
+
delete: vi.fn(),
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const URL_TO_UPLOAD = 'https://storage.example.com/acc-1/file-1.plain?X-Amz-Signature=abc'
|
|
22
|
+
|
|
23
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
describe('FilesApi', () => {
|
|
26
|
+
let client: ReturnType<typeof createMockClient>
|
|
27
|
+
let api: FilesApi
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
client = createMockClient()
|
|
31
|
+
api = new FilesApi(client)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
vi.restoreAllMocks()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe('createToUpload', () => {
|
|
39
|
+
it('calls client.post with /files/create-to-upload and body', async () => {
|
|
40
|
+
const created: CreateToUploadResult = {
|
|
41
|
+
urlToUpload: URL_TO_UPLOAD,
|
|
42
|
+
id: 'file-1',
|
|
43
|
+
name: 'report.txt',
|
|
44
|
+
mimetype: 'text/plain',
|
|
45
|
+
}
|
|
46
|
+
vi.mocked(client.post).mockResolvedValue(created)
|
|
47
|
+
const body = { name: 'report.txt', mimetype: 'text/plain', attachedType: 'campaign.file' }
|
|
48
|
+
const result = await api.createToUpload(body)
|
|
49
|
+
expect(client.post).toHaveBeenCalledWith('/files/create-to-upload', body, undefined)
|
|
50
|
+
expect(result).toEqual(created)
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe('upload', () => {
|
|
55
|
+
it('sends through client.requestExternal when the client has it', async () => {
|
|
56
|
+
const requestExternal = vi.fn().mockResolvedValue(new Response(null, { status: 200 }))
|
|
57
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch')
|
|
58
|
+
api = new FilesApi({ ...client, requestExternal })
|
|
59
|
+
await api.upload(URL_TO_UPLOAD, 'content', 'text/plain')
|
|
60
|
+
expect(requestExternal).toHaveBeenCalledWith('PUT', URL_TO_UPLOAD, 'content', {
|
|
61
|
+
'Content-Type': 'text/plain',
|
|
62
|
+
})
|
|
63
|
+
expect(fetchSpy).not.toHaveBeenCalled()
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('without client.requestExternal, PUTs the content to the signed URL with the global fetch', async () => {
|
|
67
|
+
const spy = vi
|
|
68
|
+
.spyOn(globalThis, 'fetch')
|
|
69
|
+
.mockResolvedValue(new Response(null, { status: 200 }))
|
|
70
|
+
await api.upload(URL_TO_UPLOAD, 'content', 'text/plain')
|
|
71
|
+
expect(spy).toHaveBeenCalledWith(URL_TO_UPLOAD, {
|
|
72
|
+
method: 'PUT',
|
|
73
|
+
headers: { 'Content-Type': 'text/plain' },
|
|
74
|
+
body: 'content',
|
|
75
|
+
})
|
|
76
|
+
expect(client.request).not.toHaveBeenCalled()
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('throws ApiError when the storage refuses the upload', async () => {
|
|
80
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValue(
|
|
81
|
+
new Response('<Error><Code>SignatureDoesNotMatch</Code></Error>', {
|
|
82
|
+
status: 403,
|
|
83
|
+
statusText: 'Forbidden',
|
|
84
|
+
}),
|
|
85
|
+
)
|
|
86
|
+
const captured = await api.upload(URL_TO_UPLOAD, 'content', 'text/plain').catch((e) => e)
|
|
87
|
+
expect(captured).toBeInstanceOf(ApiError)
|
|
88
|
+
expect((captured as ApiError).status).toBe(403)
|
|
89
|
+
expect((captured as ApiError).body).toBe('<Error><Code>SignatureDoesNotMatch</Code></Error>')
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('throws ApiConnectionError when the request fails', async () => {
|
|
93
|
+
vi.spyOn(globalThis, 'fetch').mockRejectedValue(new TypeError('fetch failed'))
|
|
94
|
+
await expect(api.upload(URL_TO_UPLOAD, 'content', 'text/plain')).rejects.toBeInstanceOf(
|
|
95
|
+
ApiConnectionError,
|
|
96
|
+
)
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
describe('deleteById', () => {
|
|
101
|
+
it('calls client.delete with /files/:id and resolves { success }', async () => {
|
|
102
|
+
vi.mocked(client.delete).mockResolvedValue({ success: true })
|
|
103
|
+
const result = await api.deleteById('file-1')
|
|
104
|
+
expect(client.delete).toHaveBeenCalledWith('/files/file-1', undefined)
|
|
105
|
+
expect(result).toEqual({ success: true })
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe('deprecated reads and update (no backend route)', () => {
|
|
110
|
+
it('still call the same paths', async () => {
|
|
111
|
+
await api.getById('file-1')
|
|
112
|
+
await api.getMany({ where: { id: 'file-1' } })
|
|
113
|
+
await api.updateById('file-1', { name: 'x' })
|
|
114
|
+
expect(client.get).toHaveBeenCalledWith('/files/file-1', undefined)
|
|
115
|
+
expect(client.get).toHaveBeenCalledWith(
|
|
116
|
+
`/files?query=${encodeURIComponent(JSON.stringify({ where: { id: 'file-1' } }))}`,
|
|
117
|
+
undefined,
|
|
118
|
+
)
|
|
119
|
+
expect(client.put).toHaveBeenCalledWith('/files/file-1', { name: 'x' }, undefined)
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
})
|
|
@@ -1,9 +1,114 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
|
-
import
|
|
3
|
+
import { requestExternal } from '../../core/requestExternal'
|
|
4
|
+
import type { GetByIdQuery, ListQuery, Paginated } from '../../core/types'
|
|
5
|
+
import type {
|
|
6
|
+
File,
|
|
7
|
+
CreateFilePayload,
|
|
8
|
+
UpdateFilePayload,
|
|
9
|
+
CreateToUploadPayload,
|
|
10
|
+
CreateToUploadResult,
|
|
11
|
+
DeleteFileResult,
|
|
12
|
+
} from './types'
|
|
4
13
|
|
|
5
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Files of the account. The backend serves `POST /files` (the record only, no content),
|
|
16
|
+
* `POST /files/create-to-upload` (record + signed URL to upload the content), `POST
|
|
17
|
+
* /files/duplicate-file`, `DELETE /files/:id` and the signed download `GET
|
|
18
|
+
* /files/:accountId/:filename`; there is no list, read by id nor update.
|
|
19
|
+
*/
|
|
20
|
+
export class FilesApi extends BaseCrudApi<
|
|
21
|
+
File,
|
|
22
|
+
CreateFilePayload,
|
|
23
|
+
UpdateFilePayload,
|
|
24
|
+
ListQuery<File>,
|
|
25
|
+
DeleteFileResult
|
|
26
|
+
> {
|
|
6
27
|
constructor(client: ApiClient) {
|
|
7
28
|
super(client, '/files')
|
|
8
29
|
}
|
|
30
|
+
|
|
31
|
+
/** @deprecated Not served: the backend has no GET /files, so this route answers 404. */
|
|
32
|
+
override getMany(
|
|
33
|
+
query: ListQuery<File> & { paginate: false },
|
|
34
|
+
headers?: Record<string, string>,
|
|
35
|
+
): Promise<File[]>
|
|
36
|
+
/** @deprecated Not served: the backend has no GET /files, so this route answers 404. */
|
|
37
|
+
override getMany(
|
|
38
|
+
query?: ListQuery<File> & { paginate?: true },
|
|
39
|
+
headers?: Record<string, string>,
|
|
40
|
+
): Promise<Paginated<File>>
|
|
41
|
+
/** @deprecated Not served: the backend has no GET /files, so this route answers 404. */
|
|
42
|
+
override getMany(
|
|
43
|
+
query?: ListQuery<File>,
|
|
44
|
+
headers?: Record<string, string>,
|
|
45
|
+
): Promise<Paginated<File> | File[]>
|
|
46
|
+
override getMany(
|
|
47
|
+
query?: ListQuery<File>,
|
|
48
|
+
headers?: Record<string, string>,
|
|
49
|
+
): Promise<Paginated<File> | File[]> {
|
|
50
|
+
return super.getMany(query, headers)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** @deprecated Not served: the backend has no GET /files, so this route answers 404. */
|
|
54
|
+
override getOne(query?: ListQuery<File>, headers?: Record<string, string>): Promise<File | null> {
|
|
55
|
+
return super.getOne(query, headers)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @deprecated Not served: the backend has no GET /files/:id, so this route answers 404. */
|
|
59
|
+
override getById(
|
|
60
|
+
id: string,
|
|
61
|
+
query?: GetByIdQuery<File>,
|
|
62
|
+
headers?: Record<string, string>,
|
|
63
|
+
): Promise<File> {
|
|
64
|
+
return super.getById(id, query, headers)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** @deprecated Not served: the backend has no PUT /files/:id, so this route answers 404. */
|
|
68
|
+
override updateById(
|
|
69
|
+
id: string,
|
|
70
|
+
body: UpdateFilePayload,
|
|
71
|
+
headers?: Record<string, string>,
|
|
72
|
+
): Promise<File> {
|
|
73
|
+
return super.updateById(id, body, headers)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Deletes a file. Resolves `{ success: true }`, also for an unknown id; a file of another
|
|
78
|
+
* account answers 403.
|
|
79
|
+
*/
|
|
80
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<DeleteFileResult> {
|
|
81
|
+
return super.deleteById(id, headers)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Creates the record of a file and returns the signed URL to upload its content: send the
|
|
86
|
+
* content with {@link upload}. An audio that must be converted (a voice message for the
|
|
87
|
+
* connection) is sent in `base64` instead, and then no `urlToUpload` is returned. `name` and
|
|
88
|
+
* `mimetype` are required (500 without them; an audio without `name` is named `recording`).
|
|
89
|
+
*/
|
|
90
|
+
createToUpload(
|
|
91
|
+
body: CreateToUploadPayload,
|
|
92
|
+
headers?: Record<string, string>,
|
|
93
|
+
): Promise<CreateToUploadResult> {
|
|
94
|
+
return this.client.post<CreateToUploadResult, CreateToUploadPayload>(
|
|
95
|
+
`${this.basePath}/create-to-upload`,
|
|
96
|
+
body,
|
|
97
|
+
headers,
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Uploads the content of a file to the `urlToUpload` returned by {@link createToUpload}. The URL
|
|
103
|
+
* is signed by the storage, so the request goes straight to it, without the API token (the
|
|
104
|
+
* storage refuses an `Authorization` header). `mimetype` must be the one sent to
|
|
105
|
+
* `createToUpload`. Sent through `client.requestExternal` (the global `fetch` for a client
|
|
106
|
+
* without it). A non-2xx answer of the storage throws `ApiError`.
|
|
107
|
+
*/
|
|
108
|
+
async upload(urlToUpload: string, content: BodyInit, mimetype: string): Promise<void> {
|
|
109
|
+
const headers = { 'Content-Type': mimetype }
|
|
110
|
+
await (this.client.requestExternal
|
|
111
|
+
? this.client.requestExternal('PUT', urlToUpload, content, headers)
|
|
112
|
+
: requestExternal('PUT', urlToUpload, content, headers))
|
|
113
|
+
}
|
|
9
114
|
}
|
package/src/apis/files/types.ts
CHANGED
|
@@ -23,22 +23,32 @@ export type FileStorage =
|
|
|
23
23
|
|
|
24
24
|
export type File = {
|
|
25
25
|
id: string
|
|
26
|
+
/** Signed URL to download the content. */
|
|
26
27
|
url: string
|
|
27
28
|
name: string | null
|
|
29
|
+
/** Name of the file in the storage (`<id>.<extension>`). */
|
|
30
|
+
publicFilename: string | null
|
|
28
31
|
checksum: string | null
|
|
29
32
|
mimetype: string
|
|
30
33
|
extension: string
|
|
31
|
-
isEncrypted: boolean
|
|
32
|
-
iv: string | null
|
|
33
|
-
attachedId: string | null
|
|
34
|
-
attachedType: string | null
|
|
35
|
-
storage: FileStorage
|
|
36
34
|
data: FileData
|
|
37
35
|
accountId: string
|
|
38
|
-
serviceId: string | null
|
|
39
36
|
createdAt: string
|
|
40
37
|
updatedAt: string
|
|
41
|
-
|
|
38
|
+
/** @deprecated Never answered: the file transformer leaves it out. */
|
|
39
|
+
isEncrypted?: boolean
|
|
40
|
+
/** @deprecated Never answered: the file transformer leaves it out. */
|
|
41
|
+
iv?: string | null
|
|
42
|
+
/** @deprecated Never answered: the file transformer leaves it out. */
|
|
43
|
+
attachedId?: string | null
|
|
44
|
+
/** @deprecated Never answered: the file transformer leaves it out. */
|
|
45
|
+
attachedType?: string | null
|
|
46
|
+
/** @deprecated Never answered: the file transformer leaves it out. */
|
|
47
|
+
storage?: FileStorage
|
|
48
|
+
/** @deprecated Never answered: the file transformer leaves it out. */
|
|
49
|
+
serviceId?: string | null
|
|
50
|
+
/** @deprecated Never answered: the file transformer leaves it out. */
|
|
51
|
+
deletedAt?: string | null
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
export type CreateFilePayload = {
|
|
@@ -56,3 +66,34 @@ export type UpdateFilePayload = {
|
|
|
56
66
|
attachedId?: string | null
|
|
57
67
|
attachedType?: string | null
|
|
58
68
|
}
|
|
69
|
+
|
|
70
|
+
/** Body of `FilesApi.createToUpload`. */
|
|
71
|
+
export type CreateToUploadPayload = {
|
|
72
|
+
/** File name (commas are replaced by spaces). Required, except for an audio. */
|
|
73
|
+
name?: string
|
|
74
|
+
mimetype: string
|
|
75
|
+
/** What the file is attached to, e.g. `'message.file'` (default), `'campaign.file'`, `'quickreply.file'`. */
|
|
76
|
+
attachedType?: string
|
|
77
|
+
/** Connection that will send the file (used to decide the audio conversion). */
|
|
78
|
+
serviceId?: string
|
|
79
|
+
/** Audio sent as a voice message (default `true`). */
|
|
80
|
+
isPtt?: boolean
|
|
81
|
+
/** Audio sent as a document, with no conversion (default `false`). */
|
|
82
|
+
sendAsDocument?: boolean
|
|
83
|
+
/** Content of an audio that must be converted (required in that case). */
|
|
84
|
+
base64?: string
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Result of `FilesApi.createToUpload`. */
|
|
88
|
+
export type CreateToUploadResult = {
|
|
89
|
+
/** Signed URL to send the content to (`FilesApi.upload`); absent when the audio was converted. */
|
|
90
|
+
urlToUpload?: string
|
|
91
|
+
id: string
|
|
92
|
+
name: string
|
|
93
|
+
mimetype: string
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Result of `FilesApi.deleteById`. */
|
|
97
|
+
export type DeleteFileResult = {
|
|
98
|
+
success: boolean
|
|
99
|
+
}
|