@vulog/aima-booking 1.2.22 → 1.2.23

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/index.d.mts CHANGED
@@ -261,7 +261,7 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
261
261
  requiresActionReturnURL: z$1.ZodOptional<z$1.ZodString>;
262
262
  online: z$1.ZodBoolean;
263
263
  amountType: z$1.ZodEnum<["FIXED", "PERCENTAGE"]>;
264
- amountValue: z$1.ZodOptional<z$1.ZodNumber>;
264
+ amountValue: z$1.ZodNumber;
265
265
  preferredPaymentMethods: z$1.ZodOptional<z$1.ZodArray<z$1.ZodObject<{
266
266
  pspReference: z$1.ZodString;
267
267
  amount: z$1.ZodDefault<z$1.ZodNumber>;
@@ -278,8 +278,8 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
278
278
  scope: "RENTAL" | "DEPOSIT";
279
279
  online: boolean;
280
280
  amountType: "FIXED" | "PERCENTAGE";
281
+ amountValue: number;
281
282
  requiresActionReturnURL?: string | undefined;
282
- amountValue?: number | undefined;
283
283
  preferredPaymentMethods?: {
284
284
  pspReference: string;
285
285
  amount: number;
@@ -289,8 +289,8 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
289
289
  scope: "RENTAL" | "DEPOSIT";
290
290
  online: boolean;
291
291
  amountType: "FIXED" | "PERCENTAGE";
292
+ amountValue: number;
292
293
  requiresActionReturnURL?: string | undefined;
293
- amountValue?: number | undefined;
294
294
  preferredPaymentMethods?: {
295
295
  pspReference: string;
296
296
  amount?: number | undefined;
@@ -302,8 +302,8 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
302
302
  scope: "RENTAL" | "DEPOSIT";
303
303
  online: boolean;
304
304
  amountType: "FIXED" | "PERCENTAGE";
305
+ amountValue: number;
305
306
  requiresActionReturnURL?: string | undefined;
306
- amountValue?: number | undefined;
307
307
  preferredPaymentMethods?: {
308
308
  pspReference: string;
309
309
  amount: number;
@@ -316,8 +316,8 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
316
316
  scope: "RENTAL" | "DEPOSIT";
317
317
  online: boolean;
318
318
  amountType: "FIXED" | "PERCENTAGE";
319
+ amountValue: number;
319
320
  requiresActionReturnURL?: string | undefined;
320
- amountValue?: number | undefined;
321
321
  preferredPaymentMethods?: {
322
322
  pspReference: string;
323
323
  amount?: number | undefined;
package/dist/index.d.ts CHANGED
@@ -261,7 +261,7 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
261
261
  requiresActionReturnURL: z$1.ZodOptional<z$1.ZodString>;
262
262
  online: z$1.ZodBoolean;
263
263
  amountType: z$1.ZodEnum<["FIXED", "PERCENTAGE"]>;
264
- amountValue: z$1.ZodOptional<z$1.ZodNumber>;
264
+ amountValue: z$1.ZodNumber;
265
265
  preferredPaymentMethods: z$1.ZodOptional<z$1.ZodArray<z$1.ZodObject<{
266
266
  pspReference: z$1.ZodString;
267
267
  amount: z$1.ZodDefault<z$1.ZodNumber>;
@@ -278,8 +278,8 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
278
278
  scope: "RENTAL" | "DEPOSIT";
279
279
  online: boolean;
280
280
  amountType: "FIXED" | "PERCENTAGE";
281
+ amountValue: number;
281
282
  requiresActionReturnURL?: string | undefined;
282
- amountValue?: number | undefined;
283
283
  preferredPaymentMethods?: {
284
284
  pspReference: string;
285
285
  amount: number;
@@ -289,8 +289,8 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
289
289
  scope: "RENTAL" | "DEPOSIT";
290
290
  online: boolean;
291
291
  amountType: "FIXED" | "PERCENTAGE";
292
+ amountValue: number;
292
293
  requiresActionReturnURL?: string | undefined;
293
- amountValue?: number | undefined;
294
294
  preferredPaymentMethods?: {
295
295
  pspReference: string;
296
296
  amount?: number | undefined;
@@ -302,8 +302,8 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
302
302
  scope: "RENTAL" | "DEPOSIT";
303
303
  online: boolean;
304
304
  amountType: "FIXED" | "PERCENTAGE";
305
+ amountValue: number;
305
306
  requiresActionReturnURL?: string | undefined;
306
- amountValue?: number | undefined;
307
307
  preferredPaymentMethods?: {
308
308
  pspReference: string;
309
309
  amount: number;
@@ -316,8 +316,8 @@ declare const triggerBRPaymentSchema: z$1.ZodObject<{
316
316
  scope: "RENTAL" | "DEPOSIT";
317
317
  online: boolean;
318
318
  amountType: "FIXED" | "PERCENTAGE";
319
+ amountValue: number;
319
320
  requiresActionReturnURL?: string | undefined;
320
- amountValue?: number | undefined;
321
321
  preferredPaymentMethods?: {
322
322
  pspReference: string;
323
323
  amount?: number | undefined;
package/dist/index.js CHANGED
@@ -509,7 +509,7 @@ var triggerBRPaymentSchema = import_zod9.default.object({
509
509
  requiresActionReturnURL: import_zod9.default.string().url().optional(),
510
510
  online: import_zod9.default.boolean(),
511
511
  amountType: import_zod9.default.enum(["FIXED", "PERCENTAGE"]),
512
- amountValue: import_zod9.default.number().nonnegative().optional(),
512
+ amountValue: import_zod9.default.number().nonnegative(),
513
513
  preferredPaymentMethods: import_zod9.default.array(
514
514
  import_zod9.default.object({
515
515
  pspReference: import_zod9.default.string(),
package/dist/index.mjs CHANGED
@@ -461,7 +461,7 @@ var triggerBRPaymentSchema = z9.object({
461
461
  requiresActionReturnURL: z9.string().url().optional(),
462
462
  online: z9.boolean(),
463
463
  amountType: z9.enum(["FIXED", "PERCENTAGE"]),
464
- amountValue: z9.number().nonnegative().optional(),
464
+ amountValue: z9.number().nonnegative(),
465
465
  preferredPaymentMethods: z9.array(
466
466
  z9.object({
467
467
  pspReference: z9.string(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vulog/aima-booking",
3
- "version": "1.2.22",
3
+ "version": "1.2.23",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -19,8 +19,8 @@
19
19
  "author": "Vulog",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@vulog/aima-client": "1.2.22",
23
- "@vulog/aima-core": "1.2.22"
22
+ "@vulog/aima-client": "1.2.23",
23
+ "@vulog/aima-core": "1.2.23"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "es-toolkit": "^1.39.9",
@@ -0,0 +1,122 @@
1
+ import { describe, test, expect, vi, beforeEach } from 'vitest';
2
+ import { Client } from '@vulog/aima-client';
3
+ import { randomUUID } from 'crypto';
4
+ import { cancelBookingRequest } from './cancelBookingRequest';
5
+ import type { SATBookingRequest } from './types';
6
+
7
+ describe('cancelBookingRequest', () => {
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
+ const minimalCancelledResponse = {
17
+ id: '09c6daa5-9b4d-471c-8d2d-627d2ce7902d',
18
+ startDate: '2026-02-17T15:15:00Z',
19
+ endDate: '2026-02-19T15:15:00Z',
20
+ returnedDate: null,
21
+ profileId: '9cf8f71b-a535-4b26-b6bd-2b9856cd1cbc',
22
+ vehicleId: null,
23
+ modelId: 2597,
24
+ journeyId: null,
25
+ station: '37a505b8-a45e-4970-9adc-3bb6f177a868',
26
+ profileType: null,
27
+ entityName: null,
28
+ status: 'CANCELLED',
29
+ creationDate: '2026-02-13T14:12:04Z',
30
+ realStartDate: null,
31
+ cancellationDate: '2026-02-16T12:32:09Z',
32
+ cancelledBy: 'b60db6f0-67d3-4beb-a835-d7bc32f448c2',
33
+ fleetId: 'FLEET_ID',
34
+ userId: 'e2a19a00-87de-4e3e-8da3-6053cb137c47',
35
+ latitude: 0,
36
+ longitude: 0,
37
+ radius: 0,
38
+ serviceId: '3ef72482-94c1-40c0-a467-abffaef03d45',
39
+ warning: null,
40
+ email: null,
41
+ credits: null,
42
+ requiresActionReturnURL: null,
43
+ trip: null,
44
+ failureReason: null,
45
+ cityId: 'a91a8d56-4bf8-4a88-9afb-3f3cc255e4f8',
46
+ vehicleResidualValue: null,
47
+ price: null,
48
+ notes: null,
49
+ plannedReturnDate: null,
50
+ deliveryAddress: null,
51
+ deliveryAddressAdditionalInfo: null,
52
+ deliveryCity: null,
53
+ deliveryPostalCode: null,
54
+ dropOffStation: null,
55
+ thresholdDateLimit: null,
56
+ cancellationFeeAmount: null,
57
+ rollingContract: false,
58
+ planDurationInMonths: null,
59
+ planName: null,
60
+ parentId: null,
61
+ contractType: null,
62
+ previous: null,
63
+ customPrice: null,
64
+ productIds: ['f271997b-1184-429d-b951-bde23c1e2711'],
65
+ preallocatedVehicleId: null,
66
+ bookingReferenceId: 'p9JNDE',
67
+ pricingDetails: [
68
+ { pricingId: '0c5363cf-2763-4df7-92e4-1d66b04fc186', providerType: 'DEFAULT' },
69
+ ],
70
+ earlyCancelledByUser: false,
71
+ completed: false,
72
+ } as unknown as SATBookingRequest;
73
+
74
+ beforeEach(() => {
75
+ postMock.mockReset();
76
+ });
77
+
78
+ test('throws Invalid args when id is not a valid UUID', async () => {
79
+ await expect(cancelBookingRequest(client, 'not-a-uuid')).rejects.toThrow(TypeError);
80
+ await expect(cancelBookingRequest(client, 'not-a-uuid')).rejects.toMatchObject({
81
+ message: 'Invalid args',
82
+ });
83
+ expect(postMock).not.toHaveBeenCalled();
84
+ });
85
+
86
+ test('calls POST with correct URL and empty body and returns data', async () => {
87
+ const id = randomUUID();
88
+ postMock.mockResolvedValueOnce({ data: minimalCancelledResponse });
89
+
90
+ const result = await cancelBookingRequest(client, id);
91
+
92
+ expect(postMock).toHaveBeenCalledTimes(1);
93
+ expect(postMock).toHaveBeenCalledWith(
94
+ `/boapi/proxy/user/scheduledBooking/fleets/FLEET_ID/bookingrequests/${id}/cancel`,
95
+ {}
96
+ );
97
+ expect(result).toEqual(minimalCancelledResponse);
98
+ expect(result.status).toBe('CANCELLED');
99
+ });
100
+
101
+ test('throws when client.post rejects', async () => {
102
+ const id = randomUUID();
103
+ const networkError = new Error('Network error');
104
+ postMock.mockRejectedValueOnce(networkError);
105
+
106
+ let thrown: unknown;
107
+ try {
108
+ await cancelBookingRequest(client, id);
109
+ } catch (e) {
110
+ thrown = e;
111
+ }
112
+ expect(thrown).toBeDefined();
113
+ const err = thrown as Error & { cause?: unknown };
114
+ expect(err instanceof Error).toBe(true);
115
+ const isWrapped =
116
+ err.name === 'TypeError' &&
117
+ err.message === 'Failed to cancel booking request' &&
118
+ err.cause === networkError;
119
+ const isPropagated = err.message === 'Network error';
120
+ expect(isWrapped || isPropagated).toBe(true);
121
+ });
122
+ });
@@ -0,0 +1,28 @@
1
+ import { Client } from '@vulog/aima-client';
2
+ import z from 'zod';
3
+
4
+ import { SATBookingRequest } from './types';
5
+
6
+ const schema = z.object({
7
+ id: z.string().uuid(),
8
+ });
9
+
10
+ export const cancelBookingRequest = async (client: Client, id: string): Promise<SATBookingRequest> => {
11
+ const result = schema.safeParse({ id });
12
+ if (!result.success) {
13
+ throw new TypeError('Invalid args', {
14
+ cause: result.error.issues,
15
+ });
16
+ }
17
+ return client
18
+ .post<SATBookingRequest>(
19
+ `/boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/bookingrequests/${id}/cancel`,
20
+ {}
21
+ )
22
+ .then(({ data }) => data)
23
+ .catch((error) => {
24
+ throw new TypeError('Failed to cancel booking request', {
25
+ cause: error,
26
+ });
27
+ });
28
+ };
@@ -0,0 +1,135 @@
1
+ import { describe, test, expect, vi, beforeEach } from 'vitest';
2
+ import { Client } from '@vulog/aima-client';
3
+ import { randomUUID } from 'crypto';
4
+ import { releaseBRPayment } from './releaseBRPayment';
5
+ import type { SATBookingRequest } from './types';
6
+
7
+ describe('releaseBRPayment', () => {
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
+ const minimalResponse = {
17
+ id: randomUUID(),
18
+ startDate: '2026-02-17T15:15:00Z',
19
+ endDate: '2026-02-19T15:15:00Z',
20
+ returnedDate: null,
21
+ profileId: '9cf8f71b-a535-4b26-b6bd-2b9856cd1cbc',
22
+ vehicleId: null,
23
+ modelId: 2597,
24
+ journeyId: null,
25
+ station: '37a505b8-a45e-4970-9adc-3bb6f177a868',
26
+ profileType: null,
27
+ entityName: null,
28
+ status: 'CONFIRMED',
29
+ creationDate: '2026-02-13T14:12:04Z',
30
+ realStartDate: null,
31
+ cancellationDate: null,
32
+ cancelledBy: null,
33
+ fleetId: 'FLEET_ID',
34
+ userId: 'e2a19a00-87de-4e3e-8da3-6053cb137c47',
35
+ latitude: 0,
36
+ longitude: 0,
37
+ radius: 0,
38
+ serviceId: '3ef72482-94c1-40c0-a467-abffaef03d45',
39
+ warning: null,
40
+ email: null,
41
+ credits: null,
42
+ requiresActionReturnURL: null,
43
+ trip: null,
44
+ failureReason: null,
45
+ cityId: 'a91a8d56-4bf8-4a88-9afb-3f3cc255e4f8',
46
+ vehicleResidualValue: null,
47
+ price: null,
48
+ notes: null,
49
+ plannedReturnDate: null,
50
+ deliveryAddress: null,
51
+ deliveryAddressAdditionalInfo: null,
52
+ deliveryCity: null,
53
+ deliveryPostalCode: null,
54
+ dropOffStation: null,
55
+ thresholdDateLimit: null,
56
+ cancellationFeeAmount: null,
57
+ rollingContract: false,
58
+ planDurationInMonths: null,
59
+ planName: null,
60
+ parentId: null,
61
+ contractType: null,
62
+ previous: null,
63
+ customPrice: null,
64
+ productIds: ['f271997b-1184-429d-b951-bde23c1e2711'],
65
+ preallocatedVehicleId: null,
66
+ bookingReferenceId: 'p9JNDE',
67
+ pricingDetails: [
68
+ { pricingId: '0c5363cf-2763-4df7-92e4-1d66b04fc186', providerType: 'DEFAULT' },
69
+ ],
70
+ earlyCancelledByUser: false,
71
+ completed: false,
72
+ } as unknown as SATBookingRequest;
73
+
74
+ beforeEach(() => {
75
+ postMock.mockReset();
76
+ });
77
+
78
+ test('throws Invalid args when bookingRequestId is not a valid UUID', async () => {
79
+ await expect(
80
+ releaseBRPayment(client, 'not-a-uuid' as any, randomUUID())
81
+ ).rejects.toThrow(TypeError);
82
+ await expect(
83
+ releaseBRPayment(client, 'not-a-uuid' as any, randomUUID())
84
+ ).rejects.toMatchObject({ message: 'Invalid args' });
85
+ expect(postMock).not.toHaveBeenCalled();
86
+ });
87
+
88
+ test('throws Invalid args when pspReference is not a valid UUID', async () => {
89
+ await expect(
90
+ releaseBRPayment(client, randomUUID(), 'not-a-uuid')
91
+ ).rejects.toThrow(TypeError);
92
+ await expect(
93
+ releaseBRPayment(client, randomUUID(), 'not-a-uuid')
94
+ ).rejects.toMatchObject({ message: 'Invalid args' });
95
+ expect(postMock).not.toHaveBeenCalled();
96
+ });
97
+
98
+ test('calls POST with correct URL and empty body and returns data', async () => {
99
+ const bookingRequestId = randomUUID();
100
+ const pspReference = randomUUID();
101
+ postMock.mockResolvedValueOnce({ data: minimalResponse });
102
+
103
+ const result = await releaseBRPayment(client, bookingRequestId, pspReference);
104
+
105
+ expect(postMock).toHaveBeenCalledTimes(1);
106
+ expect(postMock).toHaveBeenCalledWith(
107
+ `boapi/proxy/user/scheduledBooking/fleets/FLEET_ID/bookingrequests/${bookingRequestId}/paymentintent/${pspReference}/cancel`,
108
+ {}
109
+ );
110
+ expect(result).toEqual(minimalResponse);
111
+ });
112
+
113
+ test('throws when client.post rejects', async () => {
114
+ const bookingRequestId = randomUUID();
115
+ const pspReference = randomUUID();
116
+ const networkError = new Error('Network error');
117
+ postMock.mockRejectedValueOnce(networkError);
118
+
119
+ let thrown: unknown;
120
+ try {
121
+ await releaseBRPayment(client, bookingRequestId, pspReference);
122
+ } catch (e) {
123
+ thrown = e;
124
+ }
125
+ expect(thrown).toBeDefined();
126
+ const err = thrown as Error & { cause?: unknown };
127
+ expect(err instanceof Error).toBe(true);
128
+ const isWrapped =
129
+ err.name === 'TypeError' &&
130
+ err.message === 'Failed to release booking request payment' &&
131
+ err.cause === networkError;
132
+ const isPropagated = err.message === 'Network error';
133
+ expect(isWrapped || isPropagated).toBe(true);
134
+ });
135
+ });
@@ -0,0 +1,38 @@
1
+ // /scheduledBooking/fleets/{fleetId}/bookingrequests/{id}/paymentintent/{pspReference}/cancel
2
+
3
+ import { UUID } from 'crypto';
4
+
5
+ import { Client } from '@vulog/aima-client';
6
+
7
+ import z from 'zod';
8
+
9
+ import { SATBookingRequest } from './types';
10
+
11
+ const releaseBRPaymentSchema = z.object({
12
+ bookingRequestId: z.string().uuid(),
13
+ pspReference: z.string().uuid(),
14
+ });
15
+
16
+ export const releaseBRPayment = async (
17
+ client: Client,
18
+ bookingRequestId: UUID,
19
+ pspReference: string
20
+ ): Promise<SATBookingRequest> => {
21
+ const resultPayload = releaseBRPaymentSchema.safeParse({ bookingRequestId, pspReference });
22
+ if (!resultPayload.success) {
23
+ throw new TypeError('Invalid args', {
24
+ cause: resultPayload.error.issues,
25
+ });
26
+ }
27
+ return client
28
+ .post<SATBookingRequest>(
29
+ `boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/paymentintent/${pspReference}/cancel`,
30
+ {}
31
+ )
32
+ .then(({ data }) => data)
33
+ .catch((error) => {
34
+ throw new TypeError('Failed to release booking request payment', {
35
+ cause: error,
36
+ });
37
+ });
38
+ };
@@ -13,7 +13,7 @@ const triggerBRPaymentSchema = z.object({
13
13
  requiresActionReturnURL: z.string().url().optional(),
14
14
  online: z.boolean(),
15
15
  amountType: z.enum(['FIXED', 'PERCENTAGE']),
16
- amountValue: z.number().nonnegative().optional(),
16
+ amountValue: z.number().nonnegative(),
17
17
  preferredPaymentMethods: z
18
18
  .array(
19
19
  z.object({