@driveflux/api-functions 1.0.43 → 1.0.45

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.
@@ -475,8 +475,8 @@ export declare const notionDatabaseSchema: <T extends ZodObject<any>>(properties
475
475
  }, z.core.$strip>>;
476
476
  icon: z.ZodUnion<[ZodObject<{
477
477
  type: z.ZodEnum<{
478
- file: "file";
479
478
  external: "external";
479
+ file: "file";
480
480
  }>;
481
481
  name: z.ZodOptional<z.ZodString>;
482
482
  file: z.ZodOptional<ZodObject<{
@@ -492,8 +492,8 @@ export declare const notionDatabaseSchema: <T extends ZodObject<any>>(properties
492
492
  }, z.core.$strip>]>;
493
493
  cover: z.ZodNullable<ZodObject<{
494
494
  type: z.ZodEnum<{
495
- file: "file";
496
495
  external: "external";
496
+ file: "file";
497
497
  }>;
498
498
  name: z.ZodOptional<z.ZodString>;
499
499
  file: z.ZodOptional<ZodObject<{
@@ -1,8 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  export declare const notionFileSchema: z.ZodObject<{
3
3
  type: z.ZodEnum<{
4
- file: "file";
5
4
  external: "external";
5
+ file: "file";
6
6
  }>;
7
7
  name: z.ZodOptional<z.ZodString>;
8
8
  file: z.ZodOptional<z.ZodObject<{
@@ -188,8 +188,8 @@ export declare const knowledgeBaseRetrieveDatabaseSchema: z.ZodObject<{
188
188
  }, z.core.$strip>>;
189
189
  icon: z.ZodUnion<[z.ZodObject<{
190
190
  type: z.ZodEnum<{
191
- file: "file";
192
191
  external: "external";
192
+ file: "file";
193
193
  }>;
194
194
  name: z.ZodOptional<z.ZodString>;
195
195
  file: z.ZodOptional<z.ZodObject<{
@@ -205,8 +205,8 @@ export declare const knowledgeBaseRetrieveDatabaseSchema: z.ZodObject<{
205
205
  }, z.core.$strip>]>;
206
206
  cover: z.ZodNullable<z.ZodObject<{
207
207
  type: z.ZodEnum<{
208
- file: "file";
209
208
  external: "external";
209
+ file: "file";
210
210
  }>;
211
211
  name: z.ZodOptional<z.ZodString>;
212
212
  file: z.ZodOptional<z.ZodObject<{
@@ -611,8 +611,8 @@ export declare const knowledgeBaseRetrievePageSchema: z.ZodObject<{
611
611
  archived: z.ZodBoolean;
612
612
  icon: z.ZodNullable<z.ZodUnion<[z.ZodObject<{
613
613
  type: z.ZodEnum<{
614
- file: "file";
615
614
  external: "external";
615
+ file: "file";
616
616
  }>;
617
617
  name: z.ZodOptional<z.ZodString>;
618
618
  file: z.ZodOptional<z.ZodObject<{
@@ -1123,8 +1123,8 @@ export declare const knowledgeBaseQueryDatabaseSchema: z.ZodObject<{
1123
1123
  archived: z.ZodBoolean;
1124
1124
  icon: z.ZodNullable<z.ZodUnion<[z.ZodObject<{
1125
1125
  type: z.ZodEnum<{
1126
- file: "file";
1127
1126
  external: "external";
1127
+ file: "file";
1128
1128
  }>;
1129
1129
  name: z.ZodOptional<z.ZodString>;
1130
1130
  file: z.ZodOptional<z.ZodObject<{
@@ -58,8 +58,8 @@ export declare const notionPagePropertyEmailSchema: ZodObject<{
58
58
  export declare const notionPagePropertyFilesSchema: ZodObject<{
59
59
  files: z.ZodArray<ZodObject<{
60
60
  type: z.ZodEnum<{
61
- file: "file";
62
61
  external: "external";
62
+ file: "file";
63
63
  }>;
64
64
  name: z.ZodOptional<z.ZodString>;
65
65
  file: z.ZodOptional<ZodObject<{
@@ -536,8 +536,8 @@ export declare const notionPageSchema: <T extends ZodObject<any>>(properties: T)
536
536
  archived: z.ZodBoolean;
537
537
  icon: z.ZodNullable<z.ZodUnion<[ZodObject<{
538
538
  type: z.ZodEnum<{
539
- file: "file";
540
539
  external: "external";
540
+ file: "file";
541
541
  }>;
542
542
  name: z.ZodOptional<z.ZodString>;
543
543
  file: z.ZodOptional<ZodObject<{
@@ -581,8 +581,8 @@ export declare const notionPagesSchema: <T extends ZodObject<any>>(properties: T
581
581
  archived: z.ZodBoolean;
582
582
  icon: z.ZodNullable<z.ZodUnion<[ZodObject<{
583
583
  type: z.ZodEnum<{
584
- file: "file";
585
584
  external: "external";
585
+ file: "file";
586
586
  }>;
587
587
  name: z.ZodOptional<z.ZodString>;
588
588
  file: z.ZodOptional<ZodObject<{
@@ -1,6 +1,6 @@
1
1
  import { config } from '@driveflux/config/backend';
2
2
  import { loadCoupon, PROBLEM_APPLICABLE_NOT_FOUND } from '@driveflux/coupon';
3
- import { prisma } from '@driveflux/db';
3
+ import { prisma, } from '@driveflux/db';
4
4
  import { generateId } from '@driveflux/db/id';
5
5
  import { EMPTY_BILLING_ADDRESS } from '@driveflux/db/models/other';
6
6
  import { PURPOSE_RESERVATION } from '@driveflux/db/models/subscription';
@@ -14,15 +14,16 @@ import { isAfter } from 'date-fns/isAfter';
14
14
  import { subMinutes } from 'date-fns/subMinutes';
15
15
  import { createScopedLogger } from '../create-logger.js';
16
16
  const log = createScopedLogger('reservation:invoice');
17
- export const updateReservationInvoiceIfNeeded = async (oldReservationInvoice, newParams)=>{
17
+ export const updateReservationInvoiceIfNeeded = async (oldReservationInvoice, newParams) => {
18
18
  const couponIsDifferent = oldReservationInvoice.couponCode !== newParams.couponCode;
19
- if (!couponIsDifferent && oldReservationInvoice.stripePaymentIntentId === newParams.paymentIntentId) {
19
+ if (!couponIsDifferent &&
20
+ oldReservationInvoice.stripePaymentIntentId === newParams.paymentIntentId) {
20
21
  return new Ok(oldReservationInvoice);
21
22
  }
22
23
  // If the coupon or payment intent are differnt we should update the invoice
23
24
  let update = {
24
25
  stripePaymentIntentId: newParams.paymentIntentId,
25
- couponCode: newParams.couponCode
26
+ couponCode: newParams.couponCode,
26
27
  };
27
28
  // If the coupon is different, we need to apply the coupon to the invoice
28
29
  if (couponIsDifferent) {
@@ -30,56 +31,63 @@ export const updateReservationInvoiceIfNeeded = async (oldReservationInvoice, ne
30
31
  const result = await coupons.applyCouponToUnsavedInvoice(newParams.couponCode, oldReservationInvoice);
31
32
  if (result.ok) {
32
33
  const { discounts, ...rest } = result.val;
33
- const toDisconnect = discounts ? oldReservationInvoice.discountIds?.filter((id)=>!discounts.connect?.some((d)=>d.id === id)) : undefined;
34
- const disconnectClauses = toDisconnect?.length ? {
35
- disconnect: toDisconnect.map((id)=>({
36
- id
37
- }))
38
- } : undefined;
34
+ const toDisconnect = discounts
35
+ ? oldReservationInvoice.discountIds?.filter((id) => !discounts.connect?.some((d) => d.id === id))
36
+ : undefined;
37
+ const disconnectClauses = toDisconnect?.length
38
+ ? {
39
+ disconnect: toDisconnect.map((id) => ({ id })),
40
+ }
41
+ : undefined;
39
42
  update = {
40
43
  ...update,
41
44
  ...rest,
42
- ...discounts || disconnectClauses ? {
43
- discounts: {
44
- ...discounts || {},
45
- ...disconnectClauses || {}
45
+ ...(discounts || disconnectClauses
46
+ ? {
47
+ discounts: {
48
+ ...(discounts || {}),
49
+ ...(disconnectClauses || {}),
50
+ },
46
51
  }
47
- } : {},
52
+ : {}),
48
53
  metadata: {
49
54
  ...update.metadata,
50
- couponCode: newParams.couponCode
55
+ couponCode: newParams.couponCode,
51
56
  },
52
57
  providerMetadata: {
53
58
  ...update.providerMetadata,
54
- couponCode: newParams.couponCode
55
- }
59
+ couponCode: newParams.couponCode,
60
+ },
56
61
  };
57
62
  }
58
63
  if (result.err && result.val.code !== PROBLEM_APPLICABLE_NOT_FOUND) {
59
64
  return result;
60
65
  }
61
- } else if (oldReservationInvoice.discountIds.length) {
66
+ }
67
+ else if (oldReservationInvoice.discountIds.length) {
62
68
  // No discounts, so we disconnect all of them
63
69
  update = {
64
70
  discounts: {
65
- disconnect: oldReservationInvoice.discountIds.map((id)=>({
66
- id
67
- }))
68
- }
71
+ disconnect: oldReservationInvoice.discountIds.map((id) => ({
72
+ id,
73
+ })),
74
+ },
69
75
  };
70
76
  }
71
77
  }
72
78
  let updated = await wrapInResult(biller.updateInvoice(oldReservationInvoice.id, update));
73
79
  // If the invoice was locked due to pending status and we're more than 1 minute old, we unlock it
74
80
  if (updated.err && updated.val.code === 'invoice_pending') {
75
- if (oldReservationInvoice.lockedAt && isAfter(oldReservationInvoice.lockedAt, subMinutes(new Date(), 1)) || !oldReservationInvoice.lockedAt) {
81
+ if ((oldReservationInvoice.lockedAt &&
82
+ isAfter(oldReservationInvoice.lockedAt, subMinutes(new Date(), 1))) ||
83
+ !oldReservationInvoice.lockedAt) {
76
84
  updated = await wrapInResult(biller.updateInvoice(oldReservationInvoice.id, {
77
85
  ...update,
78
86
  locked: false,
79
87
  lockedAt: null,
80
88
  lockReason: null,
81
89
  unlockAt: null,
82
- status: 'draft'
90
+ status: 'draft',
83
91
  }));
84
92
  }
85
93
  }
@@ -88,7 +96,7 @@ export const updateReservationInvoiceIfNeeded = async (oldReservationInvoice, ne
88
96
  }
89
97
  return new Ok(updated.val);
90
98
  };
91
- export const createReservationInvoice = async ({ invoiceId, couponCode, plan, mileagePackage, referralCode, reservationId, paymentIntentId, freeReservation, freeReservationReason, analytics, vehicle, payer, subscribingUser })=>{
99
+ export const createReservationInvoice = async ({ invoiceId, couponCode, plan, mileagePackage, referralCode, reservationId, paymentIntentId, freeReservation, freeReservationReason, analytics, vehicle, payer, subscribingUser, }) => {
92
100
  if (freeReservation) {
93
101
  // It's a free reservation, so we don't need to add a coupon code
94
102
  return await wrapInResult(biller.createInvoice(getInvoiceCreateDetails({
@@ -101,17 +109,21 @@ export const createReservationInvoice = async ({ invoiceId, couponCode, plan, mi
101
109
  freeReservation,
102
110
  freeReservationReason,
103
111
  analytics,
104
- reservationId
112
+ reservationId,
105
113
  })));
106
114
  }
107
115
  let finalCouponCode = couponCode;
108
116
  // If we don't have a reservation coupon ID, we apply the referral discount if any
109
- const referral = referralCode && await prisma.referral.findUnique({
110
- where: {
111
- id: referralCode
112
- }
113
- });
114
- if (!finalCouponCode && referral && referral.discountToReceiverCouponId && referral.discountToReceiverCouponApplicationName === 'reservationFee') {
117
+ const referral = referralCode &&
118
+ (await prisma.referral.findUnique({
119
+ where: {
120
+ id: referralCode,
121
+ },
122
+ }));
123
+ if (!finalCouponCode &&
124
+ referral &&
125
+ referral.discountToReceiverCouponId &&
126
+ referral.discountToReceiverCouponApplicationName === 'reservationFee') {
115
127
  const referralCoupon = await loadCoupon(referral.discountToReceiverCouponId);
116
128
  if (referralCoupon) {
117
129
  finalCouponCode = referralCoupon.code;
@@ -130,20 +142,18 @@ export const createReservationInvoice = async ({ invoiceId, couponCode, plan, mi
130
142
  freeReservation,
131
143
  freeReservationReason,
132
144
  analytics,
133
- reservationId
145
+ reservationId,
134
146
  }),
135
147
  lines: [
136
148
  {
137
149
  amount: reservationAmount,
138
150
  description: `Reservation fee for ${vehicleName(vehicle)}`,
139
- chargingFor: 'reservationFee'
140
- }
141
- ]
151
+ chargingFor: 'reservationFee',
152
+ },
153
+ ],
142
154
  };
143
155
  if (finalCouponCode) {
144
- log.debug({
145
- finalCouponCode
146
- }, 'Applying coupon code to invoice');
156
+ log.debug({ finalCouponCode }, 'Applying coupon code to invoice');
147
157
  const withCoupon = await coupons.applyCouponToUnsavedInvoice(finalCouponCode, invoiceCreateDetails, 'reservationFee', {
148
158
  subscriptionPlans: plan,
149
159
  subscriptionMileagePackages: mileagePackage,
@@ -151,25 +161,24 @@ export const createReservationInvoice = async ({ invoiceId, couponCode, plan, mi
151
161
  vehicleMake: vehicle.make,
152
162
  userId: subscribingUser.id,
153
163
  businessId: payer.object === 'business' ? payer.id : undefined,
154
- vehicleType: vehicle.type
164
+ vehicleType: vehicle.type,
155
165
  });
156
- if (withCoupon.err && withCoupon.val.code !== PROBLEM_APPLICABLE_NOT_FOUND) {
166
+ if (withCoupon.err &&
167
+ withCoupon.val.code !== PROBLEM_APPLICABLE_NOT_FOUND) {
157
168
  return withCoupon;
158
169
  }
159
- log.debug({
160
- couponUpdates: withCoupon.val
161
- }, 'Coupon applied to invoice');
170
+ log.debug({ couponUpdates: withCoupon.val }, 'Coupon applied to invoice');
162
171
  if (withCoupon.ok) {
163
172
  invoiceCreateDetails = {
164
173
  ...withCoupon.val,
165
174
  metadata: {
166
175
  ...withCoupon.val.metadata,
167
- couponCode: finalCouponCode
176
+ couponCode: finalCouponCode,
168
177
  },
169
178
  providerMetadata: {
170
179
  ...withCoupon.val.providerMetadata,
171
- couponCode: finalCouponCode
172
- }
180
+ couponCode: finalCouponCode,
181
+ },
173
182
  };
174
183
  }
175
184
  }
@@ -177,15 +186,15 @@ export const createReservationInvoice = async ({ invoiceId, couponCode, plan, mi
177
186
  ...invoiceCreateDetails,
178
187
  providerMetadata: {
179
188
  ...invoiceCreateDetails.providerMetadata,
180
- invoiceId: invoiceCreateDetails.id
181
- }
189
+ invoiceId: invoiceCreateDetails.id,
190
+ },
182
191
  }));
183
192
  if (result.err) {
184
193
  return result;
185
194
  }
186
195
  return new Ok(result.val);
187
196
  };
188
- const getInvoiceCreateDetails = ({ invoiceId, payer, date, reservationDiscountId, vehicle, plan, mileagePackage, couponCode, paymentIntentId, freeReservation, freeReservationReason, analytics, reservationId })=>{
197
+ const getInvoiceCreateDetails = ({ invoiceId, payer, date, reservationDiscountId, vehicle, plan, mileagePackage, couponCode, paymentIntentId, freeReservation, freeReservationReason, analytics, reservationId, }) => {
189
198
  return {
190
199
  id: invoiceId || generateId('Invoice'),
191
200
  taxPercentage: 0,
@@ -201,13 +210,15 @@ const getInvoiceCreateDetails = ({ invoiceId, payer, date, reservationDiscountId
201
210
  description: 'Reservation fee for a FLUX subscription',
202
211
  footer: `Invoice for a FLUX subscription reservation. Due by ${format(date ?? new Date())}`,
203
212
  invoiceUrl: `${config.appUrl}/invoice-preview/${invoiceId}`,
204
- ...reservationDiscountId ? {
205
- discounts: {
206
- connect: {
207
- id: reservationDiscountId
208
- }
213
+ ...(reservationDiscountId
214
+ ? {
215
+ discounts: {
216
+ connect: {
217
+ id: reservationDiscountId,
218
+ },
219
+ },
209
220
  }
210
- } : {},
221
+ : {}),
211
222
  lines: [],
212
223
  subscriptionDetails: {
213
224
  vehicleId: vehicle.id,
@@ -216,7 +227,7 @@ const getInvoiceCreateDetails = ({ invoiceId, payer, date, reservationDiscountId
216
227
  variant: vehicle.variant,
217
228
  year: vehicle.year,
218
229
  plan: plan,
219
- mileagePackage: mileagePackage
230
+ mileagePackage: mileagePackage,
220
231
  },
221
232
  // Legacy field:
222
233
  stripePaymentIntentId: paymentIntentId,
@@ -226,18 +237,14 @@ const getInvoiceCreateDetails = ({ invoiceId, payer, date, reservationDiscountId
226
237
  mileagePackage,
227
238
  vehicleId: vehicle.id,
228
239
  vehicleName: vehicleName(vehicle),
229
- ...reservationId ? {
230
- reservationId
231
- } : {},
232
- ...couponCode ? {
233
- couponCode
234
- } : {}
240
+ ...(reservationId ? { reservationId } : {}),
241
+ ...(couponCode ? { couponCode } : {}),
235
242
  },
236
243
  autoRetry: {
237
244
  enabled: false,
238
245
  interval: 0,
239
246
  maxAttempts: 0,
240
- attempts: 0
247
+ attempts: 0,
241
248
  },
242
249
  metadata: {
243
250
  purpose: PURPOSE_RESERVATION,
@@ -246,10 +253,11 @@ const getInvoiceCreateDetails = ({ invoiceId, payer, date, reservationDiscountId
246
253
  plan,
247
254
  mileagePackage,
248
255
  couponCode,
249
- ...freeReservation && freeReservationReason ? {
250
- freeReservationReason
251
- } : {},
252
- analytics
253
- }
256
+ ...(freeReservation && freeReservationReason
257
+ ? { freeReservationReason }
258
+ : {}),
259
+ analytics,
260
+ },
254
261
  };
255
262
  };
263
+ //# sourceMappingURL=invoice.js.map
@@ -3,18 +3,20 @@ import { makeProblem, PROBLEM_EXTERNAL } from '@driveflux/problem';
3
3
  import { Err, Ok } from '@driveflux/result';
4
4
  import { createScopedLogger } from '../create-logger.js';
5
5
  const log = createScopedLogger('reservation:payment-intent-sync');
6
- export const ensurePaymentIntentIdIsSynced = async (invoice, paymentIntentId)=>{
6
+ export const ensurePaymentIntentIdIsSynced = async (invoice, paymentIntentId) => {
7
7
  const stripe = biller.getPaymentProvider('stripe').getStripe();
8
8
  try {
9
9
  await stripe.paymentIntents.update(paymentIntentId, {
10
10
  metadata: {
11
11
  ...invoice.providerMetadata,
12
- invoiceId: invoice.id
13
- }
12
+ invoiceId: invoice.id,
13
+ },
14
14
  });
15
15
  return new Ok(true);
16
- } catch (error) {
16
+ }
17
+ catch (error) {
17
18
  log.error(error, 'Error updating payment intent metadata');
18
19
  return new Err(makeProblem(PROBLEM_EXTERNAL, 'Error updating payment intent metadata'));
19
20
  }
20
21
  };
22
+ //# sourceMappingURL=payment-intent-sync.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@driveflux/api-functions",
3
- "version": "1.0.43",
3
+ "version": "1.0.45",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./notion": {
@@ -73,14 +73,14 @@
73
73
  ],
74
74
  "dependencies": {
75
75
  "@casl/ability": "^6.7.3",
76
- "@driveflux/auth": "4.0.33",
76
+ "@driveflux/auth": "4.0.34",
77
77
  "@driveflux/billing": "8.0.3",
78
78
  "@driveflux/config": "3.0.3",
79
79
  "@driveflux/coupon": "9.0.3",
80
80
  "@driveflux/db": "4.0.3",
81
81
  "@driveflux/email": "7.0.3",
82
82
  "@driveflux/email-templates": "1.0.3",
83
- "@driveflux/engine": "1.0.7",
83
+ "@driveflux/engine": "1.0.9",
84
84
  "@driveflux/fetch": "8.0.0",
85
85
  "@driveflux/format-money": "7.0.0",
86
86
  "@driveflux/problem": "6.0.0",