@vulog/aima-business 1.2.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/index.cjs +668 -0
  2. package/dist/index.d.cts +346 -0
  3. package/dist/index.d.mts +346 -0
  4. package/dist/index.mjs +609 -0
  5. package/package.json +42 -0
  6. package/src/addBusinessCredit.ts +31 -0
  7. package/src/addStripePayment.ts +18 -0
  8. package/src/addTripNote.test.ts +67 -0
  9. package/src/addTripNote.ts +30 -0
  10. package/src/addUserToBusiness.test.ts +74 -0
  11. package/src/addUserToBusiness.ts +49 -0
  12. package/src/archiveBusinessProfile.ts +28 -0
  13. package/src/bulkAddBusinessUsers.ts +27 -0
  14. package/src/businessDelegatedAdmin.test.ts +68 -0
  15. package/src/businessDelegatedAdmin.ts +32 -0
  16. package/src/businessOwner.test.ts +68 -0
  17. package/src/businessOwner.ts +32 -0
  18. package/src/chargeBusinessProduct.ts +31 -0
  19. package/src/createBusiness.test.ts +54 -0
  20. package/src/createBusiness.ts +23 -0
  21. package/src/createBusinessCostCenter.test.ts +61 -0
  22. package/src/createBusinessCostCenter.ts +34 -0
  23. package/src/deactivateBusinessProfile.ts +22 -0
  24. package/src/deleteBusinessCostCenter.test.ts +45 -0
  25. package/src/deleteBusinessCostCenter.ts +23 -0
  26. package/src/deleteInvitationRequest.test.ts +45 -0
  27. package/src/deleteInvitationRequest.ts +13 -0
  28. package/src/getBillingGroups.ts +9 -0
  29. package/src/getBusinessById.test.ts +47 -0
  30. package/src/getBusinessById.ts +15 -0
  31. package/src/getBusinessContacts.ts +17 -0
  32. package/src/getBusinessCostCenterById.ts +27 -0
  33. package/src/getBusinessCostCenters.ts +18 -0
  34. package/src/getBusinessInviteLink.ts +17 -0
  35. package/src/getBusinessInvoiceProducts.ts +24 -0
  36. package/src/getBusinessInvoiceTrips.ts +20 -0
  37. package/src/getBusinessInvoices.test.ts +92 -0
  38. package/src/getBusinessInvoices.ts +43 -0
  39. package/src/getBusinessPaymentDetails.ts +20 -0
  40. package/src/getBusinessProducts.ts +9 -0
  41. package/src/getBusinessTripById.ts +15 -0
  42. package/src/getBusinessUserById.ts +26 -0
  43. package/src/getBusinessUserGlobalById.ts +15 -0
  44. package/src/getBusinessUsers.test.ts +70 -0
  45. package/src/getBusinessUsers.ts +43 -0
  46. package/src/getBusinessWallet.test.ts +46 -0
  47. package/src/getBusinessWallet.ts +17 -0
  48. package/src/getBusinesses.test.ts +133 -0
  49. package/src/getBusinesses.ts +36 -0
  50. package/src/getEntityBalance.ts +17 -0
  51. package/src/getEntityProducts.ts +15 -0
  52. package/src/getEntityTrips.ts +13 -0
  53. package/src/getEntityTripsCost.ts +17 -0
  54. package/src/getInvitationRequest.test.ts +46 -0
  55. package/src/getInvitationRequest.ts +17 -0
  56. package/src/getInvoicePdf.test.ts +62 -0
  57. package/src/getInvoicePdf.ts +16 -0
  58. package/src/getInvoiceRefundNote.ts +17 -0
  59. package/src/getInvoiceRefundableAmount.ts +20 -0
  60. package/src/getOngoingTripNotes.ts +17 -0
  61. package/src/getOngoingTrips.test.ts +43 -0
  62. package/src/getOngoingTrips.ts +9 -0
  63. package/src/getStripePublishableKey.ts +9 -0
  64. package/src/getStripeSetup.ts +17 -0
  65. package/src/index.ts +58 -0
  66. package/src/inviteBusinessUser.ts +31 -0
  67. package/src/listBusinessUsersGlobal.test.ts +65 -0
  68. package/src/listBusinessUsersGlobal.ts +26 -0
  69. package/src/redeemBusinessPromoCode.ts +18 -0
  70. package/src/refundInvoice.test.ts +72 -0
  71. package/src/refundInvoice.ts +33 -0
  72. package/src/refundInvoiceAmount.ts +20 -0
  73. package/src/searchBusinessUsersByName.ts +27 -0
  74. package/src/searchBusinessUsersGlobal.ts +18 -0
  75. package/src/sendBusinessIban.ts +29 -0
  76. package/src/setInvoiceExternalPayment.ts +33 -0
  77. package/src/types.ts +163 -0
  78. package/src/updateBusiness.test.ts +65 -0
  79. package/src/updateBusiness.ts +35 -0
  80. package/src/updateBusinessCostCenter.ts +41 -0
  81. package/src/updateBusinessProfileStatus.ts +22 -0
  82. package/src/updateBusinessUserProfile.ts +51 -0
  83. package/src/updateInvoiceStatus.test.ts +54 -0
  84. package/src/updateInvoiceStatus.ts +19 -0
  85. package/tsconfig.json +9 -0
  86. package/tsdown.config.ts +8 -0
  87. package/vitest.config.ts +1 -0
