@ikatec/digisac-api-sdk 4.10.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apis/contactBlockLists/ContactBlockListsApi.cjs +28 -0
- package/dist/apis/contactBlockLists/ContactBlockListsApi.cjs.map +1 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.d.ts +24 -0
- package/dist/apis/contactBlockLists/ContactBlockListsApi.d.ts.map +1 -1
- package/dist/apis/contactBlockLists/ContactBlockListsApi.mjs +28 -0
- package/dist/apis/contactBlockLists/ContactBlockListsApi.mjs.map +1 -1
- package/dist/apis/contactBlockLists/types.d.ts +6 -1
- package/dist/apis/contactBlockLists/types.d.ts.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.cjs +31 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.cjs.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.d.ts +28 -2
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.d.ts.map +1 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.mjs +31 -1
- package/dist/apis/contactBlockListsControls/ContactBlockListsControlsApi.mjs.map +1 -1
- package/dist/apis/contactBlockListsControls/types.d.ts +7 -0
- package/dist/apis/contactBlockListsControls/types.d.ts.map +1 -1
- package/dist/apis/distribution/DistributionApi.cjs +25 -0
- package/dist/apis/distribution/DistributionApi.cjs.map +1 -1
- package/dist/apis/distribution/DistributionApi.d.ts +20 -1
- package/dist/apis/distribution/DistributionApi.d.ts.map +1 -1
- package/dist/apis/distribution/DistributionApi.mjs +25 -0
- package/dist/apis/distribution/DistributionApi.mjs.map +1 -1
- package/dist/apis/distribution/types.d.ts +18 -1
- package/dist/apis/distribution/types.d.ts.map +1 -1
- package/dist/apis/integrations/IntegrationsApi.cjs +17 -0
- package/dist/apis/integrations/IntegrationsApi.cjs.map +1 -1
- package/dist/apis/integrations/IntegrationsApi.d.ts +15 -2
- package/dist/apis/integrations/IntegrationsApi.d.ts.map +1 -1
- package/dist/apis/integrations/IntegrationsApi.mjs +17 -0
- package/dist/apis/integrations/IntegrationsApi.mjs.map +1 -1
- package/dist/apis/integrations/types.d.ts +15 -6
- package/dist/apis/integrations/types.d.ts.map +1 -1
- package/dist/core/BaseCrudApi.cjs +3 -1
- package/dist/core/BaseCrudApi.cjs.map +1 -1
- package/dist/core/BaseCrudApi.d.ts +6 -4
- package/dist/core/BaseCrudApi.d.ts.map +1 -1
- package/dist/core/BaseCrudApi.mjs +3 -1
- package/dist/core/BaseCrudApi.mjs.map +1 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/apis/contactBlockLists/ContactBlockListsApi.test.ts +57 -0
- package/src/apis/contactBlockLists/ContactBlockListsApi.ts +44 -0
- package/src/apis/contactBlockLists/types.ts +6 -1
- package/src/apis/contactBlockListsControls/ContactBlockListsControlsApi.test.ts +48 -0
- package/src/apis/contactBlockListsControls/ContactBlockListsControlsApi.ts +49 -2
- package/src/apis/contactBlockListsControls/types.ts +7 -0
- package/src/apis/distribution/DistributionApi.test.ts +65 -0
- package/src/apis/distribution/DistributionApi.ts +39 -1
- package/src/apis/distribution/types.ts +17 -1
- package/src/apis/integrations/IntegrationsApi.test.ts +42 -0
- package/src/apis/integrations/IntegrationsApi.ts +35 -2
- package/src/apis/integrations/types.ts +25 -6
- package/src/apis/payloads.test-d.ts +58 -0
- package/src/core/BaseCrudApi.test-d.ts +11 -1
- package/src/core/BaseCrudApi.ts +15 -6
- package/src/core/types.ts +4 -2
|
@@ -1,19 +1,57 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import type { ListQuery } from '../../core/types'
|
|
3
3
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
4
|
+
import type { Department } from '../departments/types'
|
|
4
5
|
import type { Distribution, CreateDistributionPayload, UpdateDistributionPayload } from './types'
|
|
5
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Ticket distribution rules. `getById` answers `null` for an unknown id and always includes `departments` and
|
|
9
|
+
* `roles` (the query is ignored).
|
|
10
|
+
*/
|
|
6
11
|
export class DistributionApi extends BaseCrudApi<
|
|
7
12
|
Distribution,
|
|
8
13
|
CreateDistributionPayload,
|
|
9
14
|
UpdateDistributionPayload,
|
|
10
15
|
ListQuery<Distribution>,
|
|
11
|
-
void
|
|
16
|
+
void,
|
|
17
|
+
Distribution | undefined,
|
|
18
|
+
Distribution | Department[]
|
|
12
19
|
> {
|
|
13
20
|
constructor(client: ApiClient) {
|
|
14
21
|
super(client, '/distribution')
|
|
15
22
|
}
|
|
16
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Creates a distribution. Resolves the distribution (without `departments`/`roles`), or no body
|
|
26
|
+
* (`undefined`) when `departments` is sent — find it by name with `getMany` in that case.
|
|
27
|
+
* @permissions distribution.create
|
|
28
|
+
*/
|
|
29
|
+
override create(
|
|
30
|
+
body: CreateDistributionPayload,
|
|
31
|
+
headers?: Record<string, string>,
|
|
32
|
+
): Promise<Distribution | undefined> {
|
|
33
|
+
return super.create(body, headers)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Updates a distribution. The backend reads the id from the body, so it is sent there too. It replaces
|
|
38
|
+
* the links: omitting `roles` or `departments` clears them. Resolves the stored distribution (with
|
|
39
|
+
* `deletedAt`, without the links) or, when `departments` is sent, the updated departments. An unknown id
|
|
40
|
+
* answers 500.
|
|
41
|
+
* @permissions distribution.view OR distribution.update
|
|
42
|
+
*/
|
|
43
|
+
override updateById(
|
|
44
|
+
id: string,
|
|
45
|
+
body: UpdateDistributionPayload,
|
|
46
|
+
headers?: Record<string, string>,
|
|
47
|
+
): Promise<Distribution | Department[]> {
|
|
48
|
+
return this.client.put<Distribution | Department[], UpdateDistributionPayload & { id: string }>(
|
|
49
|
+
`${this.basePath}/${id}`,
|
|
50
|
+
{ ...body, id },
|
|
51
|
+
headers,
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
17
55
|
/**
|
|
18
56
|
* Deletes a distribution. Resolves with no body, also for an unknown id (200).
|
|
19
57
|
* @permissions distribution.view OR distribution.destroy
|
|
@@ -11,7 +11,8 @@ export type Distribution = {
|
|
|
11
11
|
distributeQueue: boolean
|
|
12
12
|
accountId: string
|
|
13
13
|
archivedAt: string | null
|
|
14
|
-
|
|
14
|
+
/** Only in the answer of `updateById` (the stored model, not transformed). */
|
|
15
|
+
deletedAt?: string | null
|
|
15
16
|
createdAt: string
|
|
16
17
|
updatedAt: string
|
|
17
18
|
// relationships
|
|
@@ -21,6 +22,9 @@ export type Distribution = {
|
|
|
21
22
|
|
|
22
23
|
export type DistributionRelationships = 'departments' | 'roles'
|
|
23
24
|
|
|
25
|
+
/** A department or a role linked to a distribution (only the id is read). */
|
|
26
|
+
export type DistributionLink = { id: string }
|
|
27
|
+
|
|
24
28
|
export type CreateDistributionPayload = {
|
|
25
29
|
name: string
|
|
26
30
|
maxNum: number
|
|
@@ -28,8 +32,17 @@ export type CreateDistributionPayload = {
|
|
|
28
32
|
timeToRedistribute?: number
|
|
29
33
|
redistributeAssignedTickets?: boolean
|
|
30
34
|
distributeQueue?: boolean
|
|
35
|
+
/** An archived distribution is skipped by the distribution crons. */
|
|
36
|
+
archivedAt?: string | null
|
|
37
|
+
/** Departments to distribute; a department has at most one distribution. */
|
|
38
|
+
departments?: DistributionLink[]
|
|
39
|
+
roles?: DistributionLink[]
|
|
31
40
|
}
|
|
32
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The update replaces the links: send `departments` and `roles` again to keep them — omitting them
|
|
44
|
+
* clears them.
|
|
45
|
+
*/
|
|
33
46
|
export type UpdateDistributionPayload = {
|
|
34
47
|
name?: string
|
|
35
48
|
maxNum?: number
|
|
@@ -37,4 +50,7 @@ export type UpdateDistributionPayload = {
|
|
|
37
50
|
timeToRedistribute?: number
|
|
38
51
|
redistributeAssignedTickets?: boolean
|
|
39
52
|
distributeQueue?: boolean
|
|
53
|
+
archivedAt?: string | null
|
|
54
|
+
departments?: DistributionLink[]
|
|
55
|
+
roles?: DistributionLink[]
|
|
40
56
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { IntegrationsApi } from './IntegrationsApi'
|
|
3
|
+
import type { ApiClient } from '../../core/ApiClient'
|
|
4
|
+
|
|
5
|
+
// ── Mock client factory ──────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
function createMockClient(): ApiClient {
|
|
8
|
+
return {
|
|
9
|
+
setAccessToken: vi.fn().mockReturnThis(),
|
|
10
|
+
request: vi.fn(),
|
|
11
|
+
get: vi.fn(),
|
|
12
|
+
post: vi.fn(),
|
|
13
|
+
put: vi.fn(),
|
|
14
|
+
patch: vi.fn(),
|
|
15
|
+
delete: vi.fn(),
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
describe('IntegrationsApi', () => {
|
|
22
|
+
let client: ReturnType<typeof createMockClient>
|
|
23
|
+
let api: IntegrationsApi
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
client = createMockClient()
|
|
27
|
+
api = new IntegrationsApi(client)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('create posts to /integrations and resolves the empty object the route answers', async () => {
|
|
31
|
+
vi.mocked(client.post).mockResolvedValue({})
|
|
32
|
+
const body = { type: 'menu_button', url: 'https://example.com', icon: '', text: 'QA' }
|
|
33
|
+
await expect(api.create(body)).resolves.toEqual({})
|
|
34
|
+
expect(client.post).toHaveBeenCalledWith('/integrations', body, undefined)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('updateById puts to /integrations/:id and resolves the empty object', async () => {
|
|
38
|
+
vi.mocked(client.put).mockResolvedValue({})
|
|
39
|
+
await expect(api.updateById('int-1', { text: 'QA 2' })).resolves.toEqual({})
|
|
40
|
+
expect(client.put).toHaveBeenCalledWith('/integrations/int-1', { text: 'QA 2' }, undefined)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -1,19 +1,52 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import type { ListQuery } from '../../core/types'
|
|
3
3
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
Integration,
|
|
6
|
+
CreateIntegrationPayload,
|
|
7
|
+
UpdateIntegrationPayload,
|
|
8
|
+
IntegrationWriteResponse,
|
|
9
|
+
} from './types'
|
|
5
10
|
|
|
11
|
+
/** Integrations of the account (buttons and events of the UI). `getById` answers `null` for an unknown id. */
|
|
6
12
|
export class IntegrationsApi extends BaseCrudApi<
|
|
7
13
|
Integration,
|
|
8
14
|
CreateIntegrationPayload,
|
|
9
15
|
UpdateIntegrationPayload,
|
|
10
16
|
ListQuery<Integration>,
|
|
11
|
-
'OK'
|
|
17
|
+
'OK',
|
|
18
|
+
IntegrationWriteResponse,
|
|
19
|
+
IntegrationWriteResponse
|
|
12
20
|
> {
|
|
13
21
|
constructor(client: ApiClient) {
|
|
14
22
|
super(client, '/integrations')
|
|
15
23
|
}
|
|
16
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Creates an integration. Resolves `{}` — also when the type is unique (`event_ticket_transfer`,
|
|
27
|
+
* `event_ticket_closed`), already exists in the account and nothing is created. Find the integration with
|
|
28
|
+
* `getMany` (e.g. by `text`).
|
|
29
|
+
* @permissions integrations.create
|
|
30
|
+
*/
|
|
31
|
+
override create(
|
|
32
|
+
body: CreateIntegrationPayload,
|
|
33
|
+
headers?: Record<string, string>,
|
|
34
|
+
): Promise<IntegrationWriteResponse> {
|
|
35
|
+
return super.create(body, headers)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Updates an integration. Resolves `{}`; read it again with `getById`. An unknown id answers 500.
|
|
40
|
+
* @permissions integrations.view OR integrations.update
|
|
41
|
+
*/
|
|
42
|
+
override updateById(
|
|
43
|
+
id: string,
|
|
44
|
+
body: UpdateIntegrationPayload,
|
|
45
|
+
headers?: Record<string, string>,
|
|
46
|
+
): Promise<IntegrationWriteResponse> {
|
|
47
|
+
return super.updateById(id, body, headers)
|
|
48
|
+
}
|
|
49
|
+
|
|
17
50
|
/**
|
|
18
51
|
* Deletes an integration. Resolves the text `'OK'`; an unknown id answers 500.
|
|
19
52
|
* @permissions integrations.view OR integrations.destroy
|
|
@@ -1,27 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The types the UI shows: buttons (`menu_button` in the header, `context_menu_button_*` in the contact and
|
|
3
|
+
* message menus) and events that open the integration when a ticket is transferred or closed (unique per
|
|
4
|
+
* account). The backend accepts any string.
|
|
5
|
+
*/
|
|
6
|
+
export type IntegrationType =
|
|
7
|
+
| 'menu_button'
|
|
8
|
+
| 'context_menu_button_contact_modal'
|
|
9
|
+
| 'context_menu_button_contact_side_list'
|
|
10
|
+
| 'context_menu_button_message'
|
|
11
|
+
| 'event_ticket_transfer'
|
|
12
|
+
| 'event_ticket_closed'
|
|
13
|
+
| (string & {})
|
|
14
|
+
|
|
15
|
+
export type IntegrationSize = 'sm' | 'md' | 'lg' | (string & {})
|
|
16
|
+
|
|
1
17
|
export type Integration = {
|
|
2
18
|
id: string
|
|
3
|
-
type:
|
|
19
|
+
type: IntegrationType
|
|
4
20
|
url: string | null
|
|
5
21
|
icon: string | null
|
|
6
22
|
text: string | null
|
|
7
|
-
size:
|
|
23
|
+
size: IntegrationSize | null
|
|
8
24
|
accountId: string
|
|
9
25
|
createdAt: string
|
|
10
26
|
updatedAt: string
|
|
11
27
|
}
|
|
12
28
|
|
|
29
|
+
/** What `create` and `updateById` resolve to: an empty object. */
|
|
30
|
+
export type IntegrationWriteResponse = Record<string, never>
|
|
31
|
+
|
|
13
32
|
export type CreateIntegrationPayload = {
|
|
14
|
-
type:
|
|
33
|
+
type: IntegrationType
|
|
15
34
|
url?: string
|
|
16
35
|
icon?: string
|
|
17
36
|
text?: string
|
|
18
|
-
size?:
|
|
37
|
+
size?: IntegrationSize
|
|
19
38
|
}
|
|
20
39
|
|
|
21
40
|
export type UpdateIntegrationPayload = {
|
|
22
|
-
type?:
|
|
41
|
+
type?: IntegrationType
|
|
23
42
|
url?: string | null
|
|
24
43
|
icon?: string | null
|
|
25
44
|
text?: string | null
|
|
26
|
-
size?:
|
|
45
|
+
size?: IntegrationSize | null
|
|
27
46
|
}
|
|
@@ -54,6 +54,8 @@ import type { SummarizeTicketResult } from './contacts/types'
|
|
|
54
54
|
import { CustomFieldsApi } from './customFields/CustomFieldsApi'
|
|
55
55
|
import { DepartmentsApi } from './departments/DepartmentsApi'
|
|
56
56
|
import type { Department } from './departments/types'
|
|
57
|
+
import type { Distribution } from './distribution/types'
|
|
58
|
+
import type { ContactBlockList } from './contactBlockLists/types'
|
|
57
59
|
import { DistributionApi } from './distribution/DistributionApi'
|
|
58
60
|
import { FilesApi } from './files/FilesApi'
|
|
59
61
|
import type { CreateToUploadResult, DeleteFileResult, File } from './files/types'
|
|
@@ -545,6 +547,62 @@ expectType<Promise<'OK'>>(new ContactBlockListsControlsApi(client).deleteById('c
|
|
|
545
547
|
expectType<Promise<boolean>>(new RolesApi(client).deleteById('r-1'))
|
|
546
548
|
expectType<Promise<void>>(new AcceptanceTermsApi(client).deleteById('t-1'))
|
|
547
549
|
expectType<Promise<void>>(new DistributionApi(client).deleteById('d-1'))
|
|
550
|
+
|
|
551
|
+
// ── create/updateById: what each route really answers (QARC-1008) ─────
|
|
552
|
+
|
|
553
|
+
expectType<Promise<Distribution | undefined>>(
|
|
554
|
+
new DistributionApi(client).create({
|
|
555
|
+
name: 'd',
|
|
556
|
+
maxNum: 1,
|
|
557
|
+
redistributeAll: false,
|
|
558
|
+
departments: [{ id: 'dep-1' }],
|
|
559
|
+
}),
|
|
560
|
+
)
|
|
561
|
+
expectType<Promise<Distribution | Department[]>>(
|
|
562
|
+
new DistributionApi(client).updateById('d-1', {
|
|
563
|
+
name: 'd',
|
|
564
|
+
roles: [{ id: 'r-1' }],
|
|
565
|
+
departments: [],
|
|
566
|
+
}),
|
|
567
|
+
)
|
|
568
|
+
expectType<Promise<Record<string, never>>>(
|
|
569
|
+
new IntegrationsApi(client).create({ type: 'menu_button', text: 'x' }),
|
|
570
|
+
)
|
|
571
|
+
expectType<Promise<Record<string, never>>>(
|
|
572
|
+
new IntegrationsApi(client).updateById('i-1', { text: 'x' }),
|
|
573
|
+
)
|
|
574
|
+
expectType<Promise<void>>(
|
|
575
|
+
new ContactBlockListsControlsApi(client).create({
|
|
576
|
+
reason: 'r',
|
|
577
|
+
servicesIds: ['s-1'],
|
|
578
|
+
contactBlockListsIds: ['l-1'],
|
|
579
|
+
action: 'block',
|
|
580
|
+
revertExceptions: false,
|
|
581
|
+
}),
|
|
582
|
+
)
|
|
583
|
+
expectType<Promise<{ count: number }>>(
|
|
584
|
+
new ContactBlockListsApi(client).count({ where: { name: 'x' } }),
|
|
585
|
+
)
|
|
586
|
+
expectType<Promise<{ count: number }>>(new ContactBlockListsControlsApi(client).count())
|
|
587
|
+
expectType<Promise<Paginated<ContactBlockList>>>(
|
|
588
|
+
new ContactBlockListsApi(client).getMany({ include: ['importFile'] }),
|
|
589
|
+
)
|
|
590
|
+
expectError(
|
|
591
|
+
new DistributionApi(client).create({
|
|
592
|
+
name: 'd',
|
|
593
|
+
maxNum: 1,
|
|
594
|
+
redistributeAll: false,
|
|
595
|
+
departments: ['dep-1'],
|
|
596
|
+
}),
|
|
597
|
+
)
|
|
598
|
+
expectError(
|
|
599
|
+
new ContactBlockListsControlsApi(client).create({
|
|
600
|
+
reason: 'r',
|
|
601
|
+
servicesIds: [],
|
|
602
|
+
contactBlockListsIds: [],
|
|
603
|
+
action: 'remove',
|
|
604
|
+
}),
|
|
605
|
+
)
|
|
548
606
|
expectType<Promise<false>>(new KnowledgeBaseApi(client).deleteById('k-1'))
|
|
549
607
|
expectType<Promise<false>>(new KnowledgeBaseItemApi(client).deleteById('k-1'))
|
|
550
608
|
expectType<Promise<DeleteFileResult>>(new FilesApi(client).deleteById('f-1'))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { expectError, expectType } from 'tsd'
|
|
2
2
|
import type { ApiClient } from './ApiClient'
|
|
3
3
|
import { BaseCrudApi } from './BaseCrudApi'
|
|
4
|
-
import type { Paginated } from './types'
|
|
4
|
+
import type { ListQuery, Paginated } from './types'
|
|
5
5
|
|
|
6
6
|
// ── Test model ──────────────────────────────────────────────────────
|
|
7
7
|
|
|
@@ -40,6 +40,16 @@ expectType<Promise<Item>>(api.create({ name: 'x' }))
|
|
|
40
40
|
expectType<Promise<Item>>(api.updateById('1', {}))
|
|
41
41
|
expectType<Promise<Item>>(api.deleteById('1'))
|
|
42
42
|
|
|
43
|
+
// Routes that do not answer the resource on create/update (TCreateResponse, TUpdateResponse)
|
|
44
|
+
const writes = new BaseCrudApi<Item, CreateItem, UpdateItem, ListQuery<Item>, 'OK', void, Item[]>(
|
|
45
|
+
client,
|
|
46
|
+
'/items',
|
|
47
|
+
)
|
|
48
|
+
expectType<Promise<void>>(writes.create({ name: 'x' }))
|
|
49
|
+
expectType<Promise<Item[]>>(writes.updateById('1', {}))
|
|
50
|
+
expectType<Promise<'OK'>>(writes.deleteById('1'))
|
|
51
|
+
expectType<Promise<Item>>(writes.getById('1'))
|
|
52
|
+
|
|
43
53
|
expectError(api.create({}))
|
|
44
54
|
expectError(api.create({ name: 1 }))
|
|
45
55
|
expectError(api.updateById('1', { name: 1 }))
|
package/src/core/BaseCrudApi.ts
CHANGED
|
@@ -16,7 +16,9 @@ export type {
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Generic CRUD resource: the reads of `BaseReadApi` plus `create`, `updateById` and `deleteById`.
|
|
19
|
-
* `TDeleteResponse` is what `deleteById` resolves to (most routes answer the text `'OK'`)
|
|
19
|
+
* `TDeleteResponse` is what `deleteById` resolves to (most routes answer the text `'OK'`);
|
|
20
|
+
* `TCreateResponse` and `TUpdateResponse` are what `create` and `updateById` resolve to, for the routes
|
|
21
|
+
* that do not answer the resource (an empty body, `{}`, another model).
|
|
20
22
|
*/
|
|
21
23
|
export class BaseCrudApi<
|
|
22
24
|
TResponse,
|
|
@@ -24,24 +26,31 @@ export class BaseCrudApi<
|
|
|
24
26
|
TUpdate = TCreate,
|
|
25
27
|
TQuery extends ListQuery<TResponse> = ListQuery<TResponse>,
|
|
26
28
|
TDeleteResponse = TResponse,
|
|
29
|
+
TCreateResponse = TResponse,
|
|
30
|
+
TUpdateResponse = TResponse,
|
|
27
31
|
>
|
|
28
32
|
extends BaseReadApi<TResponse, TQuery>
|
|
29
|
-
implements
|
|
33
|
+
implements
|
|
34
|
+
CrudApi<TResponse, TCreate, TUpdate, TQuery, TDeleteResponse, TCreateResponse, TUpdateResponse>
|
|
30
35
|
{
|
|
31
36
|
/**
|
|
32
37
|
* Creates a new resource.
|
|
33
38
|
* @permissions $resourceName.create
|
|
34
39
|
*/
|
|
35
|
-
create(body: TCreate, headers?: Record<string, string>): Promise<
|
|
36
|
-
return this.client.post<
|
|
40
|
+
create(body: TCreate, headers?: Record<string, string>): Promise<TCreateResponse> {
|
|
41
|
+
return this.client.post<TCreateResponse, TCreate>(this.basePath, body, headers)
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
/**
|
|
40
45
|
* Updates an existing resource by ID.
|
|
41
46
|
* @permissions $resourceName.update
|
|
42
47
|
*/
|
|
43
|
-
updateById(
|
|
44
|
-
|
|
48
|
+
updateById(
|
|
49
|
+
id: string,
|
|
50
|
+
body: TUpdate,
|
|
51
|
+
headers?: Record<string, string>,
|
|
52
|
+
): Promise<TUpdateResponse> {
|
|
53
|
+
return this.client.put<TUpdateResponse, TUpdate>(`${this.basePath}/${id}`, body, headers)
|
|
45
54
|
}
|
|
46
55
|
|
|
47
56
|
/**
|
package/src/core/types.ts
CHANGED
|
@@ -160,8 +160,10 @@ export type CrudApi<
|
|
|
160
160
|
TUpdate = TCreate,
|
|
161
161
|
TQuery extends ListQuery<TResponse> = ListQuery<TResponse>,
|
|
162
162
|
TDeleteResponse = TResponse,
|
|
163
|
+
TCreateResponse = TResponse,
|
|
164
|
+
TUpdateResponse = TResponse,
|
|
163
165
|
> = HasGetMany<TResponse, TQuery> &
|
|
164
166
|
HasGetById<TResponse> &
|
|
165
|
-
HasCreate<
|
|
166
|
-
HasUpdateById<
|
|
167
|
+
HasCreate<TCreateResponse, TCreate> &
|
|
168
|
+
HasUpdateById<TUpdateResponse, TUpdate> &
|
|
167
169
|
HasDeleteById<TDeleteResponse>
|