@ikatec/digisac-api-sdk 1.4.0 → 2.1.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 (77) hide show
  1. package/dist/_chunks/{chunk-DortyG5C.cjs → chunk-Dk0Otj32.cjs} +19 -0
  2. package/dist/_chunks/scopes-CppNX42t.mjs +29 -0
  3. package/dist/_chunks/scopes-CppNX42t.mjs.map +1 -0
  4. package/dist/apis/authHistory/AuthHistoryApi.cjs +1 -1
  5. package/dist/apis/campaigns/CampaignsApi.cjs +12 -0
  6. package/dist/apis/campaigns/CampaignsApi.cjs.map +1 -1
  7. package/dist/apis/campaigns/CampaignsApi.d.ts +2 -2
  8. package/dist/apis/campaigns/CampaignsApi.d.ts.map +1 -1
  9. package/dist/apis/campaigns/CampaignsApi.mjs +12 -0
  10. package/dist/apis/campaigns/CampaignsApi.mjs.map +1 -1
  11. package/dist/apis/campaigns/index.cjs +8 -1
  12. package/dist/apis/campaigns/index.d.ts +1 -0
  13. package/dist/apis/campaigns/index.d.ts.map +1 -1
  14. package/dist/apis/campaigns/index.mjs +2 -1
  15. package/dist/apis/campaigns/scopes/getManyViewScope.cjs +51 -0
  16. package/dist/apis/campaigns/scopes/getManyViewScope.cjs.map +1 -0
  17. package/dist/apis/campaigns/scopes/getManyViewScope.d.ts +21 -0
  18. package/dist/apis/campaigns/scopes/getManyViewScope.d.ts.map +1 -0
  19. package/dist/apis/campaigns/scopes/getManyViewScope.mjs +49 -0
  20. package/dist/apis/campaigns/scopes/getManyViewScope.mjs.map +1 -0
  21. package/dist/apis/campaigns/scopes/getOneViewScope.cjs +27 -0
  22. package/dist/apis/campaigns/scopes/getOneViewScope.cjs.map +1 -0
  23. package/dist/apis/campaigns/scopes/getOneViewScope.d.ts +5 -0
  24. package/dist/apis/campaigns/scopes/getOneViewScope.d.ts.map +1 -0
  25. package/dist/apis/campaigns/scopes/getOneViewScope.mjs +25 -0
  26. package/dist/apis/campaigns/scopes/getOneViewScope.mjs.map +1 -0
  27. package/dist/apis/campaigns/scopes/index.cjs +21 -0
  28. package/dist/apis/campaigns/scopes/index.cjs.map +1 -0
  29. package/dist/apis/campaigns/scopes/index.d.ts +3 -0
  30. package/dist/apis/campaigns/scopes/index.d.ts.map +1 -0
  31. package/dist/apis/campaigns/scopes/index.mjs +4 -0
  32. package/dist/apis/campaigns/types.d.ts +32 -16
  33. package/dist/apis/campaigns/types.d.ts.map +1 -1
  34. package/dist/apis/contacts/ContactsApi.cjs +1 -1
  35. package/dist/apis/files/types.d.ts +1 -0
  36. package/dist/apis/files/types.d.ts.map +1 -1
  37. package/dist/apis/index.cjs +8 -1
  38. package/dist/apis/index.mjs +2 -1
  39. package/dist/apis/messages/MessagesApi.cjs +1 -1
  40. package/dist/apis/messages/types.d.ts +2 -1
  41. package/dist/apis/messages/types.d.ts.map +1 -1
  42. package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.cjs +1 -1
  43. package/dist/apis/stickerUsers/StickerUsersApi.cjs +1 -1
  44. package/dist/apis/terms/TermsApi.cjs +1 -1
  45. package/dist/core/BaseCrudApi.cjs +9 -3
  46. package/dist/core/BaseCrudApi.cjs.map +1 -1
  47. package/dist/core/BaseCrudApi.d.ts +5 -5
  48. package/dist/core/BaseCrudApi.d.ts.map +1 -1
  49. package/dist/core/BaseCrudApi.mjs +8 -2
  50. package/dist/core/BaseCrudApi.mjs.map +1 -1
  51. package/dist/core/index.d.ts +1 -1
  52. package/dist/core/index.d.ts.map +1 -1
  53. package/dist/core/types.d.ts +3 -1
  54. package/dist/core/types.d.ts.map +1 -1
  55. package/package.json +1 -1
  56. package/src/apis/authHistory/AuthHistoryApi.test.ts +110 -0
  57. package/src/apis/campaigns/CampaignsApi.test.ts +344 -0
  58. package/src/apis/campaigns/CampaignsApi.ts +14 -2
  59. package/src/apis/campaigns/index.ts +1 -0
  60. package/src/apis/campaigns/scopes/getManyViewScope.ts +79 -0
  61. package/src/apis/campaigns/scopes/getOneViewScope.ts +21 -0
  62. package/src/apis/campaigns/scopes/index.ts +2 -0
  63. package/src/apis/campaigns/types.ts +28 -16
  64. package/src/apis/clientFeedback/ClientFeedbackApi.test.ts +76 -0
  65. package/src/apis/contacts/ContactsApi.test.ts +364 -0
  66. package/src/apis/files/types.ts +1 -0
  67. package/src/apis/me/MeApi.test.ts +372 -0
  68. package/src/apis/messages/MessagesApi.test.ts +460 -0
  69. package/src/apis/messages/types.ts +2 -1
  70. package/src/apis/serviceAccessManagement/ServiceAccessManagementApi.test.ts +89 -0
  71. package/src/apis/stickerUsers/StickerUsersApi.test.ts +84 -0
  72. package/src/apis/terms/TermsApi.test.ts +196 -0
  73. package/src/apis/transcripts/TranscriptsApi.test.ts +63 -0
  74. package/src/core/BaseCrudApi.test.ts +1 -1
  75. package/src/core/BaseCrudApi.ts +16 -5
  76. package/src/core/index.ts +1 -1
  77. package/src/core/types.ts +8 -1
