@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
package/src/types.ts ADDED
@@ -0,0 +1,163 @@
1
+ /** Represents a business entity */
2
+ export type Business = {
3
+ /** Unique identifier */
4
+ id: string;
5
+ /** Business name */
6
+ name: string;
7
+ /** Business status */
8
+ status: string;
9
+ [key: string]: any;
10
+ };
11
+
12
+ /** Represents a contact within a business */
13
+ export type BusinessContact = {
14
+ /** Contact identifier */
15
+ id: string;
16
+ /** Contact name */
17
+ name: string;
18
+ /** Contact email */
19
+ email: string;
20
+ [key: string]: any;
21
+ };
22
+
23
+ /** Represents a cost center within a business */
24
+ export type CostCenter = {
25
+ /** Unique identifier */
26
+ id: string;
27
+ /** Cost center name */
28
+ name: string;
29
+ /** Parent business identifier */
30
+ businessId: string;
31
+ [key: string]: any;
32
+ };
33
+
34
+ /** Represents payment details for a business */
35
+ export type BusinessPaymentDetails = {
36
+ /** Payment method type */
37
+ paymentMethod: string;
38
+ [key: string]: any;
39
+ };
40
+
41
+ /** Represents a user linked to a business */
42
+ export type BusinessUser = {
43
+ /** User identifier */
44
+ userId: string;
45
+ /** Business identifier */
46
+ businessId: string;
47
+ /** User role within the business */
48
+ role: string;
49
+ [key: string]: any;
50
+ };
51
+
52
+ /** Represents an invitation link for a business */
53
+ export type BusinessInviteLink = {
54
+ /** Invitation URL */
55
+ url: string;
56
+ [key: string]: any;
57
+ };
58
+
59
+ /** Represents entity balance information */
60
+ export type EntityBalance = {
61
+ /** Entity identifier */
62
+ entityId: string;
63
+ /** Current balance */
64
+ balance: number;
65
+ [key: string]: any;
66
+ };
67
+
68
+ /** Represents the total cost of trips for an entity */
69
+ export type EntityTripsCost = {
70
+ /** Total cost */
71
+ totalCost: number;
72
+ [key: string]: any;
73
+ };
74
+
75
+ /** Represents a billing group in the business context */
76
+ export type BusinessBillingGroup = {
77
+ /** Group identifier */
78
+ id: string;
79
+ /** Group name */
80
+ name: string;
81
+ [key: string]: any;
82
+ };
83
+
84
+ /** Represents a Stripe setup response */
85
+ export type StripeSetup = {
86
+ /** Client secret for Stripe */
87
+ clientSecret: string;
88
+ [key: string]: any;
89
+ };
90
+
91
+ /** Represents Stripe configuration */
92
+ export type StripeConfig = {
93
+ /** Stripe publishable key */
94
+ publishableKey: string;
95
+ [key: string]: any;
96
+ };
97
+
98
+ /** Represents a business invoice */
99
+ export type BusinessInvoice = {
100
+ /** Invoice identifier */
101
+ id: string;
102
+ /** Invoice amount */
103
+ amount: number;
104
+ /** Invoice status */
105
+ status: string;
106
+ [key: string]: any;
107
+ };
108
+
109
+ /** Represents the refund note for an invoice */
110
+ export type InvoiceRefundNote = {
111
+ [key: string]: any;
112
+ };
113
+
114
+ /** Represents the refundable amount for an invoice */
115
+ export type InvoiceRefundableAmount = {
116
+ /** Invoice identifier */
117
+ invoiceId: string;
118
+ /** Refundable amount */
119
+ refundableAmount: number;
120
+ [key: string]: any;
121
+ };
122
+
123
+ /** Represents a business trip */
124
+ export type BusinessTrip = {
125
+ /** Trip identifier */
126
+ tripId: string;
127
+ [key: string]: any;
128
+ };
129
+
130
+ /** Represents a note on a trip */
131
+ export type TripNote = {
132
+ /** Note identifier */
133
+ id: string;
134
+ /** Note content */
135
+ content: string;
136
+ [key: string]: any;
137
+ };
138
+
139
+ /** Represents a product in the business context */
140
+ export type BusinessProduct = {
141
+ /** Product identifier */
142
+ id: string;
143
+ /** Product name */
144
+ name: string;
145
+ [key: string]: any;
146
+ };
147
+
148
+ /** Represents an invitation request */
149
+ export type InvitationRequest = {
150
+ /** Invitation request identifier */
151
+ id: string;
152
+ [key: string]: any;
153
+ };
154
+
155
+ /** Represents a business wallet */
156
+ export type BusinessWallet = {
157
+ [key: string]: any;
158
+ };
159
+
160
+ /** Represents a business user profile */
161
+ export type BusinessUserProfile = {
162
+ [key: string]: any;
163
+ };
@@ -0,0 +1,65 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+ import { Client } from '@vulog/aima-client';
3
+ import { updateBusiness, UpdateBusinessBody } from './updateBusiness';
4
+
5
+ describe('updateBusiness', () => {
6
+ const putMock = vi.fn();
7
+ const client = {
8
+ put: putMock,
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 update a business with valid body', async () => {
21
+ const body: UpdateBusinessBody = { name: 'Updated Corp' };
22
+ const mockResponse = { id: BUSINESS_ID, name: 'Updated Corp', status: 'ACTIVE' };
23
+ putMock.mockResolvedValueOnce({ data: mockResponse });
24
+
25
+ const result = await updateBusiness(client, BUSINESS_ID, body);
26
+
27
+ expect(result).toEqual(mockResponse);
28
+ expect(putMock).toHaveBeenCalledWith(
29
+ `/boapi/proxy/business/fleets/FLEET_ID/business/${BUSINESS_ID}`,
30
+ body
31
+ );
32
+ });
33
+
34
+ test('should update a business with empty body (no fields)', async () => {
35
+ const body: UpdateBusinessBody = {};
36
+ const mockResponse = { id: BUSINESS_ID, name: 'Existing Corp', status: 'ACTIVE' };
37
+ putMock.mockResolvedValueOnce({ data: mockResponse });
38
+
39
+ const result = await updateBusiness(client, BUSINESS_ID, body);
40
+
41
+ expect(result).toEqual(mockResponse);
42
+ expect(putMock).toHaveBeenCalledWith(
43
+ `/boapi/proxy/business/fleets/FLEET_ID/business/${BUSINESS_ID}`,
44
+ body
45
+ );
46
+ });
47
+
48
+ test('should throw for empty businessId', async () => {
49
+ await expect(updateBusiness(client, '', { name: 'Test' })).rejects.toThrow(TypeError);
50
+ });
51
+
52
+ test('should throw for non-uuid businessId', async () => {
53
+ await expect(updateBusiness(client, 'not-a-uuid', { name: 'Test' })).rejects.toThrow(TypeError);
54
+ });
55
+
56
+ test('should throw for empty name string', async () => {
57
+ const body: UpdateBusinessBody = { name: '' };
58
+ await expect(updateBusiness(client, BUSINESS_ID, body)).rejects.toThrow(TypeError);
59
+ });
60
+
61
+ test('should throw for name exceeding 255 characters', async () => {
62
+ const body: UpdateBusinessBody = { name: 'a'.repeat(256) };
63
+ await expect(updateBusiness(client, BUSINESS_ID, body)).rejects.toThrow(TypeError);
64
+ });
65
+ });
@@ -0,0 +1,35 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { Business } from './types';
5
+
6
+ export type UpdateBusinessBody = {
7
+ name?: string;
8
+ };
9
+
10
+ const updateBusinessBodySchema = z.object({
11
+ name: z.string().trim().min(1).max(255).optional(),
12
+ });
13
+
14
+ export const updateBusiness = async (
15
+ client: Client,
16
+ businessId: string,
17
+ body: UpdateBusinessBody
18
+ ): Promise<Business> => {
19
+ const parsedId = z.string().trim().min(1).uuid().safeParse(businessId);
20
+ if (!parsedId.success) {
21
+ throw new TypeError('Invalid args', { cause: parsedId.error.issues });
22
+ }
23
+
24
+ const result = updateBusinessBodySchema.safeParse(body);
25
+ if (!result.success) {
26
+ throw new TypeError('Invalid args', { cause: result.error.issues });
27
+ }
28
+
29
+ return client
30
+ .put<Business>(
31
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${parsedId.data}`,
32
+ result.data
33
+ )
34
+ .then(({ data }) => data);
35
+ };
@@ -0,0 +1,41 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { CostCenter } from './types';
5
+
6
+ export type UpdateCostCenterBody = {
7
+ name?: string;
8
+ };
9
+
10
+ const uuidSchema = z.string().trim().min(1).uuid();
11
+
12
+ const bodySchema = z.object({
13
+ name: z.string().trim().min(1).max(255).optional(),
14
+ });
15
+
16
+ export const updateBusinessCostCenter = async (
17
+ client: Client,
18
+ businessId: string,
19
+ costCenterId: string,
20
+ body: UpdateCostCenterBody
21
+ ): Promise<CostCenter> => {
22
+ const parsedBusinessId = uuidSchema.safeParse(businessId);
23
+ const parsedCostCenterId = uuidSchema.safeParse(costCenterId);
24
+ if (!parsedBusinessId.success || !parsedCostCenterId.success) {
25
+ throw new TypeError('Invalid args', {
26
+ cause: [...(parsedBusinessId.error?.issues ?? []), ...(parsedCostCenterId.error?.issues ?? [])],
27
+ });
28
+ }
29
+
30
+ const result = bodySchema.safeParse(body);
31
+ if (!result.success) {
32
+ throw new TypeError('Invalid args', { cause: result.error.issues });
33
+ }
34
+
35
+ return client
36
+ .put<CostCenter>(
37
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${parsedBusinessId.data}/costcenter/${parsedCostCenterId.data}`,
38
+ result.data
39
+ )
40
+ .then(({ data }) => data);
41
+ };
@@ -0,0 +1,22 @@
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
+ status: z.string().trim().min(1),
7
+ });
8
+
9
+ export const updateBusinessProfileStatus = async (
10
+ client: Client,
11
+ businessId: string,
12
+ status: string
13
+ ): Promise<void> => {
14
+ const result = schema.safeParse({ businessId, status });
15
+ if (!result.success) {
16
+ throw new TypeError('Invalid args', { cause: result.error.issues });
17
+ }
18
+
19
+ await client.put<void>(
20
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data.businessId}/profile/user/profile/status/${result.data.status}`
21
+ );
22
+ };
@@ -0,0 +1,51 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ import { BusinessUserProfile } from './types';
5
+
6
+ export type UpdateBusinessUserProfileBody = {
7
+ email?: string;
8
+ emailConsent?: boolean;
9
+ costCenterId?: string;
10
+ };
11
+
12
+ const uuidSchema = z.string().trim().min(1).uuid();
13
+
14
+ const bodySchema = z.object({
15
+ email: z.string().trim().email().optional(),
16
+ emailConsent: z.boolean().optional(),
17
+ costCenterId: z.string().trim().min(1).uuid().optional(),
18
+ });
19
+
20
+ export const updateBusinessUserProfile = async (
21
+ client: Client,
22
+ businessId: string,
23
+ userId: string,
24
+ profileId: string,
25
+ body: UpdateBusinessUserProfileBody
26
+ ): Promise<BusinessUserProfile> => {
27
+ const parsedBusinessId = uuidSchema.safeParse(businessId);
28
+ const parsedUserId = uuidSchema.safeParse(userId);
29
+ const parsedProfileId = uuidSchema.safeParse(profileId);
30
+ if (!parsedBusinessId.success || !parsedUserId.success || !parsedProfileId.success) {
31
+ throw new TypeError('Invalid args', {
32
+ cause: [
33
+ ...(parsedBusinessId.error?.issues ?? []),
34
+ ...(parsedUserId.error?.issues ?? []),
35
+ ...(parsedProfileId.error?.issues ?? []),
36
+ ],
37
+ });
38
+ }
39
+
40
+ const result = bodySchema.safeParse(body);
41
+ if (!result.success) {
42
+ throw new TypeError('Invalid args', { cause: result.error.issues });
43
+ }
44
+
45
+ return client
46
+ .put<BusinessUserProfile>(
47
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${parsedBusinessId.data}/user/${parsedUserId.data}/profile/${parsedProfileId.data}`,
48
+ result.data
49
+ )
50
+ .then(({ data }) => data);
51
+ };
@@ -0,0 +1,54 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+ import { Client } from '@vulog/aima-client';
3
+ import { updateInvoiceStatus } from './updateInvoiceStatus';
4
+
5
+ describe('updateInvoiceStatus', () => {
6
+ const postMock = vi.fn();
7
+ const client = {
8
+ post: postMock,
9
+ clientOptions: { fleetId: 'FLEET_ID' },
10
+ } as unknown as Client;
11
+
12
+ const INVOICE_ID = '018ab2b6-71b2-4c76-90bd-6e8d3f268618';
13
+
14
+ beforeEach(() => {
15
+ vi.clearAllMocks();
16
+ });
17
+
18
+ test('should update invoice status successfully', async () => {
19
+ postMock.mockResolvedValueOnce({ data: undefined });
20
+
21
+ const result = await updateInvoiceStatus(client, INVOICE_ID, 'PAID');
22
+
23
+ expect(result).toBeUndefined();
24
+ expect(postMock).toHaveBeenCalledWith(
25
+ `/boapi/proxy/business/fleets/FLEET_ID/invoices/${INVOICE_ID}/status/PAID`,
26
+ {}
27
+ );
28
+ });
29
+
30
+ test('should throw for empty invoiceId', async () => {
31
+ await expect(updateInvoiceStatus(client, '', 'PAID')).rejects.toThrow(TypeError);
32
+ expect(postMock).not.toHaveBeenCalled();
33
+ });
34
+
35
+ test('should throw for non-uuid invoiceId', async () => {
36
+ await expect(updateInvoiceStatus(client, 'not-a-uuid', 'PAID')).rejects.toThrow(TypeError);
37
+ expect(postMock).not.toHaveBeenCalled();
38
+ });
39
+
40
+ test('should throw for empty status', async () => {
41
+ await expect(updateInvoiceStatus(client, INVOICE_ID, '')).rejects.toThrow(TypeError);
42
+ expect(postMock).not.toHaveBeenCalled();
43
+ });
44
+
45
+ test('should throw for whitespace-only status', async () => {
46
+ await expect(updateInvoiceStatus(client, INVOICE_ID, ' ')).rejects.toThrow(TypeError);
47
+ expect(postMock).not.toHaveBeenCalled();
48
+ });
49
+
50
+ test('should throw for whitespace-only invoiceId', async () => {
51
+ await expect(updateInvoiceStatus(client, ' ', 'PAID')).rejects.toThrow(TypeError);
52
+ expect(postMock).not.toHaveBeenCalled();
53
+ });
54
+ });
@@ -0,0 +1,19 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import { z } from 'zod';
3
+
4
+ const schema = z.object({
5
+ invoiceId: z.string().trim().min(1).uuid(),
6
+ status: z.string().trim().min(1),
7
+ });
8
+
9
+ export const updateInvoiceStatus = async (client: Client, invoiceId: string, status: string): Promise<void> => {
10
+ const result = schema.safeParse({ invoiceId, status });
11
+ if (!result.success) {
12
+ throw new TypeError('Invalid args', { cause: result.error.issues });
13
+ }
14
+
15
+ await client.post<void>(
16
+ `/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/invoices/${result.data.invoiceId}/status/${result.data.status}`,
17
+ {}
18
+ );
19
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "include": ["src"],
4
+ "exclude": ["**/*.test.ts"],
5
+ "compilerOptions": {
6
+ "outDir": "dist",
7
+ "rootDir": "src"
8
+ }
9
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'tsdown';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ clean: true,
6
+ format: ['cjs', 'esm'],
7
+ dts: true,
8
+ });
@@ -0,0 +1 @@
1
+ export { default } from '../../vitest.config.base.ts';