@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.
Files changed (287) hide show
  1. package/README.md +36 -12
  2. package/dist/apis/absence/AbsenceApi.cjs +12 -0
  3. package/dist/apis/absence/AbsenceApi.cjs.map +1 -1
  4. package/dist/apis/absence/AbsenceApi.d.ts +9 -0
  5. package/dist/apis/absence/AbsenceApi.d.ts.map +1 -1
  6. package/dist/apis/absence/AbsenceApi.mjs +12 -0
  7. package/dist/apis/absence/AbsenceApi.mjs.map +1 -1
  8. package/dist/apis/acceptanceTerms/AcceptanceTermsApi.cjs +8 -0
  9. package/dist/apis/acceptanceTerms/AcceptanceTermsApi.cjs.map +1 -1
  10. package/dist/apis/acceptanceTerms/AcceptanceTermsApi.d.ts +8 -1
  11. package/dist/apis/acceptanceTerms/AcceptanceTermsApi.d.ts.map +1 -1
  12. package/dist/apis/acceptanceTerms/AcceptanceTermsApi.mjs +8 -0
  13. package/dist/apis/acceptanceTerms/AcceptanceTermsApi.mjs.map +1 -1
  14. package/dist/apis/accounts/AccountsApi.cjs +5 -0
  15. package/dist/apis/accounts/AccountsApi.cjs.map +1 -1
  16. package/dist/apis/accounts/AccountsApi.d.ts +5 -0
  17. package/dist/apis/accounts/AccountsApi.d.ts.map +1 -1
  18. package/dist/apis/accounts/AccountsApi.mjs +5 -0
  19. package/dist/apis/accounts/AccountsApi.mjs.map +1 -1
  20. package/dist/apis/accounts/types.d.ts +2 -0
  21. package/dist/apis/accounts/types.d.ts.map +1 -1
  22. package/dist/apis/activityLog/ActivityLogApi.cjs +12 -0
  23. package/dist/apis/activityLog/ActivityLogApi.cjs.map +1 -1
  24. package/dist/apis/activityLog/ActivityLogApi.d.ts +8 -0
  25. package/dist/apis/activityLog/ActivityLogApi.d.ts.map +1 -1
  26. package/dist/apis/activityLog/ActivityLogApi.mjs +12 -0
  27. package/dist/apis/activityLog/ActivityLogApi.mjs.map +1 -1
  28. package/dist/apis/categories/CategoriesApi.cjs +7 -0
  29. package/dist/apis/categories/CategoriesApi.cjs.map +1 -1
  30. package/dist/apis/categories/CategoriesApi.d.ts +7 -1
  31. package/dist/apis/categories/CategoriesApi.d.ts.map +1 -1
  32. package/dist/apis/categories/CategoriesApi.mjs +7 -0
  33. package/dist/apis/categories/CategoriesApi.mjs.map +1 -1
  34. package/dist/apis/clientFeedback/ClientFeedbackApi.cjs +5 -1
  35. package/dist/apis/clientFeedback/ClientFeedbackApi.cjs.map +1 -1
  36. package/dist/apis/clientFeedback/ClientFeedbackApi.d.ts +5 -1
  37. package/dist/apis/clientFeedback/ClientFeedbackApi.d.ts.map +1 -1
  38. package/dist/apis/clientFeedback/ClientFeedbackApi.mjs +5 -1
  39. package/dist/apis/clientFeedback/ClientFeedbackApi.mjs.map +1 -1
  40. package/dist/apis/contactBlockLists/ContactBlockListsApi.cjs +8 -0
  41. package/dist/apis/contactBlockLists/ContactBlockListsApi.cjs.map +1 -1
  42. package/dist/apis/contactBlockLists/ContactBlockListsApi.d.ts +8 -1
  43. package/dist/apis/contactBlockLists/ContactBlockListsApi.d.ts.map +1 -1
  44. package/dist/apis/contactBlockLists/ContactBlockListsApi.mjs +8 -0
  45. package/dist/apis/contactBlockLists/ContactBlockListsApi.mjs.map +1 -1
  46. package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.cjs +7 -0
  47. package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.cjs.map +1 -1
  48. package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.d.ts +7 -1
  49. package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.d.ts.map +1 -1
  50. package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.mjs +7 -0
  51. package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.mjs.map +1 -1
  52. package/dist/apis/contacts/ContactsApi.cjs +16 -3
  53. package/dist/apis/contacts/ContactsApi.cjs.map +1 -1
  54. package/dist/apis/contacts/ContactsApi.d.ts +16 -5
  55. package/dist/apis/contacts/ContactsApi.d.ts.map +1 -1
  56. package/dist/apis/contacts/ContactsApi.mjs +16 -3
  57. package/dist/apis/contacts/ContactsApi.mjs.map +1 -1
  58. package/dist/apis/contacts/types.d.ts +6 -1
  59. package/dist/apis/contacts/types.d.ts.map +1 -1
  60. package/dist/apis/creditMovements/CreditMovementsApi.cjs +17 -0
  61. package/dist/apis/creditMovements/CreditMovementsApi.cjs.map +1 -1
  62. package/dist/apis/creditMovements/CreditMovementsApi.d.ts +11 -0
  63. package/dist/apis/creditMovements/CreditMovementsApi.d.ts.map +1 -1
  64. package/dist/apis/creditMovements/CreditMovementsApi.mjs +17 -0
  65. package/dist/apis/creditMovements/CreditMovementsApi.mjs.map +1 -1
  66. package/dist/apis/customFields/CustomFieldsApi.cjs +7 -0
  67. package/dist/apis/customFields/CustomFieldsApi.cjs.map +1 -1
  68. package/dist/apis/customFields/CustomFieldsApi.d.ts +7 -1
  69. package/dist/apis/customFields/CustomFieldsApi.d.ts.map +1 -1
  70. package/dist/apis/customFields/CustomFieldsApi.mjs +7 -0
  71. package/dist/apis/customFields/CustomFieldsApi.mjs.map +1 -1
  72. package/dist/apis/departments/DepartmentsApi.cjs +21 -0
  73. package/dist/apis/departments/DepartmentsApi.cjs.map +1 -1
  74. package/dist/apis/departments/DepartmentsApi.d.ts +20 -2
  75. package/dist/apis/departments/DepartmentsApi.d.ts.map +1 -1
  76. package/dist/apis/departments/DepartmentsApi.mjs +21 -0
  77. package/dist/apis/departments/DepartmentsApi.mjs.map +1 -1
  78. package/dist/apis/departments/types.d.ts +5 -0
  79. package/dist/apis/departments/types.d.ts.map +1 -1
  80. package/dist/apis/distribution/DistributionApi.cjs +7 -0
  81. package/dist/apis/distribution/DistributionApi.cjs.map +1 -1
  82. package/dist/apis/distribution/DistributionApi.d.ts +7 -1
  83. package/dist/apis/distribution/DistributionApi.d.ts.map +1 -1
  84. package/dist/apis/distribution/DistributionApi.mjs +7 -0
  85. package/dist/apis/distribution/DistributionApi.mjs.map +1 -1
  86. package/dist/apis/files/FilesApi.cjs +49 -0
  87. package/dist/apis/files/FilesApi.cjs.map +1 -1
  88. package/dist/apis/files/FilesApi.d.ts +45 -2
  89. package/dist/apis/files/FilesApi.d.ts.map +1 -1
  90. package/dist/apis/files/FilesApi.mjs +49 -0
  91. package/dist/apis/files/FilesApi.mjs.map +1 -1
  92. package/dist/apis/files/types.d.ts +45 -7
  93. package/dist/apis/files/types.d.ts.map +1 -1
  94. package/dist/apis/holiday/HolidayApi.cjs +7 -0
  95. package/dist/apis/holiday/HolidayApi.cjs.map +1 -1
  96. package/dist/apis/holiday/HolidayApi.d.ts +7 -1
  97. package/dist/apis/holiday/HolidayApi.d.ts.map +1 -1
  98. package/dist/apis/holiday/HolidayApi.mjs +7 -0
  99. package/dist/apis/holiday/HolidayApi.mjs.map +1 -1
  100. package/dist/apis/integrations/IntegrationsApi.cjs +7 -0
  101. package/dist/apis/integrations/IntegrationsApi.cjs.map +1 -1
  102. package/dist/apis/integrations/IntegrationsApi.d.ts +7 -1
  103. package/dist/apis/integrations/IntegrationsApi.d.ts.map +1 -1
  104. package/dist/apis/integrations/IntegrationsApi.mjs +7 -0
  105. package/dist/apis/integrations/IntegrationsApi.mjs.map +1 -1
  106. package/dist/apis/interactiveMessages/InteractiveMessagesApi.cjs +7 -0
  107. package/dist/apis/interactiveMessages/InteractiveMessagesApi.cjs.map +1 -1
  108. package/dist/apis/interactiveMessages/InteractiveMessagesApi.d.ts +7 -1
  109. package/dist/apis/interactiveMessages/InteractiveMessagesApi.d.ts.map +1 -1
  110. package/dist/apis/interactiveMessages/InteractiveMessagesApi.mjs +7 -0
  111. package/dist/apis/interactiveMessages/InteractiveMessagesApi.mjs.map +1 -1
  112. package/dist/apis/interactiveMessages/types.d.ts +61 -3
  113. package/dist/apis/interactiveMessages/types.d.ts.map +1 -1
  114. package/dist/apis/kanbanBoards/KanbanBoardsApi.cjs +7 -0
  115. package/dist/apis/kanbanBoards/KanbanBoardsApi.cjs.map +1 -1
  116. package/dist/apis/kanbanBoards/KanbanBoardsApi.d.ts +7 -1
  117. package/dist/apis/kanbanBoards/KanbanBoardsApi.d.ts.map +1 -1
  118. package/dist/apis/kanbanBoards/KanbanBoardsApi.mjs +7 -0
  119. package/dist/apis/kanbanBoards/KanbanBoardsApi.mjs.map +1 -1
  120. package/dist/apis/kanbanCards/KanbanCardsApi.cjs +7 -0
  121. package/dist/apis/kanbanCards/KanbanCardsApi.cjs.map +1 -1
  122. package/dist/apis/kanbanCards/KanbanCardsApi.d.ts +7 -1
  123. package/dist/apis/kanbanCards/KanbanCardsApi.d.ts.map +1 -1
  124. package/dist/apis/kanbanCards/KanbanCardsApi.mjs +7 -0
  125. package/dist/apis/kanbanCards/KanbanCardsApi.mjs.map +1 -1
  126. package/dist/apis/knowledgeBase/KnowledgeBaseApi.cjs +8 -0
  127. package/dist/apis/knowledgeBase/KnowledgeBaseApi.cjs.map +1 -1
  128. package/dist/apis/knowledgeBase/KnowledgeBaseApi.d.ts +8 -1
  129. package/dist/apis/knowledgeBase/KnowledgeBaseApi.d.ts.map +1 -1
  130. package/dist/apis/knowledgeBase/KnowledgeBaseApi.mjs +8 -0
  131. package/dist/apis/knowledgeBase/KnowledgeBaseApi.mjs.map +1 -1
  132. package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.cjs +8 -0
  133. package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.cjs.map +1 -1
  134. package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.d.ts +8 -1
  135. package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.d.ts.map +1 -1
  136. package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.mjs +8 -0
  137. package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.mjs.map +1 -1
  138. package/dist/apis/messages/MessagesApi.cjs +23 -3
  139. package/dist/apis/messages/MessagesApi.cjs.map +1 -1
  140. package/dist/apis/messages/MessagesApi.d.ts +19 -3
  141. package/dist/apis/messages/MessagesApi.d.ts.map +1 -1
  142. package/dist/apis/messages/MessagesApi.mjs +23 -3
  143. package/dist/apis/messages/MessagesApi.mjs.map +1 -1
  144. package/dist/apis/messages/types.d.ts +3 -0
  145. package/dist/apis/messages/types.d.ts.map +1 -1
  146. package/dist/apis/notifications/NotificationsApi.cjs +7 -0
  147. package/dist/apis/notifications/NotificationsApi.cjs.map +1 -1
  148. package/dist/apis/notifications/NotificationsApi.d.ts +7 -1
  149. package/dist/apis/notifications/NotificationsApi.d.ts.map +1 -1
  150. package/dist/apis/notifications/NotificationsApi.mjs +7 -0
  151. package/dist/apis/notifications/NotificationsApi.mjs.map +1 -1
  152. package/dist/apis/organizations/OrganizationsApi.cjs +7 -0
  153. package/dist/apis/organizations/OrganizationsApi.cjs.map +1 -1
  154. package/dist/apis/organizations/OrganizationsApi.d.ts +7 -1
  155. package/dist/apis/organizations/OrganizationsApi.d.ts.map +1 -1
  156. package/dist/apis/organizations/OrganizationsApi.mjs +7 -0
  157. package/dist/apis/organizations/OrganizationsApi.mjs.map +1 -1
  158. package/dist/apis/people/PeopleApi.cjs +7 -0
  159. package/dist/apis/people/PeopleApi.cjs.map +1 -1
  160. package/dist/apis/people/PeopleApi.d.ts +7 -1
  161. package/dist/apis/people/PeopleApi.d.ts.map +1 -1
  162. package/dist/apis/people/PeopleApi.mjs +7 -0
  163. package/dist/apis/people/PeopleApi.mjs.map +1 -1
  164. package/dist/apis/planAiHistory/PlanAiHistoryApi.cjs +16 -0
  165. package/dist/apis/planAiHistory/PlanAiHistoryApi.cjs.map +1 -1
  166. package/dist/apis/planAiHistory/PlanAiHistoryApi.d.ts +10 -0
  167. package/dist/apis/planAiHistory/PlanAiHistoryApi.d.ts.map +1 -1
  168. package/dist/apis/planAiHistory/PlanAiHistoryApi.mjs +16 -0
  169. package/dist/apis/planAiHistory/PlanAiHistoryApi.mjs.map +1 -1
  170. package/dist/apis/roles/RolesApi.cjs +7 -0
  171. package/dist/apis/roles/RolesApi.cjs.map +1 -1
  172. package/dist/apis/roles/RolesApi.d.ts +6 -1
  173. package/dist/apis/roles/RolesApi.d.ts.map +1 -1
  174. package/dist/apis/roles/RolesApi.mjs +7 -0
  175. package/dist/apis/roles/RolesApi.mjs.map +1 -1
  176. package/dist/apis/services/ServicesApi.cjs +68 -0
  177. package/dist/apis/services/ServicesApi.cjs.map +1 -1
  178. package/dist/apis/services/ServicesApi.d.ts +53 -1
  179. package/dist/apis/services/ServicesApi.d.ts.map +1 -1
  180. package/dist/apis/services/ServicesApi.mjs +68 -0
  181. package/dist/apis/services/ServicesApi.mjs.map +1 -1
  182. package/dist/apis/services/types.d.ts +68 -1
  183. package/dist/apis/services/types.d.ts.map +1 -1
  184. package/dist/apis/stickers/StickersApi.cjs +20 -0
  185. package/dist/apis/stickers/StickersApi.cjs.map +1 -1
  186. package/dist/apis/stickers/StickersApi.d.ts +15 -0
  187. package/dist/apis/stickers/StickersApi.d.ts.map +1 -1
  188. package/dist/apis/stickers/StickersApi.mjs +20 -0
  189. package/dist/apis/stickers/StickersApi.mjs.map +1 -1
  190. package/dist/apis/tags/TagsApi.cjs +7 -0
  191. package/dist/apis/tags/TagsApi.cjs.map +1 -1
  192. package/dist/apis/tags/TagsApi.d.ts +7 -1
  193. package/dist/apis/tags/TagsApi.d.ts.map +1 -1
  194. package/dist/apis/tags/TagsApi.mjs +7 -0
  195. package/dist/apis/tags/TagsApi.mjs.map +1 -1
  196. package/dist/apis/timetable/TimetableApi.cjs +7 -0
  197. package/dist/apis/timetable/TimetableApi.cjs.map +1 -1
  198. package/dist/apis/timetable/TimetableApi.d.ts +7 -1
  199. package/dist/apis/timetable/TimetableApi.d.ts.map +1 -1
  200. package/dist/apis/timetable/TimetableApi.mjs +7 -0
  201. package/dist/apis/timetable/TimetableApi.mjs.map +1 -1
  202. package/dist/apis/users/UsersApi.cjs +8 -0
  203. package/dist/apis/users/UsersApi.cjs.map +1 -1
  204. package/dist/apis/users/UsersApi.d.ts +8 -1
  205. package/dist/apis/users/UsersApi.d.ts.map +1 -1
  206. package/dist/apis/users/UsersApi.mjs +8 -0
  207. package/dist/apis/users/UsersApi.mjs.map +1 -1
  208. package/dist/apis/users/types.d.ts +15 -0
  209. package/dist/apis/users/types.d.ts.map +1 -1
  210. package/dist/apis/webhooks/WebhooksApi.cjs +7 -0
  211. package/dist/apis/webhooks/WebhooksApi.cjs.map +1 -1
  212. package/dist/apis/webhooks/WebhooksApi.d.ts +7 -1
  213. package/dist/apis/webhooks/WebhooksApi.d.ts.map +1 -1
  214. package/dist/apis/webhooks/WebhooksApi.mjs +7 -0
  215. package/dist/apis/webhooks/WebhooksApi.mjs.map +1 -1
  216. package/dist/core/ApiClient.d.ts +14 -0
  217. package/dist/core/ApiClient.d.ts.map +1 -1
  218. package/dist/core/ArchivableCrudApi.cjs.map +1 -1
  219. package/dist/core/ArchivableCrudApi.d.ts +1 -1
  220. package/dist/core/ArchivableCrudApi.d.ts.map +1 -1
  221. package/dist/core/ArchivableCrudApi.mjs.map +1 -1
  222. package/dist/core/BaseApiClient.cjs +24 -3
  223. package/dist/core/BaseApiClient.cjs.map +1 -1
  224. package/dist/core/BaseApiClient.d.ts +14 -0
  225. package/dist/core/BaseApiClient.d.ts.map +1 -1
  226. package/dist/core/BaseApiClient.mjs +24 -3
  227. package/dist/core/BaseApiClient.mjs.map +1 -1
  228. package/dist/core/requestExternal.cjs +33 -0
  229. package/dist/core/requestExternal.cjs.map +1 -0
  230. package/dist/core/requestExternal.d.ts +9 -0
  231. package/dist/core/requestExternal.d.ts.map +1 -0
  232. package/dist/core/requestExternal.mjs +32 -0
  233. package/dist/core/requestExternal.mjs.map +1 -0
  234. package/package.json +1 -1
  235. package/src/apis/absence/AbsenceApi.ts +19 -0
  236. package/src/apis/acceptanceTerms/AcceptanceTermsApi.ts +13 -1
  237. package/src/apis/accounts/AccountsApi.ts +5 -0
  238. package/src/apis/accounts/types.ts +2 -0
  239. package/src/apis/activityLog/ActivityLogApi.ts +18 -0
  240. package/src/apis/categories/CategoriesApi.ts +12 -1
  241. package/src/apis/clientFeedback/ClientFeedbackApi.ts +5 -1
  242. package/src/apis/contactBlockLists/ContactBlockListsApi.ts +13 -1
  243. package/src/apis/contactBlockListsControls/ContactBlockListsControlsApi.ts +12 -1
  244. package/src/apis/contacts/ContactsApi.test.ts +20 -4
  245. package/src/apis/contacts/ContactsApi.ts +24 -5
  246. package/src/apis/contacts/types.ts +7 -1
  247. package/src/apis/creditMovements/CreditMovementsApi.ts +27 -0
  248. package/src/apis/customFields/CustomFieldsApi.ts +12 -1
  249. package/src/apis/departments/DepartmentsApi.test.ts +88 -0
  250. package/src/apis/departments/DepartmentsApi.ts +41 -2
  251. package/src/apis/departments/types.ts +6 -0
  252. package/src/apis/distribution/DistributionApi.ts +12 -1
  253. package/src/apis/files/FilesApi.test.ts +122 -0
  254. package/src/apis/files/FilesApi.ts +107 -2
  255. package/src/apis/files/types.ts +48 -7
  256. package/src/apis/holiday/HolidayApi.ts +16 -1
  257. package/src/apis/integrations/IntegrationsApi.ts +12 -1
  258. package/src/apis/interactiveMessages/InteractiveMessagesApi.ts +12 -1
  259. package/src/apis/interactiveMessages/types.ts +67 -1
  260. package/src/apis/kanbanBoards/KanbanBoardsApi.ts +12 -1
  261. package/src/apis/kanbanCards/KanbanCardsApi.ts +12 -1
  262. package/src/apis/knowledgeBase/KnowledgeBaseApi.ts +13 -1
  263. package/src/apis/knowledgeBaseItem/KnowledgeBaseItemApi.ts +13 -1
  264. package/src/apis/messages/MessagesApi.test.ts +13 -7
  265. package/src/apis/messages/MessagesApi.ts +29 -3
  266. package/src/apis/messages/types.ts +3 -0
  267. package/src/apis/notifications/NotificationsApi.ts +12 -1
  268. package/src/apis/organizations/OrganizationsApi.ts +12 -1
  269. package/src/apis/payloads.test-d.ts +275 -0
  270. package/src/apis/payloads.test.ts +41 -0
  271. package/src/apis/people/PeopleApi.ts +16 -1
  272. package/src/apis/planAiHistory/PlanAiHistoryApi.ts +26 -0
  273. package/src/apis/roles/RolesApi.ts +10 -1
  274. package/src/apis/services/ServicesApi.test.ts +45 -0
  275. package/src/apis/services/ServicesApi.ts +91 -1
  276. package/src/apis/services/types.ts +63 -1
  277. package/src/apis/stickers/StickersApi.ts +32 -0
  278. package/src/apis/tags/TagsApi.ts +16 -1
  279. package/src/apis/timetable/TimetableApi.ts +12 -1
  280. package/src/apis/users/UsersApi.ts +17 -1
  281. package/src/apis/users/types.ts +11 -0
  282. package/src/apis/webhooks/WebhooksApi.ts +16 -1
  283. package/src/core/ApiClient.ts +24 -0
  284. package/src/core/ArchivableCrudApi.ts +2 -1
  285. package/src/core/BaseApiClient.test.ts +98 -0
  286. package/src/core/BaseApiClient.ts +49 -4
  287. 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 let response: Response\n try {\n response = 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 return this.handleResponse<TResponse>(response)\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":";;;;AASA,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;EACpB,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;EAED,IAAI;AACJ,MAAI;AACF,cAAW,MAAM,MAAM,KAAK,KAAK;WAC1B,OAAO;AAEd,SAAM,IAAI,mBAAmB,cAAc,OAAO,GAAG,IAAI,WAD1C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACS,EAC5E,OAAO,OACR,CAAC;;AAGJ,SAAO,KAAK,eAA0B,SAAS;;CAGjD,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"}
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikatec/digisac-api-sdk",
3
- "version": "4.8.0",
3
+ "version": "4.10.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -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
- /** Creates a client feedback record for a ticket (accountId, ticketId, and feedback text are required). */
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 body', async () => {
206
- vi.mocked(client.post).mockResolvedValue({ ok: true })
207
- const body: ExportTemplatePayload = { serviceType: 'whatsapp', type: 'csv' }
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).toEqual({ ok: true })
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 a CSV template for importing contacts, with columns based on the service type.
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<unknown> {
36
- return this.client.post<unknown, ExportTemplatePayload>(
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; the header line is validated against the service type template.
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: string
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
+ })