@ikatec/digisac-api-sdk 4.12.0 → 4.13.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/absence/AbsenceApi.cjs +46 -2
- package/dist/apis/absence/AbsenceApi.cjs.map +1 -1
- package/dist/apis/absence/AbsenceApi.d.ts +38 -4
- package/dist/apis/absence/AbsenceApi.d.ts.map +1 -1
- package/dist/apis/absence/AbsenceApi.mjs +46 -2
- package/dist/apis/absence/AbsenceApi.mjs.map +1 -1
- package/dist/apis/absence/types.d.ts +51 -2
- package/dist/apis/absence/types.d.ts.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.cjs +10 -1
- package/dist/apis/activityLog/ActivityLogApi.cjs.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.d.ts +10 -3
- package/dist/apis/activityLog/ActivityLogApi.d.ts.map +1 -1
- package/dist/apis/activityLog/ActivityLogApi.mjs +10 -1
- package/dist/apis/activityLog/ActivityLogApi.mjs.map +1 -1
- package/dist/apis/activityLog/types.d.ts +48 -8
- package/dist/apis/activityLog/types.d.ts.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.cjs +31 -2
- package/dist/apis/creditMovements/CreditMovementsApi.cjs.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.d.ts +21 -3
- package/dist/apis/creditMovements/CreditMovementsApi.d.ts.map +1 -1
- package/dist/apis/creditMovements/CreditMovementsApi.mjs +31 -2
- package/dist/apis/creditMovements/CreditMovementsApi.mjs.map +1 -1
- package/dist/apis/creditMovements/types.d.ts +73 -2
- package/dist/apis/creditMovements/types.d.ts.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.cjs +27 -0
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.cjs.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.d.ts +22 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.d.ts.map +1 -1
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.mjs +27 -0
- package/dist/apis/knowledgeBase/KnowledgeBaseApi.mjs.map +1 -1
- package/dist/apis/knowledgeBase/types.d.ts +56 -2
- package/dist/apis/knowledgeBase/types.d.ts.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.cjs +26 -0
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.cjs.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.d.ts +24 -0
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.d.ts.map +1 -1
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.mjs +26 -0
- package/dist/apis/knowledgeBaseItem/KnowledgeBaseItemApi.mjs.map +1 -1
- package/dist/apis/knowledgeBaseItem/types.d.ts +23 -6
- package/dist/apis/knowledgeBaseItem/types.d.ts.map +1 -1
- package/dist/apis/notifications/NotificationsApi.cjs +50 -2
- package/dist/apis/notifications/NotificationsApi.cjs.map +1 -1
- package/dist/apis/notifications/NotificationsApi.d.ts +41 -3
- package/dist/apis/notifications/NotificationsApi.d.ts.map +1 -1
- package/dist/apis/notifications/NotificationsApi.mjs +50 -2
- package/dist/apis/notifications/NotificationsApi.mjs.map +1 -1
- package/dist/apis/notifications/types.d.ts +54 -8
- package/dist/apis/notifications/types.d.ts.map +1 -1
- package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.cjs.map +1 -1
- package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.d.ts +4 -1
- package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.d.ts.map +1 -1
- package/dist/apis/serviceAccessManagement/ServiceAccessManagementApi.mjs.map +1 -1
- package/dist/apis/serviceAccessManagement/types.d.ts +3 -0
- package/dist/apis/serviceAccessManagement/types.d.ts.map +1 -1
- package/dist/apis/stickerUsers/StickerUsersApi.cjs.map +1 -1
- package/dist/apis/stickerUsers/StickerUsersApi.d.ts +3 -1
- package/dist/apis/stickerUsers/StickerUsersApi.d.ts.map +1 -1
- package/dist/apis/stickerUsers/StickerUsersApi.mjs.map +1 -1
- package/dist/apis/stickerUsers/types.d.ts +4 -0
- package/dist/apis/stickerUsers/types.d.ts.map +1 -1
- package/dist/apis/stickers/StickersApi.cjs +27 -3
- package/dist/apis/stickers/StickersApi.cjs.map +1 -1
- package/dist/apis/stickers/StickersApi.d.ts +24 -4
- package/dist/apis/stickers/StickersApi.d.ts.map +1 -1
- package/dist/apis/stickers/StickersApi.mjs +27 -3
- package/dist/apis/stickers/StickersApi.mjs.map +1 -1
- package/dist/apis/stickers/types.d.ts +28 -4
- package/dist/apis/stickers/types.d.ts.map +1 -1
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.cjs +1 -2
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.cjs.map +1 -1
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.d.ts +1 -2
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.d.ts.map +1 -1
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.mjs +1 -2
- package/dist/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.mjs.map +1 -1
- package/package.json +1 -1
- package/src/apis/absence/AbsenceApi.test.ts +65 -0
- package/src/apis/absence/AbsenceApi.ts +77 -4
- package/src/apis/absence/types.ts +53 -2
- package/src/apis/activityLog/ActivityLogApi.test.ts +44 -0
- package/src/apis/activityLog/ActivityLogApi.ts +22 -3
- package/src/apis/activityLog/types.ts +47 -8
- package/src/apis/creditMovements/CreditMovementsApi.test.ts +88 -0
- package/src/apis/creditMovements/CreditMovementsApi.ts +73 -2
- package/src/apis/creditMovements/types.ts +74 -2
- package/src/apis/knowledgeBase/KnowledgeBaseApi.test.ts +54 -0
- package/src/apis/knowledgeBase/KnowledgeBaseApi.ts +61 -1
- package/src/apis/knowledgeBase/types.ts +62 -2
- package/src/apis/knowledgeBaseItem/KnowledgeBaseItemApi.test.ts +57 -0
- package/src/apis/knowledgeBaseItem/KnowledgeBaseItemApi.ts +45 -0
- package/src/apis/knowledgeBaseItem/types.ts +23 -6
- package/src/apis/me/MeApi.test.ts +1 -1
- package/src/apis/notifications/NotificationsApi.test.ts +74 -0
- package/src/apis/notifications/NotificationsApi.ts +88 -3
- package/src/apis/notifications/types.ts +65 -7
- package/src/apis/payloads.test-d.ts +46 -0
- package/src/apis/serviceAccessManagement/ServiceAccessManagementApi.ts +4 -1
- package/src/apis/serviceAccessManagement/types.ts +3 -0
- package/src/apis/stickerUsers/StickerUsersApi.ts +3 -1
- package/src/apis/stickerUsers/types.ts +4 -0
- package/src/apis/stickers/StickersApi.test.ts +58 -0
- package/src/apis/stickers/StickersApi.ts +46 -4
- package/src/apis/stickers/types.ts +29 -4
- package/src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.ts +1 -2
|
@@ -2,9 +2,10 @@ import { BaseCrudApi } from "../../core/BaseCrudApi.mjs";
|
|
|
2
2
|
|
|
3
3
|
//#region src/apis/stickers/StickersApi.ts
|
|
4
4
|
/**
|
|
5
|
-
* Stickers of the account. The backend serves `GET /stickers
|
|
6
|
-
* `GET /stickers/exist`, `POST /stickers/add` and `DELETE /stickers/remove/:stickerId
|
|
7
|
-
* no read by id, update nor `DELETE /stickers/:id`.
|
|
5
|
+
* Stickers of the account: every user of the account sees them. The backend serves `GET /stickers`,
|
|
6
|
+
* `POST /stickers`, `GET /stickers/exist`, `POST /stickers/add` and `DELETE /stickers/remove/:stickerId`;
|
|
7
|
+
* there is no read by id, update nor `DELETE /stickers/:id`. The list accepts only the `file` include.
|
|
8
|
+
* @permissions stickers.send (list) · stickers.management (create, exist, add, remove)
|
|
8
9
|
*/
|
|
9
10
|
var StickersApi = class extends BaseCrudApi {
|
|
10
11
|
constructor(client) {
|
|
@@ -25,6 +26,29 @@ var StickersApi = class extends BaseCrudApi {
|
|
|
25
26
|
deleteById(id, headers) {
|
|
26
27
|
return super.deleteById(id, headers);
|
|
27
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Finds the sticker of the account that came from the message, or from the file of `fileChecksum` or
|
|
31
|
+
* `filehash`. Resolves `{ stickerId }`, or `{}` when there is none; without `messageId` it answers 500
|
|
32
|
+
* `Invalid message ID`.
|
|
33
|
+
*/
|
|
34
|
+
exist(query, headers) {
|
|
35
|
+
return this.client.get(`${this.basePath}/exist${this.toQueryString(query)}`, headers);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Turns the file of a message of the account into a sticker (`type: 'added'`). Idempotent: a sticker that
|
|
39
|
+
* already came from the message (or its file) is answered as is, and a removed one is restored. A message
|
|
40
|
+
* without file answers 500 `Message or file not found`.
|
|
41
|
+
*/
|
|
42
|
+
add(messageId, headers) {
|
|
43
|
+
return this.client.post(`${this.basePath}/add`, { messageId }, headers);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Removes a sticker of the account (soft delete; its file stays in the storage) and clears it from the
|
|
47
|
+
* recent stickers of every user. Resolves the text `'OK'`, or `false` when there is no such sticker.
|
|
48
|
+
*/
|
|
49
|
+
remove(stickerId, headers) {
|
|
50
|
+
return this.client.delete(`${this.basePath}/remove/${stickerId}`, headers);
|
|
51
|
+
}
|
|
28
52
|
};
|
|
29
53
|
|
|
30
54
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StickersApi.mjs","names":[],"sources":["../../../src/apis/stickers/StickersApi.ts"],"sourcesContent":["import type { ApiClient } from '../../core/ApiClient'\nimport { BaseCrudApi } from '../../core/BaseCrudApi'\nimport type { GetByIdQuery } from '../../core/types'\nimport type {
|
|
1
|
+
{"version":3,"file":"StickersApi.mjs","names":[],"sources":["../../../src/apis/stickers/StickersApi.ts"],"sourcesContent":["import type { ApiClient } from '../../core/ApiClient'\nimport { BaseCrudApi } from '../../core/BaseCrudApi'\nimport type { GetByIdQuery } from '../../core/types'\nimport type {\n Sticker,\n CreateStickerPayload,\n UpdateStickerPayload,\n StickerExistQuery,\n} from './types'\n\n/**\n * Stickers of the account: every user of the account sees them. The backend serves `GET /stickers`,\n * `POST /stickers`, `GET /stickers/exist`, `POST /stickers/add` and `DELETE /stickers/remove/:stickerId`;\n * there is no read by id, update nor `DELETE /stickers/:id`. The list accepts only the `file` include.\n * @permissions stickers.send (list) · stickers.management (create, exist, add, remove)\n */\nexport class StickersApi extends BaseCrudApi<Sticker, CreateStickerPayload, UpdateStickerPayload> {\n constructor(client: ApiClient) {\n super(client, '/stickers')\n }\n\n /** @deprecated Not served: the backend has no GET /stickers/:id, so this route answers 404. */\n override getById(\n id: string,\n query?: GetByIdQuery<Sticker>,\n headers?: Record<string, string>,\n ): Promise<Sticker> {\n return super.getById(id, query, headers)\n }\n\n /** @deprecated Not served: the backend has no PUT /stickers/:id, so this route answers 404. */\n override updateById(\n id: string,\n body: UpdateStickerPayload,\n headers?: Record<string, string>,\n ): Promise<Sticker> {\n return super.updateById(id, body, headers)\n }\n\n /**\n * @deprecated Not served: the backend has no DELETE /stickers/:id (it removes a sticker by\n * `DELETE /stickers/remove/:stickerId`), so this route answers 404.\n */\n override deleteById(id: string, headers?: Record<string, string>): Promise<Sticker> {\n return super.deleteById(id, headers)\n }\n\n /**\n * Finds the sticker of the account that came from the message, or from the file of `fileChecksum` or\n * `filehash`. Resolves `{ stickerId }`, or `{}` when there is none; without `messageId` it answers 500\n * `Invalid message ID`.\n */\n exist(\n query: StickerExistQuery,\n headers?: Record<string, string>,\n ): Promise<{ stickerId?: string }> {\n return this.client.get<{ stickerId?: string }>(\n `${this.basePath}/exist${this.toQueryString(query)}`,\n headers,\n )\n }\n\n /**\n * Turns the file of a message of the account into a sticker (`type: 'added'`). Idempotent: a sticker that\n * already came from the message (or its file) is answered as is, and a removed one is restored. A message\n * without file answers 500 `Message or file not found`.\n */\n add(messageId: string, headers?: Record<string, string>): Promise<Sticker> {\n return this.client.post<Sticker, { messageId: string }>(\n `${this.basePath}/add`,\n { messageId },\n headers,\n )\n }\n\n /**\n * Removes a sticker of the account (soft delete; its file stays in the storage) and clears it from the\n * recent stickers of every user. Resolves the text `'OK'`, or `false` when there is no such sticker.\n */\n remove(stickerId: string, headers?: Record<string, string>): Promise<'OK' | false> {\n return this.client.delete<'OK' | false>(`${this.basePath}/remove/${stickerId}`, headers)\n }\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAa,cAAb,cAAiC,YAAiE;CAChG,YAAY,QAAmB;AAC7B,QAAM,QAAQ,YAAY;;;CAI5B,AAAS,QACP,IACA,OACA,SACkB;AAClB,SAAO,MAAM,QAAQ,IAAI,OAAO,QAAQ;;;CAI1C,AAAS,WACP,IACA,MACA,SACkB;AAClB,SAAO,MAAM,WAAW,IAAI,MAAM,QAAQ;;;;;;CAO5C,AAAS,WAAW,IAAY,SAAoD;AAClF,SAAO,MAAM,WAAW,IAAI,QAAQ;;;;;;;CAQtC,MACE,OACA,SACiC;AACjC,SAAO,KAAK,OAAO,IACjB,GAAG,KAAK,SAAS,QAAQ,KAAK,cAAc,MAAM,IAClD,QACD;;;;;;;CAQH,IAAI,WAAmB,SAAoD;AACzE,SAAO,KAAK,OAAO,KACjB,GAAG,KAAK,SAAS,OACjB,EAAE,WAAW,EACb,QACD;;;;;;CAOH,OAAO,WAAmB,SAAyD;AACjF,SAAO,KAAK,OAAO,OAAqB,GAAG,KAAK,SAAS,UAAU,aAAa,QAAQ"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { File } from '../files/types';
|
|
1
2
|
import type { User } from '../users/types';
|
|
3
|
+
/** A sticker of the account (every user of the account sees it). */
|
|
2
4
|
export type Sticker = {
|
|
3
5
|
id: string;
|
|
4
|
-
|
|
6
|
+
/** `'created'` (uploaded with `create`) or `'added'` (taken from a message with `add`). */
|
|
7
|
+
type: 'created' | 'added' | (string & {});
|
|
5
8
|
originFileChecksum: string | null;
|
|
6
9
|
originFilehash: string | null;
|
|
7
10
|
originMessageId: string | null;
|
|
@@ -9,17 +12,38 @@ export type Sticker = {
|
|
|
9
12
|
accountId: string;
|
|
10
13
|
createdAt: string;
|
|
11
14
|
updatedAt: string;
|
|
12
|
-
deletedAt
|
|
15
|
+
deletedAt?: string | null;
|
|
16
|
+
/** @deprecated Not served: the backend only serves the `file` include. */
|
|
13
17
|
user?: User;
|
|
18
|
+
/** The image (webp) of the sticker. */
|
|
19
|
+
file?: File;
|
|
14
20
|
};
|
|
15
|
-
|
|
21
|
+
/** The backend serves only `file` (`user` is dropped). */
|
|
22
|
+
export type StickerRelationships = 'user' | 'file';
|
|
23
|
+
/**
|
|
24
|
+
* Uploads an image as a sticker: the backend converts it to a 512x512 webp (413 when it ends up too large:
|
|
25
|
+
* 100KB static, 500KB animated). `base64` without the `data:...;base64,` prefix.
|
|
26
|
+
*/
|
|
16
27
|
export type CreateStickerPayload = {
|
|
17
|
-
|
|
28
|
+
base64: string;
|
|
29
|
+
/** The name of the file (`<name>.webp`). */
|
|
30
|
+
name: string;
|
|
31
|
+
/** @deprecated Ignored by the backend: a created sticker is always `'created'`. */
|
|
32
|
+
type?: string;
|
|
33
|
+
/** @deprecated Ignored by the backend: use `add` to take a sticker from a message. */
|
|
18
34
|
originMessageId?: string;
|
|
35
|
+
/** @deprecated Ignored by the backend. */
|
|
19
36
|
originFileChecksum?: string;
|
|
37
|
+
/** @deprecated Ignored by the backend. */
|
|
20
38
|
originFilehash?: string;
|
|
21
39
|
};
|
|
22
40
|
export type UpdateStickerPayload = {
|
|
23
41
|
type?: string;
|
|
24
42
|
};
|
|
43
|
+
/** Query of `exist`: finds a sticker of the account by the message or by the file it came from. */
|
|
44
|
+
export type StickerExistQuery = {
|
|
45
|
+
messageId: string;
|
|
46
|
+
fileChecksum?: string;
|
|
47
|
+
filehash?: string;
|
|
48
|
+
};
|
|
25
49
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/apis/stickers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/apis/stickers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAE1C,oEAAoE;AACpE,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,2FAA2F;IAC3F,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IACzC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAEzB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,uCAAuC;IACvC,IAAI,CAAC,EAAE,IAAI,CAAA;CACZ,CAAA;AAED,0DAA0D;AAC1D,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,CAAA;AAElD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,0CAA0C;IAC1C,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,0CAA0C;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,mGAAmG;AACnG,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA"}
|
|
@@ -51,8 +51,7 @@ var WhatsappBusinessTemplatesApi = class extends require_core_BaseCrudApi.BaseCr
|
|
|
51
51
|
return this.client.post(`${this.basePath}/refresh-templates`, void 0, headers);
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
-
* Reads the template balance from 360Dialog
|
|
55
|
-
* not only in the account, and calls 360Dialog when it finds one.
|
|
54
|
+
* Reads the template balance from 360Dialog (an external call, when there is a 360Dialog connection).
|
|
56
55
|
* @permissions hsm.view
|
|
57
56
|
*/
|
|
58
57
|
resume(headers) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WhatsappBusinessTemplatesApi.cjs","names":["BaseCrudApi"],"sources":["../../../src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.ts"],"sourcesContent":["import type { ApiClient } from '../../core/ApiClient'\nimport type { ListQuery } from '../../core/types'\nimport { BaseCrudApi } from '../../core/BaseCrudApi'\nimport type {\n WhatsappBusinessTemplate,\n CreateWhatsappBusinessTemplatePayload,\n UpdateWhatsappBusinessTemplatePayload,\n WhatsappBusinessTemplateHsmLimit,\n} from './types'\n\n/**\n * WhatsApp Business templates. Create, update, reads and count are local; `sendToReview`, `refreshTemplates`,\n * `resume` and the delete of a template of a `whatsapp-business` connection call the provider (Meta, 360Dialog).\n * `getById` answers `null` for an unknown id.\n */\nexport class WhatsappBusinessTemplatesApi extends BaseCrudApi<\n WhatsappBusinessTemplate,\n CreateWhatsappBusinessTemplatePayload,\n UpdateWhatsappBusinessTemplatePayload,\n ListQuery<WhatsappBusinessTemplate>,\n unknown\n> {\n constructor(client: ApiClient) {\n super(client, '/whatsapp-business-templates')\n }\n\n /**\n * Counts the templates matching the query.\n * @permissions hsm.view\n */\n count(\n query?: ListQuery<WhatsappBusinessTemplate>,\n headers?: Record<string, string>,\n ): Promise<{ count: number }> {\n return this.client.get<{ count: number }>(\n `${this.basePath}/count${this.toQueryString(query)}`,\n headers,\n )\n }\n\n /**\n * Reads the template limit of the plan of the account. Send the `accountId` of the current user: the route is\n * outside the error handler of the backend, so an unknown id gets no answer (the request waits for the timeout).\n * @permissions hsm.view\n */\n getHsmLimit(\n accountId: string,\n headers?: Record<string, string>,\n ): Promise<WhatsappBusinessTemplateHsmLimit> {\n return this.client.get<WhatsappBusinessTemplateHsmLimit>(\n `${this.basePath}/${accountId}/hsmLimit`,\n headers,\n )\n }\n\n /**\n * Deletes a template. On a `whatsapp-business` connection it goes to the provider (and answers what it answers);\n * a draft of another connection type is deleted locally (answers the stored template). An unknown id answers 500.\n * @permissions hsm.view OR hsm.destroy\n */\n override deleteById(id: string, headers?: Record<string, string>): Promise<unknown> {\n return super.deleteById(id, headers)\n }\n\n /**\n * SENDS the template to Meta for approval (through the provider of the connection). An unknown or archived\n * template answers 500 before anything is sent.\n * @permissions hsm.view OR hsm.send OR hsm.send.before.expire\n */\n sendToReview(id: string, headers?: Record<string, string>): Promise<unknown> {\n return this.client.post<unknown>(`${this.basePath}/${id}/send-to-review`, undefined, headers)\n }\n\n /**\n * Reads the templates of the connected `whatsapp-business` connections from the provider and syncs them (it may\n * archive the local templates the provider no longer has). Resolves the text `'OK'`.\n * @permissions hsm.view\n */\n refreshTemplates(headers?: Record<string, string>): Promise<'OK'> {\n return this.client.post<'OK'>(`${this.basePath}/refresh-templates`, undefined, headers)\n }\n\n /**\n * Reads the template balance from 360Dialog
|
|
1
|
+
{"version":3,"file":"WhatsappBusinessTemplatesApi.cjs","names":["BaseCrudApi"],"sources":["../../../src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.ts"],"sourcesContent":["import type { ApiClient } from '../../core/ApiClient'\nimport type { ListQuery } from '../../core/types'\nimport { BaseCrudApi } from '../../core/BaseCrudApi'\nimport type {\n WhatsappBusinessTemplate,\n CreateWhatsappBusinessTemplatePayload,\n UpdateWhatsappBusinessTemplatePayload,\n WhatsappBusinessTemplateHsmLimit,\n} from './types'\n\n/**\n * WhatsApp Business templates. Create, update, reads and count are local; `sendToReview`, `refreshTemplates`,\n * `resume` and the delete of a template of a `whatsapp-business` connection call the provider (Meta, 360Dialog).\n * `getById` answers `null` for an unknown id.\n */\nexport class WhatsappBusinessTemplatesApi extends BaseCrudApi<\n WhatsappBusinessTemplate,\n CreateWhatsappBusinessTemplatePayload,\n UpdateWhatsappBusinessTemplatePayload,\n ListQuery<WhatsappBusinessTemplate>,\n unknown\n> {\n constructor(client: ApiClient) {\n super(client, '/whatsapp-business-templates')\n }\n\n /**\n * Counts the templates matching the query.\n * @permissions hsm.view\n */\n count(\n query?: ListQuery<WhatsappBusinessTemplate>,\n headers?: Record<string, string>,\n ): Promise<{ count: number }> {\n return this.client.get<{ count: number }>(\n `${this.basePath}/count${this.toQueryString(query)}`,\n headers,\n )\n }\n\n /**\n * Reads the template limit of the plan of the account. Send the `accountId` of the current user: the route is\n * outside the error handler of the backend, so an unknown id gets no answer (the request waits for the timeout).\n * @permissions hsm.view\n */\n getHsmLimit(\n accountId: string,\n headers?: Record<string, string>,\n ): Promise<WhatsappBusinessTemplateHsmLimit> {\n return this.client.get<WhatsappBusinessTemplateHsmLimit>(\n `${this.basePath}/${accountId}/hsmLimit`,\n headers,\n )\n }\n\n /**\n * Deletes a template. On a `whatsapp-business` connection it goes to the provider (and answers what it answers);\n * a draft of another connection type is deleted locally (answers the stored template). An unknown id answers 500.\n * @permissions hsm.view OR hsm.destroy\n */\n override deleteById(id: string, headers?: Record<string, string>): Promise<unknown> {\n return super.deleteById(id, headers)\n }\n\n /**\n * SENDS the template to Meta for approval (through the provider of the connection). An unknown or archived\n * template answers 500 before anything is sent.\n * @permissions hsm.view OR hsm.send OR hsm.send.before.expire\n */\n sendToReview(id: string, headers?: Record<string, string>): Promise<unknown> {\n return this.client.post<unknown>(`${this.basePath}/${id}/send-to-review`, undefined, headers)\n }\n\n /**\n * Reads the templates of the connected `whatsapp-business` connections from the provider and syncs them (it may\n * archive the local templates the provider no longer has). Resolves the text `'OK'`.\n * @permissions hsm.view\n */\n refreshTemplates(headers?: Record<string, string>): Promise<'OK'> {\n return this.client.post<'OK'>(`${this.basePath}/refresh-templates`, undefined, headers)\n }\n\n /**\n * Reads the template balance from 360Dialog (an external call, when there is a 360Dialog connection).\n * @permissions hsm.view\n */\n resume(headers?: Record<string, string>): Promise<Record<string, unknown>[]> {\n return this.client.get<Record<string, unknown>[]>(`${this.basePath}/resume`, headers)\n }\n}\n"],"mappings":";;;;;;;;;AAeA,IAAa,+BAAb,cAAkDA,qCAMhD;CACA,YAAY,QAAmB;AAC7B,QAAM,QAAQ,+BAA+B;;;;;;CAO/C,MACE,OACA,SAC4B;AAC5B,SAAO,KAAK,OAAO,IACjB,GAAG,KAAK,SAAS,QAAQ,KAAK,cAAc,MAAM,IAClD,QACD;;;;;;;CAQH,YACE,WACA,SAC2C;AAC3C,SAAO,KAAK,OAAO,IACjB,GAAG,KAAK,SAAS,GAAG,UAAU,YAC9B,QACD;;;;;;;CAQH,AAAS,WAAW,IAAY,SAAoD;AAClF,SAAO,MAAM,WAAW,IAAI,QAAQ;;;;;;;CAQtC,aAAa,IAAY,SAAoD;AAC3E,SAAO,KAAK,OAAO,KAAc,GAAG,KAAK,SAAS,GAAG,GAAG,kBAAkB,QAAW,QAAQ;;;;;;;CAQ/F,iBAAiB,SAAiD;AAChE,SAAO,KAAK,OAAO,KAAW,GAAG,KAAK,SAAS,qBAAqB,QAAW,QAAQ;;;;;;CAOzF,OAAO,SAAsE;AAC3E,SAAO,KAAK,OAAO,IAA+B,GAAG,KAAK,SAAS,UAAU,QAAQ"}
|
|
@@ -41,8 +41,7 @@ export declare class WhatsappBusinessTemplatesApi extends BaseCrudApi<WhatsappBu
|
|
|
41
41
|
*/
|
|
42
42
|
refreshTemplates(headers?: Record<string, string>): Promise<'OK'>;
|
|
43
43
|
/**
|
|
44
|
-
* Reads the template balance from 360Dialog
|
|
45
|
-
* not only in the account, and calls 360Dialog when it finds one.
|
|
44
|
+
* Reads the template balance from 360Dialog (an external call, when there is a 360Dialog connection).
|
|
46
45
|
* @permissions hsm.view
|
|
47
46
|
*/
|
|
48
47
|
resume(headers?: Record<string, string>): Promise<Record<string, unknown>[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WhatsappBusinessTemplatesApi.d.ts","sourceRoot":"","sources":["../../../src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,EACV,wBAAwB,EACxB,qCAAqC,EACrC,qCAAqC,EACrC,gCAAgC,EACjC,MAAM,SAAS,CAAA;AAEhB;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,WAAW,CAC3D,wBAAwB,EACxB,qCAAqC,EACrC,qCAAqC,EACrC,SAAS,CAAC,wBAAwB,CAAC,EACnC,OAAO,CACR;gBACa,MAAM,EAAE,SAAS;IAI7B;;;OAGG;IACH,KAAK,CACH,KAAK,CAAC,EAAE,SAAS,CAAC,wBAAwB,CAAC,EAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAO7B;;;;OAIG;IACH,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,gCAAgC,CAAC;IAO5C;;;;OAIG;IACM,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAInF;;;;OAIG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5E;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE
|
|
1
|
+
{"version":3,"file":"WhatsappBusinessTemplatesApi.d.ts","sourceRoot":"","sources":["../../../src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,EACV,wBAAwB,EACxB,qCAAqC,EACrC,qCAAqC,EACrC,gCAAgC,EACjC,MAAM,SAAS,CAAA;AAEhB;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,WAAW,CAC3D,wBAAwB,EACxB,qCAAqC,EACrC,qCAAqC,EACrC,SAAS,CAAC,wBAAwB,CAAC,EACnC,OAAO,CACR;gBACa,MAAM,EAAE,SAAS;IAI7B;;;OAGG;IACH,KAAK,CACH,KAAK,CAAC,EAAE,SAAS,CAAC,wBAAwB,CAAC,EAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAO7B;;;;OAIG;IACH,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,gCAAgC,CAAC;IAO5C;;;;OAIG;IACM,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAInF;;;;OAIG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5E;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CAG7E"}
|
|
@@ -50,8 +50,7 @@ var WhatsappBusinessTemplatesApi = class extends BaseCrudApi {
|
|
|
50
50
|
return this.client.post(`${this.basePath}/refresh-templates`, void 0, headers);
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
* Reads the template balance from 360Dialog
|
|
54
|
-
* not only in the account, and calls 360Dialog when it finds one.
|
|
53
|
+
* Reads the template balance from 360Dialog (an external call, when there is a 360Dialog connection).
|
|
55
54
|
* @permissions hsm.view
|
|
56
55
|
*/
|
|
57
56
|
resume(headers) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WhatsappBusinessTemplatesApi.mjs","names":[],"sources":["../../../src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.ts"],"sourcesContent":["import type { ApiClient } from '../../core/ApiClient'\nimport type { ListQuery } from '../../core/types'\nimport { BaseCrudApi } from '../../core/BaseCrudApi'\nimport type {\n WhatsappBusinessTemplate,\n CreateWhatsappBusinessTemplatePayload,\n UpdateWhatsappBusinessTemplatePayload,\n WhatsappBusinessTemplateHsmLimit,\n} from './types'\n\n/**\n * WhatsApp Business templates. Create, update, reads and count are local; `sendToReview`, `refreshTemplates`,\n * `resume` and the delete of a template of a `whatsapp-business` connection call the provider (Meta, 360Dialog).\n * `getById` answers `null` for an unknown id.\n */\nexport class WhatsappBusinessTemplatesApi extends BaseCrudApi<\n WhatsappBusinessTemplate,\n CreateWhatsappBusinessTemplatePayload,\n UpdateWhatsappBusinessTemplatePayload,\n ListQuery<WhatsappBusinessTemplate>,\n unknown\n> {\n constructor(client: ApiClient) {\n super(client, '/whatsapp-business-templates')\n }\n\n /**\n * Counts the templates matching the query.\n * @permissions hsm.view\n */\n count(\n query?: ListQuery<WhatsappBusinessTemplate>,\n headers?: Record<string, string>,\n ): Promise<{ count: number }> {\n return this.client.get<{ count: number }>(\n `${this.basePath}/count${this.toQueryString(query)}`,\n headers,\n )\n }\n\n /**\n * Reads the template limit of the plan of the account. Send the `accountId` of the current user: the route is\n * outside the error handler of the backend, so an unknown id gets no answer (the request waits for the timeout).\n * @permissions hsm.view\n */\n getHsmLimit(\n accountId: string,\n headers?: Record<string, string>,\n ): Promise<WhatsappBusinessTemplateHsmLimit> {\n return this.client.get<WhatsappBusinessTemplateHsmLimit>(\n `${this.basePath}/${accountId}/hsmLimit`,\n headers,\n )\n }\n\n /**\n * Deletes a template. On a `whatsapp-business` connection it goes to the provider (and answers what it answers);\n * a draft of another connection type is deleted locally (answers the stored template). An unknown id answers 500.\n * @permissions hsm.view OR hsm.destroy\n */\n override deleteById(id: string, headers?: Record<string, string>): Promise<unknown> {\n return super.deleteById(id, headers)\n }\n\n /**\n * SENDS the template to Meta for approval (through the provider of the connection). An unknown or archived\n * template answers 500 before anything is sent.\n * @permissions hsm.view OR hsm.send OR hsm.send.before.expire\n */\n sendToReview(id: string, headers?: Record<string, string>): Promise<unknown> {\n return this.client.post<unknown>(`${this.basePath}/${id}/send-to-review`, undefined, headers)\n }\n\n /**\n * Reads the templates of the connected `whatsapp-business` connections from the provider and syncs them (it may\n * archive the local templates the provider no longer has). Resolves the text `'OK'`.\n * @permissions hsm.view\n */\n refreshTemplates(headers?: Record<string, string>): Promise<'OK'> {\n return this.client.post<'OK'>(`${this.basePath}/refresh-templates`, undefined, headers)\n }\n\n /**\n * Reads the template balance from 360Dialog
|
|
1
|
+
{"version":3,"file":"WhatsappBusinessTemplatesApi.mjs","names":[],"sources":["../../../src/apis/whatsappBusinessTemplates/WhatsappBusinessTemplatesApi.ts"],"sourcesContent":["import type { ApiClient } from '../../core/ApiClient'\nimport type { ListQuery } from '../../core/types'\nimport { BaseCrudApi } from '../../core/BaseCrudApi'\nimport type {\n WhatsappBusinessTemplate,\n CreateWhatsappBusinessTemplatePayload,\n UpdateWhatsappBusinessTemplatePayload,\n WhatsappBusinessTemplateHsmLimit,\n} from './types'\n\n/**\n * WhatsApp Business templates. Create, update, reads and count are local; `sendToReview`, `refreshTemplates`,\n * `resume` and the delete of a template of a `whatsapp-business` connection call the provider (Meta, 360Dialog).\n * `getById` answers `null` for an unknown id.\n */\nexport class WhatsappBusinessTemplatesApi extends BaseCrudApi<\n WhatsappBusinessTemplate,\n CreateWhatsappBusinessTemplatePayload,\n UpdateWhatsappBusinessTemplatePayload,\n ListQuery<WhatsappBusinessTemplate>,\n unknown\n> {\n constructor(client: ApiClient) {\n super(client, '/whatsapp-business-templates')\n }\n\n /**\n * Counts the templates matching the query.\n * @permissions hsm.view\n */\n count(\n query?: ListQuery<WhatsappBusinessTemplate>,\n headers?: Record<string, string>,\n ): Promise<{ count: number }> {\n return this.client.get<{ count: number }>(\n `${this.basePath}/count${this.toQueryString(query)}`,\n headers,\n )\n }\n\n /**\n * Reads the template limit of the plan of the account. Send the `accountId` of the current user: the route is\n * outside the error handler of the backend, so an unknown id gets no answer (the request waits for the timeout).\n * @permissions hsm.view\n */\n getHsmLimit(\n accountId: string,\n headers?: Record<string, string>,\n ): Promise<WhatsappBusinessTemplateHsmLimit> {\n return this.client.get<WhatsappBusinessTemplateHsmLimit>(\n `${this.basePath}/${accountId}/hsmLimit`,\n headers,\n )\n }\n\n /**\n * Deletes a template. On a `whatsapp-business` connection it goes to the provider (and answers what it answers);\n * a draft of another connection type is deleted locally (answers the stored template). An unknown id answers 500.\n * @permissions hsm.view OR hsm.destroy\n */\n override deleteById(id: string, headers?: Record<string, string>): Promise<unknown> {\n return super.deleteById(id, headers)\n }\n\n /**\n * SENDS the template to Meta for approval (through the provider of the connection). An unknown or archived\n * template answers 500 before anything is sent.\n * @permissions hsm.view OR hsm.send OR hsm.send.before.expire\n */\n sendToReview(id: string, headers?: Record<string, string>): Promise<unknown> {\n return this.client.post<unknown>(`${this.basePath}/${id}/send-to-review`, undefined, headers)\n }\n\n /**\n * Reads the templates of the connected `whatsapp-business` connections from the provider and syncs them (it may\n * archive the local templates the provider no longer has). Resolves the text `'OK'`.\n * @permissions hsm.view\n */\n refreshTemplates(headers?: Record<string, string>): Promise<'OK'> {\n return this.client.post<'OK'>(`${this.basePath}/refresh-templates`, undefined, headers)\n }\n\n /**\n * Reads the template balance from 360Dialog (an external call, when there is a 360Dialog connection).\n * @permissions hsm.view\n */\n resume(headers?: Record<string, string>): Promise<Record<string, unknown>[]> {\n return this.client.get<Record<string, unknown>[]>(`${this.basePath}/resume`, headers)\n }\n}\n"],"mappings":";;;;;;;;AAeA,IAAa,+BAAb,cAAkD,YAMhD;CACA,YAAY,QAAmB;AAC7B,QAAM,QAAQ,+BAA+B;;;;;;CAO/C,MACE,OACA,SAC4B;AAC5B,SAAO,KAAK,OAAO,IACjB,GAAG,KAAK,SAAS,QAAQ,KAAK,cAAc,MAAM,IAClD,QACD;;;;;;;CAQH,YACE,WACA,SAC2C;AAC3C,SAAO,KAAK,OAAO,IACjB,GAAG,KAAK,SAAS,GAAG,UAAU,YAC9B,QACD;;;;;;;CAQH,AAAS,WAAW,IAAY,SAAoD;AAClF,SAAO,MAAM,WAAW,IAAI,QAAQ;;;;;;;CAQtC,aAAa,IAAY,SAAoD;AAC3E,SAAO,KAAK,OAAO,KAAc,GAAG,KAAK,SAAS,GAAG,GAAG,kBAAkB,QAAW,QAAQ;;;;;;;CAQ/F,iBAAiB,SAAiD;AAChE,SAAO,KAAK,OAAO,KAAW,GAAG,KAAK,SAAS,qBAAqB,QAAW,QAAQ;;;;;;CAOzF,OAAO,SAAsE;AAC3E,SAAO,KAAK,OAAO,IAA+B,GAAG,KAAK,SAAS,UAAU,QAAQ"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { AbsenceApi } from './AbsenceApi'
|
|
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
|
+
requestRaw: 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('AbsenceApi', () => {
|
|
23
|
+
let client: ReturnType<typeof createMockClient>
|
|
24
|
+
let api: AbsenceApi
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
client = createMockClient()
|
|
28
|
+
api = new AbsenceApi(client)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('report serializes the query of the report', async () => {
|
|
32
|
+
vi.mocked(client.get).mockResolvedValue({ data: [] })
|
|
33
|
+
await api.report({
|
|
34
|
+
filters: { reason: 'Almoço' },
|
|
35
|
+
sort: 'createdAt',
|
|
36
|
+
order: 'ASC',
|
|
37
|
+
perPage: 50,
|
|
38
|
+
})
|
|
39
|
+
const url = vi.mocked(client.get).mock.calls[0]?.[0] as string
|
|
40
|
+
expect(url).toMatch(/^\/absence\?/)
|
|
41
|
+
expect(decodeURIComponent(url)).toContain('"filters":{"reason":"Almoço"}')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('findOpenAbsence calls client.get with /absence/find-open-absence', async () => {
|
|
45
|
+
vi.mocked(client.get).mockResolvedValue(null)
|
|
46
|
+
await expect(api.findOpenAbsence()).resolves.toBeNull()
|
|
47
|
+
expect(client.get).toHaveBeenCalledWith('/absence/find-open-absence', undefined)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('unlock posts the body to /absence/unlock', async () => {
|
|
51
|
+
vi.mocked(client.post).mockResolvedValue({ success: false, message: 'INVALID_REASON' })
|
|
52
|
+
await expect(api.unlock({ reason: 'Voltei' })).resolves.toEqual({
|
|
53
|
+
success: false,
|
|
54
|
+
message: 'INVALID_REASON',
|
|
55
|
+
})
|
|
56
|
+
expect(client.post).toHaveBeenCalledWith('/absence/unlock', { reason: 'Voltei' }, undefined)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('exportCsv calls client.get with /absence/export-csv and the query', async () => {
|
|
60
|
+
vi.mocked(client.get).mockResolvedValue('Usuário,De,Até,Motivo')
|
|
61
|
+
await api.exportCsv({ timezone: 'America/Sao_Paulo' })
|
|
62
|
+
const url = vi.mocked(client.get).mock.calls[0]?.[0] as string
|
|
63
|
+
expect(url).toMatch(/^\/absence\/export-csv\?/)
|
|
64
|
+
})
|
|
65
|
+
})
|
|
@@ -1,17 +1,90 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
|
-
import type { GetByIdQuery } from '../../core/types'
|
|
4
|
-
import type {
|
|
3
|
+
import type { GetByIdQuery, Paginated } from '../../core/types'
|
|
4
|
+
import type {
|
|
5
|
+
Absence,
|
|
6
|
+
AbsenceReportItem,
|
|
7
|
+
AbsenceReportQuery,
|
|
8
|
+
CreateAbsencePayload,
|
|
9
|
+
UnlockAbsencePayload,
|
|
10
|
+
UnlockAbsenceResponse,
|
|
11
|
+
UpdateAbsencePayload,
|
|
12
|
+
} from './types'
|
|
5
13
|
|
|
6
14
|
/**
|
|
7
|
-
* Absences of the users. The backend serves the report (`GET /absence
|
|
8
|
-
* `
|
|
15
|
+
* Absences of the users. The backend serves the report (`GET /absence`, `GET /absence/export-csv`),
|
|
16
|
+
* `GET /absence/find-open-absence`, `POST /absence`, `POST /absence/unlock` and `PUT /absence/:id`; there is
|
|
17
|
+
* no read by id nor delete. Creating an absence sets the status of the user to `away` and `unlock` sets it
|
|
18
|
+
* back to `online` (both emit `user.updated` to the webhooks).
|
|
9
19
|
*/
|
|
10
20
|
export class AbsenceApi extends BaseCrudApi<Absence, CreateAbsencePayload, UpdateAbsencePayload> {
|
|
11
21
|
constructor(client: ApiClient) {
|
|
12
22
|
super(client, '/absence')
|
|
13
23
|
}
|
|
14
24
|
|
|
25
|
+
/**
|
|
26
|
+
* The absence report of the account (`GET /absence`), always paginated, with its own query (the rows are
|
|
27
|
+
* raw: see `AbsenceReportItem`). Prefer it to `getMany`, whose `where`/`include`/`paginate` the backend
|
|
28
|
+
* ignores. Requires both permissions, always: without them it answers 403
|
|
29
|
+
* `MISSING_ABSENCE_REPORT_PERMISSION`.
|
|
30
|
+
* @permissions overview.absence.view AND myAccount.absence
|
|
31
|
+
*/
|
|
32
|
+
report(
|
|
33
|
+
query?: AbsenceReportQuery,
|
|
34
|
+
headers?: Record<string, string>,
|
|
35
|
+
): Promise<Paginated<AbsenceReportItem>> {
|
|
36
|
+
return this.client.get<Paginated<AbsenceReportItem>>(
|
|
37
|
+
`${this.basePath}${this.toQueryString(query)}`,
|
|
38
|
+
headers,
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates an absence for the current user (whatever `userId` says) and sets the user `away`. Resolves the
|
|
44
|
+
* stored absence (raw, without `user`).
|
|
45
|
+
* @permissions myAccount.absence
|
|
46
|
+
*/
|
|
47
|
+
override create(body: CreateAbsencePayload, headers?: Record<string, string>): Promise<Absence> {
|
|
48
|
+
return super.create(body, headers)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The open absence of the current user, or `null` — also `null` while `settings.absence.enabled` is off.
|
|
53
|
+
* @permissions myAccount.absence
|
|
54
|
+
*/
|
|
55
|
+
findOpenAbsence(headers?: Record<string, string>): Promise<AbsenceReportItem | null> {
|
|
56
|
+
return this.client.get<AbsenceReportItem | null>(`${this.basePath}/find-open-absence`, headers)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Ends an absence (the open one of the user when `id` is absent) and sets the user `online`. The refusals
|
|
61
|
+
* of `settings.absence` come with status 200 (`INVALID_REASON`, `INVALID_PASSWORD`); without an open
|
|
62
|
+
* absence it answers 500.
|
|
63
|
+
* @permissions myAccount.absence
|
|
64
|
+
*/
|
|
65
|
+
unlock(
|
|
66
|
+
body: UnlockAbsencePayload,
|
|
67
|
+
headers?: Record<string, string>,
|
|
68
|
+
): Promise<UnlockAbsenceResponse> {
|
|
69
|
+
return this.client.post<UnlockAbsenceResponse, UnlockAbsencePayload>(
|
|
70
|
+
`${this.basePath}/unlock`,
|
|
71
|
+
body,
|
|
72
|
+
headers,
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Exports the report as CSV (`Usuário, De, Até, Motivo`; an open absence shows `Em andamento`), sent as
|
|
78
|
+
* the attachment `<yyyy-MM-dd>_absence-control.csv`.
|
|
79
|
+
* @permissions overview.absence.view AND myAccount.absence
|
|
80
|
+
*/
|
|
81
|
+
exportCsv(query?: AbsenceReportQuery, headers?: Record<string, string>): Promise<string> {
|
|
82
|
+
return this.client.get<string>(
|
|
83
|
+
`${this.basePath}/export-csv${this.toQueryString(query)}`,
|
|
84
|
+
headers,
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
15
88
|
/** @deprecated Not served: the backend has no GET /absence/:id, so this route answers 404. */
|
|
16
89
|
override getById(
|
|
17
90
|
id: string,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { User } from '../users'
|
|
2
2
|
|
|
3
|
+
/** An absence as `PUT /absence/:id` answers it (the transformer of the backend). */
|
|
3
4
|
export type Absence = {
|
|
4
5
|
id: string
|
|
5
6
|
accountId: string
|
|
@@ -8,7 +9,8 @@ export type Absence = {
|
|
|
8
9
|
endedAt: string | null
|
|
9
10
|
createdAt: string
|
|
10
11
|
updatedAt: string
|
|
11
|
-
|
|
12
|
+
/** @deprecated Not a field of the backend: the model has no soft delete. */
|
|
13
|
+
deletedAt?: string | null
|
|
12
14
|
// relationships
|
|
13
15
|
user?: User
|
|
14
16
|
}
|
|
@@ -16,7 +18,9 @@ export type Absence = {
|
|
|
16
18
|
export type AbsenceRelationships = 'user'
|
|
17
19
|
|
|
18
20
|
export type CreateAbsencePayload = {
|
|
19
|
-
|
|
21
|
+
/** Ignored: the backend creates the absence for the current user. */
|
|
22
|
+
userId?: string
|
|
23
|
+
/** Up to 255 characters. */
|
|
20
24
|
reason?: string
|
|
21
25
|
}
|
|
22
26
|
|
|
@@ -24,3 +28,50 @@ export type UpdateAbsencePayload = {
|
|
|
24
28
|
reason?: string
|
|
25
29
|
endedAt?: string | null
|
|
26
30
|
}
|
|
31
|
+
|
|
32
|
+
/** Columns the report can be sorted by (an unknown one falls back to the default order). */
|
|
33
|
+
export type AbsenceReportSortField = 'user' | 'createdAt' | 'endedAt'
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Query of the absence report (`GET /absence` and `GET /absence/export-csv`). The backend ignores
|
|
37
|
+
* `where` and `include`: it reads only these fields.
|
|
38
|
+
*/
|
|
39
|
+
export type AbsenceReportQuery = {
|
|
40
|
+
filters?: {
|
|
41
|
+
userId?: string
|
|
42
|
+
reason?: string
|
|
43
|
+
/** Absences created at or after this date. An invalid date answers 400 `Invalid date.`. */
|
|
44
|
+
createdAt?: string
|
|
45
|
+
/** Absences ended at or before this date. */
|
|
46
|
+
endedAt?: string
|
|
47
|
+
}
|
|
48
|
+
sort?: AbsenceReportSortField
|
|
49
|
+
/** Only `'ASC'` sorts ascending: any other value sorts descending. */
|
|
50
|
+
order?: 'ASC' | 'DESC'
|
|
51
|
+
page?: number
|
|
52
|
+
/** Up to 200 (a larger value is clamped, not refused). Defaults to 15. */
|
|
53
|
+
perPage?: number
|
|
54
|
+
/** IANA zone of the dates of the CSV export (e.g. `America/Sao_Paulo`). */
|
|
55
|
+
timezone?: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A row of the report: the stored absence with its user, both raw (not transformed).
|
|
60
|
+
*/
|
|
61
|
+
export type AbsenceReportItem = Omit<Absence, 'deletedAt' | 'user'> & {
|
|
62
|
+
user?: Record<string, unknown>
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The body of `unlock`: the absence to end (the open one of the user when `id` is absent). */
|
|
66
|
+
export type UnlockAbsencePayload = {
|
|
67
|
+
id?: string
|
|
68
|
+
/** Required when `settings.absence.reason_required` is on. */
|
|
69
|
+
reason?: string
|
|
70
|
+
/** Required when `settings.absence.password_required` is on: the password of the user. */
|
|
71
|
+
password?: string
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** What `unlock` answers: the business refusals come with status 200. */
|
|
75
|
+
export type UnlockAbsenceResponse =
|
|
76
|
+
| { success: true }
|
|
77
|
+
| { success: false; message: 'INVALID_REASON' | 'INVALID_PASSWORD' }
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { ActivityLogApi } from './ActivityLogApi'
|
|
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
|
+
requestRaw: 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('ActivityLogApi', () => {
|
|
23
|
+
let client: ReturnType<typeof createMockClient>
|
|
24
|
+
let api: ActivityLogApi
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
client = createMockClient()
|
|
28
|
+
api = new ActivityLogApi(client)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('exportCsv calls client.get with /log/export-csv and the period', async () => {
|
|
32
|
+
vi.mocked(client.get).mockResolvedValue('csv')
|
|
33
|
+
await api.exportCsv({ filters: { from: '2026-10-01', to: '2026-10-17' } })
|
|
34
|
+
const url = vi.mocked(client.get).mock.calls[0]?.[0] as string
|
|
35
|
+
expect(url).toMatch(/^\/log\/export-csv\?/)
|
|
36
|
+
expect(decodeURIComponent(url)).toContain('"from":"2026-10-01"')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('create posts the stored fields of the log', async () => {
|
|
40
|
+
const body = { resourceType: 'contact', resourceId: 'c-1', event: 'update', data: { a: 1 } }
|
|
41
|
+
await api.create(body)
|
|
42
|
+
expect(client.post).toHaveBeenCalledWith('/log', body, undefined)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -1,20 +1,39 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
ActivityLog,
|
|
5
|
+
ActivityLogListQuery,
|
|
6
|
+
CreateActivityLogPayload,
|
|
7
|
+
UpdateActivityLogPayload,
|
|
8
|
+
} from './types'
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
11
|
* 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
|
|
12
|
+
* The backend serves `GET /log`, `GET /log/export-csv`, `GET /log/:id` and `POST /log`; there is no update
|
|
13
|
+
* or delete, so an entry created is permanent. `GET /log/:id` takes a MongoDB
|
|
14
|
+
* id (an UUID answers 500).
|
|
8
15
|
*/
|
|
9
16
|
export class ActivityLogApi extends BaseCrudApi<
|
|
10
17
|
ActivityLog,
|
|
11
18
|
CreateActivityLogPayload,
|
|
12
|
-
UpdateActivityLogPayload
|
|
19
|
+
UpdateActivityLogPayload,
|
|
20
|
+
ActivityLogListQuery
|
|
13
21
|
> {
|
|
14
22
|
constructor(client: ApiClient) {
|
|
15
23
|
super(client, '/log')
|
|
16
24
|
}
|
|
17
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Exports the entries of the period (`filters.from`/`filters.to`) as CSV, sent as the attachment
|
|
28
|
+
* `exportation.csv`.
|
|
29
|
+
*/
|
|
30
|
+
exportCsv(query: ActivityLogListQuery, headers?: Record<string, string>): Promise<string> {
|
|
31
|
+
return this.client.get<string>(
|
|
32
|
+
`${this.basePath}/export-csv${this.toQueryString(query)}`,
|
|
33
|
+
headers,
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
18
37
|
/** @deprecated Not served: the backend has no PUT /log/:id, so this route answers 404. */
|
|
19
38
|
override updateById(
|
|
20
39
|
id: string,
|
|
@@ -1,22 +1,61 @@
|
|
|
1
|
+
import type { ListQuery } from '../../core/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An entry of the activity log (MongoDB). The stored fields are `resourceType`, `resourceId`, `event`,
|
|
5
|
+
* `userId`, `accessTokenId` and `data`. `create` and `getById` answer through a transformer that keeps only
|
|
6
|
+
* `id`, `accountId`, `createdAt` and `updatedAt`; the list answers every stored field plus `user`.
|
|
7
|
+
*/
|
|
1
8
|
export type ActivityLog = {
|
|
2
9
|
id: string
|
|
3
10
|
accountId: string
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
resourceType?: string
|
|
12
|
+
resourceId?: string | null
|
|
13
|
+
event?: string
|
|
14
|
+
userId?: string | null
|
|
15
|
+
accessTokenId?: string | null
|
|
16
|
+
data?: Record<string, unknown>
|
|
9
17
|
createdAt: string
|
|
10
18
|
updatedAt: string
|
|
19
|
+
/** On the list: the user of the entry. */
|
|
20
|
+
user?: { id: string; name: string }
|
|
21
|
+
/** @deprecated Not a field of the backend (it is dropped on create): use `event`. */
|
|
22
|
+
action?: string
|
|
23
|
+
/** @deprecated Not a field of the backend (it is dropped on create): use `resourceType`. */
|
|
24
|
+
entity?: string
|
|
25
|
+
/** @deprecated Not a field of the backend (it is dropped on create): use `resourceId`. */
|
|
26
|
+
entityId?: string | null
|
|
11
27
|
}
|
|
12
28
|
|
|
13
29
|
export type CreateActivityLogPayload = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
30
|
+
resourceType?: string
|
|
31
|
+
resourceId?: string
|
|
32
|
+
event?: string
|
|
33
|
+
userId?: string
|
|
34
|
+
accessTokenId?: string
|
|
17
35
|
data?: Record<string, unknown>
|
|
36
|
+
/** @deprecated Dropped by the backend (not a field of the log): use `event`. */
|
|
37
|
+
action?: string
|
|
38
|
+
/** @deprecated Dropped by the backend (not a field of the log): use `resourceType`. */
|
|
39
|
+
entity?: string
|
|
40
|
+
/** @deprecated Dropped by the backend (not a field of the log): use `resourceId`. */
|
|
41
|
+
entityId?: string
|
|
18
42
|
}
|
|
19
43
|
|
|
20
44
|
export type UpdateActivityLogPayload = {
|
|
21
45
|
data?: Record<string, unknown>
|
|
22
46
|
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Query of the list and of the CSV export. The backend requires `filters.from` and `filters.to` (the
|
|
50
|
+
* period of `createdAt`); the other `filters` match the stored fields.
|
|
51
|
+
*/
|
|
52
|
+
export type ActivityLogListQuery = ListQuery<ActivityLog> & {
|
|
53
|
+
filters?: {
|
|
54
|
+
from?: string
|
|
55
|
+
to?: string
|
|
56
|
+
resourceType?: string
|
|
57
|
+
resourceId?: string
|
|
58
|
+
event?: string
|
|
59
|
+
userId?: string
|
|
60
|
+
}
|
|
61
|
+
}
|