@ikatec/digisac-api-sdk 4.8.0 → 4.10.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 +8 -0
- package/dist/apis/contactBlockLists/ContactBlockListsApi.cjs.map +1 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.d.ts +8 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.d.ts.map +1 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.mjs +8 -0
- package/dist/apis/contactBlockLists/ContactBlockListsApi.mjs.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.cjs +7 -0
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.cjs.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.d.ts +7 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.d.ts.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.mjs +7 -0
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.mjs.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 +7 -0
- package/dist/apis/distribution/DistributionApi.cjs.map +1 -1
- package/dist/apis/distribution/DistributionApi.d.ts +7 -1
- package/dist/apis/distribution/DistributionApi.d.ts.map +1 -1
- package/dist/apis/distribution/DistributionApi.mjs +7 -0
- package/dist/apis/distribution/DistributionApi.mjs.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 +7 -0
- package/dist/apis/integrations/IntegrationsApi.cjs.map +1 -1
- package/dist/apis/integrations/IntegrationsApi.d.ts +7 -1
- package/dist/apis/integrations/IntegrationsApi.d.ts.map +1 -1
- package/dist/apis/integrations/IntegrationsApi.mjs +7 -0
- package/dist/apis/integrations/IntegrationsApi.mjs.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/interactiveMessages/types.d.ts +61 -3
- package/dist/apis/interactiveMessages/types.d.ts.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 +68 -1
- 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/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/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.ts +13 -1
- package/src/apis/contactBlockListsControls/ContactBlockListsControlsApi.ts +12 -1
- 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.ts +12 -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.ts +12 -1
- package/src/apis/interactiveMessages/InteractiveMessagesApi.ts +12 -1
- package/src/apis/interactiveMessages/types.ts +67 -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 +275 -0
- package/src/apis/payloads.test.ts +41 -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 +63 -1
- 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/requestExternal.ts +43 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseApiClient.mjs","names":[],"sources":["../../src/core/BaseApiClient.ts"],"sourcesContent":["import type { ApiClient, HttpMethod } from './ApiClient'\nimport { ApiConnectionError, ApiError } from './errors'\nimport { DEFAULT_QUERY_FORMAT, type QueryFormat } from './queryString'\n\nexport interface BaseApiClientOptions {\n /** How list/get queries are serialized in the URL. Defaults to `'json'`. */\n queryFormat?: QueryFormat\n}\n\nexport class BaseApiClient implements ApiClient {\n protected readonly baseUrl: string\n protected accessToken: string | null = null\n public readonly queryFormat: QueryFormat\n\n constructor(baseUrl: string, accessToken?: string, options: BaseApiClientOptions = {}) {\n this.baseUrl = baseUrl.replace(/\\/$/, '')\n this.accessToken = accessToken || null\n this.queryFormat = options.queryFormat ?? DEFAULT_QUERY_FORMAT\n }\n\n setAccessToken(accessToken: string): this {\n this.accessToken = accessToken\n return this\n }\n\n async request<TResponse = unknown, TBody = unknown>(\n method: HttpMethod,\n endpoint: string,\n body?: TBody,\n headers?: Record<string, string>,\n ): Promise<TResponse> {\n const url = `${this.baseUrl}/${endpoint.replace(/^\\//, '')}`\n const init: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...(this.accessToken && { Authorization: `Bearer ${this.accessToken}` }),\n ...headers,\n },\n ...(body !== undefined && { body: JSON.stringify(body) }),\n }\n\n
|
|
1
|
+
{"version":3,"file":"BaseApiClient.mjs","names":[],"sources":["../../src/core/BaseApiClient.ts"],"sourcesContent":["import type { ApiClient, HttpMethod } from './ApiClient'\nimport { ApiConnectionError, ApiError } from './errors'\nimport { DEFAULT_QUERY_FORMAT, type QueryFormat } from './queryString'\nimport { requestExternal } from './requestExternal'\n\nexport interface BaseApiClientOptions {\n /** How list/get queries are serialized in the URL. Defaults to `'json'`. */\n queryFormat?: QueryFormat\n}\n\nexport class BaseApiClient implements ApiClient {\n protected readonly baseUrl: string\n protected accessToken: string | null = null\n public readonly queryFormat: QueryFormat\n\n constructor(baseUrl: string, accessToken?: string, options: BaseApiClientOptions = {}) {\n this.baseUrl = baseUrl.replace(/\\/$/, '')\n this.accessToken = accessToken || null\n this.queryFormat = options.queryFormat ?? DEFAULT_QUERY_FORMAT\n }\n\n setAccessToken(accessToken: string): this {\n this.accessToken = accessToken\n return this\n }\n\n async request<TResponse = unknown, TBody = unknown>(\n method: HttpMethod,\n endpoint: string,\n body?: TBody,\n headers?: Record<string, string>,\n ): Promise<TResponse> {\n return this.handleResponse<TResponse>(await this.send(method, endpoint, body, headers))\n }\n\n /**\n * Sends the request and resolves the raw `Response` of a 2xx answer (headers and body\n * untouched, so a binary body can be read with `arrayBuffer()`). Non-2xx throws the\n * `ApiError` subclass, as {@link request} does.\n */\n async requestRaw<TBody = unknown>(\n method: HttpMethod,\n endpoint: string,\n body?: TBody,\n headers?: Record<string, string>,\n ): Promise<Response> {\n const response = await this.send(method, endpoint, body, headers)\n if (!response.ok) {\n throw ApiError.fromResponse(\n response.status,\n response.statusText,\n response.headers,\n await this.readErrorBody(response),\n )\n }\n return response\n }\n\n /**\n * Sends a request to an absolute URL outside the API, without the base URL, the access token\n * and the JSON serialization. Resolves the raw `Response` of a 2xx answer; non-2xx throws the\n * `ApiError` subclass. Override it to intercept those requests as well.\n */\n requestExternal(\n method: HttpMethod,\n url: string,\n body?: BodyInit,\n headers?: Record<string, string>,\n ): Promise<Response> {\n return requestExternal(method, url, body, headers)\n }\n\n /** Builds and sends the request; a network failure is thrown as `ApiConnectionError`. */\n protected async send<TBody = unknown>(\n method: HttpMethod,\n endpoint: string,\n body?: TBody,\n headers?: Record<string, string>,\n ): Promise<Response> {\n const url = `${this.baseUrl}/${endpoint.replace(/^\\//, '')}`\n const init: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...(this.accessToken && { Authorization: `Bearer ${this.accessToken}` }),\n ...headers,\n },\n ...(body !== undefined && { body: JSON.stringify(body) }),\n }\n\n try {\n return await fetch(url, init)\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error)\n throw new ApiConnectionError(`Request to ${method} ${url} failed: ${reason}`, {\n cause: error,\n })\n }\n }\n\n protected async handleResponse<TResponse>(response: Response): Promise<TResponse> {\n if (!response.ok) {\n throw ApiError.fromResponse(\n response.status,\n response.statusText,\n response.headers,\n await this.readErrorBody(response),\n )\n }\n\n // 204 No Content never has a body; short-circuit before reading the stream.\n if (response.status === 204) {\n return undefined as unknown as TResponse\n }\n\n // Read body as text once and treat an empty body as \"no content\" regardless of\n // Content-Type. Servers sometimes return 200 with Content-Type: application/json\n // and an empty body (e.g. POST endpoints whose framework keeps the default JSON\n // content-type even when nothing is written). `response.json()` would throw\n // \"Unexpected end of input\" in that case.\n const text = await response.text()\n if (!text) {\n return undefined as unknown as TResponse\n }\n\n const contentType = response.headers.get('Content-Type')\n const isJson = contentType?.includes('application/json') ?? false\n\n if (isJson) {\n return JSON.parse(text) as TResponse\n }\n\n try {\n return JSON.parse(text) as TResponse\n } catch {\n return text as unknown as TResponse\n }\n }\n\n /** Reads an error body: parsed JSON when possible, the raw text otherwise, `undefined` when empty. */\n protected async readErrorBody(response: Response): Promise<unknown> {\n let text: string\n try {\n text = await response.text()\n } catch {\n return undefined\n }\n if (!text) {\n return undefined\n }\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n }\n\n get<TResponse = unknown>(endpoint: string, headers?: Record<string, string>): Promise<TResponse> {\n return this.request<TResponse>('GET', endpoint, undefined, headers)\n }\n\n post<TResponse = unknown, TBody = unknown>(\n endpoint: string,\n body?: TBody,\n headers?: Record<string, string>,\n ): Promise<TResponse> {\n return this.request<TResponse, TBody>('POST', endpoint, body, headers)\n }\n\n put<TResponse = unknown, TBody = unknown>(\n endpoint: string,\n body?: TBody,\n headers?: Record<string, string>,\n ): Promise<TResponse> {\n return this.request<TResponse, TBody>('PUT', endpoint, body, headers)\n }\n\n patch<TResponse = unknown, TBody = unknown>(\n endpoint: string,\n body?: TBody,\n headers?: Record<string, string>,\n ): Promise<TResponse> {\n return this.request<TResponse, TBody>('PATCH', endpoint, body, headers)\n }\n\n delete<TResponse = unknown>(\n endpoint: string,\n headers?: Record<string, string>,\n ): Promise<TResponse> {\n return this.request<TResponse>('DELETE', endpoint, undefined, headers)\n }\n}\n"],"mappings":";;;;;AAUA,IAAa,gBAAb,MAAgD;CAC9C,AAAmB;CACnB,AAAU,cAA6B;CACvC,AAAgB;CAEhB,YAAY,SAAiB,aAAsB,UAAgC,EAAE,EAAE;AACrF,OAAK,UAAU,QAAQ,QAAQ,OAAO,GAAG;AACzC,OAAK,cAAc,eAAe;AAClC,OAAK,cAAc,QAAQ,eAAe;;CAG5C,eAAe,aAA2B;AACxC,OAAK,cAAc;AACnB,SAAO;;CAGT,MAAM,QACJ,QACA,UACA,MACA,SACoB;AACpB,SAAO,KAAK,eAA0B,MAAM,KAAK,KAAK,QAAQ,UAAU,MAAM,QAAQ,CAAC;;;;;;;CAQzF,MAAM,WACJ,QACA,UACA,MACA,SACmB;EACnB,MAAM,WAAW,MAAM,KAAK,KAAK,QAAQ,UAAU,MAAM,QAAQ;AACjE,MAAI,CAAC,SAAS,GACZ,OAAM,SAAS,aACb,SAAS,QACT,SAAS,YACT,SAAS,SACT,MAAM,KAAK,cAAc,SAAS,CACnC;AAEH,SAAO;;;;;;;CAQT,gBACE,QACA,KACA,MACA,SACmB;AACnB,SAAO,gBAAgB,QAAQ,KAAK,MAAM,QAAQ;;;CAIpD,MAAgB,KACd,QACA,UACA,MACA,SACmB;EACnB,MAAM,MAAM,GAAG,KAAK,QAAQ,GAAG,SAAS,QAAQ,OAAO,GAAG;EAC1D,MAAM,OAAoB;GACxB;GACA,SAAS;IACP,gBAAgB;IAChB,GAAI,KAAK,eAAe,EAAE,eAAe,UAAU,KAAK,eAAe;IACvE,GAAG;IACJ;GACD,GAAI,SAAS,UAAa,EAAE,MAAM,KAAK,UAAU,KAAK,EAAE;GACzD;AAED,MAAI;AACF,UAAO,MAAM,MAAM,KAAK,KAAK;WACtB,OAAO;AAEd,SAAM,IAAI,mBAAmB,cAAc,OAAO,GAAG,IAAI,WAD1C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACS,EAC5E,OAAO,OACR,CAAC;;;CAIN,MAAgB,eAA0B,UAAwC;AAChF,MAAI,CAAC,SAAS,GACZ,OAAM,SAAS,aACb,SAAS,QACT,SAAS,YACT,SAAS,SACT,MAAM,KAAK,cAAc,SAAS,CACnC;AAIH,MAAI,SAAS,WAAW,IACtB;EAQF,MAAM,OAAO,MAAM,SAAS,MAAM;AAClC,MAAI,CAAC,KACH;AAMF,MAHoB,SAAS,QAAQ,IAAI,eAAe,EAC5B,SAAS,mBAAmB,IAAI,MAG1D,QAAO,KAAK,MAAM,KAAK;AAGzB,MAAI;AACF,UAAO,KAAK,MAAM,KAAK;UACjB;AACN,UAAO;;;;CAKX,MAAgB,cAAc,UAAsC;EAClE,IAAI;AACJ,MAAI;AACF,UAAO,MAAM,SAAS,MAAM;UACtB;AACN;;AAEF,MAAI,CAAC,KACH;AAEF,MAAI;AACF,UAAO,KAAK,MAAM,KAAK;UACjB;AACN,UAAO;;;CAIX,IAAyB,UAAkB,SAAsD;AAC/F,SAAO,KAAK,QAAmB,OAAO,UAAU,QAAW,QAAQ;;CAGrE,KACE,UACA,MACA,SACoB;AACpB,SAAO,KAAK,QAA0B,QAAQ,UAAU,MAAM,QAAQ;;CAGxE,IACE,UACA,MACA,SACoB;AACpB,SAAO,KAAK,QAA0B,OAAO,UAAU,MAAM,QAAQ;;CAGvE,MACE,UACA,MACA,SACoB;AACpB,SAAO,KAAK,QAA0B,SAAS,UAAU,MAAM,QAAQ;;CAGzE,OACE,UACA,SACoB;AACpB,SAAO,KAAK,QAAmB,UAAU,UAAU,QAAW,QAAQ"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_core_errors = require('./errors.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/core/requestExternal.ts
|
|
5
|
+
/** The URL without its query string, which may carry a signature that must not reach the logs. */
|
|
6
|
+
function withoutQuery(url) {
|
|
7
|
+
return url.replace(/[?#].*$/s, "");
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Sends a request to an absolute URL outside the API (e.g. a signed storage URL): no base URL, no
|
|
11
|
+
* `Authorization` header and no JSON serialization, `body` goes as is. Resolves the raw `Response`
|
|
12
|
+
* of a 2xx answer; non-2xx throws the `ApiError` subclass with the body as text, and a network
|
|
13
|
+
* failure throws `ApiConnectionError`.
|
|
14
|
+
*/
|
|
15
|
+
async function requestExternal(method, url, body, headers) {
|
|
16
|
+
let response;
|
|
17
|
+
try {
|
|
18
|
+
response = await fetch(url, {
|
|
19
|
+
method,
|
|
20
|
+
...headers && { headers },
|
|
21
|
+
...body !== void 0 && { body }
|
|
22
|
+
});
|
|
23
|
+
} catch (error) {
|
|
24
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
25
|
+
throw new require_core_errors.ApiConnectionError(`Request to ${method} ${withoutQuery(url)} failed: ${reason}`, { cause: error });
|
|
26
|
+
}
|
|
27
|
+
if (!response.ok) throw require_core_errors.ApiError.fromResponse(response.status, response.statusText, response.headers, await response.text().catch(() => void 0) || void 0);
|
|
28
|
+
return response;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
exports.requestExternal = requestExternal;
|
|
33
|
+
//# sourceMappingURL=requestExternal.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestExternal.cjs","names":["ApiConnectionError","ApiError"],"sources":["../../src/core/requestExternal.ts"],"sourcesContent":["import type { HttpMethod } from './ApiClient'\nimport { ApiConnectionError, ApiError } from './errors'\n\n/** The URL without its query string, which may carry a signature that must not reach the logs. */\nfunction withoutQuery(url: string): string {\n return url.replace(/[?#].*$/s, '')\n}\n\n/**\n * Sends a request to an absolute URL outside the API (e.g. a signed storage URL): no base URL, no\n * `Authorization` header and no JSON serialization, `body` goes as is. Resolves the raw `Response`\n * of a 2xx answer; non-2xx throws the `ApiError` subclass with the body as text, and a network\n * failure throws `ApiConnectionError`.\n */\nexport async function requestExternal(\n method: HttpMethod,\n url: string,\n body?: BodyInit,\n headers?: Record<string, string>,\n): Promise<Response> {\n let response: Response\n try {\n response = await fetch(url, {\n method,\n ...(headers && { headers }),\n ...(body !== undefined && { body }),\n })\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error)\n throw new ApiConnectionError(`Request to ${method} ${withoutQuery(url)} failed: ${reason}`, {\n cause: error,\n })\n }\n if (!response.ok) {\n throw ApiError.fromResponse(\n response.status,\n response.statusText,\n response.headers,\n (await response.text().catch(() => undefined)) || undefined,\n )\n }\n return response\n}\n"],"mappings":";;;;;AAIA,SAAS,aAAa,KAAqB;AACzC,QAAO,IAAI,QAAQ,YAAY,GAAG;;;;;;;;AASpC,eAAsB,gBACpB,QACA,KACA,MACA,SACmB;CACnB,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,MAAM,KAAK;GAC1B;GACA,GAAI,WAAW,EAAE,SAAS;GAC1B,GAAI,SAAS,UAAa,EAAE,MAAM;GACnC,CAAC;UACK,OAAO;EACd,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACrE,QAAM,IAAIA,uCAAmB,cAAc,OAAO,GAAG,aAAa,IAAI,CAAC,WAAW,UAAU,EAC1F,OAAO,OACR,CAAC;;AAEJ,KAAI,CAAC,SAAS,GACZ,OAAMC,6BAAS,aACb,SAAS,QACT,SAAS,YACT,SAAS,SACR,MAAM,SAAS,MAAM,CAAC,YAAY,OAAU,IAAK,OACnD;AAEH,QAAO"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { HttpMethod } from './ApiClient';
|
|
2
|
+
/**
|
|
3
|
+
* Sends a request to an absolute URL outside the API (e.g. a signed storage URL): no base URL, no
|
|
4
|
+
* `Authorization` header and no JSON serialization, `body` goes as is. Resolves the raw `Response`
|
|
5
|
+
* of a 2xx answer; non-2xx throws the `ApiError` subclass with the body as text, and a network
|
|
6
|
+
* failure throws `ApiConnectionError`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function requestExternal(method: HttpMethod, url: string, body?: BodyInit, headers?: Record<string, string>): Promise<Response>;
|
|
9
|
+
//# sourceMappingURL=requestExternal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestExternal.d.ts","sourceRoot":"","sources":["../../src/core/requestExternal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAQ7C;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,QAAQ,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,QAAQ,CAAC,CAuBnB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ApiConnectionError, ApiError } from "./errors.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/requestExternal.ts
|
|
4
|
+
/** The URL without its query string, which may carry a signature that must not reach the logs. */
|
|
5
|
+
function withoutQuery(url) {
|
|
6
|
+
return url.replace(/[?#].*$/s, "");
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Sends a request to an absolute URL outside the API (e.g. a signed storage URL): no base URL, no
|
|
10
|
+
* `Authorization` header and no JSON serialization, `body` goes as is. Resolves the raw `Response`
|
|
11
|
+
* of a 2xx answer; non-2xx throws the `ApiError` subclass with the body as text, and a network
|
|
12
|
+
* failure throws `ApiConnectionError`.
|
|
13
|
+
*/
|
|
14
|
+
async function requestExternal(method, url, body, headers) {
|
|
15
|
+
let response;
|
|
16
|
+
try {
|
|
17
|
+
response = await fetch(url, {
|
|
18
|
+
method,
|
|
19
|
+
...headers && { headers },
|
|
20
|
+
...body !== void 0 && { body }
|
|
21
|
+
});
|
|
22
|
+
} catch (error) {
|
|
23
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
24
|
+
throw new ApiConnectionError(`Request to ${method} ${withoutQuery(url)} failed: ${reason}`, { cause: error });
|
|
25
|
+
}
|
|
26
|
+
if (!response.ok) throw ApiError.fromResponse(response.status, response.statusText, response.headers, await response.text().catch(() => void 0) || void 0);
|
|
27
|
+
return response;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { requestExternal };
|
|
32
|
+
//# sourceMappingURL=requestExternal.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestExternal.mjs","names":[],"sources":["../../src/core/requestExternal.ts"],"sourcesContent":["import type { HttpMethod } from './ApiClient'\nimport { ApiConnectionError, ApiError } from './errors'\n\n/** The URL without its query string, which may carry a signature that must not reach the logs. */\nfunction withoutQuery(url: string): string {\n return url.replace(/[?#].*$/s, '')\n}\n\n/**\n * Sends a request to an absolute URL outside the API (e.g. a signed storage URL): no base URL, no\n * `Authorization` header and no JSON serialization, `body` goes as is. Resolves the raw `Response`\n * of a 2xx answer; non-2xx throws the `ApiError` subclass with the body as text, and a network\n * failure throws `ApiConnectionError`.\n */\nexport async function requestExternal(\n method: HttpMethod,\n url: string,\n body?: BodyInit,\n headers?: Record<string, string>,\n): Promise<Response> {\n let response: Response\n try {\n response = await fetch(url, {\n method,\n ...(headers && { headers }),\n ...(body !== undefined && { body }),\n })\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error)\n throw new ApiConnectionError(`Request to ${method} ${withoutQuery(url)} failed: ${reason}`, {\n cause: error,\n })\n }\n if (!response.ok) {\n throw ApiError.fromResponse(\n response.status,\n response.statusText,\n response.headers,\n (await response.text().catch(() => undefined)) || undefined,\n )\n }\n return response\n}\n"],"mappings":";;;;AAIA,SAAS,aAAa,KAAqB;AACzC,QAAO,IAAI,QAAQ,YAAY,GAAG;;;;;;;;AASpC,eAAsB,gBACpB,QACA,KACA,MACA,SACmB;CACnB,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,MAAM,KAAK;GAC1B;GACA,GAAI,WAAW,EAAE,SAAS;GAC1B,GAAI,SAAS,UAAa,EAAE,MAAM;GACnC,CAAC;UACK,OAAO;EACd,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACrE,QAAM,IAAI,mBAAmB,cAAc,OAAO,GAAG,aAAa,IAAI,CAAC,WAAW,UAAU,EAC1F,OAAO,OACR,CAAC;;AAEJ,KAAI,CAAC,SAAS,GACZ,OAAM,SAAS,aACb,SAAS,QACT,SAAS,YACT,SAAS,SACR,MAAM,SAAS,MAAM,CAAC,YAAY,OAAU,IAAK,OACnD;AAEH,QAAO"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
|
+
import type { GetByIdQuery } from '../../core/types'
|
|
3
4
|
import type { Absence, CreateAbsencePayload, UpdateAbsencePayload } from './types'
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Absences of the users. The backend serves the report (`GET /absence`), `POST /absence` and
|
|
8
|
+
* `PUT /absence/:id`; there is no read by id nor delete.
|
|
9
|
+
*/
|
|
5
10
|
export class AbsenceApi extends BaseCrudApi<Absence, CreateAbsencePayload, UpdateAbsencePayload> {
|
|
6
11
|
constructor(client: ApiClient) {
|
|
7
12
|
super(client, '/absence')
|
|
8
13
|
}
|
|
14
|
+
|
|
15
|
+
/** @deprecated Not served: the backend has no GET /absence/:id, so this route answers 404. */
|
|
16
|
+
override getById(
|
|
17
|
+
id: string,
|
|
18
|
+
query?: GetByIdQuery<Absence>,
|
|
19
|
+
headers?: Record<string, string>,
|
|
20
|
+
): Promise<Absence> {
|
|
21
|
+
return super.getById(id, query, headers)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** @deprecated Not served: the backend has no DELETE /absence/:id, so this route answers 404. */
|
|
25
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<Absence> {
|
|
26
|
+
return super.deleteById(id, headers)
|
|
27
|
+
}
|
|
9
28
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
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 {
|
|
4
5
|
AcceptanceTerm,
|
|
@@ -9,9 +10,20 @@ import type {
|
|
|
9
10
|
export class AcceptanceTermsApi extends BaseCrudApi<
|
|
10
11
|
AcceptanceTerm,
|
|
11
12
|
CreateAcceptanceTermPayload,
|
|
12
|
-
UpdateAcceptanceTermPayload
|
|
13
|
+
UpdateAcceptanceTermPayload,
|
|
14
|
+
ListQuery<AcceptanceTerm>,
|
|
15
|
+
void
|
|
13
16
|
> {
|
|
14
17
|
constructor(client: ApiClient) {
|
|
15
18
|
super(client, '/acceptance-terms')
|
|
16
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Deletes an acceptance term. Resolves with no body; a term in use answers 404 `{ message: 'Term
|
|
23
|
+
* in use' }`.
|
|
24
|
+
* @permissions acceptanceTerms.view OR acceptanceTerms.destroy
|
|
25
|
+
*/
|
|
26
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<void> {
|
|
27
|
+
return super.deleteById(id, headers)
|
|
28
|
+
}
|
|
17
29
|
}
|
|
@@ -2,6 +2,11 @@ import type { ApiClient } from '../../core/ApiClient'
|
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
3
|
import type { Account, CreateAccountPayload, UpdateAccountPayload } from './types'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Not served: the backend mounts no `/accounts` route, so every method answers 404
|
|
7
|
+
* `Route not found.`. Read and update the account of the user with `MeApi.getAccount` and
|
|
8
|
+
* `MeApi.updateAccount`; `/admin/accounts` is a super admin route, kept out of the SDK.
|
|
9
|
+
*/
|
|
5
10
|
export class AccountsApi extends BaseCrudApi<Account, CreateAccountPayload, UpdateAccountPayload> {
|
|
6
11
|
constructor(client: ApiClient) {
|
|
7
12
|
super(client, '/accounts')
|
|
@@ -121,6 +121,8 @@ export type AccountSettingsCampaign = {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
export type AccountSettings = {
|
|
124
|
+
/** Enables the block list (required by `ContactsApi.block`). */
|
|
125
|
+
isBlockListActive?: boolean
|
|
124
126
|
/** Feature flags that toggle specific platform capabilities. */
|
|
125
127
|
flags?: AccountSettingsFlags
|
|
126
128
|
/** Enables/disables specific communication channels (whatsapp, telegram, webchat, etc.). */
|
|
@@ -2,6 +2,10 @@ import type { ApiClient } from '../../core/ApiClient'
|
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
3
|
import type { ActivityLog, CreateActivityLogPayload, UpdateActivityLogPayload } from './types'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Activity log of the account (stored in MongoDB: the routes answer 503 when it is unavailable).
|
|
7
|
+
* The backend serves `GET /log`, `GET /log/:id` and `POST /log`; there is no update or delete.
|
|
8
|
+
*/
|
|
5
9
|
export class ActivityLogApi extends BaseCrudApi<
|
|
6
10
|
ActivityLog,
|
|
7
11
|
CreateActivityLogPayload,
|
|
@@ -10,4 +14,18 @@ export class ActivityLogApi extends BaseCrudApi<
|
|
|
10
14
|
constructor(client: ApiClient) {
|
|
11
15
|
super(client, '/log')
|
|
12
16
|
}
|
|
17
|
+
|
|
18
|
+
/** @deprecated Not served: the backend has no PUT /log/:id, so this route answers 404. */
|
|
19
|
+
override updateById(
|
|
20
|
+
id: string,
|
|
21
|
+
body: UpdateActivityLogPayload,
|
|
22
|
+
headers?: Record<string, string>,
|
|
23
|
+
): Promise<ActivityLog> {
|
|
24
|
+
return super.updateById(id, body, headers)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** @deprecated Not served: the backend has no DELETE /log/:id, so this route answers 404. */
|
|
28
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<ActivityLog> {
|
|
29
|
+
return super.deleteById(id, headers)
|
|
30
|
+
}
|
|
13
31
|
}
|
|
@@ -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 { Category, CreateCategoryPayload, UpdateCategoryPayload } from './types'
|
|
4
5
|
|
|
5
6
|
export class CategoriesApi extends BaseCrudApi<
|
|
6
7
|
Category,
|
|
7
8
|
CreateCategoryPayload,
|
|
8
|
-
UpdateCategoryPayload
|
|
9
|
+
UpdateCategoryPayload,
|
|
10
|
+
ListQuery<Category>,
|
|
11
|
+
'OK'
|
|
9
12
|
> {
|
|
10
13
|
constructor(client: ApiClient) {
|
|
11
14
|
super(client, '/categories')
|
|
12
15
|
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Deletes a category. Resolves the text `'OK'`; an unknown id answers 500. The route checks no
|
|
19
|
+
* permission.
|
|
20
|
+
*/
|
|
21
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<'OK'> {
|
|
22
|
+
return super.deleteById(id, headers)
|
|
23
|
+
}
|
|
13
24
|
}
|
|
@@ -8,7 +8,11 @@ export class ClientFeedbackApi
|
|
|
8
8
|
{
|
|
9
9
|
private readonly basePath = '/client-feedback'
|
|
10
10
|
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated The route is broken in the backend: it is mounted with no authentication (the
|
|
13
|
+
* account context throws, 500) and calls a `createFeedback` the resource does not have. The
|
|
14
|
+
* feedback on the AI summary is stored when the ticket is closed.
|
|
15
|
+
*/
|
|
12
16
|
create(
|
|
13
17
|
body: CreateClientFeedbackPayload,
|
|
14
18
|
headers?: Record<string, string>,
|
|
@@ -1,4 +1,5 @@
|
|
|
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 {
|
|
4
5
|
ContactBlockList,
|
|
@@ -9,9 +10,20 @@ import type {
|
|
|
9
10
|
export class ContactBlockListsApi extends BaseCrudApi<
|
|
10
11
|
ContactBlockList,
|
|
11
12
|
CreateContactBlockListPayload,
|
|
12
|
-
UpdateContactBlockListPayload
|
|
13
|
+
UpdateContactBlockListPayload,
|
|
14
|
+
ListQuery<ContactBlockList>,
|
|
15
|
+
'OK'
|
|
13
16
|
> {
|
|
14
17
|
constructor(client: ApiClient) {
|
|
15
18
|
super(client, '/contact-block-lists')
|
|
16
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Deletes a block list and its numbers. Resolves the text `'OK'`; a list being processed (or with
|
|
23
|
+
* a block/unblock in progress) answers 500.
|
|
24
|
+
* @permissions contacts.view OR contacts.destroy OR contacts.block
|
|
25
|
+
*/
|
|
26
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<'OK'> {
|
|
27
|
+
return super.deleteById(id, headers)
|
|
28
|
+
}
|
|
17
29
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
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 {
|
|
4
5
|
ContactBlockListsControl,
|
|
@@ -9,9 +10,19 @@ import type {
|
|
|
9
10
|
export class ContactBlockListsControlsApi extends BaseCrudApi<
|
|
10
11
|
ContactBlockListsControl,
|
|
11
12
|
CreateContactBlockListsControlPayload,
|
|
12
|
-
UpdateContactBlockListsControlPayload
|
|
13
|
+
UpdateContactBlockListsControlPayload,
|
|
14
|
+
ListQuery<ContactBlockListsControl>,
|
|
15
|
+
'OK'
|
|
13
16
|
> {
|
|
14
17
|
constructor(client: ApiClient) {
|
|
15
18
|
super(client, '/contact-block-lists-controls')
|
|
16
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Deletes a block/unblock run. Resolves the text `'OK'`.
|
|
23
|
+
* @permissions contacts.view OR contacts.destroy OR contacts.block
|
|
24
|
+
*/
|
|
25
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<'OK'> {
|
|
26
|
+
return super.deleteById(id, headers)
|
|
27
|
+
}
|
|
17
28
|
}
|
|
@@ -202,12 +202,13 @@ describe('ContactsApi', () => {
|
|
|
202
202
|
// ── exportTemplate ───────────────────────────────────────────────
|
|
203
203
|
|
|
204
204
|
describe('exportTemplate', () => {
|
|
205
|
-
it('calls client.post with /contacts/export-template and
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
it('calls client.post with /contacts/export-template and resolves the CSV text', async () => {
|
|
206
|
+
const csv = 'Nome;DDI;Número;Atendente Padrão;Departamento Padrão;Tags;Criado em\n'
|
|
207
|
+
vi.mocked(client.post).mockResolvedValue(csv)
|
|
208
|
+
const body: ExportTemplatePayload = { serviceType: 'whatsapp' }
|
|
208
209
|
const result = await api.exportTemplate(body)
|
|
209
210
|
expect(client.post).toHaveBeenCalledWith('/contacts/export-template', body, undefined)
|
|
210
|
-
expect(result).
|
|
211
|
+
expect(result).toBe(csv)
|
|
211
212
|
})
|
|
212
213
|
|
|
213
214
|
it('forwards custom headers', async () => {
|
|
@@ -476,6 +477,21 @@ describe('ContactsApi', () => {
|
|
|
476
477
|
|
|
477
478
|
// ── block ────────────────────────────────────────────────────────
|
|
478
479
|
|
|
480
|
+
describe('summarizeTicket', () => {
|
|
481
|
+
it('calls client.post with /contacts/:id/ticket/summary and no body', async () => {
|
|
482
|
+
vi.mocked(client.post).mockResolvedValue({ success: true })
|
|
483
|
+
const result = await api.summarizeTicket('c1')
|
|
484
|
+
expect(client.post).toHaveBeenCalledWith('/contacts/c1/ticket/summary', undefined, undefined)
|
|
485
|
+
expect(result).toEqual({ success: true })
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
it('forwards custom headers', async () => {
|
|
489
|
+
const headers = { 'X-Custom': 'value' }
|
|
490
|
+
await api.summarizeTicket('c1', headers)
|
|
491
|
+
expect(client.post).toHaveBeenCalledWith('/contacts/c1/ticket/summary', undefined, headers)
|
|
492
|
+
})
|
|
493
|
+
})
|
|
494
|
+
|
|
479
495
|
describe('block', () => {
|
|
480
496
|
it('calls client.post with /contacts/:id/block and body', async () => {
|
|
481
497
|
vi.mocked(client.post).mockResolvedValue({ ...contact, block: true })
|
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
SyncContactPayload,
|
|
22
22
|
TransferTicketPayload,
|
|
23
23
|
UpdateContactPayload,
|
|
24
|
+
SummarizeTicketResult,
|
|
24
25
|
} from './types'
|
|
25
26
|
|
|
26
27
|
export class ContactsApi extends BaseCrudApi<Contact, CreateContactPayload, UpdateContactPayload> {
|
|
@@ -29,11 +30,12 @@ export class ContactsApi extends BaseCrudApi<Contact, CreateContactPayload, Upda
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
|
-
* Downloads
|
|
33
|
+
* Downloads the CSV template (`;`-separated header line, in the language of the user) for
|
|
34
|
+
* importing contacts, with columns based on the service type. Answered with no Content-Type.
|
|
33
35
|
* @permissions contacts.view AND contacts.export
|
|
34
36
|
*/
|
|
35
|
-
exportTemplate(body: ExportTemplatePayload, headers?: Record<string, string>): Promise<
|
|
36
|
-
return this.client.post<
|
|
37
|
+
exportTemplate(body: ExportTemplatePayload, headers?: Record<string, string>): Promise<string> {
|
|
38
|
+
return this.client.post<string, ExportTemplatePayload>(
|
|
37
39
|
`${this.basePath}/export-template`,
|
|
38
40
|
body,
|
|
39
41
|
headers,
|
|
@@ -172,7 +174,9 @@ export class ContactsApi extends BaseCrudApi<Contact, CreateContactPayload, Upda
|
|
|
172
174
|
|
|
173
175
|
/**
|
|
174
176
|
* Starts the import of a CSV file previously uploaded through `FilesApi`. The import runs
|
|
175
|
-
* in the background;
|
|
177
|
+
* in the background; `csvHeaderLine` is validated against the service type template, with
|
|
178
|
+
* every column of `exportTemplate` (including "Criado em"/"Created at"): a different header
|
|
179
|
+
* answers 403 `Csv File - Invalid Header`. The file itself is only read by the job.
|
|
176
180
|
* Resolves to `'OK'`.
|
|
177
181
|
* @permissions contacts.view OR contacts.update OR contacts.create
|
|
178
182
|
*/
|
|
@@ -199,7 +203,8 @@ export class ContactsApi extends BaseCrudApi<Contact, CreateContactPayload, Upda
|
|
|
199
203
|
|
|
200
204
|
/**
|
|
201
205
|
* Blocks or unblocks a contact. Blocking closes the contact's open ticket. Requires the
|
|
202
|
-
* block list to be active on the account.
|
|
206
|
+
* block list to be active on the account (`settings.isBlockListActive`; 400 otherwise).
|
|
207
|
+
* `byUserId` and `description` are stored as sent: the backend does not fill in the user.
|
|
203
208
|
* @permissions contacts.block
|
|
204
209
|
*/
|
|
205
210
|
block(id: string, body: BlockContactPayload, headers?: Record<string, string>): Promise<Contact> {
|
|
@@ -210,6 +215,20 @@ export class ContactsApi extends BaseCrudApi<Contact, CreateContactPayload, Upda
|
|
|
210
215
|
)
|
|
211
216
|
}
|
|
212
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Generates an AI summary of the open ticket of the contact. Consumes AI credits; resolves
|
|
220
|
+
* `{ success, limitReached? }`. A contact with no open ticket (or an unknown contact) answers
|
|
221
|
+
* 400.
|
|
222
|
+
* @permissions tickets.update
|
|
223
|
+
*/
|
|
224
|
+
summarizeTicket(id: string, headers?: Record<string, string>): Promise<SummarizeTicketResult> {
|
|
225
|
+
return this.client.post<SummarizeTicketResult>(
|
|
226
|
+
`${this.basePath}/${id}/ticket/summary`,
|
|
227
|
+
undefined,
|
|
228
|
+
headers,
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
|
|
213
232
|
/**
|
|
214
233
|
* Resets the contact's unread counter. Resolves to `'OK'`.
|
|
215
234
|
* @permissions contacts.view OR contacts.update
|
|
@@ -176,9 +176,15 @@ export type UpdateContactPayload = {
|
|
|
176
176
|
tagIds?: string[]
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
/** Result of `ContactsApi.summarizeTicket`. */
|
|
180
|
+
export type SummarizeTicketResult = {
|
|
181
|
+
success: boolean
|
|
182
|
+
limitReached?: boolean
|
|
183
|
+
}
|
|
184
|
+
|
|
179
185
|
export type ExportTemplatePayload = {
|
|
180
186
|
serviceType: string
|
|
181
|
-
type
|
|
187
|
+
type?: string
|
|
182
188
|
}
|
|
183
189
|
|
|
184
190
|
export type CountContactsQuery = ListQuery<Contact> & {
|
|
@@ -6,6 +6,11 @@ import type {
|
|
|
6
6
|
UpdateCreditMovementPayload,
|
|
7
7
|
} from './types'
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Credit movements of the account (SMS and AI credits), only for reading: the writes are super
|
|
11
|
+
* admin routes (`/admin/credit-movements`). The backend serves only `GET /credit-movements` and
|
|
12
|
+
* `GET /credit-movements/:id`.
|
|
13
|
+
*/
|
|
9
14
|
export class CreditMovementsApi extends BaseCrudApi<
|
|
10
15
|
CreditMovement,
|
|
11
16
|
CreateCreditMovementPayload,
|
|
@@ -14,4 +19,26 @@ export class CreditMovementsApi extends BaseCrudApi<
|
|
|
14
19
|
constructor(client: ApiClient) {
|
|
15
20
|
super(client, '/credit-movements')
|
|
16
21
|
}
|
|
22
|
+
|
|
23
|
+
/** @deprecated Not served: the backend has no POST /credit-movements, so this route answers 404. */
|
|
24
|
+
override create(
|
|
25
|
+
body: CreateCreditMovementPayload,
|
|
26
|
+
headers?: Record<string, string>,
|
|
27
|
+
): Promise<CreditMovement> {
|
|
28
|
+
return super.create(body, headers)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** @deprecated Not served: the backend has no PUT /credit-movements/:id, so this route answers 404. */
|
|
32
|
+
override updateById(
|
|
33
|
+
id: string,
|
|
34
|
+
body: UpdateCreditMovementPayload,
|
|
35
|
+
headers?: Record<string, string>,
|
|
36
|
+
): Promise<CreditMovement> {
|
|
37
|
+
return super.updateById(id, body, headers)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** @deprecated Not served: the backend has no DELETE /credit-movements/:id, so this route answers 404. */
|
|
41
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<CreditMovement> {
|
|
42
|
+
return super.deleteById(id, headers)
|
|
43
|
+
}
|
|
17
44
|
}
|
|
@@ -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
|
+
})
|