@@ -0,0 +1,61 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+
3
+ import { Client } from '@vulog/aima-client';
4
+ import { createBusinessCostCenter } from './createBusinessCostCenter';
5
+ import { CostCenter } from './types';
6
+
7
+ describe('createBusinessCostCenter', () => {
8
+ const postMock = vi.fn();
9
+ const client = {
10
+ post: postMock,
11
+ clientOptions: {
12
+ fleetId: 'FLEET_ID',
13
+ },
14
+ } as unknown as Client;
15
+
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ });
19
+
20
+ test('should throw for invalid businessId', async () => {
21
+ await expect(
22
+ createBusinessCostCenter(client, 'bad-id', { name: 'Test' })
23
+ ).rejects.toThrow(TypeError);
24
+ });
25
+
26
+ test('should throw for empty name', async () => {
27
+ await expect(
28
+ createBusinessCostCenter(client, '550e8400-e29b-41d4-a716-446655440000', { name: '' })
29
+ ).rejects.toThrow(TypeError);
30
+ });
31
+
32
+ test('should throw for name exceeding 255 characters', async () => {
33
+ await expect(
34
+ createBusinessCostCenter(client, '550e8400-e29b-41d4-a716-446655440000', {
35
+ name: 'a'.repeat(256),
36
+ })
37
+ ).rejects.toThrow(TypeError);
38
+ });
39
+
40
+ test('should create cost center with valid args', async () => {
41
+ const businessId = '550e8400-e29b-41d4-a716-446655440000';
42
+ const body = { name: 'Marketing' };
43
+
44
+ const mockResponse: CostCenter = {
45
+ id: '660e8400-e29b-41d4-a716-446655440000',
46
+ name: 'Marketing',
47
+ businessId,
48
+ };
49
+
50
+ postMock.mockResolvedValueOnce({
51
+ data: mockResponse,
52
+ });
53
+
54
+ const result = await createBusinessCostCenter(client, businessId, body);
55
+ expect(result).toEqual(mockResponse);
56
+ expect(postMock).toBeCalledWith(
57
+ `/boapi/proxy/business/fleets/FLEET_ID/business/${businessId}/costcenter`,
58
+ { name: 'Marketing' }
59
+ );
60
+ });
61
+ });
@@ -0,0 +1,34 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { CostCenter } from './types';
5
+
6
+ export type CreateCostCenterBody = {
7
+ name: string;
8
+ };
9
+
10
+ const schema = z.object({
11
+ businessId: z.string().trim().min(1).uuid(),
12
+ name: z.string().trim().min(1).max(255),
13
+ });
14
+
15
+ export const createBusinessCostCenter = async (
16
+ client: Client,
17
+ businessId: string,
18
+ body: CreateCostCenterBody
19
+ ): Promise<CostCenter> => {
20
+ const result = schema.safeParse({ businessId, ...body });
21
+ if (!result.success) {
22
+ throw new TypeError('Invalid args', {
23
+ cause: result.error.issues,
24
+ });
25
+ }
26
+ return client
27
+ .post<CostCenter>(
28
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data.businessId}/costcenter`,
29
+ {
30
+ name: result.data.name,
31
+ }
32
+ )
33
+ .then(({ data }) => data);
34
+ };
@@ -0,0 +1,22 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ const uuidSchema = z.string().trim().min(1).uuid();
5
+
6
+ export const deactivateBusinessProfile = async (
7
+ client: Client,
8
+ businessId: string,
9
+ profileId: string
10
+ ): Promise<void> => {
11
+ const parsedBusinessId = uuidSchema.safeParse(businessId);
12
+ const parsedProfileId = uuidSchema.safeParse(profileId);
13
+ if (!parsedBusinessId.success || !parsedProfileId.success) {
14
+ throw new TypeError('Invalid args', {
15
+ cause: [...(parsedBusinessId.error?.issues ?? []), ...(parsedProfileId.error?.issues ?? [])],
16
+ });
17
+ }
18
+
19
+ await client.post<void>(
20
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${parsedBusinessId.data}/profiles/${parsedProfileId.data}/deactivate`
21
+ );
22
+ };
@@ -0,0 +1,45 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+
3
+ import { Client } from '@vulog/aima-client';
4
+ import { deleteBusinessCostCenter } from './deleteBusinessCostCenter';
5
+
6
+ describe('deleteBusinessCostCenter', () => {
7
+ const deleteMock = vi.fn();
8
+ const client = {
9
+ delete: deleteMock,
10
+ clientOptions: {
11
+ fleetId: 'FLEET_ID',
12
+ },
13
+ } as unknown as Client;
14
+
15
+ beforeEach(() => {
16
+ vi.clearAllMocks();
17
+ });
18
+
19
+ test('should throw for invalid businessId', async () => {
20
+ await expect(
21
+ deleteBusinessCostCenter(client, 'bad-id', '550e8400-e29b-41d4-a716-446655440000')
22
+ ).rejects.toThrow(TypeError);
23
+ });
24
+
25
+ test('should throw for invalid costCenterId', async () => {
26
+ await expect(
27
+ deleteBusinessCostCenter(client, '550e8400-e29b-41d4-a716-446655440000', 'bad-id')
28
+ ).rejects.toThrow(TypeError);
29
+ });
30
+
31
+ test('should delete cost center with valid args', async () => {
32
+ const businessId = '550e8400-e29b-41d4-a716-446655440000';
33
+ const costCenterId = '660e8400-e29b-41d4-a716-446655440000';
34
+
35
+ deleteMock.mockResolvedValueOnce({
36
+ data: undefined,
37
+ });
38
+
39
+ const result = await deleteBusinessCostCenter(client, businessId, costCenterId);
40
+ expect(result).toBeUndefined();
41
+ expect(deleteMock).toBeCalledWith(
42
+ `/boapi/proxy/business/fleets/FLEET_ID/business/${businessId}/costcenter/${costCenterId}`
43
+ );
44
+ });
45
+ });
@@ -0,0 +1,23 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ const schema = z.object({
5
+ businessId: z.string().trim().min(1).uuid(),
6
+ costCenterId: z.string().trim().min(1).uuid(),
7
+ });
8
+
9
+ export const deleteBusinessCostCenter = async (
10
+ client: Client,
11
+ businessId: string,
12
+ costCenterId: string
13
+ ): Promise<void> => {
14
+ const result = schema.safeParse({ businessId, costCenterId });
15
+ if (!result.success) {
16
+ throw new TypeError('Invalid args', {
17
+ cause: result.error.issues,
18
+ });
19
+ }
20
+ await client.delete(
21
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data.businessId}/costcenter/${result.data.costCenterId}`
22
+ );
23
+ };
@@ -0,0 +1,45 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+ import { Client } from '@vulog/aima-client';
3
+ import { deleteInvitationRequest } from './deleteInvitationRequest';
4
+
5
+ describe('deleteInvitationRequest', () => {
6
+ const deleteMock = vi.fn();
7
+ const client = {
8
+ delete: deleteMock,
9
+ clientOptions: {
10
+ fleetId: 'FLEET_ID',
11
+ },
12
+ } as unknown as Client;
13
+
14
+ beforeEach(() => {
15
+ vi.clearAllMocks();
16
+ });
17
+
18
+ const INVITATION_ID = '550e8400-e29b-41d4-a716-446655440000';
19
+
20
+ test('should delete invitation request with valid id', async () => {
21
+ deleteMock.mockResolvedValueOnce({ data: undefined });
22
+
23
+ const result = await deleteInvitationRequest(client, INVITATION_ID);
24
+
25
+ expect(result).toBeUndefined();
26
+ expect(deleteMock).toHaveBeenCalledWith(
27
+ `/boapi/proxy/business/fleets/FLEET_ID/invitationRequest/${INVITATION_ID}`
28
+ );
29
+ });
30
+
31
+ test('should throw for empty invitationId', async () => {
32
+ await expect(deleteInvitationRequest(client, '')).rejects.toThrow(TypeError);
33
+ expect(deleteMock).not.toHaveBeenCalled();
34
+ });
35
+
36
+ test('should throw for non-uuid invitationId', async () => {
37
+ await expect(deleteInvitationRequest(client, 'not-a-uuid')).rejects.toThrow(TypeError);
38
+ expect(deleteMock).not.toHaveBeenCalled();
39
+ });
40
+
41
+ test('should throw for whitespace-only invitationId', async () => {
42
+ await expect(deleteInvitationRequest(client, ' ')).rejects.toThrow(TypeError);
43
+ expect(deleteMock).not.toHaveBeenCalled();
44
+ });
45
+ });
@@ -0,0 +1,13 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ export const deleteInvitationRequest = async (client: Client, invitationId: string): Promise<void> => {
5
+ const result = z.string().trim().min(1).uuid().safeParse(invitationId);
6
+ if (!result.success) {
7
+ throw new TypeError('Invalid args', { cause: result.error.issues });
8
+ }
9
+
10
+ await client.delete(
11
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/invitationRequest/${result.data}`
12
+ );
13
+ };
@@ -0,0 +1,9 @@
1
+ import { Client } from '@vulog/aima-client';
2
+
3
+ import { BusinessBillingGroup } from './types';
4
+
5
+ export const getBusinessBillingGroups = async (client: Client): Promise<BusinessBillingGroup[]> => {
6
+ return client
7
+ .get<BusinessBillingGroup[]>(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/billing/groups`)
8
+ .then(({ data }) => data);
9
+ };
@@ -0,0 +1,47 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+ import { Client } from '@vulog/aima-client';
3
+ import { getBusinessById } from './getBusinessById';
4
+
5
+ describe('getBusinessById', () => {
6
+ const getMock = vi.fn();
7
+ const client = {
8
+ get: getMock,
9
+ clientOptions: {
10
+ fleetId: 'FLEET_ID',
11
+ },
12
+ } as unknown as Client;
13
+
14
+ beforeEach(() => {
15
+ vi.clearAllMocks();
16
+ });
17
+
18
+ const BUSINESS_ID = '018ab2b6-71b2-4c76-90bd-6e8d3f268618';
19
+
20
+ test('should return a business by id', async () => {
21
+ const mockResponse = {
22
+ id: BUSINESS_ID,
23
+ name: 'Acme Corp',
24
+ status: 'ACTIVE',
25
+ };
26
+ getMock.mockResolvedValueOnce({ data: mockResponse });
27
+
28
+ const result = await getBusinessById(client, BUSINESS_ID);
29
+
30
+ expect(result).toEqual(mockResponse);
31
+ expect(getMock).toHaveBeenCalledWith(
32
+ `/boapi/proxy/business/fleets/FLEET_ID/business/${BUSINESS_ID}`
33
+ );
34
+ });
35
+
36
+ test('should throw for empty businessId', async () => {
37
+ await expect(getBusinessById(client, '')).rejects.toThrow(TypeError);
38
+ });
39
+
40
+ test('should throw for non-uuid businessId', async () => {
41
+ await expect(getBusinessById(client, 'not-a-uuid')).rejects.toThrow(TypeError);
42
+ });
43
+
44
+ test('should throw for whitespace-only businessId', async () => {
45
+ await expect(getBusinessById(client, ' ')).rejects.toThrow(TypeError);
46
+ });
47
+ });
@@ -0,0 +1,15 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { Business } from './types';
5
+
6
+ export const getBusinessById = async (client: Client, businessId: string): Promise<Business> => {
7
+ const result = z.string().trim().min(1).uuid().safeParse(businessId);
8
+ if (!result.success) {
9
+ throw new TypeError('Invalid args', { cause: result.error.issues });
10
+ }
11
+
12
+ return client
13
+ .get<Business>(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data}`)
14
+ .then(({ data }) => data);
15
+ };
@@ -0,0 +1,17 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { BusinessContact } from './types';
5
+
6
+ export const getBusinessContacts = async (client: Client, businessId: string): Promise<BusinessContact[]> => {
7
+ const result = z.string().trim().min(1).uuid().safeParse(businessId);
8
+ if (!result.success) {
9
+ throw new TypeError('Invalid args', { cause: result.error.issues });
10
+ }
11
+
12
+ return client
13
+ .get<
14
+ BusinessContact[]
15
+ >(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data}/contacts`)
16
+ .then(({ data }) => data);
17
+ };
@@ -0,0 +1,27 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { CostCenter } from './types';
5
+
6
+ const schema = z.object({
7
+ businessId: z.string().trim().min(1).uuid(),
8
+ costCenterId: z.string().trim().min(1).uuid(),
9
+ });
10
+
11
+ export const getBusinessCostCenterById = async (
12
+ client: Client,
13
+ businessId: string,
14
+ costCenterId: string
15
+ ): Promise<CostCenter> => {
16
+ const result = schema.safeParse({ businessId, costCenterId });
17
+ if (!result.success) {
18
+ throw new TypeError('Invalid args', {
19
+ cause: result.error.issues,
20
+ });
21
+ }
22
+ return client
23
+ .get<CostCenter>(
24
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data.businessId}/costcenter/${result.data.costCenterId}`
25
+ )
26
+ .then(({ data }) => data);
27
+ };
@@ -0,0 +1,18 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { CostCenter } from './types';
5
+
6
+ export const getBusinessCostCenters = async (client: Client, businessId: string): Promise<CostCenter[]> => {
7
+ const result = z.string().trim().min(1).uuid().safeParse(businessId);
8
+ if (!result.success) {
9
+ throw new TypeError('Invalid args', {
10
+ cause: result.error.issues,
11
+ });
12
+ }
13
+ return client
14
+ .get<
15
+ CostCenter[]
16
+ >(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data}/costcenter`)
17
+ .then(({ data }) => data);
18
+ };
@@ -0,0 +1,17 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { BusinessInviteLink } from './types';
5
+
6
+ export const getBusinessInviteLink = async (client: Client, businessId: string): Promise<BusinessInviteLink> => {
7
+ const result = z.string().trim().min(1).uuid().safeParse(businessId);
8
+ if (!result.success) {
9
+ throw new TypeError('Invalid args', { cause: result.error.issues });
10
+ }
11
+
12
+ return client
13
+ .get<BusinessInviteLink>(
14
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data}/user/invite/link`
15
+ )
16
+ .then(({ data }) => data);
17
+ };
@@ -0,0 +1,24 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ const uuidSchema = z.string().trim().min(1).uuid();
5
+
6
+ export const getBusinessInvoiceProducts = async (
7
+ client: Client,
8
+ entityId: string,
9
+ invoiceId: string
10
+ ): Promise<any[]> => {
11
+ const parsedEntityId = uuidSchema.safeParse(entityId);
12
+ const parsedInvoiceId = uuidSchema.safeParse(invoiceId);
13
+ if (!parsedEntityId.success || !parsedInvoiceId.success) {
14
+ throw new TypeError('Invalid args', {
15
+ cause: [...(parsedEntityId.error?.issues ?? []), ...(parsedInvoiceId.error?.issues ?? [])],
16
+ });
17
+ }
18
+
19
+ return client
20
+ .get<
21
+ any[]
22
+ >(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/entities/${parsedEntityId.data}/businessInvoices/${parsedInvoiceId.data}/products`)
23
+ .then(({ data }) => data);
24
+ };
@@ -0,0 +1,20 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ const uuidSchema = z.string().trim().min(1).uuid();
5
+
6
+ export const getBusinessInvoiceTrips = async (client: Client, entityId: string, invoiceId: string): Promise<any[]> => {
7
+ const parsedEntityId = uuidSchema.safeParse(entityId);
8
+ const parsedInvoiceId = uuidSchema.safeParse(invoiceId);
9
+ if (!parsedEntityId.success || !parsedInvoiceId.success) {
10
+ throw new TypeError('Invalid args', {
11
+ cause: [...(parsedEntityId.error?.issues ?? []), ...(parsedInvoiceId.error?.issues ?? [])],
12
+ });
13
+ }
14
+
15
+ return client
16
+ .get<
17
+ any[]
18
+ >(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/entities/${parsedEntityId.data}/businessInvoices/${parsedInvoiceId.data}/trips`)
19
+ .then(({ data }) => data);
20
+ };
@@ -0,0 +1,92 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+ import { Client } from '@vulog/aima-client';
3
+ import { getBusinessInvoices } from './getBusinessInvoices';
4
+
5
+ describe('getBusinessInvoices', () => {
6
+ const getMock = vi.fn();
7
+ const client = {
8
+ get: getMock,
9
+ clientOptions: { fleetId: 'FLEET_ID' },
10
+ } as unknown as Client;
11
+
12
+ const entityId = 'ed539d7d-d815-405b-bc00-71008fb1954c';
13
+
14
+ beforeEach(() => {
15
+ vi.clearAllMocks();
16
+ });
17
+
18
+ test('should call GET with correct endpoint and default pagination', async () => {
19
+ const mockInvoices = [
20
+ { id: 'inv-1', amount: 100, status: 'PAID' },
21
+ { id: 'inv-2', amount: 200, status: 'PENDING' },
22
+ ];
23
+ getMock.mockResolvedValueOnce({
24
+ data: mockInvoices,
25
+ headers: { number: 0, size: 100, totalelements: 2, totalpages: 1 },
26
+ });
27
+
28
+ const result = await getBusinessInvoices(client, entityId);
29
+
30
+ expect(getMock).toHaveBeenCalledTimes(1);
31
+ const url = getMock.mock.calls[0][0] as string;
32
+ expect(url).toContain(`/boapi/proxy/business/fleets/FLEET_ID/entities/${entityId}/businessInvoices?`);
33
+ expect(url).toContain('page=0');
34
+ expect(url).toContain('size=100');
35
+ expect(result.data).toEqual(mockInvoices);
36
+ expect(result.page).toBe(0);
37
+ expect(result.pageSize).toBe(100);
38
+ expect(result.total).toBe(2);
39
+ expect(result.totalPages).toBe(1);
40
+ });
41
+
42
+ test('should pass custom pagination options', async () => {
43
+ getMock.mockResolvedValueOnce({
44
+ data: [],
45
+ headers: { number: 2, size: 25, totalelements: 0, totalpages: 0 },
46
+ });
47
+
48
+ await getBusinessInvoices(client, entityId, { page: 2, pageSize: 25, sort: 'amount', sortDirection: 'DESC' });
49
+
50
+ const url = getMock.mock.calls[0][0] as string;
51
+ expect(url).toContain('page=2');
52
+ expect(url).toContain('size=25');
53
+ expect(url).toContain('sort=amount%2CDESC');
54
+ });
55
+
56
+ test('should handle empty response', async () => {
57
+ getMock.mockResolvedValueOnce({
58
+ data: [],
59
+ headers: { number: 0, size: 100, totalelements: 0, totalpages: 0 },
60
+ });
61
+
62
+ const result = await getBusinessInvoices(client, entityId);
63
+
64
+ expect(result).toEqual({
65
+ data: [],
66
+ page: 0,
67
+ pageSize: 100,
68
+ total: 0,
69
+ totalPages: 0,
70
+ });
71
+ });
72
+
73
+ test('should throw TypeError for invalid entityId', async () => {
74
+ await expect(getBusinessInvoices(client, 'not-a-uuid')).rejects.toThrow(TypeError);
75
+ expect(getMock).not.toHaveBeenCalled();
76
+ });
77
+
78
+ test('should throw TypeError for empty entityId', async () => {
79
+ await expect(getBusinessInvoices(client, '')).rejects.toThrow(TypeError);
80
+ expect(getMock).not.toHaveBeenCalled();
81
+ });
82
+
83
+ test('should throw TypeError for invalid pagination options', async () => {
84
+ await expect(getBusinessInvoices(client, entityId, { page: -1 })).rejects.toThrow(TypeError);
85
+ expect(getMock).not.toHaveBeenCalled();
86
+ });
87
+
88
+ test('should throw TypeError for invalid page size', async () => {
89
+ await expect(getBusinessInvoices(client, entityId, { pageSize: 0 })).rejects.toThrow(TypeError);
90
+ expect(getMock).not.toHaveBeenCalled();
91
+ });
92
+ });
@@ -0,0 +1,43 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { createPaginableOptionsSchema, PaginableOptions, PaginableResponse } from '@vulog/aima-core';
3
+ import { z } from 'zod';
4
+
5
+ import { BusinessInvoice } from './types';
6
+
7
+ export const getBusinessInvoices = async (
8
+ client: Client,
9
+ entityId: string,
10
+ options?: PaginableOptions
11
+ ): Promise<PaginableResponse<BusinessInvoice>> => {
12
+ const resultId = z.string().trim().min(1).uuid().safeParse(entityId);
13
+ if (!resultId.success) {
14
+ throw new TypeError('Invalid args', { cause: resultId.error.issues });
15
+ }
16
+
17
+ const paginableOptionsSchema = createPaginableOptionsSchema();
18
+
19
+ const resultOptions = paginableOptionsSchema.safeParse(options ?? {});
20
+ if (!resultOptions.success) {
21
+ throw new TypeError('Invalid options', { cause: resultOptions.error.issues });
22
+ }
23
+
24
+ const finalOptions = resultOptions.data;
25
+
26
+ const searchParams = new URLSearchParams();
27
+ searchParams.append('page', finalOptions.page!.toString());
28
+ searchParams.append('size', finalOptions.pageSize!.toString());
29
+
30
+ if (finalOptions.sort) {
31
+ searchParams.append('sort', `${finalOptions.sort.toString()},${finalOptions.sortDirection!.toString()}`);
32
+ }
33
+
34
+ const url = `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/entities/${resultId.data}/businessInvoices?${searchParams.toString()}`;
35
+
36
+ return client.get<BusinessInvoice[]>(url).then(({ data, headers }) => ({
37
+ data,
38
+ page: headers.number,
39
+ pageSize: headers.size,
40
+ total: headers.totalelements,
41
+ totalPages: headers.totalpages,
42
+ }));
43
+ };
@@ -0,0 +1,20 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { BusinessPaymentDetails } from './types';
5
+
6
+ export const getBusinessPaymentDetails = async (
7
+ client: Client,
8
+ businessId: string
9
+ ): Promise<BusinessPaymentDetails> => {
10
+ const result = z.string().trim().min(1).uuid().safeParse(businessId);
11
+ if (!result.success) {
12
+ throw new TypeError('Invalid args', { cause: result.error.issues });
13
+ }
14
+
15
+ return client
16
+ .get<BusinessPaymentDetails>(
17
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data}/paymentDetails`
18
+ )
19
+ .then(({ data }) => data);
20
+ };
@@ -0,0 +1,9 @@
1
+ import { Client } from '@vulog/aima-client';
2
+
3
+ import { BusinessProduct } from './types';
4
+
5
+ export const getBusinessProducts = async (client: Client): Promise<BusinessProduct[]> => {
6
+ return client
7
+ .get<BusinessProduct[]>(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/product`)
8
+ .then(({ data }) => data);
9
+ };
@@ -0,0 +1,15 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { BusinessTrip } from './types';
5
+
6
+ export const getBusinessTripById = async (client: Client, tripId: string): Promise<BusinessTrip> => {
7
+ const result = z.string().trim().min(1).uuid().safeParse(tripId);
8
+ if (!result.success) {
9
+ throw new TypeError('Invalid args', { cause: result.error.issues });
10
+ }
11
+
12
+ return client
13
+ .get<BusinessTrip>(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/trip/${result.data}`)
14
+ .then(({ data }) => data);
15
+ };
@@ -0,0 +1,26 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { BusinessUser } from './types';
5
+
6
+ const uuidSchema = z.string().trim().min(1).uuid();
7
+
8
+ export const getBusinessUserById = async (
9
+ client: Client,
10
+ businessId: string,
11
+ userId: string
12
+ ): Promise<BusinessUser> => {
13
+ const parsedBusinessId = uuidSchema.safeParse(businessId);
14
+ const parsedUserId = uuidSchema.safeParse(userId);
15
+ if (!parsedBusinessId.success || !parsedUserId.success) {
16
+ throw new TypeError('Invalid args', {
17
+ cause: [...(parsedBusinessId.error?.issues ?? []), ...(parsedUserId.error?.issues ?? [])],
18
+ });
19
+ }
20
+
21
+ return client
22
+ .get<BusinessUser>(
23
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${parsedBusinessId.data}/user/${parsedUserId.data}`
24
+ )
25
+ .then(({ data }) => data);
26
+ };