@@ -0,0 +1,196 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { TermsApi } from './TermsApi'
3
+ import type { ApiClient } from '../../core/ApiClient'
4
+ import type { Term, CreateTermPayload } from './types'
5
+ import type { Paginated } from '../../core/types'
6
+
7
+ // ── Mock client factory ──────────────────────────────────────────────
8
+
9
+ function createMockClient(): ApiClient {
10
+ return {
11
+ setAccessToken: vi.fn().mockReturnThis(),
12
+ request: vi.fn(),
13
+ get: vi.fn(),
14
+ post: vi.fn(),
15
+ put: vi.fn(),
16
+ patch: vi.fn(),
17
+ delete: vi.fn(),
18
+ }
19
+ }
20
+
21
+ // ── Fixtures ─────────────────────────────────────────────────────────
22
+
23
+ const term: Term = {
24
+ id: 'term-1',
25
+ title: { en: 'Terms of Service' },
26
+ text: { en: 'You agree to...' },
27
+ expirationDate: '2025-01-01',
28
+ version: '1.0',
29
+ agnusId: 'agnus-1',
30
+ accountId: null,
31
+ userId: null,
32
+ agreementDate: null,
33
+ createdAt: '2024-01-01T00:00:00Z',
34
+ updatedAt: '2024-01-01T00:00:00Z',
35
+ }
36
+
37
+ const paginated: Paginated<Term> = {
38
+ data: [term],
39
+ total: 1,
40
+ limit: 10,
41
+ skip: 0,
42
+ currentPage: 1,
43
+ lastPage: 1,
44
+ from: 1,
45
+ to: 1,
46
+ }
47
+
48
+ // ── Tests ────────────────────────────────────────────────────────────
49
+
50
+ describe('TermsApi', () => {
51
+ let client: ReturnType<typeof createMockClient>
52
+ let api: TermsApi
53
+
54
+ beforeEach(() => {
55
+ client = createMockClient()
56
+ api = new TermsApi(client)
57
+ })
58
+
59
+ // ── getMany ──────────────────────────────────────────────────────
60
+
61
+ describe('getMany', () => {
62
+ it('calls client.get with /terms when no query is provided', async () => {
63
+ vi.mocked(client.get).mockResolvedValue(paginated)
64
+ const result = await api.getMany()
65
+ expect(client.get).toHaveBeenCalledWith('/terms', undefined)
66
+ expect(result).toEqual(paginated)
67
+ })
68
+
69
+ it('serializes query parameters', async () => {
70
+ vi.mocked(client.get).mockResolvedValue(paginated)
71
+ await api.getMany({ page: 2 })
72
+ const url = vi.mocked(client.get).mock.calls[0][0] as string
73
+ expect(url).toContain('/terms?')
74
+ expect(url).toContain('page=2')
75
+ })
76
+
77
+ it('forwards custom headers', async () => {
78
+ vi.mocked(client.get).mockResolvedValue(paginated)
79
+ const headers = { 'X-Custom': 'value' }
80
+ await api.getMany(undefined, headers)
81
+ expect(client.get).toHaveBeenCalledWith('/terms', headers)
82
+ })
83
+ })
84
+
85
+ // ── getById ──────────────────────────────────────────────────────
86
+
87
+ describe('getById', () => {
88
+ it('calls client.get with /terms/:id', async () => {
89
+ vi.mocked(client.get).mockResolvedValue(term)
90
+ const result = await api.getById('term-1')
91
+ expect(client.get).toHaveBeenCalledWith('/terms/term-1', undefined)
92
+ expect(result).toEqual(term)
93
+ })
94
+
95
+ it('forwards custom headers', async () => {
96
+ vi.mocked(client.get).mockResolvedValue(term)
97
+ const headers = { 'X-Tenant': 'abc' }
98
+ await api.getById('term-1', undefined, headers)
99
+ expect(client.get).toHaveBeenCalledWith('/terms/term-1', headers)
100
+ })
101
+ })
102
+
103
+ // ── create ───────────────────────────────────────────────────────
104
+
105
+ describe('create', () => {
106
+ it('calls client.post with /terms and body', async () => {
107
+ vi.mocked(client.post).mockResolvedValue(term)
108
+ const body: CreateTermPayload = {
109
+ title: { en: 'ToS' },
110
+ text: { en: 'Text' },
111
+ expirationDate: '2025-01-01',
112
+ version: '1.0',
113
+ agnusId: 'agnus-1',
114
+ }
115
+ const result = await api.create(body)
116
+ expect(client.post).toHaveBeenCalledWith('/terms', body, undefined)
117
+ expect(result).toEqual(term)
118
+ })
119
+ })
120
+
121
+ // ── updateById ───────────────────────────────────────────────────
122
+
123
+ describe('updateById', () => {
124
+ it('calls client.put with /terms/:id and body', async () => {
125
+ vi.mocked(client.put).mockResolvedValue(term)
126
+ const result = await api.updateById('term-1', { version: '1.1' })
127
+ expect(client.put).toHaveBeenCalledWith('/terms/term-1', { version: '1.1' }, undefined)
128
+ expect(result).toEqual(term)
129
+ })
130
+
131
+ it('forwards custom headers', async () => {
132
+ vi.mocked(client.put).mockResolvedValue(term)
133
+ const headers = { 'If-Match': 'etag' }
134
+ await api.updateById('term-1', { version: '2.0' }, headers)
135
+ expect(client.put).toHaveBeenCalledWith('/terms/term-1', { version: '2.0' }, headers)
136
+ })
137
+ })
138
+
139
+ // ── deleteById ───────────────────────────────────────────────────
140
+
141
+ describe('deleteById', () => {
142
+ it('calls client.delete with /terms/:id', async () => {
143
+ vi.mocked(client.delete).mockResolvedValue(term)
144
+ const result = await api.deleteById('term-1')
145
+ expect(client.delete).toHaveBeenCalledWith('/terms/term-1', undefined)
146
+ expect(result).toEqual(term)
147
+ })
148
+
149
+ it('forwards custom headers', async () => {
150
+ vi.mocked(client.delete).mockResolvedValue(term)
151
+ const headers = { 'X-Reason': 'cleanup' }
152
+ await api.deleteById('term-1', headers)
153
+ expect(client.delete).toHaveBeenCalledWith('/terms/term-1', headers)
154
+ })
155
+ })
156
+
157
+ // ── getNotAgreed ─────────────────────────────────────────────────
158
+
159
+ describe('getNotAgreed', () => {
160
+ it('calls client.get with /terms/terms-not-agreed when no query is provided', async () => {
161
+ vi.mocked(client.get).mockResolvedValue(paginated)
162
+ const result = await api.getNotAgreed()
163
+ expect(client.get).toHaveBeenCalledWith('/terms/terms-not-agreed', undefined)
164
+ expect(result).toEqual(paginated)
165
+ })
166
+
167
+ it('serializes query parameters', async () => {
168
+ vi.mocked(client.get).mockResolvedValue(paginated)
169
+ await api.getNotAgreed({ page: 1, perPage: 5 })
170
+ const url = vi.mocked(client.get).mock.calls[0][0] as string
171
+ expect(url).toContain('/terms/terms-not-agreed?')
172
+ expect(url).toContain('page=1')
173
+ })
174
+
175
+ it('forwards custom headers', async () => {
176
+ vi.mocked(client.get).mockResolvedValue(paginated)
177
+ const headers = { 'X-Custom': 'h' }
178
+ await api.getNotAgreed(undefined, headers)
179
+ expect(client.get).toHaveBeenCalledWith('/terms/terms-not-agreed', headers)
180
+ })
181
+ })
182
+
183
+ // ── Error propagation ────────────────────────────────────────────
184
+
185
+ describe('error propagation', () => {
186
+ it('propagates errors from getMany', async () => {
187
+ vi.mocked(client.get).mockRejectedValue(new Error('Network error'))
188
+ await expect(api.getMany()).rejects.toThrow('Network error')
189
+ })
190
+
191
+ it('propagates errors from getNotAgreed', async () => {
192
+ vi.mocked(client.get).mockRejectedValue(new Error('Forbidden'))
193
+ await expect(api.getNotAgreed()).rejects.toThrow('Forbidden')
194
+ })
195
+ })
196
+ })
@@ -0,0 +1,63 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { TranscriptsApi } from './TranscriptsApi'
3
+ import type { ApiClient } from '../../core/ApiClient'
4
+ import type { TranscriptResponse } 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
+ // ── Tests ────────────────────────────────────────────────────────────
21
+
22
+ describe('TranscriptsApi', () => {
23
+ let client: ReturnType<typeof createMockClient>
24
+ let api: TranscriptsApi
25
+
26
+ beforeEach(() => {
27
+ client = createMockClient()
28
+ api = new TranscriptsApi(client)
29
+ })
30
+
31
+ // ── getById ──────────────────────────────────────────────────────
32
+
33
+ describe('getById', () => {
34
+ it('calls client.get with /transcripts/:id', async () => {
35
+ const response: TranscriptResponse = {
36
+ id: 'msg-1',
37
+ isTranscribing: true,
38
+ transcribeError: false,
39
+ }
40
+ vi.mocked(client.get).mockResolvedValue(response)
41
+ const result = await api.getById('msg-1')
42
+ expect(client.get).toHaveBeenCalledWith('/transcripts/msg-1', undefined)
43
+ expect(result).toEqual(response)
44
+ })
45
+
46
+ it('forwards custom headers', async () => {
47
+ const response: TranscriptResponse = {
48
+ id: 'msg-2',
49
+ isTranscribing: false,
50
+ transcribeError: true,
51
+ }
52
+ vi.mocked(client.get).mockResolvedValue(response)
53
+ const headers = { 'X-Custom': 'h' }
54
+ await api.getById('msg-2', headers)
55
+ expect(client.get).toHaveBeenCalledWith('/transcripts/msg-2', headers)
56
+ })
57
+
58
+ it('propagates errors from client.get', async () => {
59
+ vi.mocked(client.get).mockRejectedValue(new Error('Not found'))
60
+ await expect(api.getById('missing')).rejects.toThrow('Not found')
61
+ })
62
+ })
63
+ })
@@ -147,7 +147,7 @@ describe('BaseCrudApi', () => {
147
147
  vi.mocked(client.get).mockResolvedValue({ id: '1', name: 'x' })
148
148
  const headers = { 'X-Tenant': '123' }
149
149
 
150
- await api.getById('1', headers)
150
+ await api.getById('1', undefined, headers)
151
151
  expect(client.get).toHaveBeenCalledWith('/items/1', headers)
152
152
  })
