@ikatec/digisac-api-sdk 4.4.0 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apis/cards/CardsApi.cjs +70 -0
- package/dist/apis/cards/CardsApi.cjs.map +1 -1
- package/dist/apis/cards/CardsApi.d.ts +53 -1
- package/dist/apis/cards/CardsApi.d.ts.map +1 -1
- package/dist/apis/cards/CardsApi.mjs +70 -0
- package/dist/apis/cards/CardsApi.mjs.map +1 -1
- package/dist/apis/cards/types.d.ts +84 -0
- package/dist/apis/cards/types.d.ts.map +1 -1
- package/dist/apis/kanbanBoards/types.d.ts +33 -4
- package/dist/apis/kanbanBoards/types.d.ts.map +1 -1
- package/dist/apis/kanbanCards/KanbanCardsApi.cjs +8 -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 +8 -0
- package/dist/apis/kanbanCards/KanbanCardsApi.mjs.map +1 -1
- package/dist/apis/kanbanCards/types.d.ts +17 -5
- package/dist/apis/kanbanCards/types.d.ts.map +1 -1
- package/dist/apis/kanbanColumns/KanbanColumnsApi.cjs +9 -0
- package/dist/apis/kanbanColumns/KanbanColumnsApi.cjs.map +1 -1
- package/dist/apis/kanbanColumns/KanbanColumnsApi.d.ts +8 -1
- package/dist/apis/kanbanColumns/KanbanColumnsApi.d.ts.map +1 -1
- package/dist/apis/kanbanColumns/KanbanColumnsApi.mjs +9 -0
- package/dist/apis/kanbanColumns/KanbanColumnsApi.mjs.map +1 -1
- package/dist/apis/kanbanColumns/types.d.ts +14 -3
- package/dist/apis/kanbanColumns/types.d.ts.map +1 -1
- package/dist/apis/messages/MessagesApi.cjs +4 -1
- package/dist/apis/messages/MessagesApi.cjs.map +1 -1
- package/dist/apis/messages/MessagesApi.d.ts +5 -2
- package/dist/apis/messages/MessagesApi.d.ts.map +1 -1
- package/dist/apis/messages/MessagesApi.mjs +4 -1
- package/dist/apis/messages/MessagesApi.mjs.map +1 -1
- package/dist/apis/messages/types.d.ts +13 -0
- package/dist/apis/messages/types.d.ts.map +1 -1
- package/dist/apis/pipeline/PipelineApi.cjs +133 -0
- package/dist/apis/pipeline/PipelineApi.cjs.map +1 -1
- package/dist/apis/pipeline/PipelineApi.d.ts +102 -1
- package/dist/apis/pipeline/PipelineApi.d.ts.map +1 -1
- package/dist/apis/pipeline/PipelineApi.mjs +133 -0
- package/dist/apis/pipeline/PipelineApi.mjs.map +1 -1
- package/dist/apis/pipeline/types.d.ts +164 -0
- package/dist/apis/pipeline/types.d.ts.map +1 -1
- package/dist/apis/tags/TagsApi.cjs +3 -2
- package/dist/apis/tags/TagsApi.cjs.map +1 -1
- package/dist/apis/tags/TagsApi.d.ts +6 -5
- package/dist/apis/tags/TagsApi.d.ts.map +1 -1
- package/dist/apis/tags/TagsApi.mjs +3 -2
- package/dist/apis/tags/TagsApi.mjs.map +1 -1
- package/dist/apis/tags/types.d.ts +5 -0
- package/dist/apis/tags/types.d.ts.map +1 -1
- package/dist/apis/users/types.d.ts +21 -3
- package/dist/apis/users/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/apis/cards/CardsApi.test.ts +128 -0
- package/src/apis/cards/CardsApi.ts +124 -1
- package/src/apis/cards/types.ts +81 -0
- package/src/apis/kanbanBoards/types.ts +36 -4
- package/src/apis/kanbanCards/KanbanCardsApi.test.ts +46 -0
- package/src/apis/kanbanCards/KanbanCardsApi.ts +23 -1
- package/src/apis/kanbanCards/types.ts +18 -5
- package/src/apis/kanbanColumns/KanbanColumnsApi.test.ts +46 -0
- package/src/apis/kanbanColumns/KanbanColumnsApi.ts +24 -1
- package/src/apis/kanbanColumns/types.ts +15 -3
- package/src/apis/me/MeApi.test.ts +3 -3
- package/src/apis/messages/MessagesApi.test.ts +11 -0
- package/src/apis/messages/MessagesApi.ts +6 -3
- package/src/apis/messages/types.ts +13 -0
- package/src/apis/payloads.test-d.ts +30 -0
- package/src/apis/pipeline/PipelineApi.test.ts +193 -0
- package/src/apis/pipeline/PipelineApi.ts +274 -1
- package/src/apis/pipeline/types.ts +162 -0
- package/src/apis/tags/TagsApi.test.ts +5 -0
- package/src/apis/tags/TagsApi.ts +8 -6
- package/src/apis/tags/types.ts +6 -0
- package/src/apis/users/UsersApi.test.ts +3 -3
- package/src/apis/users/types.ts +23 -3
|
@@ -45,6 +45,17 @@ const message: Message = {
|
|
|
45
45
|
obfuscated: false,
|
|
46
46
|
reactionParentMessageId: null,
|
|
47
47
|
hsmId: null,
|
|
48
|
+
isFromBot: false,
|
|
49
|
+
accountId: 'acc-1',
|
|
50
|
+
serviceId: 'svc-1',
|
|
51
|
+
contactId: 'ctt-1',
|
|
52
|
+
fromId: null,
|
|
53
|
+
toId: 'ctt-1',
|
|
54
|
+
userId: 'usr-1',
|
|
55
|
+
ticketId: 'tkt-1',
|
|
56
|
+
ticketUserId: 'usr-1',
|
|
57
|
+
ticketDepartmentId: 'dep-1',
|
|
58
|
+
quotedMessageId: null,
|
|
48
59
|
createdAt: '2024-01-01T00:00:00Z',
|
|
49
60
|
updatedAt: '2024-01-01T00:00:00Z',
|
|
50
61
|
deletedAt: null,
|
|
@@ -101,9 +101,12 @@ export class MessagesApi extends BaseCrudApi<Message, CreateMessagePayload, Upda
|
|
|
101
101
|
)
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Triggers an AI-generated summary for the conversation associated with the given message.
|
|
106
|
+
* Resolves to `'OK'`.
|
|
107
|
+
*/
|
|
108
|
+
summarize(id: string, headers?: Record<string, string>): Promise<string> {
|
|
109
|
+
return this.client.post<string>(`${this.basePath}/${id}/summarize`, undefined, headers)
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
/** Checks whether a message is out of the visible range (i.e. there are more than `limit` messages after it). */
|
|
@@ -113,6 +113,19 @@ export type Message = {
|
|
|
113
113
|
transcribeError?: boolean
|
|
114
114
|
reactionParentMessageId: string | null
|
|
115
115
|
hsmId: string | null
|
|
116
|
+
isFromBot: boolean
|
|
117
|
+
accountId: string
|
|
118
|
+
serviceId: string
|
|
119
|
+
contactId: string
|
|
120
|
+
/** The contact that sent the message; `null` when it is from the account. */
|
|
121
|
+
fromId: string | null
|
|
122
|
+
toId: string | null
|
|
123
|
+
/** The user that sent the message; `null` for a received one. */
|
|
124
|
+
userId: string | null
|
|
125
|
+
ticketId: string | null
|
|
126
|
+
ticketUserId: string | null
|
|
127
|
+
ticketDepartmentId: string | null
|
|
128
|
+
quotedMessageId: string | null
|
|
116
129
|
createdAt: string
|
|
117
130
|
updatedAt: string
|
|
118
131
|
deletedAt: string | null
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { expectError } from 'tsd'
|
|
2
2
|
import type { ApiClient } from '../core/ApiClient'
|
|
3
|
+
import { CardsApi } from './cards/CardsApi'
|
|
3
4
|
import { ContactsApi } from './contacts/ContactsApi'
|
|
5
|
+
import { KanbanColumnsApi } from './kanbanColumns/KanbanColumnsApi'
|
|
6
|
+
import { PipelineApi } from './pipeline/PipelineApi'
|
|
4
7
|
import { PersonalAccessTokensApi } from './personalAccessTokens/PersonalAccessTokensApi'
|
|
5
8
|
import { RolesApi } from './roles/RolesApi'
|
|
6
9
|
import { TagsApi } from './tags/TagsApi'
|
|
@@ -63,3 +66,30 @@ const tags = new TagsApi(client)
|
|
|
63
66
|
tags.attachContacts('t-1', { where: { id: { $in: ['c-1', 'c-2'] } } })
|
|
64
67
|
expectError(tags.attachContacts('t-1', {}))
|
|
65
68
|
expectError(tags.detachContacts('t-1', { include: ['tags'] }))
|
|
69
|
+
|
|
70
|
+
// ── pipelines: moving the cards of a deleted status needs the target ─
|
|
71
|
+
|
|
72
|
+
const pipelines = new PipelineApi(client)
|
|
73
|
+
pipelines.deleteStatus('st-1', { action: 'move-to-another', newStatusId: 'st-2' })
|
|
74
|
+
pipelines.deleteStatus('st-1', { action: 'keep-without-status' })
|
|
75
|
+
expectError(pipelines.deleteStatus('st-1', { action: 'move-to-another' }))
|
|
76
|
+
expectError(pipelines.createAutomation({ pipelineId: 'p-1', type: 'email' }))
|
|
77
|
+
expectError(pipelines.deleteStage('s-1', { typeAction: 'archive' }))
|
|
78
|
+
|
|
79
|
+
// ── cards: getCards is not scoped by the backend and only answers the attributes asked ─
|
|
80
|
+
|
|
81
|
+
const cards = new CardsApi(client)
|
|
82
|
+
cards.getCards({
|
|
83
|
+
where: { accountId: 'a-1', pipelineId: 'p-1' },
|
|
84
|
+
attributes: ['id', 'title'],
|
|
85
|
+
order: [['contact.name', 'ASC']],
|
|
86
|
+
})
|
|
87
|
+
expectError(cards.getCards({ where: { pipelineId: 'p-1' }, attributes: ['id'] }))
|
|
88
|
+
expectError(cards.getCards({ where: { accountId: 'a-1' } }))
|
|
89
|
+
expectError(cards.saveComment({ comment: 'no card nor id' }))
|
|
90
|
+
|
|
91
|
+
// ── kanban columns: the backend computes the position ───────────────
|
|
92
|
+
|
|
93
|
+
const columns = new KanbanColumnsApi(client)
|
|
94
|
+
columns.reorder('col-1', { beforeColumnId: 'col-0', afterColumnId: 'col-2' })
|
|
95
|
+
expectError(columns.reorder('col-1', { position: 'M' }))
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import type { ApiClient } from '../../core/ApiClient'
|
|
3
|
+
import { PipelineApi } from './PipelineApi'
|
|
4
|
+
|
|
5
|
+
// ── Mock client factory ──────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
function createMockClient(): ApiClient {
|
|
8
|
+
return {
|
|
9
|
+
setAccessToken: vi.fn().mockReturnThis(),
|
|
10
|
+
request: vi.fn(),
|
|
11
|
+
get: vi.fn(),
|
|
12
|
+
post: vi.fn(),
|
|
13
|
+
put: vi.fn(),
|
|
14
|
+
patch: vi.fn(),
|
|
15
|
+
delete: vi.fn(),
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const headers = { 'X-Custom': 'value' }
|
|
20
|
+
|
|
21
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
describe('PipelineApi', () => {
|
|
24
|
+
let client: ReturnType<typeof createMockClient>
|
|
25
|
+
let api: PipelineApi
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
client = createMockClient()
|
|
29
|
+
api = new PipelineApi(client)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
describe('stages', () => {
|
|
33
|
+
const stage = { name: 'Proposta', pipelineId: 'p1', position: 2 }
|
|
34
|
+
|
|
35
|
+
it('createStage calls client.post with /pipelines/stage and body', async () => {
|
|
36
|
+
vi.mocked(client.post).mockResolvedValue({ id: 's1', ...stage })
|
|
37
|
+
const result = await api.createStage(stage)
|
|
38
|
+
expect(client.post).toHaveBeenCalledWith('/pipelines/stage', stage, undefined)
|
|
39
|
+
expect(result).toEqual({ id: 's1', ...stage })
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('createStage resolves to the refusal code the backend answers with 200', async () => {
|
|
43
|
+
vi.mocked(client.post).mockResolvedValue('STAGES_LIMIT')
|
|
44
|
+
await expect(api.createStage(stage)).resolves.toBe('STAGES_LIMIT')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('updateStage calls client.put with /pipelines/stage/:id and body', async () => {
|
|
48
|
+
const body = { ...stage, id: 's1', statuses: [{ id: 'st1', name: 'Novo', position: 1 }] }
|
|
49
|
+
await api.updateStage('s1', body, headers)
|
|
50
|
+
expect(client.put).toHaveBeenCalledWith('/pipelines/stage/s1', body, headers)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('deleteStage calls client.request with DELETE and the destination of the cards', async () => {
|
|
54
|
+
vi.mocked(client.request).mockResolvedValue('MESSAGE_STAGE_DELETED')
|
|
55
|
+
const body = { typeAction: 'move' as const, idNewStage: 's2', user: { id: 'u1' } }
|
|
56
|
+
const result = await api.deleteStage('s1', body)
|
|
57
|
+
expect(client.request).toHaveBeenCalledWith('DELETE', '/pipelines/stage/s1', body, undefined)
|
|
58
|
+
expect(result).toBe('MESSAGE_STAGE_DELETED')
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('deleteStage sends an empty body by default', async () => {
|
|
62
|
+
await api.deleteStage('s1')
|
|
63
|
+
expect(client.request).toHaveBeenCalledWith('DELETE', '/pipelines/stage/s1', {}, undefined)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('getStageTotals calls client.post with /pipelines/stage-totals/:id and the filters', async () => {
|
|
67
|
+
const filters = { nameTitle: 'Acme', createdFrom: '01/09/2026' }
|
|
68
|
+
await api.getStageTotals('s1', filters)
|
|
69
|
+
expect(client.post).toHaveBeenCalledWith('/pipelines/stage-totals/s1', filters, undefined)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('getStageTotals sends no filter by default', async () => {
|
|
73
|
+
await api.getStageTotals('s1')
|
|
74
|
+
expect(client.post).toHaveBeenCalledWith('/pipelines/stage-totals/s1', {}, undefined)
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
describe('statuses', () => {
|
|
79
|
+
it('getStatuses calls client.get with /pipelines/statuses/:pipelineId', async () => {
|
|
80
|
+
vi.mocked(client.get).mockResolvedValue([{ id: 'st1', name: 'Novo' }])
|
|
81
|
+
const result = await api.getStatuses('p1', headers)
|
|
82
|
+
expect(client.get).toHaveBeenCalledWith('/pipelines/statuses/p1', headers)
|
|
83
|
+
expect(result).toEqual([{ id: 'st1', name: 'Novo' }])
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('getStatus calls client.get with /pipelines/status/:id', async () => {
|
|
87
|
+
await api.getStatus('st1')
|
|
88
|
+
expect(client.get).toHaveBeenCalledWith('/pipelines/status/st1', undefined)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('deleteStatus calls client.post with /pipelines/delete-status/:id and the action', async () => {
|
|
92
|
+
vi.mocked(client.post).mockResolvedValue('MESSAGE_STATUS_DELETED')
|
|
93
|
+
const body = { action: 'move-to-another' as const, newStatusId: 'st2' }
|
|
94
|
+
const result = await api.deleteStatus('st1', body)
|
|
95
|
+
expect(client.post).toHaveBeenCalledWith('/pipelines/delete-status/st1', body, undefined)
|
|
96
|
+
expect(result).toBe('MESSAGE_STATUS_DELETED')
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('renameStatus posts only newStatusName to the delete-status route', async () => {
|
|
100
|
+
vi.mocked(client.post).mockResolvedValue('MESSAGE_STATUS_RENAMED')
|
|
101
|
+
const result = await api.renameStatus('st1', 'Qualificado', headers)
|
|
102
|
+
expect(client.post).toHaveBeenCalledWith(
|
|
103
|
+
'/pipelines/delete-status/st1',
|
|
104
|
+
{ newStatusName: 'Qualificado' },
|
|
105
|
+
headers,
|
|
106
|
+
)
|
|
107
|
+
expect(result).toBe('MESSAGE_STATUS_RENAMED')
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
describe('automations', () => {
|
|
112
|
+
const body = {
|
|
113
|
+
pipelineId: 'p1',
|
|
114
|
+
type: 'notification' as const,
|
|
115
|
+
config: { notify: 'high' as const },
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
it('createAutomation calls client.post with /pipelines/automations and body', async () => {
|
|
119
|
+
await api.createAutomation(body)
|
|
120
|
+
expect(client.post).toHaveBeenCalledWith('/pipelines/automations', body, undefined)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('updateAutomation calls client.put with /pipelines/automations/:id and body', async () => {
|
|
124
|
+
await api.updateAutomation('a1', body, headers)
|
|
125
|
+
expect(client.put).toHaveBeenCalledWith('/pipelines/automations/a1', body, headers)
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
it('deleteAutomation calls client.delete with /pipelines/automations/:id', async () => {
|
|
129
|
+
await api.deleteAutomation('a1')
|
|
130
|
+
expect(client.delete).toHaveBeenCalledWith('/pipelines/automations/a1', undefined)
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('getAutomation calls client.get with /pipelines/automations/:pipelineId', async () => {
|
|
134
|
+
vi.mocked(client.get).mockResolvedValue([])
|
|
135
|
+
const result = await api.getAutomation('p1')
|
|
136
|
+
expect(client.get).toHaveBeenCalledWith('/pipelines/automations/p1', undefined)
|
|
137
|
+
expect(result).toEqual([])
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
describe('pipeline actions', () => {
|
|
142
|
+
it('duplicate calls client.post with /pipelines/duplicate/:pipelineId and no body', async () => {
|
|
143
|
+
await api.duplicate('p1', headers)
|
|
144
|
+
expect(client.post).toHaveBeenCalledWith('/pipelines/duplicate/p1', undefined, headers)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('archive posts archive: true to /pipelines/:id/archive', async () => {
|
|
148
|
+
await api.archive('p1')
|
|
149
|
+
expect(client.post).toHaveBeenCalledWith(
|
|
150
|
+
'/pipelines/p1/archive',
|
|
151
|
+
{ archive: true },
|
|
152
|
+
undefined,
|
|
153
|
+
)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('unarchive posts archive: false to /pipelines/:id/archive', async () => {
|
|
157
|
+
await api.unarchive('p1')
|
|
158
|
+
expect(client.post).toHaveBeenCalledWith(
|
|
159
|
+
'/pipelines/p1/archive',
|
|
160
|
+
{ archive: false },
|
|
161
|
+
undefined,
|
|
162
|
+
)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('exportCsv calls client.post with /pipelines/:id/export and resolves to the CSV text', async () => {
|
|
166
|
+
vi.mocked(client.post).mockResolvedValue('Funil;\n')
|
|
167
|
+
const body = { createdAtInit: '2026-09-01 00:00:00', createdAtFinal: '2026-09-30 23:59:59' }
|
|
168
|
+
const result = await api.exportCsv('p1', body)
|
|
169
|
+
expect(client.post).toHaveBeenCalledWith('/pipelines/p1/export', body, undefined)
|
|
170
|
+
expect(result).toBe('Funil;\n')
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('getManyWithTotals serializes the query on /pipelines/withTotals', async () => {
|
|
174
|
+
await api.getManyWithTotals({ archive: true })
|
|
175
|
+
const expected = `/pipelines/withTotals?query=${encodeURIComponent(JSON.stringify({ archive: true }))}`
|
|
176
|
+
expect(client.get).toHaveBeenCalledWith(expected, undefined)
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it('getManyWithTotals sends no query string without a query', async () => {
|
|
180
|
+
await api.getManyWithTotals()
|
|
181
|
+
expect(client.get).toHaveBeenCalledWith('/pipelines/withTotals', undefined)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
describe('error propagation', () => {
|
|
186
|
+
it('propagates errors from createStage', async () => {
|
|
187
|
+
vi.mocked(client.post).mockRejectedValue(new Error('Validation failed'))
|
|
188
|
+
await expect(api.createStage({ name: 'x', pipelineId: 'p1', position: 1 })).rejects.toThrow(
|
|
189
|
+
'Validation failed',
|
|
190
|
+
)
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
})
|
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
CreatePipelineAutomationPayload,
|
|
5
|
+
CreatePipelinePayload,
|
|
6
|
+
CreatePipelineStagePayload,
|
|
7
|
+
DeletePipelineStagePayload,
|
|
8
|
+
DeletePipelineStageResult,
|
|
9
|
+
DeletePipelineStatusPayload,
|
|
10
|
+
ExportPipelinePayload,
|
|
11
|
+
Pipeline,
|
|
12
|
+
PipelineAutomation,
|
|
13
|
+
PipelineRecord,
|
|
14
|
+
PipelineStage,
|
|
15
|
+
PipelineStageRefusal,
|
|
16
|
+
PipelineStageStatusWithCount,
|
|
17
|
+
PipelineStageTotals,
|
|
18
|
+
PipelineStageTotalsFilters,
|
|
19
|
+
PipelineStatusRef,
|
|
20
|
+
PipelinesWithTotals,
|
|
21
|
+
PipelinesWithTotalsQuery,
|
|
22
|
+
UpdatePipelineAutomationPayload,
|
|
23
|
+
UpdatePipelinePayload,
|
|
24
|
+
UpdatePipelineStagePayload,
|
|
25
|
+
} from './types'
|
|
4
26
|
|
|
5
27
|
export class PipelineApi extends BaseCrudApi<
|
|
6
28
|
Pipeline,
|
|
@@ -10,4 +32,255 @@ export class PipelineApi extends BaseCrudApi<
|
|
|
10
32
|
constructor(client: ApiClient) {
|
|
11
33
|
super(client, '/pipelines')
|
|
12
34
|
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Adds a stage (with its statuses and reasons) to a pipeline. Resolves to the stage as stored,
|
|
38
|
+
* without the statuses/reasons, or to a refusal code with 200: `'STAGES_LIMIT'` (the pipeline
|
|
39
|
+
* already has 10 stages) or `'STAGE_ALREADY_EXIST'` (same name).
|
|
40
|
+
* @permissions pipelines.update
|
|
41
|
+
*/
|
|
42
|
+
createStage(
|
|
43
|
+
body: CreatePipelineStagePayload,
|
|
44
|
+
headers?: Record<string, string>,
|
|
45
|
+
): Promise<PipelineStage | PipelineStageRefusal> {
|
|
46
|
+
return this.client.post<PipelineStage | PipelineStageRefusal, CreatePipelineStagePayload>(
|
|
47
|
+
`${this.basePath}/stage`,
|
|
48
|
+
body,
|
|
49
|
+
headers,
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Updates a stage. `statuses` and `reasons` replace the whole set: items with `id` are kept
|
|
55
|
+
* and updated, items without it are created and the missing ones are deleted — omitting the
|
|
56
|
+
* lists deletes every status and reason of the stage. Resolves to the stage as stored, or to
|
|
57
|
+
* `'STAGE_ALREADY_EXIST'`.
|
|
58
|
+
* @permissions pipelines.update
|
|
59
|
+
*/
|
|
60
|
+
updateStage(
|
|
61
|
+
id: string,
|
|
62
|
+
body: UpdatePipelineStagePayload,
|
|
63
|
+
headers?: Record<string, string>,
|
|
64
|
+
): Promise<PipelineStage | 'STAGE_ALREADY_EXIST'> {
|
|
65
|
+
return this.client.put<PipelineStage | 'STAGE_ALREADY_EXIST', UpdatePipelineStagePayload>(
|
|
66
|
+
`${this.basePath}/stage/${id}`,
|
|
67
|
+
body,
|
|
68
|
+
headers,
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Deletes a stage and moves its cards (see {@link DeletePipelineStagePayload}). Resolves to
|
|
74
|
+
* `'MESSAGE_STAGE_DELETED'`, or to `'PIPELINES_MIN_STAGES'` (nothing deleted) when the pipeline
|
|
75
|
+
* has only 2 stages. The backend also serves this under `PUT /pipelines/delete-stage/{id}`.
|
|
76
|
+
* @permissions pipelines.update
|
|
77
|
+
*/
|
|
78
|
+
deleteStage(
|
|
79
|
+
id: string,
|
|
80
|
+
body: DeletePipelineStagePayload = {},
|
|
81
|
+
headers?: Record<string, string>,
|
|
82
|
+
): Promise<DeletePipelineStageResult> {
|
|
83
|
+
return this.client.request<DeletePipelineStageResult, DeletePipelineStagePayload>(
|
|
84
|
+
'DELETE',
|
|
85
|
+
`${this.basePath}/stage/${id}`,
|
|
86
|
+
body,
|
|
87
|
+
headers,
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Lists the statuses of every stage of a pipeline (`[]` for an unknown pipeline).
|
|
93
|
+
* @permissions pipelines.view
|
|
94
|
+
*/
|
|
95
|
+
getStatuses(pipelineId: string, headers?: Record<string, string>): Promise<PipelineStatusRef[]> {
|
|
96
|
+
return this.client.get<PipelineStatusRef[]>(`${this.basePath}/statuses/${pipelineId}`, headers)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Gets a stage status with the number of cards using it. An unknown id resolves to
|
|
101
|
+
* `{ cardsCount: 0 }` with 200, not to an error.
|
|
102
|
+
* @permissions pipelines.view
|
|
103
|
+
*/
|
|
104
|
+
getStatus(
|
|
105
|
+
id: string,
|
|
106
|
+
headers?: Record<string, string>,
|
|
107
|
+
): Promise<PipelineStageStatusWithCount | { cardsCount: 0 }> {
|
|
108
|
+
return this.client.get<PipelineStageStatusWithCount | { cardsCount: 0 }>(
|
|
109
|
+
`${this.basePath}/status/${id}`,
|
|
110
|
+
headers,
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Deletes a stage status, keeping its cards without status or moving them to another one.
|
|
116
|
+
* Resolves to `'MESSAGE_STATUS_DELETED'`.
|
|
117
|
+
* @permissions pipelines.view
|
|
118
|
+
*/
|
|
119
|
+
deleteStatus(
|
|
120
|
+
id: string,
|
|
121
|
+
body: DeletePipelineStatusPayload,
|
|
122
|
+
headers?: Record<string, string>,
|
|
123
|
+
): Promise<'MESSAGE_STATUS_DELETED'> {
|
|
124
|
+
return this.client.post<'MESSAGE_STATUS_DELETED', DeletePipelineStatusPayload>(
|
|
125
|
+
`${this.basePath}/delete-status/${id}`,
|
|
126
|
+
body,
|
|
127
|
+
headers,
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Renames a stage status — same route as {@link deleteStatus}, without an `action`.
|
|
133
|
+
* Resolves to `'MESSAGE_STATUS_RENAMED'`; an empty name fails with 500.
|
|
134
|
+
* @permissions pipelines.view
|
|
135
|
+
*/
|
|
136
|
+
renameStatus(
|
|
137
|
+
id: string,
|
|
138
|
+
newStatusName: string,
|
|
139
|
+
headers?: Record<string, string>,
|
|
140
|
+
): Promise<'MESSAGE_STATUS_RENAMED'> {
|
|
141
|
+
return this.client.post<'MESSAGE_STATUS_RENAMED', { newStatusName: string }>(
|
|
142
|
+
`${this.basePath}/delete-status/${id}`,
|
|
143
|
+
{ newStatusName },
|
|
144
|
+
headers,
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Creates an automation of a pipeline. Resolves to the automation as stored.
|
|
150
|
+
* @permissions pipelines.update
|
|
151
|
+
*/
|
|
152
|
+
createAutomation(
|
|
153
|
+
body: CreatePipelineAutomationPayload,
|
|
154
|
+
headers?: Record<string, string>,
|
|
155
|
+
): Promise<PipelineAutomation> {
|
|
156
|
+
return this.client.post<PipelineAutomation, CreatePipelineAutomationPayload>(
|
|
157
|
+
`${this.basePath}/automations`,
|
|
158
|
+
body,
|
|
159
|
+
headers,
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Updates an automation. Resolves to the automation as stored.
|
|
165
|
+
* @permissions pipelines.update
|
|
166
|
+
*/
|
|
167
|
+
updateAutomation(
|
|
168
|
+
id: string,
|
|
169
|
+
body: UpdatePipelineAutomationPayload,
|
|
170
|
+
headers?: Record<string, string>,
|
|
171
|
+
): Promise<PipelineAutomation> {
|
|
172
|
+
return this.client.put<PipelineAutomation, UpdatePipelineAutomationPayload>(
|
|
173
|
+
`${this.basePath}/automations/${id}`,
|
|
174
|
+
body,
|
|
175
|
+
headers,
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Deletes an automation. Resolves with no content; an unknown id fails with 500.
|
|
181
|
+
* @permissions pipelines.update
|
|
182
|
+
*/
|
|
183
|
+
deleteAutomation(id: string, headers?: Record<string, string>): Promise<void> {
|
|
184
|
+
return this.client.delete<void>(`${this.basePath}/automations/${id}`, headers)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Gets the automation of a pipeline — a single object (the first one found), or `[]` when
|
|
189
|
+
* the pipeline has none.
|
|
190
|
+
* @permissions pipelines.view
|
|
191
|
+
*/
|
|
192
|
+
getAutomation(
|
|
193
|
+
pipelineId: string,
|
|
194
|
+
headers?: Record<string, string>,
|
|
195
|
+
): Promise<PipelineAutomation | []> {
|
|
196
|
+
return this.client.get<PipelineAutomation | []>(
|
|
197
|
+
`${this.basePath}/automations/${pipelineId}`,
|
|
198
|
+
headers,
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Copies a pipeline as `"<name> (copy)"`, with its stages, statuses, reasons and automations
|
|
204
|
+
* (not its departments). Resolves to the new pipeline as stored, without the stages.
|
|
205
|
+
* @permissions pipelines.view
|
|
206
|
+
*/
|
|
207
|
+
duplicate(pipelineId: string, headers?: Record<string, string>): Promise<PipelineRecord> {
|
|
208
|
+
return this.client.post<PipelineRecord>(
|
|
209
|
+
`${this.basePath}/duplicate/${pipelineId}`,
|
|
210
|
+
undefined,
|
|
211
|
+
headers,
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Archives a pipeline. Resolves to the pipeline with its stages and their card totals.
|
|
217
|
+
* @permissions pipelines.update
|
|
218
|
+
*/
|
|
219
|
+
archive(id: string, headers?: Record<string, string>): Promise<Pipeline> {
|
|
220
|
+
return this.client.post<Pipeline, { archive: boolean }>(
|
|
221
|
+
`${this.basePath}/${id}/archive`,
|
|
222
|
+
{ archive: true },
|
|
223
|
+
headers,
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Restores an archived pipeline. Resolves to the pipeline with its stages and their totals.
|
|
229
|
+
* @permissions pipelines.update
|
|
230
|
+
*/
|
|
231
|
+
unarchive(id: string, headers?: Record<string, string>): Promise<Pipeline> {
|
|
232
|
+
return this.client.post<Pipeline, { archive: boolean }>(
|
|
233
|
+
`${this.basePath}/${id}/archive`,
|
|
234
|
+
{ archive: false },
|
|
235
|
+
headers,
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Exports the cards of a pipeline as CSV text (`;` as the delimiter): a summary block
|
|
241
|
+
* followed by one row per card.
|
|
242
|
+
* @permissions pipelines.view
|
|
243
|
+
*/
|
|
244
|
+
exportCsv(
|
|
245
|
+
id: string,
|
|
246
|
+
body: ExportPipelinePayload = {},
|
|
247
|
+
headers?: Record<string, string>,
|
|
248
|
+
): Promise<string> {
|
|
249
|
+
return this.client.post<string, ExportPipelinePayload>(
|
|
250
|
+
`${this.basePath}/${id}/export`,
|
|
251
|
+
body,
|
|
252
|
+
headers,
|
|
253
|
+
)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Lists the pipelines of the account with their stages and card totals. Not paginated.
|
|
258
|
+
* @permissions pipelines.view
|
|
259
|
+
*/
|
|
260
|
+
getManyWithTotals(
|
|
261
|
+
query?: PipelinesWithTotalsQuery,
|
|
262
|
+
headers?: Record<string, string>,
|
|
263
|
+
): Promise<PipelinesWithTotals> {
|
|
264
|
+
return this.client.get<PipelinesWithTotals>(
|
|
265
|
+
`${this.basePath}/withTotals${this.toQueryString(query)}`,
|
|
266
|
+
headers,
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Gets the card totals of a stage, optionally filtered like the board. Resolves to `null`
|
|
272
|
+
* for an unknown stage.
|
|
273
|
+
* @permissions pipelines.update OR pipelines.opportunity.update
|
|
274
|
+
*/
|
|
275
|
+
getStageTotals(
|
|
276
|
+
stageId: string,
|
|
277
|
+
filters: PipelineStageTotalsFilters = {},
|
|
278
|
+
headers?: Record<string, string>,
|
|
279
|
+
): Promise<PipelineStageTotals | null> {
|
|
280
|
+
return this.client.post<PipelineStageTotals | null, PipelineStageTotalsFilters>(
|
|
281
|
+
`${this.basePath}/stage-totals/${stageId}`,
|
|
282
|
+
filters,
|
|
283
|
+
headers,
|
|
284
|
+
)
|
|
285
|
+
}
|
|
13
286
|
}
|