153
153
  })
@@ -1,10 +1,11 @@
1
1
  import qs from 'qs'
2
2
  import type { ApiClient } from './ApiClient'
3
- import type { CrudApi, ListQuery, Paginated } from './types'
3
+ import type { CrudApi, GetByIdQuery, ListQuery, Paginated } from './types'
4
4
  export type {
5
5
  WhereClause,
6
6
  IncludeItem,
7
7
  ListQuery,
8
+ GetByIdQuery,
8
9
  Paginated,
9
10
  HasGetMany,
10
11
  HasGetById,
@@ -20,12 +21,17 @@ export class BaseCrudApi<
20
21
  TUpdate = TCreate,
21
22
  TQuery extends ListQuery<TResponse> = ListQuery<TResponse>,
22
23
  > implements CrudApi<TResponse, TCreate, TUpdate, TQuery> {
23
- protected readonly client: ApiClient
24
- protected readonly basePath: string
24
+ public readonly client: ApiClient
25
+ public readonly basePath: string
25
26
 
26
27
  constructor(client: ApiClient, basePath: string) {
27
28
  this.client = client
28
29
  this.basePath = basePath.replace(/\/$/, '')
30
+ this.getMany = this.getMany.bind(this)
31
+ this.getById = this.getById.bind(this)
32
+ this.create = this.create.bind(this)
33
+ this.updateById = this.updateById.bind(this)
34
+ this.deleteById = this.deleteById.bind(this)
29
35
  }
30
36
 
31
37
  getMany(
@@ -51,8 +57,13 @@ export class BaseCrudApi<
51
57
  * Returns a single resource by ID.
52
58
  * @permissions $resourceName.view
53
59
  */
54
- getById(id: string, headers?: Record<string, string>): Promise<TResponse> {
55
- return this.client.get<TResponse>(`${this.basePath}/${id}`, headers)
60
+ getById(
61
+ id: string,
62
+ query?: GetByIdQuery<TResponse>,
63
+ headers?: Record<string, string>,
64
+ ): Promise<TResponse> {
65
+ const queryString = query ? `?${qs.stringify(query)}` : ''
66
+ return this.client.get<TResponse>(`${this.basePath}/${id}${queryString}`, headers)
56
67
  }
57
68
 
58
69
  /**
package/src/core/index.ts CHANGED
@@ -2,4 +2,4 @@ export type { ApiClient, HttpMethod } from './ApiClient'
2
2
  export { BaseApiClient, ApiError } from './BaseApiClient'
3
3
  export type { ValidationError } from './BaseApiClient'
4
4
  export { BaseCrudApi } from './BaseCrudApi'
5
- export type { WhereClause, IncludeItem, ListQuery, Paginated } from './types'
5
+ export type { WhereClause, IncludeItem, ListQuery, GetByIdQuery, Paginated } from './types'
package/src/core/types.ts CHANGED
@@ -74,6 +74,7 @@ type TypedIncludeObject<T> = {
74
74
  [K in AssociationKeys<T>]: {
75
75
  model: K
76
76
  as?: string
77
+ attributes?: (keyof Unwrap<T[K]> & string)[]
77
78
  include?: IncludeItem<Unwrap<T[K]>>[]
78
79
  required?: boolean
79
80
  where?: WhereClause<Unwrap<T[K]>>
@@ -126,8 +127,14 @@ export interface HasGetMany<TResponse, TQuery extends ListQuery<TResponse> = Lis
126
127
  ): Promise<Paginated<TResponse>>
127
128
  }
128
129
 
130
+ export type GetByIdQuery<T = Record<string, unknown>> = Pick<ListQuery<T>, 'include' | 'attributes'>
131
+
129
132
  export interface HasGetById<TResponse> {
130
- getById(id: string, headers?: Record<string, string>): Promise<TResponse>
133
+ getById(
134
+ id: string,
135
+ query?: GetByIdQuery<TResponse>,
136
+ headers?: Record<string, string>,
137
+ ): Promise<TResponse>
131
138
  }
132
139
 
133
140
  export interface HasCreate<TResponse, TCreate> {